aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/index.rst99
-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
-rw-r--r--test/src/iterable_suite.cpp136
5 files changed, 409 insertions, 2 deletions
diff --git a/doc/src/index.rst b/doc/src/index.rst
index cd016b9..a54d54c 100644
--- a/doc/src/index.rst
+++ b/doc/src/index.rst
@@ -99,6 +99,18 @@ Class template :cpp:class:`new_type`
.. versionadded:: 1.1.0
+ .. cpp:type:: reverse_iterator = typename BaseType::reverse_iterator
+
+ :enablement: This type alias shall be defined iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` has a member type :cpp:type:`reverse_iterator <new_type::base_type::reverse_iterator>` and the :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable`.
+
+ .. versionadded:: 1.1.0
+
+ .. cpp:type:: const_reverse_iterator = typename BaseType::const_reverse_iterator
+
+ :enablement: This type alias shall be defined iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` has a member type :cpp:type:`const_reverse_iterator <new_type::base_type::const_reverse_iterator>` and the :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable`.
+
+ .. versionadded:: 1.1.0
+
**Static Data Members**
.. cpp:var:: static derivation_clause_type constexpr derivation_clause = DerivationClause
@@ -242,6 +254,39 @@ Class template :cpp:class:`new_type`
.. versionadded:: 1.1.0
+ .. cpp:function:: constexpr iterator rbegin()
+
+ Get a reverse iterator to the beginning of the object contained by this :cpp:class:`new_type`
+
+ :enablement: This function shall be available iff.
+
+ a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
+ b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`rbegin() <new_type::base_type::rbegin()>` that returns an instance of type :cpp:type:`reverse_iterator`
+
+ .. versionadded:: 1.1.0
+
+ .. cpp:function:: constexpr iterator rbegin() const
+
+ Get a constant reverse iterator to the beginning of the object contained by this :cpp:class:`new_type`
+
+ :enablement: This function shall be available iff.
+
+ a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
+ b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`rbegin() const <new_type::base_type::rbegin()>` that returns an instance of type :cpp:type:`const_reverse_iterator`
+
+ .. versionadded:: 1.1.0
+
+ .. cpp:function:: constexpr iterator crbegin() const
+
+ Get a constant reverse iterator to the beginning of the object contained by this :cpp:class:`new_type`
+
+ :enablement: This function shall be available iff.
+
+ a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
+ b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`crbegin() const <new_type::base_type::crbegin()>` that returns an instance of type :cpp:type:`const_reverse_iterator`
+
+ .. versionadded:: 1.1.0
+
:literal:`namespace`-level functions and function templates
-----------------------------------------------------------
@@ -750,6 +795,60 @@ Iterators
.. versionadded:: 1.1.0
+.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
+ constexpr new_type<BaseType, TagType, DerivationClause>::reverse_iterator rbegin(new_type<BaseType, TagType, DerivationClause> & obj)
+
+ Get a reverse iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
+
+ :tparam BaseType: |BaseTypeDoc|
+ :tparam TagType: |TagTypeDoc|
+ :tparam DerivationClause: |DerivationClauseDoc|
+ :param obj: The object to retrieve the iterator from
+ :returns: An iterator to the begining of the object of contained by :literal:`obj`.
+ :throws: Any exception
+ :enablement: This function shall be available iff.
+
+ a) :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
+ b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`rbegin(BaseType &)` that returns an instance of type :cpp:type:`new_type::reverse_iterator`
+
+ .. versionadded:: 1.1.0
+
+.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
+ constexpr new_type<BaseType, TagType, DerivationClause>::const_reverse_iterator rbegin(new_type<BaseType, TagType, DerivationClause> const & obj)
+
+ Get a constant reverse iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
+
+ :tparam BaseType: |BaseTypeDoc|
+ :tparam TagType: |TagTypeDoc|
+ :tparam DerivationClause: |DerivationClauseDoc|
+ :param obj: The object to retrieve the iterator from
+ :returns: An iterator to the begining of the object of contained by :cpp:var:`obj`.
+ :throws: Any exception
+ :enablement: This function shall be available iff.
+
+ a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
+ b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`rbegin(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_reverse_iterator`
+
+ .. versionadded:: 1.1.0
+
+.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
+ constexpr new_type<BaseType, TagType, DerivationClause>::const_reverse_iterator crbegin(new_type<BaseType, TagType, DerivationClause> const & obj)
+
+ Get a constant reverse iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
+
+ :tparam BaseType: |BaseTypeDoc|
+ :tparam TagType: |TagTypeDoc|
+ :tparam DerivationClause: |DerivationClauseDoc|
+ :param obj: The object to retrieve the iterator from
+ :returns: An iterator to the begining of the object of contained by :cpp:var:`obj`.
+ :throws: Any exception
+ :enablement: This function shall be available iff.
+
+ a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
+ b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`crbegin(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_reverse_iterator`
+
+ .. versionadded:: 1.1.0
+
:cpp:class:`std::hash` Support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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
diff --git a/test/src/iterable_suite.cpp b/test/src/iterable_suite.cpp
index 3bdb16b..778dc35 100644
--- a/test/src/iterable_suite.cpp
+++ b/test/src/iterable_suite.cpp
@@ -18,10 +18,15 @@ namespace
{
using iterator = void *;
using const_iterator = void const *;
+ using reverse_iterator = void *;
+ using const_reverse_iterator = void const *;
auto begin() -> iterator;
auto begin() const -> const_iterator;
auto cbegin() const -> const_iterator;
+ auto rbegin() -> reverse_iterator;
+ auto rbegin() const -> const_reverse_iterator;
+ auto crbegin() const -> const_reverse_iterator;
};
} // namespace
@@ -135,6 +140,117 @@ inline namespace cbegin_tests
} // namespace cbegin_tests
+inline namespace rbegin_tests
+{
+
+ auto a_new__type_not_deriving_iterable_has_no_rbegin() -> void
+ {
+ using type_alias = nt::new_type<int, struct tag>;
+ ASSERT(!(nt::impl::has_rbegin_v<type_alias>));
+ }
+
+ auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_rbegin() -> void
+ {
+ static_assert(!nt::impl::has_rbegin_v<int>);
+ using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>;
+ ASSERT(!(nt::impl::has_rbegin_v<type_alias>));
+ }
+
+ auto a_new__type_based_on_an_iterable_type_with_member_rbegin_deriving_iterable_has_member_rbegin() -> void
+ {
+ static_assert(nt::impl::has_member_rbegin_v<with_member>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
+ ASSERT(nt::impl::has_member_rbegin_v<type_alias>);
+ }
+
+ auto a_new__type_based_on_an_iterable_type_with_constant_member_rbegin_deriving_iterable_has_constant_member_rbegin() -> void
+ {
+ static_assert(nt::impl::has_member_rbegin_v<with_member const>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
+ ASSERT(nt::impl::has_member_rbegin_v<type_alias const>);
+ }
+
+ auto a_new__type_based_on_an_iterable_type_without_free_rbegin_deriving_iterable_has_no_free_rbegin() -> void
+ {
+ static_assert(!nt::impl::has_free_rbegin_v<with_member>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
+ ASSERT(!nt::impl::has_free_rbegin_v<type_alias>);
+ }
+
+ auto a_new__type_based_on_an_iterable_type_without_constant_free_rbegin_deriving_iterable_has_no_constant_free_rbegin() -> void
+ {
+ static_assert(!nt::impl::has_free_rbegin_v<with_member const>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
+ ASSERT(!nt::impl::has_free_rbegin_v<type_alias const>);
+ }
+
+ auto accessing_the_first_element_of_a_reverse_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type()
+ -> void
+ {
+ using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>;
+ auto weak = std::array{42, 21, 10};
+ auto strong = type_alias{{42, 21, 10}};
+ ASSERT_EQUAL(*weak.rbegin(), *strong.rbegin());
+ }
+
+ auto an_iterator_obtained_via_member_rbegin_compares_equal_to_an_iterator_obtained_via_free_rbegin() -> void
+ {
+ using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>;
+ auto instance = type_alias{{42, 21, 10}};
+ ASSERT_EQUAL(rbegin(instance), instance.rbegin());
+ }
+
+} // namespace rbegin_tests
+
+inline namespace crbegin_tests
+{
+
+ auto a_new__type_not_deriving_iterable_has_no_crbegin() -> void
+ {
+ using type_alias = nt::new_type<int, struct tag>;
+ ASSERT(!(nt::impl::has_crbegin_v<type_alias>));
+ }
+
+ auto a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_crbegin() -> void
+ {
+ static_assert(!nt::impl::has_crbegin_v<int>);
+ using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>;
+ ASSERT(!(nt::impl::has_crbegin_v<type_alias>));
+ }
+
+ auto a_new__type_based_on_an_iterable_type_with_member_crbegin_deriving_iterable_has_member_crbegin() -> void
+ {
+ static_assert(nt::impl::has_member_crbegin_v<with_member>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
+ ASSERT(nt::impl::has_member_crbegin_v<type_alias>);
+ }
+
+ auto a_new__type_based_on_an_iterable_type_without_free_crbegin_deriving_iterable_has_no_free_crbegin() -> void
+ {
+ static_assert(!nt::impl::has_free_crbegin_v<with_member>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
+ ASSERT(!nt::impl::has_free_crbegin_v<type_alias>);
+ }
+
+ auto
+ accessing_the_first_element_of_a_constant_reverse_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type()
+ -> void
+ {
+ using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>;
+ auto weak = std::array{42, 21, 10};
+ auto strong = type_alias{{42, 21, 10}};
+ ASSERT_EQUAL(*weak.crbegin(), *strong.crbegin());
+ }
+
+ auto an_iterator_obtained_via_member_crbegin_compares_equal_to_an_iterator_obtained_via_free_crbegin() -> void
+ {
+ using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>;
+ auto instance = type_alias{{42, 21, 10}};
+ ASSERT_EQUAL(crbegin(instance), instance.crbegin());
+ }
+
+} // namespace crbegin_tests
+
auto iterable_suite() -> std::pair<cute::suite, std::string>
{
return {
@@ -150,13 +266,31 @@ auto iterable_suite() -> std::pair<cute::suite, std::string>
KAWAII(accessing_the_first_element_of_an_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type),
KAWAII(an_iterator_obtained_via_member_begin_compares_equal_to_an_iterator_obtained_via_free_begin),
- /// 'begin' Tests
+ /// 'cbegin' Tests
KAWAII(a_new__type_not_deriving_iterable_has_no_cbegin),
KAWAII(a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_cbegin),
KAWAII(a_new__type_based_on_an_iterable_type_with_member_cbegin_deriving_iterable_has_member_cbegin),
KAWAII(a_new__type_based_on_an_iterable_type_without_free_cbegin_deriving_iterable_has_no_free_cbegin),
KAWAII(accessing_the_first_element_of_a_constant_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type),
KAWAII(an_iterator_obtained_via_member_cbegin_compares_equal_to_an_iterator_obtained_via_free_cbegin),
+
+ /// 'rbegin' Tests
+ KAWAII(a_new__type_not_deriving_iterable_has_no_rbegin),
+ KAWAII(a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_rbegin),
+ KAWAII(a_new__type_based_on_an_iterable_type_with_member_rbegin_deriving_iterable_has_member_rbegin),
+ KAWAII(a_new__type_based_on_an_iterable_type_with_constant_member_rbegin_deriving_iterable_has_constant_member_rbegin),
+ KAWAII(a_new__type_based_on_an_iterable_type_without_free_rbegin_deriving_iterable_has_no_free_rbegin),
+ KAWAII(a_new__type_based_on_an_iterable_type_without_constant_free_rbegin_deriving_iterable_has_no_constant_free_rbegin),
+ KAWAII(accessing_the_first_element_of_a_reverse_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type),
+ KAWAII(an_iterator_obtained_via_member_rbegin_compares_equal_to_an_iterator_obtained_via_free_rbegin),
+
+ /// 'cbegin' Tests
+ KAWAII(a_new__type_not_deriving_iterable_has_no_crbegin),
+ KAWAII(a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_crbegin),
+ KAWAII(a_new__type_based_on_an_iterable_type_with_member_crbegin_deriving_iterable_has_member_crbegin),
+ KAWAII(a_new__type_based_on_an_iterable_type_without_free_crbegin_deriving_iterable_has_no_free_crbegin),
+ KAWAII(accessing_the_first_element_of_a_constant_reverse_iterator_on_a_new__type_yields_the_same_value_as_accessing_it_through_an_unwrapped_type),
+ KAWAII(an_iterator_obtained_via_member_crbegin_compares_equal_to_an_iterator_obtained_via_free_crbegin),
// clang-format on
},
"Iterable Tests"};