diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2019-12-29 19:15:26 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2019-12-29 19:15:26 +0100 |
| commit | f14db076fe96a62a1f7b0f76f7fd851714147162 (patch) | |
| tree | 3027e24d266779d203c1a4dbb65db3c054edc0d8 | |
| parent | 3a07d605ebb5d9dbee350800d551039a5b80ac6b (diff) | |
| download | newtype-f14db076fe96a62a1f7b0f76f7fd851714147162.tar.xz newtype-f14db076fe96a62a1f7b0f76f7fd851714147162.zip | |
doc: restructure documentation
| -rw-r--r-- | CMakeLists.txt | 28 | ||||
| -rw-r--r-- | doc/src/index.rst | 301 | ||||
| -rw-r--r-- | examples/src/basic_usage.cpp | 39 | ||||
| -rw-r--r-- | examples/src/basic_usage_with_read.cpp | 39 | ||||
| -rw-r--r-- | examples/src/basic_usage_with_show.cpp | 41 | ||||
| -rw-r--r-- | include/newtype/impl/new_type_storage.hpp | 1 | ||||
| -rw-r--r-- | include/newtype/new_type.hpp | 18 |
7 files changed, 323 insertions, 144 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 55d4da0..1067eb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,13 @@ if(BUILD_DOCS) message(FATAL_ERROR "Could not find pipenv") endif() + set(DOC_SOURCES + "${PROJECT_SOURCE_DIR}/doc/src/index.rst" + "${PROJECT_SOURCE_DIR}/doc/src/conf.py" + "${PROJECT_SOURCE_DIR}/examples/src/basic_usage.cpp" + "${PROJECT_SOURCE_DIR}/examples/src/basic_usage_with_show.cpp" + ) + add_custom_target("pipenv_install" COMMAND "${PIPENV_EXE}" "install" ">/dev/null" COMMENT "Installing pipenv dependencies" @@ -110,14 +117,14 @@ if(BUILD_DOCS) add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/doc/html/index.html" COMMAND "${PIPENV_EXE}" "run" "sphinx-build" "-b" "singlehtml" "${PROJECT_SOURCE_DIR}/doc/src" "${PROJECT_BINARY_DIR}/doc/html" ">/dev/null" - DEPENDS "${PROJECT_SOURCE_DIR}/doc/src/index.rst" "${PROJECT_SOURCE_DIR}/doc/src/conf.py" + DEPENDS ${DOC_SOURCES} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc" COMMENT "Compiling HTML documentation" ) add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/doc/man/newtype.3" COMMAND "${PIPENV_EXE}" "run" "sphinx-build" "-b" "man" "${PROJECT_SOURCE_DIR}/doc/src" "${PROJECT_BINARY_DIR}/doc/man" ">/dev/null" - DEPENDS "${PROJECT_SOURCE_DIR}/doc/src/index.rst" "${PROJECT_SOURCE_DIR}/doc/src/conf.py" + DEPENDS ${DOC_SOURCES} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc" COMMENT "Compiling man pages" ) @@ -135,7 +142,22 @@ if(BUILD_DOCS) install(FILES "${PROJECT_BINARY_DIR}/doc/man/${PROJECT_NAME}.3" DESTINATION "share/man/man3" ) - endif() +endif() + +# 'newtype' examples + +option(BUILD_EXAMPLES "Build the library examples" OFF) + +if(BUILD_EXAMPLES) + add_executable("ex_basic_usage" "examples/src/basic_usage.cpp") + target_link_libraries("ex_basic_usage" "${PROJECT_NAME}") + + add_executable("ex_basic_usage_with_show" "examples/src/basic_usage_with_show.cpp") + target_link_libraries("ex_basic_usage_with_show" "${PROJECT_NAME}") + + add_executable("ex_basic_usage_with_read" "examples/src/basic_usage_with_read.cpp") + target_link_libraries("ex_basic_usage_with_read" "${PROJECT_NAME}") +endif() # CMake support files diff --git a/doc/src/index.rst b/doc/src/index.rst index ab52381..ac24f36 100644 --- a/doc/src/index.rst +++ b/doc/src/index.rst @@ -1,204 +1,223 @@ +.. cpp:namespace-push:: nt + ############# Documentation ############# The ``newtype`` library provides types and functions to facilitate the creation of strong type aliases. -API -=== +Example Usage +############# -.. cpp:namespace-push:: nt +:ref:`new-type-usage-basic` below demonstrates the basic usage of :cpp:class:`new_type`. +In it, :cpp:class:`new_type` is used to create thre new strong aliases :literal:`Width`, :literal:`Height`, and :literal:`Area` that all alias :literal:`unsigned int`. + +.. literalinclude:: ../../examples/src/basic_usage.cpp + :language: c++ + :linenos: + :name: new-type-usage-basic + :caption: Basic usage of :cpp:class:`new_type` + +However, using :cpp:class:`new_type` in this fashion seem quite cumbersome. +Starting from the bottom, :literal:`unsigned int` can normally be shifted on to any :cpp:class:`std::basic_ostream`, like :cpp:var:`std::cout` in this example. +Since printing values, among other things, is a common scenario, ``newtype`` provides facilities to support automatic derivation of supporting functions. + +.. literalinclude:: ../../examples/src/basic_usage_with_show.cpp + :language: c++ + :linenos: + :name: new-type-usage-basic-show + :caption: Improved usability using the :cpp:var:`Show` derivation tag + +:ref:`new-type-usage-basic-show` demonstrates how the function template :cpp:func:`deriving` can be used to enable automatic derivation of the stream output operator for :literal:`Area`. +Similarly, it is possible to derive the stream input operators of :literal:`Width` and :literal:`Height`, as shown in :ref:`new-type-usage-basic-read` below. + +.. literalinclude:: ../../examples/src/basic_usage_with_read.cpp + :language: c++ + :linenos: + :name: new-type-usage-basic-read + :caption: Deriving input operations using the :cpp:var:`Read` derivation tag + +API +### This section of the documentation describes the public API of the *new_type*. It provides detailed descriptions of the types and functions designed to be used by applications. Additionally, this section provides usage examples that demonstrate the use and properties of the public API. +Header :literal:`<newtype/new_type.hpp>` +======================================== + +This header contains the definitions of the class template :cpp:class:`new_type` as well as a set of associated namespace-level functions. + Class template :cpp:class:`new_type` ------------------------------------ +The class template :cpp:class:`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. + .. cpp:class:: template<typename BaseType, typename TagType, auto DerivationClause = deriving()> \ new_type - The class template :cpp:class:`new_type` is designed to allow the creation of new types based on existing types. - Similarly to the Haskell :literal:`newtype`, this class template creates a new type that is layout equivalent to the underlying type. + **Member Type Aliases** - :tparam BaseType: The underlying type of the new strong alias - :tparam TagType: A type uniquely identifying this string alias - :tparam DerivationClause: A :cpp:class:`derivation_clause` listing all features that shall be automatically derived. + .. cpp:type:: base_type = BaseType + .. cpp:type:: tag_type = TagType -Usage -~~~~~ + .. cpp:type:: derivation_clause_type = decltype(DerivationClause) -:ref:`new-type-usage-simple` below demonstrate the most basic usage of :cpp:class:`new_type`. -In it, :cpp:class:`new_type` is used to create a new strong alias :literal:`width` for :literal:`unsigned int`. + **Static Data Members** -.. code-block:: c++ - :linenos: - :name: new-type-usage-simple - :caption: Creating a new strong alias for :literal:`unsigned int` + .. cpp:var:: derivation_clause_type constexpr static derivation_clause = DerivationClause - #include <newtype/new_type.hpp> + **Constructors** - using width = nt::new_type<unsigned int, struct width_tag>; + .. cpp:function:: constexpr new_type() -The class template :cpp:class:`new_type` expects the desired underlying type as its first template argument, :literal:`unsigned int` in the example above. -As a second template argument, :cpp:class:`new_type` expects a tag- or phantom-type. -Neither the underlying type, nor the tag-type are is required to be complete. + **noexcept specification:** This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow default-construtible. -The class template :cpp:class:`new_type` takes as a third template argument an instance of :cpp:class:`derivation_clause`. -Derivation clauses make it possible to let the implementation derive certain operations automatically. -For example, the derivation tag :cpp:var:`Arithmetic` enables automatic derivation of arithmetic operations for a given instance of :cpp:class:`new_type` (see :ref:`new-type-usage-deriving-arithmetic` below). + **default definition:** This constructor shall be defined as :literal:`= default` iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is default-construtible. + Otherwise, this constructor shall be explicitely deleted. -.. code-block:: c++ - :linenos: - :name: new-type-usage-deriving-arithmetic - :caption: Automatically deriving arithmetic operations + .. cpp:function:: constexpr new_type(new_type const &) - #include <newtype/new_type.hpp> + **noexcept specification:**: This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow copy-construtible. - using width = nt::new_type<unsigned int, struct width_tag, deriving(nt::Arithmetic)>; + **default definition:** This constructor shall be defined as :literal:`= default` iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is copy-construtible. + Otherwise, this constructor shall be explicitely deleted. -Synopsis -~~~~~~~~ + .. cpp:function:: constexpr new_type(new_type &&) -.. code-block:: c++ + **noexcept specification:**: This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow move-construtible. - namespace nt - { - template<typename BaseType, typename TagType, auto DerivationClause = deriving()> - class new_type - { - public: + **default definition:** This constructor shall be defined as :literal:`= default` iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is move-construtible. + Otherwise, this constructor shall be explicitely deleted. - // Type aliases + .. cpp:function:: constexpr new_type(BaseType &) - using base_type = BaseType; - using tag_type = TagType; - using derivation_clause_type = decltype(DerivationClause); + **noexcept specification:** This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow copy-construtible. - // Derivation clause access + **enablement:** This constructor shall be defined iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is copy-construtible. + Otherwise, this constructor shall be explicitely deleted. - auto constexpr static derivation_clause = DerivationClause; + .. cpp:function:: constexpr new_type(BaseType &&) - // Constructors + **noexcept specification:** This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow move-construtible. - constexpr new_type() noexcept(std::is_nothrow_default_constructible_v<BaseType>) = /*see below*/; + **enablement:** This constructor shall be defined iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is move-construtible. + Otherwise, this constructor shall be explicitely deleted. - constexpr new_type(new_type const &) noexcept(std::is_nothrow_copy_constructible_v<BaseType>) = /*see below*/; + **Assignment Operators** - constexpr new_type(new_type &&) noexcept(std::is_nothrow_move_constructible_v<BaseType>) = /*see below*/; + .. cpp:function:: constexpr new_type & operator=(new_type const &) - constexpr explicit new_type(BaseType const &) noexcept(std::is_nothrow_copy_constructible_v<BaseType>); + **noexcept specification:** This assignment operator shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow copy-assignable. - constexpr explicit new_type(BaseType &&) noexcept(std::is_nothrow_move_constructible_v<BaseType>); + **default definition:** This assignment operator shall be defined as :literal:`= default` iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is copy-assignable. + Otherwise, this assignment operator shall be explicitely deleted. - // Assignment operators + .. cpp:function:: constexpr new_type & operator=(new_type &&) - auto constexpr operator=(new_type const &) noexcept(std::is_nothrow_copy_assignable_v<BaseType>) -> new_type & = /*see below*/ + **noexcept specification:** This assignment operator shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow move-assignable. - auto constexpr operator=(new_type &&) noexcept(std::is_nothrow_move_assignable_v<BaseType>) -> new_type & = /*see below*/ + **default definition:** This assignment operator shall be defined as :literal:`= default` iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is move-assignable. + Otherwise, this assignment operator shall be explicitely deleted. - // Accessors + **Accessors** - auto constexpr decay() const noexcept -> BaseType; + .. cpp:function:: constexpr BaseType decay() const - /* EXPLICIT: see below */ constexpr operator base_type() const noexcept(/*see below*/) + **noexcept specification:** This member function shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow copy-assignable. - // Indirection operators + .. cpp:function:: constexpr operator BaseType() const - auto constexpr operator->() noexcept -> std::enable_if_t<DerivationClause(nt::Indirection), BaseType *>; + **noexcept specification:** This conversion operator shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is nothrow copy-assignable. - auto constexpr operator->() const noexcept -> std::enable_if_t<DerivationClause(nt::Indirection), BaseType const *>; + **explicit specification:** This conversion operator shall be explicit unless this :cpp:class:`new_type`'s :cpp:var:`derivation_clause` contains :cpp:var:`ImplicitConversion`. - private: - BaseType m_value; // exposition only - }; + **Member Access Trough Pointer** - // Equality comparison operators - - template<typename BaseType, - typename TagType, - auto DerivationClause> - auto constexpr operator==(new_type<BaseType, TagType, DerivationClause> const &, - new_type<BaseType, TagType, DerivationClause> const &) noexcept(/*see below*/) - -> bool; - - template<typename BaseType, - typename TagType, - auto DerivationClause> - auto constexpr operator!=(new_type<BaseType, TagType, DerivationClause> const &, - new_type<BaseType, TagType, DerivationClause> const &) noexcept(/*see below*/) - -> bool; - - // Relational operators - - template<typename BaseType, - typename TagType, - auto DerivationClause> - auto constexpr operator<(new_type<BaseType, TagType, DerivationClause> const &, - new_type<BaseType, TagType, DerivationClause> const &) noexcept(/*see below*/) - -> std::enable_if_t<DerivationClause(nt::Relational) && /*see below*/, bool>; - - template<typename BaseType, - typename TagType, - auto DerivationClause> - auto constexpr operator>(new_type<BaseType, TagType, DerivationClause> const &, - new_type<BaseType, TagType, DerivationClause> const &) noexcept(/*see below*/) - -> std::enable_if_t<DerivationClause(nt::Relational) && /*see below*/, bool>; - - template<typename BaseType, - typename TagType, - auto DerivationClause> - auto constexpr operator<=(new_type<BaseType, TagType, DerivationClause> const &, - new_type<BaseType, TagType, DerivationClause> const &) noexcept(/*see below*/) - -> std::enable_if_t<DerivationClause(nt::Relational) && /*see below*/, bool>; - - template<typename BaseType, - typename TagType, - auto DerivationClause> - auto constexpr operator>=(new_type<BaseType, TagType, DerivationClause> const &, - new_type<BaseType, TagType, DerivationClause> const &) noexcept(/*see below*/) - -> std::enable_if_t<DerivationClause(nt::Relational) && /*see below*/, bool>; - - // Stream input/output operators - - template<typename BaseType, - typename TagType, - auto DerivationClause, - typename CharType, - typename StreamTraits> - auto operator<<(std::basic_ostream<CharType, StreamTraits> &, - new_type<BaseType, TagType, DerivationClause> const &) noexcept(/*see below*/) - -> std::enable_if_t<DerivationClause(nt::Show) && /*see below*/, std::basic_ostream<CharType, StreamTraits>> &; - - template<typename BaseType, - typename TagType, - auto DerivationClause, - typename CharType, - typename StreamTraits> - auto operator>>(std::basic_istream<CharType, StreamTraits> &, - new_type<BaseType, TagType, DerivationClause> &) noexcept(/*see below*/) - -> std::enable_if_t<DerivationClause(nt::Read) && /*see below*/, std::basic_istream<CharType, StreamTraits>> &; - } + .. cpp:function:: constexpr BaseType operator->() noexcept + + **enablement:** This operator shall be available iff. this :cpp:class:`new_type`'s :cpp:var:`derivation_clause` contains :cpp:var:`Indirection` + + .. cpp:function:: constexpr BaseType const * operator->() const noexcept + + **enablement:** This operator shall be available iff. this :cpp:class:`new_type`'s :cpp:var:`derivation_clause` contains :cpp:var:`Indirection` + +Namespace-level functions and function templates +------------------------------------------------ + +The functions and functions templates described in this section provide additional functionality for the class template :cpp:class:`new_type` that is not part of the class itself. + +Equality Comparison Operators +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. cpp:function:: template<typename BaseType, \ + typename TagType, \ + auto DerivationClause> \ + constexpr bool operator==(new_type<BaseType, TagType, DerivationClause> const &,\ + new_type<BaseType, TagType, DerivationClause> const &) + + **noexcept specification:** This conversion operator shall be noexcept iff. :cpp:type:`new_type<BaseType, TagType, DerivationClause>::base_type` is nothrow equals-comparable. + + **enablement:** This operator shall be available iff. :cpp:type:`new_type<BaseType, TagType, DerivationClause>::base_type` supports comparison using the operator :literal:`==` + +.. cpp:function:: template<typename BaseType, \ + typename TagType, \ + auto DerivationClause> \ + constexpr bool operator!=(new_type<BaseType, TagType, DerivationClause> const &,\ + new_type<BaseType, TagType, DerivationClause> const &) + + **noexcept specification:** This conversion operator shall be noexcept iff. :cpp:type:`new_type<BaseType, TagType, DerivationClause>::base_type` is nothrow not-equals-comparable. + + **enablement:** This operator shall be available iff. this :cpp:type:`new_type<BaseType, TagType, DerivationClause>::base_type` supports comparison using the operator :literal:`!=` + +Relational Comparison Operators +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. cpp:function:: template<typename BaseType, \ + typename TagType, \ + auto DerivationClause> \ + constexpr bool operator<(new_type<BaseType, TagType, DerivationClause> const &, \ + new_type<BaseType, TagType, DerivationClause> const &) -Member Type Aliases -~~~~~~~~~~~~~~~~~~~ +.. cpp:function:: template<typename BaseType, \ + typename TagType, \ + auto DerivationClause> \ + constexpr bool operator>(new_type<BaseType, TagType, DerivationClause> const &, \ + new_type<BaseType, TagType, DerivationClause> const &) -Static Data Members -~~~~~~~~~~~~~~~~~~~ +.. cpp:function:: template<typename BaseType, \ + typename TagType, \ + auto DerivationClause> \ + constexpr bool operator<=(new_type<BaseType, TagType, DerivationClause> const &, \ + new_type<BaseType, TagType, DerivationClause> const &) -Special Member Functions -~~~~~~~~~~~~~~~~~~~~~~~~ +.. cpp:function:: template<typename BaseType, \ + typename TagType, \ + auto DerivationClause> \ + constexpr bool operator>=(new_type<BaseType, TagType, DerivationClause> const &, \ + new_type<BaseType, TagType, DerivationClause> const &) -Free Equality Comparison Operators -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Stream I/O Operators +~~~~~~~~~~~~~~~~~~~~ -Free Relational Operators -~~~~~~~~~~~~~~~~~~~~~~~~~ +.. cpp:function:: template<typename BaseType, \ + typename TagType, \ + auto DerivationClause, \ + typename CharType, \ + typename StreamTraits> \ + std::basic_ostream<CharType, StreamTraits> & operator<<(std::basic_ostream<CharType, StreamTraits> &, \ + new_type<BaseType, TagType, DerivationClause> const &) -Free Stream Input/Ouput Operators -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. cpp:function:: template<typename BaseType, \ + typename TagType, \ + auto DerivationClause, \ + typename CharType, \ + typename StreamTraits> \ + std::basic_istream<CharType, StreamTraits> & operator>>(std::basic_istream<CharType, StreamTraits> &, \ + new_type<BaseType, TagType, DerivationClause> &) Class template :cpp:class:`derivation_clause` --------------------------------------------- diff --git a/examples/src/basic_usage.cpp b/examples/src/basic_usage.cpp new file mode 100644 index 0000000..a2a50cd --- /dev/null +++ b/examples/src/basic_usage.cpp @@ -0,0 +1,39 @@ +#include <newtype/new_type.hpp> + +#include <iostream> + +using Width = nt::new_type<unsigned int, struct width_tag>; +using Height = nt::new_type<unsigned int, struct height_tag>; +using Area = nt::new_type<unsigned int, struct area_tag>; + +struct Rectangle +{ + constexpr Rectangle(Width w, Height h) + : width{w} + , height{h} + { + } + + auto constexpr area() const noexcept -> Area + { + return {width.decay() * height.decay()}; + } + +private: + Width width; + Height height; +}; + +int main() +{ + auto w{0u}, h{0u}; + + std::cin >> w >> h; + + auto width = Width{w}; + auto height = Height{h}; + + auto rect = Rectangle{width, height}; + + std::cout << rect.area().decay() << '\n'; +}
\ No newline at end of file diff --git a/examples/src/basic_usage_with_read.cpp b/examples/src/basic_usage_with_read.cpp new file mode 100644 index 0000000..87fcc1a --- /dev/null +++ b/examples/src/basic_usage_with_read.cpp @@ -0,0 +1,39 @@ +#include <newtype/derivable.hpp> +#include <newtype/deriving.hpp> +#include <newtype/new_type.hpp> + +#include <iostream> + +using Width = nt::new_type<unsigned int, struct width_tag, deriving(nt::Read)>; +using Height = nt::new_type<unsigned int, struct height_tag, deriving(nt::Read)>; +using Area = nt::new_type<unsigned int, struct area_tag, deriving(nt::Show)>; + +struct Rectangle +{ + constexpr Rectangle(Width w, Height h) + : width{w} + , height{h} + { + } + + auto constexpr area() const noexcept -> Area + { + return {width.decay() * height.decay()}; + } + +private: + Width width; + Height height; +}; + +int main() +{ + auto width = Width{}; + auto height = Height{}; + + std::cin >> width >> height; + + auto rect = Rectangle{width, height}; + + std::cout << rect.area() << '\n'; +}
\ No newline at end of file diff --git a/examples/src/basic_usage_with_show.cpp b/examples/src/basic_usage_with_show.cpp new file mode 100644 index 0000000..1a83968 --- /dev/null +++ b/examples/src/basic_usage_with_show.cpp @@ -0,0 +1,41 @@ +#include <newtype/derivable.hpp> +#include <newtype/deriving.hpp> +#include <newtype/new_type.hpp> + +#include <iostream> + +using Width = nt::new_type<unsigned int, struct width_tag>; +using Height = nt::new_type<unsigned int, struct height_tag>; +using Area = nt::new_type<unsigned int, struct area_tag, deriving(nt::Show)>; + +struct Rectangle +{ + constexpr Rectangle(Width w, Height h) + : width{w} + , height{h} + { + } + + auto constexpr area() const noexcept -> Area + { + return {width.decay() * height.decay()}; + } + +private: + Width width; + Height height; +}; + +int main() +{ + auto w{0u}, h{0u}; + + std::cin >> w >> h; + + auto width = Width{w}; + auto height = Height{h}; + + auto rect = Rectangle{width, height}; + + std::cout << rect.area() << '\n'; +}
\ No newline at end of file diff --git a/include/newtype/impl/new_type_storage.hpp b/include/newtype/impl/new_type_storage.hpp index 5f64771..5cec601 100644 --- a/include/newtype/impl/new_type_storage.hpp +++ b/include/newtype/impl/new_type_storage.hpp @@ -2,6 +2,7 @@ #define NEWTYPE_IMPL_NEW_TYPE_STORAGE_HPP #include <type_traits> +#include <utility> namespace nt::impl { diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp index 0b7d6d0..77b531e 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -39,6 +39,8 @@ namespace nt using super = impl::new_type_move_assignment<BaseType, TagType>; public: + /// @section Type aliases + /** * @brief The base type of this nt::new_type * @@ -60,6 +62,8 @@ namespace nt */ using derivation_clause_type = decltype(DerivationClause); + /// @section Derivation clause access + /** * @brief The derivation clause fo this nt::new_type * @@ -67,6 +71,8 @@ namespace nt */ auto constexpr static derivation_clause = DerivationClause; + /// @section Constructors + using super::super; /** @@ -95,6 +101,8 @@ namespace nt */ constexpr new_type(new_type &&) noexcept(std::is_nothrow_move_constructible_v<BaseType>) = default; + /// @section Assignment operators + /** * @brief Copy-assign the value of an existing instance of this nt::new_type to this instance * @@ -115,6 +123,8 @@ namespace nt */ auto constexpr operator=(new_type &&) noexcept(std::is_nothrow_move_assignable_v<BaseType>) -> new_type & = default; + /// @section Accessors + /** * @brief Obtain a copy of the contained base type object * @@ -147,6 +157,8 @@ namespace nt return decay(); } + /// @section Indirection operators + /** * @brief Perform an access to a member of the base type * @@ -170,6 +182,8 @@ namespace nt } }; + /// @section Equality comparison operators + /** * @brief Compare two objects for equality * @@ -202,6 +216,8 @@ namespace nt return lhs.decay() != rhs.decay(); } + /// @section Relational operators + /** * @brief Check if one nt::new_type object is less-than an other * @@ -274,6 +290,8 @@ namespace nt return lhs.decay() >= rhs.decay(); } + /// @section Stream input/output operators + /** * @brief Write the contained base type object to a standard output stream * |
