aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/src/index.rst301
1 files changed, 160 insertions, 141 deletions
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`
---------------------------------------------