From 943033bc921bb328bbc354f15627dbf4bd6ab1e4 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 22 Feb 2020 18:29:07 +0100 Subject: new_type: fix enablement of begin --- include/newtype/impl/type_traits_extensions.hpp | 23 +--------------- include/newtype/new_type.hpp | 25 +++++++++++++----- test/src/iterable_suite.cpp | 35 +++++++++++++++++++++---- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp index 7096578..80ba5b0 100644 --- a/include/newtype/impl/type_traits_extensions.hpp +++ b/include/newtype/impl/type_traits_extensions.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include namespace nt::impl @@ -1054,26 +1053,6 @@ namespace nt::impl inline namespace iterable { - template - struct has_std_begin : std::false_type - { - }; - - template - struct has_std_begin()))>> - : std::is_same()))>> - { - }; - - template - struct has_std_begin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_std_begin_v = has_std_begin::value; - template struct has_free_begin : std::false_type { @@ -1115,7 +1094,7 @@ namespace nt::impl auto constexpr has_member_begin_v = has_member_begin::value; template - struct has_begin : std::disjunction, has_free_begin, has_member_begin> + struct has_begin : std::disjunction, has_member_begin> { }; diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp index 0cf6ec3..0db01b2 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -62,6 +61,16 @@ namespace nt -> std::enable_if_t, new_type &>; + template + auto constexpr friend begin(new_type & obj) + -> std::enable_if_t, + typename new_type::iterator>; + + template + auto constexpr friend begin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator>; + using super = impl::new_type_move_assignment; public: @@ -448,21 +457,23 @@ namespace nt /** * Get an iterator to the beginning of the object contained by an instance of new_type */ - template> + template auto constexpr begin(new_type & obj) - -> std::enable_if_t, typename NewType::iterator> + -> std::enable_if_t, + typename new_type::iterator> { - return begin(obj); + return begin(obj.m_value); } /** * Get a constant iterator to the beginning of the object contained by an instance of new_type */ - template> + template auto constexpr begin(new_type const & obj) - -> std::enable_if_t, typename NewType::const_iterator> + -> std::enable_if_t, + typename new_type::const_iterator> { - return begin(obj); + return begin(obj.m_value); } } // namespace nt diff --git a/test/src/iterable_suite.cpp b/test/src/iterable_suite.cpp index 2470571..bf478e1 100644 --- a/test/src/iterable_suite.cpp +++ b/test/src/iterable_suite.cpp @@ -14,7 +14,16 @@ namespace { -} + struct with_member + { + using iterator = void *; + using const_iterator = void const *; + + auto begin() -> iterator; + auto begin() const -> const_iterator; + }; + +} // namespace inline namespace begin_tests { @@ -34,18 +43,32 @@ inline namespace begin_tests auto a_new__type_based_on_an_iterable_type_with_member_begin_deriving_iterable_has_member_begin() -> void { - static_assert(nt::impl::has_member_begin_v>); - using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; + static_assert(nt::impl::has_member_begin_v); + using type_alias = nt::new_type; ASSERT(nt::impl::has_member_begin_v); } auto a_new__type_based_on_an_iterable_type_with_constant_member_begin_deriving_iterable_has_constant_member_begin() -> void { - static_assert(nt::impl::has_member_begin_v>); - using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; + static_assert(nt::impl::has_member_begin_v); + using type_alias = nt::new_type; ASSERT(nt::impl::has_member_begin_v); } + auto a_new__type_based_on_an_iterable_type_without_free_begin_deriving_iterable_has_no_free_begin() -> void + { + static_assert(!nt::impl::has_free_begin_v); + using type_alias = nt::new_type; + ASSERT(!nt::impl::has_free_begin_v); + } + + auto a_new__type_based_on_an_iterable_type_without_constant_free_begin_deriving_iterable_has_no_constant_free_begin() -> void + { + static_assert(!nt::impl::has_free_begin_v); + using type_alias = nt::new_type; + ASSERT(!nt::impl::has_free_begin_v); + } + } // namespace begin_tests auto iterable_suite() -> std::pair @@ -56,6 +79,8 @@ auto iterable_suite() -> std::pair KAWAII(a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_begin), KAWAII(a_new__type_based_on_an_iterable_type_with_member_begin_deriving_iterable_has_member_begin), KAWAII(a_new__type_based_on_an_iterable_type_with_constant_member_begin_deriving_iterable_has_constant_member_begin), + KAWAII(a_new__type_based_on_an_iterable_type_without_free_begin_deriving_iterable_has_no_free_begin), + KAWAII(a_new__type_based_on_an_iterable_type_without_constant_free_begin_deriving_iterable_has_no_constant_free_begin), }, "Iterable Tests"}; } \ No newline at end of file -- cgit v1.2.3