aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/newtype/impl/new_type_iterator_types.hpp24
-rw-r--r--include/newtype/impl/type_traits_extensions.hpp90
-rw-r--r--include/newtype/new_type.hpp62
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