From 52d5330cbb866f050a8f0736c139586c8a22c387 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 21 Feb 2020 21:19:45 +0100 Subject: new_type: begin Iterable implementation --- include/newtype/derivable.hpp | 7 +++ include/newtype/impl/new_type_iterator_types.hpp | 42 +++++++++++++ include/newtype/impl/type_traits_extensions.hpp | 72 +++++++++++++++++++++ include/newtype/new_type.hpp | 80 +++++++++++++++++++++++- 4 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 include/newtype/impl/new_type_iterator_types.hpp (limited to 'include') diff --git a/include/newtype/derivable.hpp b/include/newtype/derivable.hpp index 19c79d9..faa844d 100644 --- a/include/newtype/derivable.hpp +++ b/include/newtype/derivable.hpp @@ -60,6 +60,13 @@ namespace nt */ auto constexpr Indirection = derivable{}; + /** + * @brief A tag to enable derivation of the iterator accessors + * + * @since 1.0.0 + */ + auto constexpr Iterable = derivable{}; + /** * @brief A tag to enable derivation of the stream input operator * diff --git a/include/newtype/impl/new_type_iterator_types.hpp b/include/newtype/impl/new_type_iterator_types.hpp new file mode 100644 index 0000000..037f08d --- /dev/null +++ b/include/newtype/impl/new_type_iterator_types.hpp @@ -0,0 +1,42 @@ +#ifndef NEWTYPE_IMPL_NEW_TYPE_ITERATOR_TYPES_HPP +#define NEWTYPE_IMPL_NEW_TYPE_ITERATOR_TYPES_HPP + +#include "newtype/version.hpp" + +#include + +namespace nt::impl +{ + + template> + struct new_type_iterator + { + }; + + template + struct new_type_iterator> + { + using iterator = typename T::iterator; + }; + + template> + struct new_type_const_iterator + { + }; + + template + struct new_type_const_iterator> + { + using const_iterator = typename T::const_iterator; + }; + + template + struct new_type_iterator_types + : new_type_iterator + , new_type_const_iterator + { + }; + +} // namespace nt::impl + +#endif \ No newline at end of file diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp index 1f46fb4..7096578 100644 --- a/include/newtype/impl/type_traits_extensions.hpp +++ b/include/newtype/impl/type_traits_extensions.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace nt::impl @@ -1051,6 +1052,77 @@ namespace nt::impl } // namespace std_support + inline namespace iterable + { + template + struct has_std_begin : std::false_type + { + }; + + template + struct has_std_begin()))>> + : std::is_same()))>> + { + }; + + template + struct has_std_begin()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_std_begin_v = has_std_begin::value; + + template + struct has_free_begin : std::false_type + { + }; + + template + struct has_free_begin()))>> + : std::is_same()))>> + { + }; + + template + struct has_free_begin()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_begin_v = has_free_begin::value; + + template + struct has_member_begin : std::false_type + { + }; + + template + struct has_member_begin().begin())>> + : std::is_same().begin())>> + { + }; + + template + struct has_member_begin().begin())>> + : std::is_same().begin())>> + { + }; + + template + auto constexpr has_member_begin_v = has_member_begin::value; + + template + struct has_begin : std::disjunction, has_free_begin, has_member_begin> + { + }; + + template + auto constexpr has_begin_v = has_begin::value; + } // namespace iterable + } // 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 ed1de44..0aa1a2e 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -3,12 +3,14 @@ #include "newtype/derivable.hpp" #include "newtype/deriving.hpp" +#include "newtype/impl/new_type_iterator_types.hpp" #include "newtype/impl/new_type_storage.hpp" #include "newtype/impl/type_traits_extensions.hpp" #include "newtype/version.hpp" #include #include +#include #include #include @@ -26,7 +28,9 @@ namespace nt * @tparam DervivationClause An nt::derivation_clause describing which features shall be automatically derived for the new type alias */ template - class new_type : impl::new_type_move_assignment + class new_type + : impl::new_type_move_assignment + , public impl::new_type_iterator_types { static_assert(!std::is_reference_v, "The base type must not be a reference type"); static_assert(!std::is_void_v>, "The base type must not be possibly cv-qualified void"); @@ -209,6 +213,51 @@ namespace nt { return std::addressof(this->m_value); } + + /// @section Iterators + + /** + * @brief Get the begin iterator of the base type + * + * @return An iterator to the beginning of the base type sequence + * @throw Any exception thrown by the overload of 'begin' selected + */ + template * = nullptr> + auto constexpr begin() + -> std::enable_if_t, typename NewType::iterator> + { + if constexpr (impl::has_member_begin_v) + { + return this->m_value.begin(); + } + else + { + using std::begin; + return begin(this->m_value); + } + } + + /** + * @brief Get the begin iterator of the base type + * + * @note Overload for constant instances + * @return An iterator to the beginning of the base type sequence + * @throw Any exception thrown by the overload of 'begin' selected + */ + template + auto constexpr begin() const + -> std::enable_if_t, typename NewType::const_iterator> + { + if constexpr (impl::has_member_begin_v) + { + return this->m_value.begin(); + } + else + { + using std::begin; + return begin(this->m_value); + } + } }; /// @section Equality comparison operators @@ -569,6 +618,35 @@ namespace nt return lhs; } + /// @section Free Iterator Accessors + + /** + * @brief Get the begin iterator of the base type + * + * @return An iterator to the beginning of the base type sequence + * @throw Any exception thrown by the overload of 'begin' selected + */ + template> + auto constexpr begin(new_type & obj) + -> std::enable_if_t, typename NewType::iterator> + { + return begin(obj); + } + + /** + * @brief Get the begin iterator of the base type + * + * @note Overload for constant instances + * @return An iterator to the beginning of the base type sequence + * @throw Any exception thrown by the overload of 'begin' selected + */ + template> + auto constexpr begin(new_type const & obj) + -> std::enable_if_t, typename NewType::const_iterator> + { + return begin(obj); + } + } // namespace nt namespace std -- cgit v1.2.3 From c4e3450fb1de240ec10eea27e8b9079cab5f8a55 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 22 Feb 2020 17:16:23 +0100 Subject: new_type: adjust enablement of begin --- include/newtype/new_type.hpp | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp index 0aa1a2e..ef36a75 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -224,17 +224,9 @@ namespace nt */ template * = nullptr> auto constexpr begin() - -> std::enable_if_t, typename NewType::iterator> + -> std::enable_if_t, typename NewType::iterator> { - if constexpr (impl::has_member_begin_v) - { - return this->m_value.begin(); - } - else - { - using std::begin; - return begin(this->m_value); - } + return this->m_value.begin(); } /** @@ -245,18 +237,10 @@ namespace nt * @throw Any exception thrown by the overload of 'begin' selected */ template - auto constexpr begin() const - -> std::enable_if_t, typename NewType::const_iterator> + auto constexpr begin() const -> std::enable_if_t, + typename NewType::const_iterator> { - if constexpr (impl::has_member_begin_v) - { - return this->m_value.begin(); - } - else - { - using std::begin; - return begin(this->m_value); - } + return this->m_value.begin(); } }; -- cgit v1.2.3 From db75b825ab983ac731516622898a706035473d15 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 22 Feb 2020 17:50:10 +0100 Subject: doc: reduce header inline documentation --- include/newtype/new_type.hpp | 271 +++++++++---------------------------------- 1 file changed, 54 insertions(+), 217 deletions(-) (limited to 'include') diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp index ef36a75..0cf6ec3 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -18,14 +18,7 @@ namespace nt { /** - * @brief Create a new type based on an existing one - * - * The class template nt::new_type is designed to allow the creation of new types based on existing types. Similarly to the Haskell newtype, - * this class template creates a new type that is layout equivalent to the underlying type. - * - * @tparam BaseType An existing type that shall aliased - * @tparam TagType A unique type to identify this nt::new_type - * @tparam DervivationClause An nt::derivation_clause describing which features shall be automatically derived for the new type alias + * Create a new type based on an existing one */ template class new_type @@ -72,96 +65,65 @@ namespace nt using super = impl::new_type_move_assignment; public: - /// @section Type aliases + /// Member Type Aliases /** - * @brief The base type of this nt::new_type - * - * This type alias provides convenient access to the contained objects type + * The base type of this nt::new_type */ using base_type = BaseType; /** - * @brief The tag type of this nt::new_type - * - * This type alias provides convenient access to the tag type of this nt::new_type instance + * The tag type of this nt::new_type */ using tag_type = TagType; /** - * @brief The type of the derivation clause of this nt::newtype - * - * This type alias provides convenient access to the type of the derivation clause of this nt::new_type instance + * The type of the derivation clause of this nt::newtype */ using derivation_clause_type = decltype(DerivationClause); - /// @section Derivation clause access + /// Static Data Members /** - * @brief The derivation clause fo this nt::new_type - * - * This static data-member provides conevient access to the derivation clause of this nt::new_type instance + * The derivation clause fo this nt::new_type */ auto constexpr static derivation_clause = DerivationClause; - /// @section Constructors + /// Constructors using super::super; /** - * @brief Construct an instance of this nt::new_type by default initializing the contained object - * - * @note This constructor is available iff. the base type is default-constructible. Otherwise is is defined as deleted. - * @throw This constructor throws any exception thrown the base type constructor. It is noexcept iff. the base type constructor is noexcept + * Construct an instance of this nt::new_type by default initializing the contained object */ constexpr new_type() noexcept(std::is_nothrow_default_constructible_v) = default; /** - * @brief Copy-construct an instance of this nt::new_type from an existing one - * - * @note This constructor is available iff. the base type is copy-constructible. Otherwise is is defined as deleted. - * @throw This constructor throws any exception thrown the base type copy-constructor. It is noexcept iff. the base type copy-constructor - * is noexcept + * Copy-construct an instance of this nt::new_type from an existing one */ constexpr new_type(new_type const &) noexcept(std::is_nothrow_copy_constructible_v) = default; /** - * @brief Move-construct an instance of this nt::new_type from an existing one - * - * @note This constructor is available iff. the base type is move-constructible. Otherwise is is defined as deleted. - * @throw This constructor throws any exception thrown the base type move-constructor. It is noexcept iff. the base types move-constructor - * is noexcept + * Move-construct an instance of this nt::new_type from an existing one */ constexpr new_type(new_type &&) noexcept(std::is_nothrow_move_constructible_v) = default; - /// @section Assignment operators + /// Assignment Operators /** - * @brief Copy-assign the value of an existing instance of this nt::new_type to this instance - * - * @note This assignment operator is available iff. the base type is copy-assignable. Otherwise it is defined as deleted. - * @throw This assignment operator throws any exception thrown by the base type copy-assignment operator. It is noexcept iff. the base type - * copy-assignment operator is noexcept. - * @return A reference to this instance + * Copy-assign the value of an existing instance of this nt::new_type to this instance */ auto constexpr operator=(new_type const &) noexcept(std::is_nothrow_copy_assignable_v) -> new_type & = default; /** - * @brief Move-assign the value of an existing instance of this nt::new_type to this instance - * - * @note This assignment operator is available iff. the base type is move-assignable. Otherwise it is defined as deleted. - * @throw This assignment operator throws any exception thrown by the base type move-assignment operator. It is noexcept iff. the base type - * move-assignment operator is noexcept. - * @return A reference to this instance + * Move-assign the value of an existing instance of this nt::new_type to this instance */ auto constexpr operator=(new_type &&) noexcept(std::is_nothrow_move_assignable_v) -> new_type & = default; - /// @section Accessors + /// Accessors /** - * @brief Obtain a copy of the contained base type object - * - * @return BaseType + * Retrieve a copy of the object contained by this new_type object */ auto constexpr decay() const noexcept(std::is_nothrow_copy_constructible_v) -> BaseType { @@ -169,9 +131,7 @@ namespace nt } /** - * @brief Convert this instance into the equivalent base type value - * - * @note This is only available if the derivation clause of this nt::new_type contains nt::ImplicitConversion + * Retrieve a copy of the object contained by this new_type object */ template * = nullptr> constexpr operator base_type() const noexcept(std::is_nothrow_copy_constructible_v) @@ -180,9 +140,7 @@ namespace nt } /** - * @brief Convert this instance into the equivalent base type value - * - * @note This overload is only avalaible if the derivation clause of this nt::new_type does not contain nt::ImplicitConversion + * Convert this instance into the equivalent base type value */ template * = nullptr> explicit constexpr operator base_type() const noexcept(std::is_nothrow_copy_constructible_v) @@ -190,12 +148,10 @@ namespace nt return decay(); } - /// @section Indirection operators + /// Member Access Through Pointer /** - * @brief Perform an access to a member of the base type - * - * @return A pointer to the contained base type object + * Perform "member access through pointer" via a pointer to object contained by this new_type */ template auto constexpr operator-> () noexcept -> std::enable_if_t @@ -204,9 +160,7 @@ namespace nt } /** - * @brief Perform an access to a member of the base type - * - * @return A pointer to the contained base type object + * Perform "member access through pointer" via a pointer to object contained by this new_type */ template auto constexpr operator-> () const noexcept -> std::enable_if_t @@ -214,13 +168,10 @@ namespace nt return std::addressof(this->m_value); } - /// @section Iterators + /// Iterators /** - * @brief Get the begin iterator of the base type - * - * @return An iterator to the beginning of the base type sequence - * @throw Any exception thrown by the overload of 'begin' selected + * Get an iterator to the beginning of the object contained by this new_type */ template * = nullptr> auto constexpr begin() @@ -230,11 +181,7 @@ namespace nt } /** - * @brief Get the begin iterator of the base type - * - * @note Overload for constant instances - * @return An iterator to the beginning of the base type sequence - * @throw Any exception thrown by the overload of 'begin' selected + * Get an iterator to the beginning of the object contained by this new_type */ template auto constexpr begin() const -> std::enable_if_t, @@ -244,14 +191,10 @@ namespace nt } }; - /// @section Equality comparison operators + /// Equality Comparison Operators /** - * @brief Compare two objects for equality - * - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Check two instances of new_type for equality */ template auto constexpr @@ -263,11 +206,7 @@ namespace nt } /** - * @brief Compare an instance of a given nt::new_type with an object of its base type - * - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Check an instance of new_type for equality with an instance of BaseType */ template auto constexpr operator==(new_type const & lhs, @@ -278,11 +217,7 @@ namespace nt } /** - * @brief Compare an instance of the base type with an instance of a given nt::new_type - * - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Check an instance of BaseType for equality with an instance of new_type */ template auto constexpr @@ -294,11 +229,7 @@ namespace nt } /** - * @brief Compare two objects for non-equality - * - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Check two instances of new_type for in-equality */ template auto constexpr @@ -310,11 +241,7 @@ namespace nt } /** - * @brief Compare an instance of a given nt::new_type with an object of its base type - * - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Check an instance of new_type for in-equality with an instance of BaseType */ template auto constexpr operator!=(new_type const & lhs, @@ -325,11 +252,7 @@ namespace nt } /** - * @brief Compare an instance of the base type with an instance of a given nt::new_type - * - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Check an instance of BaseType for in-equality with an instance of new_type */ template auto constexpr @@ -340,16 +263,10 @@ namespace nt return lhs != rhs.decay(); } - /// @section Relational operators + /// Relational Comparison Operators /** - * @brief Check if one nt::new_type object is less-than an other - * - * @note This operator is only available if the the derivation clause of this nt::new_type does contains nt::Relational and the base type is - * less-than comparable. - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Compare two instances of the same new_type using '<' (less-than) */ template auto constexpr @@ -361,13 +278,7 @@ namespace nt } /** - * Check if one nt::new_type object is greater-than an other - * - * @note This operator is only available if the the derivation clause of this nt::new_type does contains nt::Relational and the base type is - * greater-than comparable. - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Compare two instances of the same new_type using '>' (greater-than) */ template auto constexpr @@ -379,13 +290,7 @@ namespace nt } /** - * Check if one nt::new_type object is less-than or equal-to an other - * - * @note This operator is only available if the the derivation clause of this nt::new_type does contains nt::Relational and the base type is - * less-than-or-equal-to comparable. - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Compare two instances of the same new_type using '<=' (less-than-equal) */ template auto constexpr @@ -397,13 +302,7 @@ namespace nt } /** - * Check if one nt::new_type object is greater-than or equal-to an other - * - * @note This operator is only available if the the derivation clause of this nt::new_type does contains nt::Relational and the base type is - * greater-than-or-equal comparable - * @throw This comparison operator throws any exception thrown by the base type comparison operator. It it noexcept iff. the base type - * comparison operator is noexcept. - * @return true iff. the base type comparison operator returns true, false otherwise. + * Compare two instances of the same new_type using '>=' (greater-than-equal) */ template auto constexpr @@ -414,15 +313,10 @@ namespace nt return lhs.decay() >= rhs.decay(); } - /// @section Stream input/output operators + /// Stream I/O Operators /** - * @brief Write the contained base type object to a standard output stream - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type object contains nt::Show. - * @param output The output stream to write to - * @param source An instance of an nt::new_type that shall be written to the stream - * @return The a reference to the output stream + * Write an instance of new_type to a standard ostream */ template auto operator<<(std::basic_ostream & output, new_type const & source) noexcept( @@ -434,12 +328,7 @@ namespace nt } /** - * @brief Read an object of the base type from a standard input stream - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type object contains nt::Read. - * @param output The input stream to read from - * @param source An instance of an nt::new_type that shall be read from the stream - * @return The a reference to the input stream + * Read an instance of new_type from the a standard istream */ template auto operator>>(std::basic_istream & input, new_type & target) noexcept( @@ -450,16 +339,10 @@ namespace nt return input >> target.m_value; } - /// @section Arithmetic operators + /// Arithmetic Operators /** - * @brief Add two instances of the same nt::new_type - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type objects contains nt::Arithmetic and the base - * type is addable. - * @param lhs The left-hand side of the addition - * @param rhs The right-hand side of the addition - * @return a new instance of the same nt::new_type + * Add two instances of the same new_type */ template auto constexpr @@ -471,13 +354,7 @@ namespace nt } /** - * @brief Add two instances of the same nt::new_type, modifying the left-hand side - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type objects contains nt::Arithmetic and the base - * type is addable. - * @param lhs The left-hand side of the addition - * @param rhs The right-hand side of the addition - * @return a reference to the the modified value + * Add two instances of the same new_type by overwriting the first one */ template auto constexpr operator+=(new_type & lhs, @@ -490,13 +367,7 @@ namespace nt } /** - * @brief Subtract two instances of the same nt::new_type - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type objects contains nt::Arithmetic and the base - * type is subtractable. - * @param lhs The left-hand side of the subtraction - * @param rhs The right-hand side of the subtraction - * @return a new instance of the same nt::new_type + * Subtract two instances of the same new_type */ template auto constexpr @@ -508,13 +379,7 @@ namespace nt } /** - * @brief Subtract two instances of the same nt::new_type, modifying the left-hand side - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type objects contains nt::Arithmetic and the base - * type is subtractable. - * @param lhs The left-hand side of the subtractition - * @param rhs The right-hand side of the subtractition - * @return a reference to the the modified value + * Subtract two instances of the same new_type by overwriting the first one */ template auto constexpr @@ -528,13 +393,7 @@ namespace nt } /** - * @brief Multiply two instances of the same nt::new_type - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type objects contains nt::Arithmetic and the base - * type is multipliable. - * @param lhs The left-hand side of the multiplication - * @param rhs The right-hand side of the multiplication - * @return a new instance of the same nt::new_type + * Multiply two instances of the same new_type */ template auto constexpr @@ -546,13 +405,7 @@ namespace nt } /** - * @brief Multiply two instances of the same nt::new_type, modifying the left-hand side - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type objects contains nt::Arithmetic and the base - * type is multiplyable. - * @param lhs The left-hand side of the multiplication - * @param rhs The right-hand side of the multiplication - * @return a reference to the the modified value + * Multiply two instances of the same new_type by overwriting the first one */ template auto constexpr @@ -566,13 +419,7 @@ namespace nt } /** - * @brief Divide two instances of the same nt::new_type - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type objects contains nt::Arithmetic and the base - * type is dividable. - * @param lhs The left-hand side of the division - * @param rhs The right-hand side of the division - * @return a new instance of the same nt::new_type + * Divide two instances of the same nt::new_type */ template auto constexpr @@ -584,13 +431,7 @@ namespace nt } /** - * @brief Divide two instances of the same nt::new_type, modifying the left-hand side - * - * @note This operator is only available if the derivation clause of the passed in nt::new_type objects contains nt::Arithmetic and the base - * type is dividable. - * @param lhs The left-hand side of the division - * @param rhs The right-hand side of the division - * @return a reference to the the modified value + * Divide two instances of the same new_type by overwriting the first one */ template auto constexpr operator/=(new_type & lhs, @@ -602,13 +443,10 @@ namespace nt return lhs; } - /// @section Free Iterator Accessors + /// Iterators /** - * @brief Get the begin iterator of the base type - * - * @return An iterator to the beginning of the base type sequence - * @throw Any exception thrown by the overload of 'begin' selected + * Get an iterator to the beginning of the object contained by an instance of new_type */ template> auto constexpr begin(new_type & obj) @@ -618,11 +456,7 @@ namespace nt } /** - * @brief Get the begin iterator of the base type - * - * @note Overload for constant instances - * @return An iterator to the beginning of the base type sequence - * @throw Any exception thrown by the overload of 'begin' selected + * Get a constant iterator to the beginning of the object contained by an instance of new_type */ template> auto constexpr begin(new_type const & obj) @@ -635,6 +469,9 @@ namespace nt namespace std { + /** + * Hash an instance of new_type using the hash implementation of the base type + */ template struct hash> { -- cgit v1.2.3 From 943033bc921bb328bbc354f15627dbf4bd6ab1e4 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 22 Feb 2020 18:29:07 +0100 Subject: new_type: fix enablement of begin --- include/newtype/impl/type_traits_extensions.hpp | 23 +---------------------- include/newtype/new_type.hpp | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 29 deletions(-) (limited to 'include') 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 #include #include -#include #include namespace nt::impl @@ -1054,26 +1053,6 @@ namespace nt::impl inline namespace iterable { - template - struct has_std_begin : std::false_type - { - }; - - template - struct has_std_begin()))>> - : std::is_same()))>> - { - }; - - template - struct has_std_begin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_std_begin_v = has_std_begin::value; - template struct has_free_begin : std::false_type { @@ -1115,7 +1094,7 @@ namespace nt::impl auto constexpr has_member_begin_v = has_member_begin::value; template - struct has_begin : std::disjunction, has_free_begin, has_member_begin> + struct has_begin : std::disjunction, has_member_begin> { }; 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 #include -#include #include #include @@ -62,6 +61,16 @@ namespace nt -> std::enable_if_t, new_type &>; + template + auto constexpr friend begin(new_type & obj) + -> std::enable_if_t, + typename new_type::iterator>; + + template + auto constexpr friend begin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator>; + using super = impl::new_type_move_assignment; public: @@ -448,21 +457,23 @@ namespace nt /** * Get an iterator to the beginning of the object contained by an instance of new_type */ - template> + template auto constexpr begin(new_type & obj) - -> std::enable_if_t, typename NewType::iterator> + -> std::enable_if_t, + typename new_type::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> + template auto constexpr begin(new_type const & obj) - -> std::enable_if_t, typename NewType::const_iterator> + -> std::enable_if_t, + typename new_type::const_iterator> { - return begin(obj); + return begin(obj.m_value); } } // namespace nt -- cgit v1.2.3 From bb58e65e6596a2ffac2e85e9fda1e8568aa9b4b1 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 25 Feb 2020 20:57:06 +0100 Subject: new_type: implement cbegin --- include/newtype/impl/type_traits_extensions.hpp | 43 +++++++++++++++++++++++-- include/newtype/new_type.hpp | 20 ++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) (limited to 'include') 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 struct has_free_begin : std::false_type @@ -1100,7 +1100,46 @@ namespace nt::impl template auto constexpr has_begin_v = has_begin::value; - } // namespace iterable + } // namespace iterable_begin + + inline namespace iterable_cbegin + { + template + struct has_free_cbegin : std::false_type + { + }; + + template + struct has_free_cbegin()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_cbegin_v = has_free_cbegin::value; + + template + struct has_member_cbegin : std::false_type + { + }; + + template + struct has_member_cbegin().cbegin())>> + : std::is_same().cbegin())> + { + }; + + template + auto constexpr has_member_cbegin_v = has_member_cbegin::value; + + template + struct has_cbegin : std::disjunction, has_member_cbegin> + { + }; + + template + auto constexpr has_cbegin_v = has_cbegin::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, typename new_type::const_iterator>; + template + auto constexpr friend cbegin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator>; + using super = impl::new_type_move_assignment; public: @@ -198,6 +203,13 @@ namespace nt { return this->m_value.begin(); } + + template + auto constexpr cbegin() const -> std::enable_if_t, + typename NewType::const_iterator> + { + return this->m_value.cbegin(); + } }; /// Equality Comparison Operators @@ -476,6 +488,14 @@ namespace nt return begin(obj.m_value); } + template + auto constexpr cbegin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator> + { + return cbegin(obj.m_value); + } + } // namespace nt namespace std -- cgit v1.2.3 From dc369b4c559b33868ffdb99eb4a2feadd90a84f2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 27 Feb 2020 09:32:48 +0100 Subject: new_type: remove doc comments --- include/newtype/derivable.hpp | 63 --- include/newtype/derivation_clause.hpp | 45 -- include/newtype/deriving.hpp | 3 - include/newtype/impl/type_traits_extensions.hpp | 563 ------------------------ include/newtype/new_type.hpp | 149 ------- 5 files changed, 823 deletions(-) (limited to 'include') diff --git a/include/newtype/derivable.hpp b/include/newtype/derivable.hpp index faa844d..c798c59 100644 --- a/include/newtype/derivable.hpp +++ b/include/newtype/derivable.hpp @@ -12,80 +12,17 @@ namespace nt using tag_type = DerivableTag; }; - /** - * @brief A set of standard derivation tags - * - * This convenience namespace contains all standard derivation tags. - * - * @since 1.0.0 - */ inline namespace derivables { - /** - * @brief A tag to enable derivation of arithmetic operators - * - * @since 1.0.0 - */ auto constexpr Arithmetic = derivable{}; - - /** - * @brief A tag to enable derivation of "equality comparison with base type" operators - * - * @note Deriving this feature seriously weakens the using nt::new_type instance - * @since 1.0.0 - */ auto constexpr EqBase = derivable{}; - - /** - * @brief A tag to enable derivation of a specialization of std::hash - * - * @since 1.0.0 - */ auto constexpr Hash = derivable{}; - - /** - * @brief A tag to enable derivation of the implicit "conversion to base type" operator - * - * @note If this tag is not present in the derivation clause of any given nt::new_type, the type instance only supports explicit - * "conversion to base type" - * @since 1.0.0 - */ auto constexpr ImplicitConversion = derivable{}; - - /** - * @brief A tag to enable access to the members of the base type object through a pointer - * - * @since 1.0.0 - */ auto constexpr Indirection = derivable{}; - - /** - * @brief A tag to enable derivation of the iterator accessors - * - * @since 1.0.0 - */ auto constexpr Iterable = derivable{}; - - /** - * @brief A tag to enable derivation of the stream input operator - * - * @since 1.0.0 - */ auto constexpr Read = derivable{}; - - /** - * @brief A tag to enable derivation of the relational operators - * - * @since 1.0.0 - */ auto constexpr Relational = derivable{}; - - /** - * @brief A tag to enable derivation of the stream output operator - * - * @since 1.0.0 - */ auto constexpr Show = derivable{}; } // namespace derivables diff --git a/include/newtype/derivation_clause.hpp b/include/newtype/derivation_clause.hpp index edb2f85..6de70e1 100644 --- a/include/newtype/derivation_clause.hpp +++ b/include/newtype/derivation_clause.hpp @@ -9,11 +9,6 @@ namespace nt { - /** - * A @p deriving clause type - * - * @tparam DerivableTags A list of tag types defining a set of derivable features - */ template struct derivation_clause { @@ -21,88 +16,48 @@ namespace nt { } - /** - * Check whether the derivation clause contains a given derivable - */ template auto constexpr operator()(derivable) const noexcept -> bool { return (std::is_same_v || ...); } - /** - * Check whether the derivation clause contains all derivables in a given lists - */ template auto constexpr operator()(derivable, derivable...) const noexcept -> bool { return (*this)(derivable{}) && (*this)(derivable{}...); } - /** - * Check whether this derivation clause is less than an other derivation clause - * - * A derivation clause is considered less than an other derivation clause iff. its set of derivables is a strict subset of - * the set derivables of the other. - */ template auto constexpr operator<(derivation_clause other) const noexcept -> bool { return (sizeof...(DerivableTags) < sizeof...(OtherDerivableTags)) && other(derivable{}...); } - /** - * Check whether this derivation clause is greater than an other derivation clause - * - * A derivation clause is considered greater than an other derivation clause iff. its set of derivables is a strict superset - * of the set derivables of the other. - */ template auto constexpr operator>(derivation_clause other) const noexcept -> bool { return other < *this; } - /** - * Check whether this derivation clause is equal to an other derivation clause - * - * Two derivation clauses are considered equal if both have the same set of derivables - */ template auto constexpr operator==(derivation_clause other) const noexcept -> bool { return sizeof...(DerivableTags) == sizeof...(OtherDerivableTags) && other(derivable{}...); } - /** - * Check whether this derivation clause is not equal to an other derivation clause - * - * Two derivation clauses are considered not equal if neither has the same set of derivables as the other - */ template auto constexpr operator!=(derivation_clause other) const noexcept -> bool { return !(*this == other); } - /** - * Check whether this derivation clause is less-than or equal to an other derivation clause - * - * @see nt::distinct::operator== - * @see nt::distinct::operator< - */ template auto constexpr operator<=(derivation_clause other) const noexcept -> bool { return *this < other || *this == other; } - /** - * Check whether this derivation clause is greater-than or equal to an other derivation clause - * - * @see nt::distinct::operator== - * @see nt::distinct::operator< - */ template auto constexpr operator>=(derivation_clause other) const noexcept -> bool { diff --git a/include/newtype/deriving.hpp b/include/newtype/deriving.hpp index e762c9b..ae10bab 100644 --- a/include/newtype/deriving.hpp +++ b/include/newtype/deriving.hpp @@ -10,9 +10,6 @@ namespace nt { - /** - * Create a new derivation clause with the given derivables - */ template auto constexpr deriving(derivable... features) noexcept -> derivation_clause { diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp index ee33730..a9bd6af 100644 --- a/include/newtype/impl/type_traits_extensions.hpp +++ b/include/newtype/impl/type_traits_extensions.hpp @@ -14,125 +14,57 @@ namespace nt::impl inline namespace equality_comparable { - /** - * @brief A trait to test if a given type is comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the base case for non-equals-comparable T - */ template struct is_equality_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the case for equals-comparable T - */ template struct is_equality_comparable() == std::declval())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator== - * - * @tparam T The type to test - */ template auto constexpr is_equality_comparable_v = is_equality_comparable::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept equals-comparable or non-equals-comparable T - */ template struct is_nothrow_equality_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the case for equals-comparable T detemining if T is noexcept comparable using operator== - */ template struct is_nothrow_equality_comparable() == std::declval())>> : std::bool_constant() == std::declval())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator== - * - * @tparam T The type to test - */ template auto constexpr is_nothrow_equality_comparable_v = is_nothrow_equality_comparable::value; - /** - * @brief A trait to test if a given type is comparable using operator!= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-not-equals-comparable T - */ template struct is_inequality_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator!= - * - * @tparam T The type to test - * @note This specialization forms the case for not-equals-comparable T - */ template struct is_inequality_comparable() != std::declval())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator!= - * - * @tparam T The type to test - */ template auto constexpr is_inequality_comparable_v = is_inequality_comparable::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator!= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept not-equals-comparable or non-not-equals-comparable T - */ template struct is_nothrow_inequality_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the case for equals-comparable T detemining if T is noexcept comparable using operator!= - */ template struct is_nothrow_inequality_comparable() != std::declval())>> : std::bool_constant() != std::declval())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator!= - * - * @tparam T The type to test - */ template auto constexpr is_nothrow_inequality_comparable_v = is_nothrow_inequality_comparable::value; @@ -141,250 +73,112 @@ namespace nt::impl inline namespace relationally_comparable { - /** - * @brief A trait to test if a given type is comparable using operator< - * - * @tparam T The type to test - * @note This specialization forms the base case for non-less-than-comparable T - */ template struct is_less_than_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator< - * - * @tparam T The type to test - * @note This specialization forms the case for less-than-comparable T - */ template struct is_less_than_comparable() < std::declval())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator< - * - * @tparam T The type to test - */ template auto constexpr is_less_than_comparable_v = is_less_than_comparable::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator< - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept less-than-comparable or non-less-than-comparable T - */ template struct is_nothrow_less_than_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator< - * - * @tparam T The type to test - * @note This specialization forms the case for less-than-comparable T detemining if T is noexcept comparable using operator< - */ template struct is_nothrow_less_than_comparable() < std::declval())>> : std::bool_constant() < std::declval())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator< - * - * @tparam T The type to test - */ template auto constexpr is_nothrow_less_than_comparable_v = is_nothrow_less_than_comparable::value; - /** - * @brief A trait to test if a given type is comparable using operator> - * - * @tparam T The type to test - * @note This specialization forms the base case for non-greater-than-comparable T - */ template struct is_greater_than_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator> - * - * @tparam T The type to test - * @note This specialization forms the case for greater-than-comparable T - */ template struct is_greater_than_comparable() > std::declval())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator> - * - * @tparam T The type to test - */ template auto constexpr is_greater_than_comparable_v = is_greater_than_comparable::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator> - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept greater-than-comparable or non-greater-than-comparable T - */ template struct is_nothrow_greater_than_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator> - * - * @tparam T The type to test - * @note This specialization forms the case for greater-than-comparable T detemining if T is noexcept comparable using operator> - */ template struct is_nothrow_greater_than_comparable() > std::declval())>> : std::bool_constant() > std::declval())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator> - * - * @tparam T The type to test - */ template auto constexpr is_nothrow_greater_than_comparable_v = is_nothrow_greater_than_comparable::value; - /** - * @brief A trait to test if a given type is comparable using operator<= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-less-than-or-equal-to-comparable T - */ template struct is_less_than_equal_to_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator<= - * - * @tparam T The type to test - * @note This specialization forms the case for less-than-or-equal-to-comparable T - */ template struct is_less_than_equal_to_comparable() <= std::declval())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator<= - * - * @tparam T The type to test - */ template auto constexpr is_less_than_equal_to_comparable_v = is_less_than_equal_to_comparable::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator<= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept less-than-or-equal-to-comparable or non-less-than-or-equal-to-comparable T - */ template struct is_nothrow_less_than_equal_to_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator<= - * - * @tparam T The type to test - * @note This specialization forms the case for less-than-or-equal-to-comparable T detemining if T is noexcept comparable using operator<= - */ template struct is_nothrow_less_than_equal_to_comparable() <= std::declval())>> : std::bool_constant() <= std::declval())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator<= - * - * @tparam T The type to test - */ template auto constexpr is_nothrow_less_than_equal_to_comparable_v = is_nothrow_less_than_equal_to_comparable::value; - /** - * @brief A trait to test if a given type is comparable using operator>= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-greater-th