diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2020-02-25 20:57:06 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2020-02-25 20:57:06 +0100 |
| commit | bb58e65e6596a2ffac2e85e9fda1e8568aa9b4b1 (patch) | |
| tree | e02730d64bd32c9b3251bc5d19448f197741ba12 /include | |
| parent | 62ca586910736b5aba6d622ec27a7b00e3c37359 (diff) | |
| download | newtype-bb58e65e6596a2ffac2e85e9fda1e8568aa9b4b1.tar.xz newtype-bb58e65e6596a2ffac2e85e9fda1e8568aa9b4b1.zip | |
new_type: implement cbegin
Diffstat (limited to 'include')
| -rw-r--r-- | include/newtype/impl/type_traits_extensions.hpp | 43 | ||||
| -rw-r--r-- | include/newtype/new_type.hpp | 20 |
2 files changed, 61 insertions, 2 deletions
diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp index 80ba5b0..ee33730 100644 --- a/include/newtype/impl/type_traits_extensions.hpp +++ b/include/newtype/impl/type_traits_extensions.hpp @@ -1051,7 +1051,7 @@ namespace nt::impl } // namespace std_support - inline namespace iterable + inline namespace iterable_begin { template<typename T, typename = void> struct has_free_begin : std::false_type @@ -1100,7 +1100,46 @@ namespace nt::impl template<typename T> auto constexpr has_begin_v = has_begin<T>::value; - } // namespace iterable + } // 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 } // namespace nt::impl diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp index 0db01b2..474ac88 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -71,6 +71,11 @@ namespace nt -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_begin_v<BaseTypeT>, 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>; + using super = impl::new_type_move_assignment<BaseType, TagType>; public: @@ -198,6 +203,13 @@ namespace nt { 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> + { + return this->m_value.cbegin(); + } }; /// Equality Comparison Operators @@ -476,6 +488,14 @@ namespace nt return begin(obj.m_value); } + template<typename BaseType, typename TagType, auto DerivationClause> + auto constexpr cbegin(new_type<BaseType, TagType, DerivationClause> const & obj) + -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_cbegin_v<BaseType const>, + typename new_type<BaseType, TagType, DerivationClause>::const_iterator> + { + return cbegin(obj.m_value); + } + } // namespace nt namespace std |
