diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2020-02-22 18:29:07 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2020-02-22 18:29:07 +0100 |
| commit | 943033bc921bb328bbc354f15627dbf4bd6ab1e4 (patch) | |
| tree | b0ccb557b745fa778ef876d72647cc1c9de86e5e | |
| parent | 89a9db0dfee60421a5d1a6093af0e554c6cf6be6 (diff) | |
| download | newtype-943033bc921bb328bbc354f15627dbf4bd6ab1e4.tar.xz newtype-943033bc921bb328bbc354f15627dbf4bd6ab1e4.zip | |
new_type: fix enablement of begin
| -rw-r--r-- | include/newtype/impl/type_traits_extensions.hpp | 23 | ||||
| -rw-r--r-- | include/newtype/new_type.hpp | 25 | ||||
| -rw-r--r-- | 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 <cstddef> #include <functional> #include <iosfwd> -#include <iterator> #include <type_traits> namespace nt::impl @@ -1055,26 +1054,6 @@ namespace nt::impl inline namespace iterable { template<typename T, typename = void> - struct has_std_begin : std::false_type - { - }; - - template<typename T> - struct has_std_begin<T, std::void_t<decltype(std::begin(std::declval<T &>()))>> - : std::is_same<typename T::iterator, std::remove_cvref_t<decltype(std::begin(std::declval<T &>()))>> - { - }; - - template<typename T> - struct has_std_begin<T const, std::void_t<decltype(std::begin(std::declval<T const &>()))>> - : std::is_same<typename T::const_iterator, std::remove_cvref_t<decltype(std::begin(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_std_begin_v = has_std_begin<T>::value; - - template<typename T, typename = void> struct has_free_begin : std::false_type { }; @@ -1115,7 +1094,7 @@ namespace nt::impl auto constexpr has_member_begin_v = has_member_begin<T>::value; template<typename T> - struct has_begin : std::disjunction<has_std_begin<T>, has_free_begin<T>, has_member_begin<T>> + struct has_begin : std::disjunction<has_free_begin<T>, has_member_begin<T>> { }; 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 <functional> #include <istream> -#include <iterator> #include <ostream> #include <type_traits> @@ -62,6 +61,16 @@ namespace nt -> std::enable_if_t<DerivationClauseV(nt::Arithmetic) && impl::is_divide_assignable_v<BaseTypeT>, new_type<BaseTypeT, TagTypeT, DerivationClauseV> &>; + template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> + auto constexpr friend begin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) + -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_begin_v<BaseTypeT>, + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::iterator>; + + template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> + auto constexpr friend begin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) + -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_begin_v<BaseTypeT>, + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator>; + using super = impl::new_type_move_assignment<BaseType, TagType>; public: @@ -448,21 +457,23 @@ namespace nt /** * Get an iterator to the beginning of the object contained by an instance of new_type */ - template<typename BaseType, typename TagType, auto DerivationClause, typename NewType = new_type<BaseType, TagType, DerivationClause>> + template<typename BaseType, typename TagType, auto DerivationClause> auto constexpr begin(new_type<BaseType, TagType, DerivationClause> & obj) - -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_begin_v<BaseType>, typename NewType::iterator> + -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_begin_v<BaseType>, + typename new_type<BaseType, TagType, DerivationClause>::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<typename BaseType, typename TagType, auto DerivationClause, typename NewType = new_type<BaseType, TagType, DerivationClause>> + template<typename BaseType, typename TagType, auto DerivationClause> auto constexpr begin(new_type<BaseType, TagType, DerivationClause> const & obj) - -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_begin_v<BaseType const>, typename NewType::const_iterator> + -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_begin_v<BaseType const>, + typename new_type<BaseType, TagType, DerivationClause>::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<std::array<int, 3>>); - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; + 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>); } 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<std::array<int const, 3>>); - using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>; + 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>); } + 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<with_member>); + 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_an_iterable_type_without_constant_free_begin_deriving_iterable_has_no_constant_free_begin() -> 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>); + } + } // namespace begin_tests auto iterable_suite() -> std::pair<cute::suite, std::string> @@ -56,6 +79,8 @@ auto iterable_suite() -> std::pair<cute::suite, std::string> 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 |
