diff --git a/source/simple/support/range.hpp b/source/simple/support/range.hpp index 6bc1501f3c3e2824c4acd7091f6dd1098ba2c9fb..074bf0d14fa6de311c6315337f43f81d09068310 100644 --- a/source/simple/support/range.hpp +++ b/source/simple/support/range.hpp @@ -13,10 +13,10 @@ namespace simple::support { template<typename Type, typename = std::nullptr_t> - struct range_based_for_loopable : public std::false_type {}; + struct is_iterable : public std::false_type {}; template<typename Type> - struct range_based_for_loopable<Type, + struct is_iterable<Type, decltype( void(std::declval<Type>() != std::declval<Type>()), void(*std::declval<Type>()), @@ -31,6 +31,9 @@ namespace simple::support array<Type, 2> bounds; + using iterator = std::conditional_t<is_iterable<Type>{}, + Type, void>; + constexpr static range limit() { static_assert(std::numeric_limits<Type>::is_specialized); @@ -47,19 +50,19 @@ namespace simple::support return bounds == other.bounds; } - template <typename T = Type, - std::enable_if_t<range_based_for_loopable<T>{}>...> + template <typename It = Type, + std::enable_if_t<is_iterable<It>{}>...> [[nodiscard]] constexpr Type begin() const { return lower(); } - template <typename T = Type, - std::enable_if_t<range_based_for_loopable<T>{}>...> + template <typename It = Type, + std::enable_if_t<is_iterable<It>{}>...> [[nodiscard]] constexpr Type end() const { return upper(); } - template <typename T = Type, - std::enable_if_t<range_based_for_loopable<T>{}>...> + template <typename It = Type, + std::enable_if_t<is_iterable<It>{}>...> [[nodiscard]] constexpr auto rbegin() const { return std::make_reverse_iterator(upper()); } - template <typename T = Type, - std::enable_if_t<range_based_for_loopable<T>{}>...> + template <typename It = Type, + std::enable_if_t<is_iterable<It>{}>...> [[nodiscard]] constexpr auto rend() const { return std::make_reverse_iterator(lower()); } diff --git a/unit_tests/range.cpp b/unit_tests/range.cpp index 3851611044861690eb192d5ac7440159a6c376ba..e7852aa15aca6c1806a02e9a1d3ed4adee5147b5 100644 --- a/unit_tests/range.cpp +++ b/unit_tests/range.cpp @@ -235,6 +235,12 @@ void Arithmetic() } } +void Iterator() +{ + static_assert(std::is_same_v<int*, range<int*>::iterator>); + static_assert(std::is_same_v<void, range<int>::iterator>); +} + constexpr bool Constexprness() { range<int> v{}; @@ -289,6 +295,7 @@ int main() SubRange(); Limit(); Arithmetic(); + Iterator(); static_assert(Constexprness()); return 0; }