diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2020-03-01 12:06:23 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2020-03-01 12:06:23 +0100 |
| commit | 081688443d12de12d7b66b44630e4c7e0681fabe (patch) | |
| tree | b733b58441a74f451f5a005664058cfe026373a3 | |
| parent | 943b85617691a9a14472ceac29dc81e38134ef9a (diff) | |
| download | newtype-081688443d12de12d7b66b44630e4c7e0681fabe.tar.xz newtype-081688443d12de12d7b66b44630e4c7e0681fabe.zip | |
new_type: restructure iterable tests
| -rw-r--r-- | include/newtype/impl/type_traits_extensions.hpp | 4 | ||||
| -rw-r--r-- | test/src/iterable_suite.cpp | 790 |
2 files changed, 477 insertions, 317 deletions
diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp index 121e2c0..dc41649 100644 --- a/include/newtype/impl/type_traits_extensions.hpp +++ b/include/newtype/impl/type_traits_extensions.hpp @@ -587,7 +587,7 @@ namespace nt::impl template<typename T> struct has_free_rbegin<T, std::void_t<decltype(rbegin(std::declval<T &>()))>> - : std::is_same<typename T::reverse_iterator, std::remove_cvref_t<decltype(begin(std::declval<T &>()))>> + : std::is_same<typename T::reverse_iterator, std::remove_cvref_t<decltype(rbegin(std::declval<T &>()))>> { }; @@ -767,7 +767,7 @@ namespace nt::impl template<typename T> struct has_free_rend<T, std::void_t<decltype(rend(std::declval<T &>()))>> - : std::is_same<typename T::reverse_iterator, std::remove_cvref_t<decltype(end(std::declval<T &>()))>> + : std::is_same<typename T::reverse_iterator, std::remove_cvref_t<decltype(rend(std::declval<T &>()))>> { }; diff --git a/test/src/iterable_suite.cpp b/test/src/iterable_suite.cpp index a75ab19..3b46024 100644 --- a/test/src/iterable_suite.cpp +++ b/test/src/iterable_suite.cpp @@ -8,18 +8,20 @@ #include <cute/cute.h> +#include <algorithm> #include <array> #include <iterator> +#include <numeric> namespace { struct with_member { - using iterator = void *; - using const_iterator = void const *; - using reverse_iterator = void *; - using const_reverse_iterator = void const *; + using iterator = char *; + using const_iterator = char const *; + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; auto begin() -> iterator; auto begin() const -> const_iterator; @@ -36,9 +38,77 @@ namespace auto crend() const -> const_reverse_iterator; }; + struct with_free + { + using iterator = char *; + using const_iterator = char const *; + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + }; + + auto begin(with_free &) -> with_free::iterator + { + return {}; + } + + auto begin(with_free const &) -> with_free::const_iterator + { + return {}; + } + + auto cbegin(with_free const &) -> with_free::const_iterator + { + return {}; + } + + auto rbegin(with_free &) -> with_free::reverse_iterator + { + return {}; + } + + auto rbegin(with_free const &) -> with_free::const_reverse_iterator + { + return {}; + } + + auto crbegin(with_free const &) -> with_free::const_reverse_iterator + { + return {}; + } + + auto end(with_free &) -> with_free::iterator + { + return {}; + } + + auto end(with_free const &) -> with_free::const_iterator + { + return {}; + } + + auto cend(with_free const &) -> with_free::const_iterator + { + return {}; + } + + auto rend(with_free &) -> with_free::reverse_iterator + { + return {}; + } + + auto rend(with_free const &) -> with_free::const_reverse_iterator + { + return {}; + } + + auto crend(with_free const &) -> with_free::const_reverse_iterator + { + return {}; + } + } // namespace -inline namespace begin_tests +inline namespace combined_enablement_tests { auto a_new__type_not_deriving_iterable_has_no_begin() -> void @@ -47,513 +117,603 @@ inline namespace begin_tests ASSERT(!(nt::impl::has_begin_v<type_alias>)); } - auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_begin() -> void + auto a_new__type_not_deriving_iterable_has_no_constant_begin() -> void { - static_assert(!nt::impl::has_begin_v<int>); - using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; - ASSERT(!(nt::impl::has_begin_v<type_alias>)); + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_begin_v<type_alias const>)); } - auto a_new__type_based_on_an_iterable_type_with_member_begin_deriving_iterable_has_member_begin() -> void + auto a_new__type_not_deriving_iterable_has_no_cbegin() -> void { - static_assert(nt::impl::has_member_begin_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_begin_v<type_alias>); + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_cbegin_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_with_constant_member_begin_deriving_iterable_has_constant_member_begin() -> void + auto a_new__type_not_deriving_iterable_has_no_rbegin() -> void { - static_assert(nt::impl::has_member_begin_v<with_member const>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_begin_v<type_alias const>); + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_rbegin_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_without_free_begin_deriving_iterable_has_no_free_begin() -> void + auto a_new__type_not_deriving_iterable_has_no_constant_rbegin() -> void { - static_assert(!nt::impl::has_free_begin_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_begin_v<type_alias>); + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_rbegin_v<type_alias const>)); } - auto a_new__type_based_on_an_iterable_type_without_constant_free_begin_deriving_iterable_has_no_constant_free_begin() -> void + auto a_new__type_not_deriving_iterable_has_no_crbegin() -> void { - static_assert(!nt::impl::has_free_begin_v<with_member const>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_begin_v<type_alias const>); + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_crbegin_v<type_alias>)); } - auto accessing_the_first_element_of_an_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type() -> void + auto a_new__type_not_deriving_iterable_has_no_end() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto weak = std::array{42, 21, 10}; - auto strong = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(*weak.begin(), *strong.begin()); + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_end_v<type_alias>)); } - auto an_iterator_obtained_via_member_begin_compares_equal_to_an_iterator_obtained_via_free_begin() -> void + auto a_new__type_not_deriving_iterable_has_no_constant_end() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto instance = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(begin(instance), instance.begin()); + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_end_v<type_alias const>)); } -} // namespace begin_tests + auto a_new__type_not_deriving_iterable_has_no_cend() -> void + { + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_cend_v<type_alias>)); + } -inline namespace cbegin_tests -{ + auto a_new__type_not_deriving_iterable_has_no_rend() -> void + { + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_rend_v<type_alias>)); + } - auto a_new__type_not_deriving_iterable_has_no_cbegin() -> void + auto a_new__type_not_deriving_iterable_has_no_constant_rend() -> void { using type_alias = nt::new_type<int, struct tag>; - ASSERT(!(nt::impl::has_cbegin_v<type_alias>)); + ASSERT(!(nt::impl::has_rend_v<type_alias const>)); + } + + auto a_new__type_not_deriving_iterable_has_no_crend() -> void + { + using type_alias = nt::new_type<int, struct tag>; + ASSERT(!(nt::impl::has_crend_v<type_alias>)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_begin() -> void + { + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_begin_v<type_alias>)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_begin() -> void + { + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_begin_v<type_alias const>)); } - auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_cbegin() -> void + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cbegin() -> void { - static_assert(!nt::impl::has_cbegin_v<int>); using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; ASSERT(!(nt::impl::has_cbegin_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_with_member_cbegin_deriving_iterable_has_member_cbegin() -> void + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rbegin() -> void { - static_assert(nt::impl::has_member_cbegin_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_cbegin_v<type_alias>); + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_rbegin_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_without_free_cbegin_deriving_iterable_has_no_free_cbegin() -> void + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rbegin() -> void { - static_assert(!nt::impl::has_free_cbegin_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_cbegin_v<type_alias>); + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_rbegin_v<type_alias const>)); } - auto accessing_the_first_element_of_a_constant_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type() - -> void + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crbegin() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto weak = std::array{42, 21, 10}; - auto strong = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(*weak.cbegin(), *strong.cbegin()); + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_crbegin_v<type_alias>)); } - auto an_iterator_obtained_via_member_cbegin_compares_equal_to_an_iterator_obtained_via_free_cbegin() -> void + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_end() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto instance = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(cbegin(instance), instance.cbegin()); + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_end_v<type_alias>)); } -} // namespace cbegin_tests + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_end() -> void + { + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_end_v<type_alias const>)); + } -inline namespace rbegin_tests -{ + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cend() -> void + { + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_cend_v<type_alias>)); + } - auto a_new__type_not_deriving_iterable_has_no_rbegin() -> void + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rend() -> void { - using type_alias = nt::new_type<int, struct tag>; - ASSERT(!(nt::impl::has_rbegin_v<type_alias>)); + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_rend_v<type_alias>)); } - auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_rbegin() -> void + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rend() -> void { - static_assert(!nt::impl::has_rbegin_v<int>); using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; - ASSERT(!(nt::impl::has_rbegin_v<type_alias>)); + ASSERT(!(nt::impl::has_rend_v<type_alias const>)); } - auto a_new__type_based_on_an_iterable_type_with_member_rbegin_deriving_iterable_has_member_rbegin() -> void + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crend() -> void { - static_assert(nt::impl::has_member_rbegin_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_rbegin_v<type_alias>); + using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_crend_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_with_constant_member_rbegin_deriving_iterable_has_constant_member_rbegin() -> void +} // namespace combined_enablement_tests + +inline namespace member_enablement_tests +{ + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_begin() -> void { - static_assert(nt::impl::has_member_rbegin_v<with_member const>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_rbegin_v<type_alias const>); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_begin_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_without_free_rbegin_deriving_iterable_has_no_free_rbegin() -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_begin() -> void { - static_assert(!nt::impl::has_free_rbegin_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_rbegin_v<type_alias>); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_begin_v<type_alias const>)); } - auto a_new__type_based_on_an_iterable_type_without_constant_free_rbegin_deriving_iterable_has_no_constant_free_rbegin() -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cbegin() -> void { - static_assert(!nt::impl::has_free_rbegin_v<with_member const>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_rbegin_v<type_alias const>); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_cbegin_v<type_alias>)); } - auto accessing_the_first_element_of_a_reverse_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type() - -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rbegin() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto weak = std::array{42, 21, 10}; - auto strong = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(*weak.rbegin(), *strong.rbegin()); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_rbegin_v<type_alias>)); } - auto an_iterator_obtained_via_member_rbegin_compares_equal_to_an_iterator_obtained_via_free_rbegin() -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rbegin() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto instance = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(rbegin(instance), instance.rbegin()); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_rbegin_v<type_alias const>)); } -} // namespace rbegin_tests + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crbegin() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_crbegin_v<type_alias>)); + } -inline namespace crbegin_tests -{ + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_end() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_end_v<type_alias>)); + } - auto a_new__type_not_deriving_iterable_has_no_crbegin() -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_end() -> void { - using type_alias = nt::new_type<int, struct tag>; - ASSERT(!(nt::impl::has_crbegin_v<type_alias>)); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_end_v<type_alias const>)); } - auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_crbegin() -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cend() -> void { - static_assert(!nt::impl::has_crbegin_v<int>); - using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; - ASSERT(!(nt::impl::has_crbegin_v<type_alias>)); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_cend_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_with_member_crbegin_deriving_iterable_has_member_crbegin() -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rend() -> void { - static_assert(nt::impl::has_member_crbegin_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_crbegin_v<type_alias>); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_rend_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_without_free_crbegin_deriving_iterable_has_no_free_crbegin() -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rend() -> void { - static_assert(!nt::impl::has_free_crbegin_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_crbegin_v<type_alias>); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_rend_v<type_alias const>)); } - auto - accessing_the_first_element_of_a_constant_reverse_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type() - -> void + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crend() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto weak = std::array{42, 21, 10}; - auto strong = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(*weak.crbegin(), *strong.crbegin()); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_member_crend_v<type_alias>)); } - auto an_iterator_obtained_via_member_crbegin_compares_equal_to_an_iterator_obtained_via_free_crbegin() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_begin() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto instance = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(crbegin(instance), instance.crbegin()); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_member_begin_v<type_alias>); } -} // namespace crbegin_tests + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_begin() -> void + { + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_member_begin_v<type_alias const>); + } -inline namespace end_tests -{ + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cbegin() -> void + { + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_member_cbegin_v<type_alias>); + } - auto a_new__type_not_deriving_iterable_has_no_end() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rbegin() -> void { - using type_alias = nt::new_type<int, struct tag>; - ASSERT(!(nt::impl::has_end_v<type_alias>)); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_member_rbegin_v<type_alias>); } - auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_end() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rbegin() -> void { - static_assert(!nt::impl::has_end_v<int>); - using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; - ASSERT(!(nt::impl::has_end_v<type_alias>)); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_member_rbegin_v<type_alias const>); } - auto a_new__type_based_on_an_iterable_type_with_member_end_deriving_iterable_has_member_end() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crbegin() -> void + { + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_member_crbegin_v<type_alias>); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_end() -> void { - static_assert(nt::impl::has_member_end_v<with_member>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; ASSERT(nt::impl::has_member_end_v<type_alias>); } - auto a_new__type_based_on_an_iterable_type_with_constant_member_end_deriving_iterable_has_constant_member_end() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_end() -> void { - static_assert(nt::impl::has_member_end_v<with_member const>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; ASSERT(nt::impl::has_member_end_v<type_alias const>); } - auto a_new__type_based_on_an_iterable_type_without_free_end_deriving_iterable_has_no_free_end() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cend() -> void { - static_assert(!nt::impl::has_free_end_v<with_member>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_end_v<type_alias>); + ASSERT(nt::impl::has_member_cend_v<type_alias>); } - auto a_new__type_based_on_an_iterable_type_without_constant_free_end_deriving_iterable_has_no_constant_free_end() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rend() -> void { - static_assert(!nt::impl::has_free_end_v<with_member const>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_end_v<type_alias const>); + ASSERT(nt::impl::has_member_rend_v<type_alias>); } - auto accessing_the_last_element_of_an_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rend() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto weak = std::array{42, 21, 10}; - auto strong = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(*(weak.end() - 1), *(strong.end() - 1)); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_member_rend_v<type_alias const>); } - auto an_iterator_obtained_via_member_end_compares_equal_to_an_iterator_obtained_via_free_end() -> void + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crend() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto instance = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(end(instance), instance.end()); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_member_crend_v<type_alias>); } -} // namespace end_tests +} // namespace member_enablement_tests -inline namespace cend_tests +inline namespace free_enablement_tests { - - auto a_new__type_not_deriving_iterable_has_no_cend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_begin() -> void { - using type_alias = nt::new_type<int, struct tag>; - ASSERT(!(nt::impl::has_cend_v<type_alias>)); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_free_begin_v<type_alias>)); } - auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_cend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_begin() -> void { - static_assert(!nt::impl::has_cend_v<int>); - using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; - ASSERT(!(nt::impl::has_cend_v<type_alias>)); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_free_begin_v<type_alias const>)); } - auto a_new__type_based_on_an_iterable_type_with_member_cend_deriving_iterable_has_member_cend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cbegin() -> void { - static_assert(nt::impl::has_member_cend_v<with_member>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_cend_v<type_alias>); + ASSERT(!(nt::impl::has_free_cbegin_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_without_free_cend_deriving_iterable_has_no_free_cend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rbegin() -> void { - static_assert(!nt::impl::has_free_cend_v<with_member>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_cend_v<type_alias>); + ASSERT(!(nt::impl::has_free_rbegin_v<type_alias>)); } - auto accessing_the_last_element_of_a_constant_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type() - -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rbegin() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto weak = std::array{42, 21, 10}; - auto strong = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(*(weak.cend() - 1), *(strong.cend() - 1)); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_free_rbegin_v<type_alias const>)); } - auto an_iterator_obtained_via_member_cend_compares_equal_to_an_iterator_obtained_via_free_cend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crbegin() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto instance = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(cend(instance), instance.cend()); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_free_crbegin_v<type_alias>)); } -} // namespace cend_tests - -inline namespace rend_tests -{ - - auto a_new__type_not_deriving_iterable_has_no_rend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_end() -> void { - using type_alias = nt::new_type<int, struct tag>; - ASSERT(!(nt::impl::has_rend_v<type_alias>)); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_free_end_v<type_alias>)); } - auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_rend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_end() -> void { - static_assert(!nt::impl::has_rend_v<int>); - using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; - ASSERT(!(nt::impl::has_rend_v<type_alias>)); + using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; + ASSERT(!(nt::impl::has_free_end_v<type_alias const>)); } - auto a_new__type_based_on_an_iterable_type_with_member_rend_deriving_iterable_has_member_rend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cend() -> void { - static_assert(nt::impl::has_member_rend_v<with_member>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_rend_v<type_alias>); + ASSERT(!(nt::impl::has_free_cend_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_with_constant_member_rend_deriving_iterable_has_constant_member_rend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rend() -> void { - static_assert(nt::impl::has_member_rend_v<with_member const>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_rend_v<type_alias const>); + ASSERT(!(nt::impl::has_free_rend_v<type_alias>)); } - auto a_new__type_based_on_an_iterable_type_without_free_rend_deriving_iterable_has_no_free_rend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rend() -> void { - static_assert(!nt::impl::has_free_rend_v<with_member>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_rend_v<type_alias>); + ASSERT(!(nt::impl::has_free_rend_v<type_alias const>)); } - auto a_new__type_based_on_an_iterable_type_without_constant_free_rend_deriving_iterable_has_no_constant_free_rend() -> void + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crend() -> void { - static_assert(!nt::impl::has_free_rend_v<with_member const>); using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_rend_v<type_alias const>); + ASSERT(!(nt::impl::has_free_crend_v<type_alias>)); } - auto accessing_the_last_element_of_a_reverse_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type() -> void + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_begin() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto weak = std::array{42, 21, 10}; - auto strong = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(*(weak.rend() - 1), *(strong.rend() - 1)); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_begin_v<type_alias>); } - auto an_iterator_obtained_via_member_rend_compares_equal_to_an_iterator_obtained_via_free_rend() -> void + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_begin() -> void { - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; - auto instance = type_alias{{42, 21, 10}}; - ASSERT_EQUAL(rend(instance), instance.rend()); + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_begin_v<type_alias const>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cbegin() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_cbegin_v<type_alias>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rbegin() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_rbegin_v<type_alias>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rbegin() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_rbegin_v<type_alias const>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crbegin() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_crbegin_v<type_alias>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_end() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_end_v<type_alias>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_end() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_end_v<type_alias const>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cend() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_cend_v<type_alias>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rend() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_rend_v<type_alias>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rend() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_rend_v<type_alias const>); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crend() -> void + { + using type_alias = nt::new_type<with_free, struct tag, deriving(nt::Iterable)>; + ASSERT(nt::impl::has_free_crend_v<type_alias>); } -} // namespace rend_tests +} // namespace free_enablement_tests -inline namespace crend_tests +inline namespace semantic_tests { - auto a_new__type_not_deriving_iterable_has_no_crend() -> void + auto a_non_const_object_of_iterable_new__type_can_be_used_in_value_range_for() -> void { - using type_alias = nt::new_type<int, struct tag>; - ASSERT(!(nt::impl::has_crend_v<type_alias>)); + using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; + auto object = type_alias{{1, 2, 3}}; + for (auto e : object) + { + (void)e; + } + ASSERT(true); } - auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_crend() -> void + auto a_const_object_of_iterable_new__type_can_be_used_in_value_range_for() -> void { - static_assert(!nt::impl::has_crend_v<int>); - using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>; - ASSERT(!(nt::impl::has_crend_v<type_alias>)); + using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; + auto const object = type_alias{{1, 2, 3}}; + for (auto e : object) + { + (void)e; + } + ASSERT(true); } - auto a_new__type_based_on_an_iterable_type_with_member_crend_deriving_iterable_has_member_crend() -> void + auto a_non_const_object_of_iterable_new__type_can_be_used_in_reference_range_for() -> void { - static_assert(nt::impl::has_member_crend_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(nt::impl::has_member_crend_v<type_alias>); + using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; + auto object = type_alias{{1, 2, 3}}; + for (auto & e : object) + { + (void)e; + } + ASSERT(true); } - auto a_new__type_based_on_an_iterable_type_without_free_crend_deriving_iterable_has_no_free_crend() -> void + auto a_const_object_of_iterable_new__type_can_be_used_in_const_reference_range_for() -> void { - static_assert(!nt::impl::has_free_crend_v<with_member>); - using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>; - ASSERT(!nt::impl::has_free_crend_v<type_alias>); + using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; + auto const object = type_alias{{1, 2, 3}}; + for (auto const & e : object) + { + (void)e; + } + ASSERT(true); } - auto - accessing_the_last_element_of_a_constant_reverse_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type() - -> void + auto applying_accumulate_to_an_interable_new__type_yields_the_same_result_as_when_applied_to_the_base_type() -> void { using typ |
