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