aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/newtype/impl/type_traits_extensions.hpp23
-rw-r--r--include/newtype/new_type.hpp25
-rw-r--r--test/src/iterable_suite.cpp35
3 files changed, 49 insertions, 34 deletions
diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp
index 7096578..80ba5b0 100644
--- a/include/newtype/impl/type_traits_extensions.hpp
+++ b/include/newtype/impl/type_traits_extensions.hpp
@@ -6,7 +6,6 @@
#include <cstddef>
#include <functional>
#include <iosfwd>
-#include <iterator>
#include <type_traits>
namespace nt::impl
@@ -1055,26 +1054,6 @@ namespace nt::impl
inline namespace iterable
{
template<typename T, typename = void>
- struct has_std_begin : std::false_type
- {
- };
-
- template<typename T>
- struct has_std_begin<T, std::void_t<decltype(std::begin(std::declval<T &>()))>>
- : std::is_same<typename T::iterator, std::remove_cvref_t<decltype(std::begin(std::declval<T &>()))>>
- {
- };
-
- template<typename T>
- struct has_std_begin<T const, std::void_t<decltype(std::begin(std::declval<T const &>()))>>
- : std::is_same<typename T::const_iterator, std::remove_cvref_t<decltype(std::begin(std::declval<T const &>()))>>
- {
- };
-
- template<typename T>
- auto constexpr has_std_begin_v = has_std_begin<T>::value;
-
- template<typename T, typename = void>
struct has_free_begin : std::false_type
{
};
@@ -1115,7 +1094,7 @@ namespace nt::impl
auto constexpr has_member_begin_v = has_member_begin<T>::value;
template<typename T>
- struct has_begin : std::disjunction<has_std_begin<T>, has_free_begin<T>, has_member_begin<T>>
+ struct has_begin : std::disjunction<has_free_begin<T>, has_member_begin<T>>
{
};
diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp
index 0cf6ec3..0db01b2 100644
--- a/include/newtype/new_type.hpp
+++ b/include/newtype/new_type.hpp
@@ -10,7 +10,6 @@
#include <functional>
#include <istream>
-#include <iterator>
#include <ostream>
#include <type_traits>
@@ -62,6 +61,16 @@ namespace nt
-> std::enable_if_t<DerivationClauseV(nt::Arithmetic) && impl::is_divide_assignable_v<BaseTypeT>,
new_type<BaseTypeT, TagTypeT, DerivationClauseV> &>;
+ template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV>
+ auto constexpr friend begin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj)
+ -> std::enable_if_t<DerivationClauseV(nt::Iterable) && impl::has_free_begin_v<BaseTypeT>,
+ typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::iterator>;
+
+ 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>,
+ typename new_type<BaseTypeT, TagTypeT, DerivationClauseV>::const_iterator>;
+
using super = impl::new_type_move_assignment<BaseType, TagType>;
public:
@@ -448,21 +457,23 @@ namespace nt
/**
* Get an iterator to the beginning of the object contained by an instance of new_type
*/
- template<typename BaseType, typename TagType, auto DerivationClause, typename NewType = new_type<BaseType, TagType, DerivationClause>>
+ template<typename BaseType, typename TagType, auto DerivationClause>
auto constexpr begin(new_type<BaseType, TagType, DerivationClause> & obj)
- -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_begin_v<BaseType>, typename NewType::iterator>
+ -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_begin_v<BaseType>,
+ typename new_type<BaseType, TagType, DerivationClause>::iterator>
{
- return begin(obj);
+ return begin(obj.m_value);
}
/**
* Get a constant iterator to the beginning of the object contained by an instance of new_type
*/
- template<typename BaseType, typename TagType, auto DerivationClause, typename NewType = new_type<BaseType, TagType, DerivationClause>>
+ template<typename BaseType, typename TagType, auto DerivationClause>
auto constexpr begin(new_type<BaseType, TagType, DerivationClause> const & obj)
- -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_begin_v<BaseType const>, typename NewType::const_iterator>
+ -> std::enable_if_t<DerivationClause(nt::Iterable) && impl::has_free_begin_v<BaseType const>,
+ typename new_type<BaseType, TagType, DerivationClause>::const_iterator>
{
- return begin(obj);
+ return begin(obj.m_value);
}
} // namespace nt
diff --git a/test/src/iterable_suite.cpp b/test/src/iterable_suite.cpp
index 2470571..bf478e1 100644
--- a/test/src/iterable_suite.cpp
+++ b/test/src/iterable_suite.cpp
@@ -14,7 +14,16 @@
namespace
{
-}
+ struct with_member
+ {
+ using iterator = void *;
+ using const_iterator = void const *;
+
+ auto begin() -> iterator;
+ auto begin() const -> const_iterator;
+ };
+
+} // namespace
inline namespace begin_tests
{
@@ -34,18 +43,32 @@ inline namespace begin_tests
auto a_new__type_based_on_an_iterable_type_with_member_begin_deriving_iterable_has_member_begin() -> void
{
- static_assert(nt::impl::has_member_begin_v<std::array<int, 3>>);
- using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>;
+ static_assert(nt::impl::has_member_begin_v<with_member>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
ASSERT(nt::impl::has_member_begin_v<type_alias>);
}
auto a_new__type_based_on_an_iterable_type_with_constant_member_begin_deriving_iterable_has_constant_member_begin() -> void
{
- static_assert(nt::impl::has_member_begin_v<std::array<int const, 3>>);
- using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>;
+ static_assert(nt::impl::has_member_begin_v<with_member const>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
ASSERT(nt::impl::has_member_begin_v<type_alias const>);
}
+ auto a_new__type_based_on_an_iterable_type_without_free_begin_deriving_iterable_has_no_free_begin() -> void
+ {
+ static_assert(!nt::impl::has_free_begin_v<with_member>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
+ ASSERT(!nt::impl::has_free_begin_v<type_alias>);
+ }
+
+ auto a_new__type_based_on_an_iterable_type_without_constant_free_begin_deriving_iterable_has_no_constant_free_begin() -> void
+ {
+ static_assert(!nt::impl::has_free_begin_v<with_member const>);
+ using type_alias = nt::new_type<with_member, struct tag, deriving(nt::Iterable)>;
+ ASSERT(!nt::impl::has_free_begin_v<type_alias const>);
+ }
+
} // namespace begin_tests
auto iterable_suite() -> std::pair<cute::suite, std::string>
@@ -56,6 +79,8 @@ auto iterable_suite() -> std::pair<cute::suite, std::string>
KAWAII(a_new__type_based_on_a_non_iterable_type_deriving_iterable_has_no_begin),
KAWAII(a_new__type_based_on_an_iterable_type_with_member_begin_deriving_iterable_has_member_begin),
KAWAII(a_new__type_based_on_an_iterable_type_with_constant_member_begin_deriving_iterable_has_constant_member_begin),
+ KAWAII(a_new__type_based_on_an_iterable_type_without_free_begin_deriving_iterable_has_no_free_begin),
+ KAWAII(a_new__type_based_on_an_iterable_type_without_constant_free_begin_deriving_iterable_has_no_constant_free_begin),
},
"Iterable Tests"};
} \ No newline at end of file