diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2023-06-09 11:10:52 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2023-06-09 11:10:52 +0200 |
| commit | e42a927fbb40bab04a1398695efffccf8f284cdc (patch) | |
| tree | 82d587d1606df5d36279cae91239c5e0c6cdeeb8 | |
| parent | bc83f6dd1330b6b9cb39c8600242d17ff964de36 (diff) | |
| download | newtype-e42a927fbb40bab04a1398695efffccf8f284cdc.tar.xz newtype-e42a927fbb40bab04a1398695efffccf8f284cdc.zip | |
concepts: replace iterator traits
| -rw-r--r-- | source/lib/include/newtype/concepts.hpp | 232 | ||||
| -rw-r--r-- | source/lib/include/newtype/derivation_clause.hpp | 7 | ||||
| -rw-r--r-- | source/lib/include/newtype/impl/type_traits_extensions.hpp | 360 | ||||
| -rw-r--r-- | source/lib/include/newtype/newtype.hpp | 226 | ||||
| -rw-r--r-- | source/tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | source/tests/src/iterable.cpp | 576 |
6 files changed, 620 insertions, 782 deletions
diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index 42713f5..fc625ed 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -204,6 +204,238 @@ namespace nt::concepts } // namespace iostreamable + inline namespace iterable + { + + template<typename SubjectType> + concept free_begin = requires(SubjectType & subject) { + typename SubjectType::iterator; + { + begin(subject) + } -> std::same_as<typename SubjectType::iterator>; + }; + + template<typename SubjectType> + concept const_free_begin = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + begin(subject) + } -> std::same_as<typename SubjectType::const_iterator>; + }; + + template<typename SubjectType> + concept member_begin = requires(SubjectType & subject) { + typename SubjectType::iterator; + { + subject.begin() + } -> std::same_as<typename SubjectType::iterator>; + }; + + template<typename SubjectType> + concept const_member_begin = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + subject.begin() + } -> std::same_as<typename SubjectType::const_iterator>; + }; + + template<typename SubjectType> + concept beginnable = free_begin<SubjectType> || member_begin<SubjectType>; + + template<typename SubjectType> + concept const_beginnable = const_free_begin<SubjectType> || const_member_begin<SubjectType>; + + template<typename SubjectType> + concept free_cbegin = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + cbegin(subject) + } -> std::same_as<typename SubjectType::const_iterator>; + }; + + template<typename SubjectType> + concept member_cbegin = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + subject.cbegin() + } -> std::same_as<typename SubjectType::const_iterator>; + }; + + template<typename SubjectType> + concept cbeginnable = free_cbegin<SubjectType> || member_cbegin<SubjectType>; + + template<typename SubjectType> + concept free_rbegin = requires(SubjectType & subject) { + typename SubjectType::reverse_iterator; + { + rbegin(subject) + } -> std::same_as<typename SubjectType::reverse_iterator>; + }; + + template<typename SubjectType> + concept const_free_rbegin = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + rbegin(subject) + } -> std::same_as<typename SubjectType::const_reverse_iterator>; + }; + + template<typename SubjectType> + concept member_rbegin = requires(SubjectType & subject) { + typename SubjectType::reverse_iterator; + { + subject.rbegin() + } -> std::same_as<typename SubjectType::reverse_iterator>; + }; + + template<typename SubjectType> + concept const_member_rbegin = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + subject.rbegin() + } -> std::same_as<typename SubjectType::const_reverse_iterator>; + }; + + template<typename SubjectType> + concept rbeginnable = free_rbegin<SubjectType> || member_rbegin<SubjectType>; + + template<typename SubjectType> + concept const_rbeginnable = const_free_rbegin<SubjectType> || const_member_rbegin<SubjectType>; + + template<typename SubjectType> + concept free_crbegin = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + crbegin(subject) + } -> std::same_as<typename SubjectType::const_reverse_iterator>; + }; + + template<typename SubjectType> + concept member_crbegin = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + subject.crbegin() + } -> std::same_as<typename SubjectType::const_reverse_iterator>; + }; + + template<typename SubjectType> + concept crbeginnable = free_crbegin<SubjectType> || member_crbegin<SubjectType>; + + template<typename SubjectType> + concept free_end = requires(SubjectType & subject) { + typename SubjectType::iterator; + { + end(subject) + } -> std::same_as<typename SubjectType::iterator>; + }; + + template<typename SubjectType> + concept const_free_end = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + end(subject) + } -> std::same_as<typename SubjectType::const_iterator>; + }; + + template<typename SubjectType> + concept member_end = requires(SubjectType & subject) { + typename SubjectType::iterator; + { + subject.end() + } -> std::same_as<typename SubjectType::iterator>; + }; + + template<typename SubjectType> + concept const_member_end = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + subject.end() + } -> std::same_as<typename SubjectType::const_iterator>; + }; + + template<typename SubjectType> + concept endable = free_end<SubjectType> || member_end<SubjectType>; + + template<typename SubjectType> + concept const_endable = const_free_end<SubjectType> || const_member_end<SubjectType>; + + template<typename SubjectType> + concept free_cend = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + cend(subject) + } -> std::same_as<typename SubjectType::const_iterator>; + }; + + template<typename SubjectType> + concept member_cend = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + subject.cend() + } -> std::same_as<typename SubjectType::const_iterator>; + }; + + template<typename SubjectType> + concept cendable = free_cend<SubjectType> || member_cend<SubjectType>; + + template<typename SubjectType> + concept free_rend = requires(SubjectType & subject) { + typename SubjectType::reverse_iterator; + { + rend(subject) + } -> std::same_as<typename SubjectType::reverse_iterator>; + }; + + template<typename SubjectType> + concept const_free_rend = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + rend(subject) + } -> std::same_as<typename SubjectType::const_reverse_iterator>; + }; + + template<typename SubjectType> + concept member_rend = requires(SubjectType & subject) { + typename SubjectType::reverse_iterator; + { + subject.rend() + } -> std::same_as<typename SubjectType::reverse_iterator>; + }; + + template<typename SubjectType> + concept const_member_rend = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + subject.rend() + } -> std::same_as<typename SubjectType::const_reverse_iterator>; + }; + + template<typename SubjectType> + concept rendable = free_rend<SubjectType> || member_rend<SubjectType>; + + template<typename SubjectType> + concept const_rendable = const_free_rend<SubjectType> || const_member_rend<SubjectType>; + + template<typename SubjectType> + concept free_crend = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + crend(subject) + } -> std::same_as<typename SubjectType::const_reverse_iterator>; + }; + + template<typename SubjectType> + concept member_crend = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + subject.crend() + } -> std::same_as<typename SubjectType::const_reverse_iterator>; + }; + + template<typename SubjectType> + concept crendable = free_crend<SubjectType> || member_crend<SubjectType>; + } // namespace iterable + inline namespace standard_extensions { diff --git a/source/lib/include/newtype/derivation_clause.hpp b/source/lib/include/newtype/derivation_clause.hpp index c4aa051..eb3e8f1 100644 --- a/source/lib/include/newtype/derivation_clause.hpp +++ b/source/lib/include/newtype/derivation_clause.hpp @@ -12,6 +12,9 @@ namespace nt template<typename... DerivableTags> struct derivation_clause { + template<auto... Needles> + using contains = std::disjunction<std::is_same<DerivableTags, typename decltype(Needles)::tag_type>...>; + constexpr derivation_clause(derivable<DerivableTags>...) noexcept { } @@ -65,8 +68,8 @@ namespace nt } }; - template<typename DerivationClause, auto Feature> - concept contains = requires(DerivationClause clause) { requires clause(Feature); }; + template<typename DerivationClause, auto... Features> + concept contains = requires(DerivationClause clause) { requires DerivationClause::template contains<Features...>::value; }; } // namespace nt diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp index 3bf2c8d..dd25905 100644 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -124,366 +124,6 @@ namespace nt::impl } // namespace compound_arithmetic - inline namespace iterable_begin - { - template<typename T, typename = void> - struct has_free_begin : std::false_type - { - }; - - template<typename T> - struct has_free_begin<T, std::void_t<decltype(begin(std::declval<T &>()))>> - : std::is_same<typename T::iterator, std::remove_cvref_t<decltype(begin(std::declval<T &>()))>> - { - }; - - template<typename T> - struct has_free_begin<T const, std::void_t<decltype(begin(std::declval<T const &>()))>> - : std::is_same<typename T::const_iterator, std::remove_cvref_t<decltype(begin(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_free_begin_v = has_free_begin<T>::value; - - template<typename T, typename = void> - struct has_member_begin : std::false_type - { - }; - - template<typename T> - struct has_member_begin<T, std::void_t<decltype(std::declval<T &>().begin())>> - : std::is_same<typename T::iterator, std::remove_cvref_t<decltype(std::declval<T &>().begin())>> - { - }; - - template<typename T> - struct has_member_begin<T const, std::void_t<decltype(std::declval<T const &>().begin())>> - : std::is_same<typename T::const_iterator, std::remove_cvref_t<decltype(std::declval<T const &>().begin())>> - { - }; - - template<typename T> - auto constexpr has_member_begin_v = has_member_begin<T>::value; - - template<typename T> - struct has_begin : std::disjunction<has_free_begin<T>, has_member_begin<T>> - { - }; - - template<typename T> - auto constexpr has_begin_v = has_begin<T>::value; - } // namespace iterable_begin - - inline namespace iterable_cbegin - { - template<typename T, typename = void> - struct has_free_cbegin : std::false_type - { - }; - - template<typename T> - struct has_free_cbegin<T, std::void_t<decltype(cbegin(std::declval<T const &>()))>> - : std::is_same<typename T::const_iterator, std::remove_cvref_t<decltype(cbegin(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_free_cbegin_v = has_free_cbegin<T>::value; - - template<typename T, typename = void> - struct has_member_cbegin : std::false_type - { - }; - - template<typename T> - struct has_member_cbegin<T, std::void_t<decltype(std::declval<T const &>().cbegin())>> - : std::is_same<typename T::const_iterator, decltype(std::declval<T const &>().cbegin())> - { - }; - - template<typename T> - auto constexpr has_member_cbegin_v = has_member_cbegin<T>::value; - - template<typename T> - struct has_cbegin : std::disjunction<has_free_cbegin<T>, has_member_cbegin<T>> - { - }; - - template<typename T> - auto constexpr has_cbegin_v = has_cbegin<T>::value; - } // namespace iterable_cbegin - - inline namespace iterable_rbegin - { - template<typename T, typename = void> - struct has_free_rbegin : std::false_type - { - }; - - 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(rbegin(std::declval<T &>()))>> - { - }; - - template<typename T> - struct has_free_rbegin<T const, std::void_t<decltype(rbegin(std::declval<T const &>()))>> - : std::is_same<typename T::const_reverse_iterator, std::remove_cvref_t<decltype(rbegin(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_free_rbegin_v = has_free_rbegin<T>::value; - - template<typename T, typename = void> - struct has_member_rbegin : std::false_type - { - }; - - template<typename T> - struct has_member_rbegin<T, std::void_t<decltype(std::declval<T &>().rbegin())>> - : std::is_same<typename T::reverse_iterator, std::remove_cvref_t<decltype(std::declval<T &>().rbegin())>> - { - }; - - template<typename T> - struct has_member_rbegin<T const, std::void_t<decltype(std::declval<T const &>().rbegin())>> - : std::is_same<typename T::const_reverse_iterator, std::remove_cvref_t<decltype(std::declval<T const &>().rbegin())>> - { - }; - - template<typename T> - auto constexpr has_member_rbegin_v = has_member_rbegin<T>::value; - - template<typename T> - struct has_rbegin : std::disjunction<has_free_rbegin<T>, has_member_rbegin<T>> - { - }; - - template<typename T> - auto constexpr has_rbegin_v = has_rbegin<T>::value; - } // namespace iterable_rbegin - - inline namespace iterable_crbegin - { - template<typename T, typename = void> - struct has_free_crbegin : std::false_type - { - }; - - template<typename T> - struct has_free_crbegin<T, std::void_t<decltype(crbegin(std::declval<T const &>()))>> - : std::is_same<typename T::const_reverse_iterator, std::remove_cvref_t<decltype(crbegin(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_free_crbegin_v = has_free_crbegin<T>::value; - - template<typename T, typename = void> - struct has_member_crbegin : std::false_type - { - }; - - template<typename T> - struct has_member_crbegin<T, std::void_t<decltype(std::declval<T const &>().crbegin())>> - : std::is_same<typename T::const_reverse_iterator, std::remove_cvref_t<decltype(std::declval<T const &>().crbegin())>> - { - }; - - template<typename T> - auto constexpr has_member_crbegin_v = has_member_crbegin<T>::value; - - template<typename T> - struct has_crbegin : std::disjunction<has_free_crbegin<T>, has_member_crbegin<T>> - { - }; - - template<typename T> - auto constexpr has_crbegin_v = has_crbegin<T>::value; - } // namespace iterable_crbegin - - inline namespace iterable_end - { - template<typename T, typename = void> - struct has_free_end : std::false_type - { - }; - - template<typename T> - struct has_free_end<T, std::void_t<decltype(end(std::declval<T &>()))>> - : std::is_same<typename T::iterator, std::remove_cvref_t<decltype(end(std::declval<T &>()))>> - { - }; - - template<typename T> - struct has_free_end<T const, std::void_t<decltype(end(std::declval<T const &>()))>> - : std::is_same<typename T::const_iterator, std::remove_cvref_t<decltype(end(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_free_end_v = has_free_end<T>::value; - - template<typename T, typename = void> - struct has_member_end : std::false_type - { - }; - - template<typename T> - struct has_member_end<T, std::void_t<decltype(std::declval<T &>().end())>> - : std::is_same<typename T::iterator, std::remove_cvref_t<decltype(std::declval<T &>().end())>> - { - }; - - template<typename T> - struct has_member_end<T const, std::void_t<decltype(std::declval<T const &>().end())>> - : std::is_same<typename T::const_iterator, std::remove_cvref_t<decltype(std::declval<T const &>().end())>> - { - }; - - template<typename T> - auto constexpr has_member_end_v = has_member_end<T>::value; - - template<typename T> - struct has_end : std::disjunction<has_free_end<T>, has_member_end<T>> - { - }; - - template<typename T> - auto constexpr has_end_v = has_end<T>::value; - } // namespace iterable_end - - inline namespace iterable_cend - { - template<typename T, typename = void> - struct has_free_cend : std::false_type - { - }; - - template<typename T> - struct has_free_cend<T, std::void_t<decltype(cend(std::declval<T const &>()))>> - : std::is_same<typename T::const_iterator, std::remove_cvref_t<decltype(cend(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_free_cend_v = has_free_cend<T>::value; - - template<typename T, typename = void> - struct has_member_cend : std::false_type - { - }; - - template<typename T> - struct has_member_cend<T, std::void_t<decltype(std::declval<T const &>().cend())>> - : std::is_same<typename T::const_iterator, decltype(std::declval<T const &>().cend())> - { - }; - - template<typename T> - auto constexpr has_member_cend_v = has_member_cend<T>::value; - - template<typename T> - struct has_cend : std::disjunction<has_free_cend<T>, has_member_cend<T>> - { - }; - - template<typename T> - auto constexpr has_cend_v = has_cend<T>::value; - } // namespace iterable_cend - - inline namespace iterable_rend - { - template<typename T, typename = void> - struct has_free_rend : std::false_type - { - }; - - 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(rend(std::declval<T &>()))>> - { - }; - - template<typename T> - struct has_free_rend<T const, std::void_t<decltype(rend(std::declval<T const &>()))>> - : std::is_same<typename T::const_reverse_iterator, std::remove_cvref_t<decltype(rend(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_free_rend_v = has_free_rend<T>::value; - - template<typename T, typename = void> - struct has_member_rend : std::false_type - { - }; - - template<typename T> - struct has_member_rend<T, std::void_t<decltype(std::declval<T &>().rend())>> - : std::is_same<typename T::reverse_iterator, std::remove_cvref_t<decltype(std::declval<T &>().rend())>> - { - }; - - template<typename T> - struct has_member_rend<T const, std::void_t<decltype(std::declval<T const &>().rend())>> - : std::is_same<typename T::const_reverse_iterator, std::remove_cvref_t<decltype(std::declval<T const &>().rend())>> - { - }; - - template<typename T> - auto constexpr has_member_rend_v = has_member_rend<T>::value; - - template<typename T> - struct has_rend : std::disjunction<has_free_rend<T>, has_member_rend<T>> - { - }; - - template<typename T> - auto constexpr has_rend_v = has_rend<T>::value; - } // namespace iterable_rend - - inline namespace iterable_crend - { - template<typename T, typename = void> - struct has_free_crend : std::false_type - { - }; - - template<typename T> - struct has_free_crend<T, std::void_t<decltype(crend(std::declval<T const &>()))>> - : std::is_same<typename T::const_reverse_iterator, std::remove_cvref_t<decltype(crend(std::declval<T const &>()))>> - { - }; - - template<typename T> - auto constexpr has_free_crend_v = has_free_crend<T>::value; - - template<typename T, typename = void> - struct has_member_crend : std::false_type - { - }; - - template<typename T> - struct has_member_crend<T, std::void_t<decltype(std::declval<T const &>().crend())>> - : std::is_same<typename T::const_reverse_iterator, std::remove_cvref_t<decltype(std::declval<T const &>().crend())>> - { - }; - - template<typename T> - auto constexpr has_member_crend_v = has_member_crend<T>::value; - - template<typename T> - struct has_crend : std::disjunction<has_free_crend<T>, has_member_crend<T>> - { - }; - - template<typename T> - auto constexpr has_crend_v = has_crend<T>::value; - } // namespace iterable_crend - } // namespace nt::impl #endif
\ No newline at end of file diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index 4642122..b5eca97 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -61,65 +61,53 @@ 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<nt::concepts::free_begin BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend begin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) -> + 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 const>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator>; + template<nt::concepts::const_free_begin BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend begin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend cbegin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_cbegin_v<BaseTypeT const>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator>; + template<nt::concepts::free_cbegin BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend cbegin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend rbegin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_rbegin_v<BaseTypeT>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::reverse_iterator>; + template<nt::concepts::free_rbegin BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend rbegin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::reverse_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend rbegin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_rbegin_v<BaseTypeT const>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_reverse_iterator>; + template<nt::concepts::const_free_rbegin BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend rbegin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_reverse_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend crbegin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_crbegin_v<BaseTypeT const>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_reverse_iterator>; + template<nt::concepts::free_crbegin BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend crbegin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_reverse_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend end(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_end_v<BaseTypeT>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::iterator>; + template<nt::concepts::free_end BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend end(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend end(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_end_v<BaseTypeT const>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator>; + template<nt::concepts::const_free_end BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend end(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend cend(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_cend_v<BaseTypeT const>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator>; + template<nt::concepts::free_cend BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend cend(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend rend(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_rend_v<BaseTypeT>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::reverse_iterator>; + template<nt::concepts::free_rend BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend rend(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::reverse_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend rend(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_rend_v<BaseTypeT const>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_reverse_iterator>; + template<nt::concepts::const_free_rend BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend rend(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_reverse_iterator; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> - auto constexpr friend crend(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) - -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_crend_v<BaseTypeT const>, - typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_reverse_iterator>; + template<nt::concepts::free_crend BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> + auto constexpr friend crend(new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & obj) -> + typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_reverse_iterator; using super = impl::new_type_move_assignment<BaseType, TagType>; @@ -168,86 +156,74 @@ namespace nt return std::addressof(this->m_value); } - template<typename NewType = new_type, std::enable_if_t<NewType::derivation_clause(nt::Iterable)> * = nullptr> - auto constexpr begin() - -> std::enable_if_t<NewType::derivation_clause(nt::Iterable) && impl::has_member_begin_v<BaseType>, typename NewType::iterator> + template<nt::concepts::member_begin BaseTypeT = BaseType, nt::contains<nt::Iterable> auto DerivationClauseV = DerivationClause> + auto constexpr begin() -> typename new_type<BaseTypeT, TagType, DerivationClauseV>::iterator { return this->m_value.begin(); } - template<typename NewType = new_type> - auto constexpr begin() const -> std::enable_if_t<NewType::derivation_clause(nt::Iterable) && impl::has_member_begin_v<BaseType const>, - typename NewType::const_iterator> + template<nt::concepts::const_member_begin BaseTypeT = BaseType, nt::contains<nt::Iterable> auto DerivationClauseV = DerivationClause> + auto constexpr begin() const -> typename new_type<BaseTypeT, TagType, DerivationClauseV>::const_iterator { return this->m_value.begin(); } - template<typename NewType = new_type> - auto constexpr cbegin() const -> std::enable_if_t<NewType::derivation_clause(nt::Iterable) && impl::has_member_cbegin_v<BaseType const>, - typename NewType::const_iterator> + template<nt::concepts::member_cbegin BaseTypeT = BaseType, nt::contains<nt::Iterable> auto DerivationClauseV = DerivationClause> + auto constexpr cbegin() const -> typename new_type<BaseTypeT, TagType, DerivationClauseV>::const_iterator { return this->m_value.cbegin(); } - template<typename NewType = new_type, std::enable_if_t<NewType::derivation_clause(nt::Iterable)> * = nullptr> - auto constexpr rbegin() - -> std::enable_if_t<NewType::derivation_clause(nt::Iterable) && impl::has_member_rbegin_v<BaseType>, typename NewType::reverse_iterator> + template<nt::concepts::member_cbegin BaseTypeT = BaseType, nt::contains<nt::Iterable> auto DerivationClauseV = DerivationClause> + auto constexpr rbegin() -> typename new_type<BaseTypeT, TagType, DerivationClauseV>::reverse_iterator { return this->m_value.rbegin(); } - template<typename NewType = new_type> - auto constexpr rbegin() const -> std::enable_if_t<NewType::derivation_clause(nt::Iterable) && impl::has_member_rbegin_v<BaseType const>, - typename NewType::const_reverse_iterator> + template<nt::concepts::member_cbegin BaseTypeT = BaseType, nt::contains<nt::Iterable> auto DerivationClauseV = DerivationClause> + auto constexpr rbegin() const -> typename new_type<BaseTypeT, TagType, DerivationClauseV>::const_reverse_iterator { return this->m_value.rbegin(); } - template<typename NewType = new_type> - auto constexpr crbegin() const -> std::enable_if_t<NewType::derivation_clause(nt::Iterable) && impl::has_member_crbegin_v<BaseType const>, - typename NewType::const_reverse_iterator> + template<nt::concepts::member_crbegin BaseTypeT = BaseType, nt::contains<nt::Iterable> auto DerivationClauseV = DerivationClause> + auto constexpr crbegin() const -> typename new_type<BaseTypeT, TagType, DerivationClauseV>::const_reverse_iterator { return this->m_value.crbegin(); } - template<typename NewType = new_type, std::enable_if_t<NewType::derivation_clause(nt::Iterable)> * = nullptr> - auto constexpr end() - -> std::enable_if_t<NewType::derivation_clause(nt::Iterable) && impl::has_member_end_v<BaseType>, typename NewType::iterator> + template<nt::concepts::member_end BaseTypeT = BaseType, nt::contains<nt::Iterable> auto DerivationClauseV = DerivationClause> + auto constexpr end() -> typename new_type<BaseTypeT, TagType, DerivationClauseV>::iterator { return this->m_value.end(); } - template<typename NewType = new_type> - auto constexpr end() const -> std::enable_if_t<NewType::derivation_clause(nt::Iterable) && impl::has_member_end_v<BaseType const>, - typename NewType::const_iterator> + template<nt::concepts::const_member_end BaseTypeT = BaseType, nt::contains<nt::Iterable> auto DerivationClauseV = DerivationClause> |
