aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/newtype/impl/type_traits_extensions.hpp4
-rw-r--r--test/src/iterable_suite.cpp790
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 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.crend() - 1), *(strong.crend() - 1));
+ auto const nt_object = type_alias{{1, 2, 3}};
+ auto const bt_object = type_alias::base_type{1, 2, 3};
+
+ auto nt_result = std::accumulate(std::cbegin(nt_object), std::cend(nt_object), 0);
+ auto bt_result = std::accumulate(std::cbegin(bt_object), std::cend(bt_object), 0);
+
+ ASSERT_EQUAL(bt_result, nt_result);
}
- auto an_iterator_obtained_via_member_crend_compares_equal_to_an_iterator_obtained_via_free_crend() -> void
+ auto iterating_over_an_iterable_new__type_yields_the_elements_in_the_same_order_as_when_iterating_the_base_type() -> void
{
+ using std::cbegin, std::cend, std::equal;
using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>;
- auto instance = type_alias{{42, 21, 10}};
- ASSERT_EQUAL(crend(instance), instance.crend());
+ auto const nt_object = type_alias{{1, 2, 3}};
+ auto const bt_obj