diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/newtype/impl/new_type_iterator_types.hpp | 24 | ||||
| -rw-r--r-- | include/newtype/impl/type_traits_extensions.hpp | 90 | ||||
| -rw-r--r-- | include/newtype/new_type.hpp | 62 |
3 files changed, 175 insertions, 1 deletions
diff --git a/include/newtype/impl/new_type_iterator_types.hpp b/include/newtype/impl/new_type_iterator_types.hpp index 037f08d..2ea8274 100644 --- a/include/newtype/impl/new_type_iterator_types.hpp +++ b/include/newtype/impl/new_type_iterator_types.hpp @@ -30,10 +30,34 @@ namespace nt::impl using const_iterator = typename T::const_iterator; }; + template<typename T, bool = false, typename = std::void_t<>> + struct new_type_reverse_iterator + { + }; + + template<typename T> + struct new_type_reverse_iterator<T, true, std::void_t<typename T::reverse_iterator>> + { + using reverse_iterator = typename T::reverse_iterator; + }; + + template<typename T, bool = false, typename = std::void_t<>> + struct new_type_const_reverse_iterator + { + }; + + template<typename T> + struct new_type_const_reverse_iterator<T, true, std::void_t<typename T::const_reverse_iterator>> + { + using const_reverse_iterator = typename T::const_reverse_iterator; + }; + template<typename T, bool Enabled> struct new_type_iterator_types : new_type_iterator<T, Enabled> , new_type_const_iterator<T, Enabled> + , new_type_reverse_iterator<T, Enabled> + , new_type_const_reverse_iterator<T, Enabled> { }; diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp index a9bd6af..f7dafef 100644 --- a/include/newtype/impl/type_traits_extensions.hpp +++ b/include/newtype/impl/type_traits_extensions.hpp @@ -578,6 +578,96 @@ namespace nt::impl 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(begin(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_rbegin + { + 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_rbegin + } // namespace nt::impl #endif
\ No newline at end of file diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp index 24ac71a..36a3927 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -65,7 +65,7 @@ namespace nt 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>, + -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_begin_v<BaseTypeT const>, typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator>; template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> @@ -73,6 +73,21 @@ namespace nt -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_cbegin_v<BaseTypeT const>, 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<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<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>; + using super = impl::new_type_move_assignment<BaseType, TagType>; public: @@ -140,6 +155,27 @@ namespace nt { 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> + { + 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> + { + 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> + { + return this->m_value.crbegin(); + } }; template<typename BaseType, typename TagType, auto DerivationClause> @@ -350,6 +386,30 @@ namespace nt return cbegin(obj.m_value); } + template<typename BaseType, typename TagType, auto DerivationClause> + auto constexpr rbegin(new_type<BaseType, TagType, DerivationClause> & obj) + -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_rbegin_v<BaseType>, + typename new_type<BaseType, TagType, DerivationClause>::reverse_iterator> + { + return rbegin(obj.m_value); + } + + template<typename BaseType, typename TagType, auto DerivationClause> + auto constexpr rbegin(new_type<BaseType, TagType, DerivationClause> const & obj) + -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_rbegin_v<BaseType const>, + typename new_type<BaseType, TagType, DerivationClause>::const_reverse_iterator> + { + return rbegin(obj.m_value); + } + + template<typename BaseType, typename TagType, auto DerivationClause> + auto constexpr crbegin(new_type<BaseType, TagType, DerivationClause> const & obj) + -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_crbegin_v<BaseType const>, + typename new_type<BaseType, TagType, DerivationClause>::const_reverse_iterator> + { + return crbegin(obj.m_value); + } + } // namespace nt namespace std |
