aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/CMakeLists.txt19
-rw-r--r--source/doc/.gitignore2
-rw-r--r--source/doc/CMakeLists.txt81
-rw-r--r--source/doc/requirements.txt1
-rw-r--r--source/doc/src/conf.py48
-rw-r--r--source/doc/src/index.rst1271
-rw-r--r--source/examples/CMakeLists.txt15
-rw-r--r--source/examples/src/basic_usage.cpp39
-rw-r--r--source/examples/src/basic_usage_with_read.cpp37
-rw-r--r--source/examples/src/basic_usage_with_show.cpp39
-rw-r--r--source/lib/CMakeLists.txt16
-rw-r--r--source/lib/include/newtype/newtype.hpp753
-rw-r--r--source/tests/CMakeLists.txt33
-rw-r--r--source/tests/src/arithmetic.cpp297
-rw-r--r--source/tests/src/constructors.cpp102
-rw-r--r--source/tests/src/conversion.cpp133
-rw-r--r--source/tests/src/derivation_clause.cpp63
-rw-r--r--source/tests/src/equality_comparison.cpp102
-rw-r--r--source/tests/src/hash.cpp59
-rw-r--r--source/tests/src/io_operators.cpp110
-rw-r--r--source/tests/src/iterable.cpp1060
-rw-r--r--source/tests/src/relational_operators.cpp249
-rw-r--r--source/tests/src/threeway_comparison.cpp52
23 files changed, 0 insertions, 4581 deletions
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
deleted file mode 100644
index 984e085..0000000
--- a/source/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION "3.25.0")
-
-project("newtype"
- LANGUAGES CXX
- DESCRIPTION "A library of types and functions to create strong type aliases"
-)
-
-enable_testing()
-
-# Project Options
-
-option(BUILD_EXAMPLES "Build the library examples" OFF)
-
-# Project Components
-
-add_subdirectory("doc")
-add_subdirectory("examples")
-add_subdirectory("lib")
-add_subdirectory("tests") \ No newline at end of file
diff --git a/source/doc/.gitignore b/source/doc/.gitignore
deleted file mode 100644
index ee826c1..0000000
--- a/source/doc/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Pipfile
-Pipfile.lock
diff --git a/source/doc/CMakeLists.txt b/source/doc/CMakeLists.txt
deleted file mode 100644
index 7a9e27d..0000000
--- a/source/doc/CMakeLists.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-find_package("Python3"
- REQUIRED
- COMPONENTS "Interpreter"
-)
-
-set(DOCENV_DIR "${PROJECT_BINARY_DIR}/docenv")
-
-if(NOT EXISTS "${DOCENV_DIR}")
- message(STATUS "Creating Python virtual environment")
- execute_process(COMMAND "${Python3_EXECUTABLE}"
- "-m"
- "venv"
- "${DOCENV_DIR}"
- OUTPUT_QUIET
- )
- message(STATUS "Installing documentation requirements")
- execute_process(COMMAND
- "${DOCENV_DIR}/bin/python"
- "-m"
- "pip"
- "install"
- "-r"
- "${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt"
- OUTPUT_QUIET
- )
-else()
- message(STATUS "Reusing existing Python virtual environment")
-endif()
-
-file(GLOB SOURCES
- CONFIGURE_DEPENDS
- "${CMAKE_CURRENT_SOURCE_DIR}/src/*"
- "${PROJECT_SOURCE_DIR}/examples/src/*"
-)
-
-add_custom_target("docs"
- ALL
- DEPENDS
- "${CMAKE_CURRENT_BINARY_DIR}/html/index.html"
- "${CMAKE_CURRENT_BINARY_DIR}/man/newtype.3"
- WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
- COMMENT "Building documentation"
-)
-
-add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/html/index.html"
- COMMAND "${DOCENV_DIR}/bin/sphinx-build"
- "-q"
- "-b"
- "singlehtml"
- "-E"
- "${CMAKE_CURRENT_SOURCE_DIR}/src"
- "${CMAKE_CURRENT_BINARY_DIR}/html"
- DEPENDS ${SOURCES}
- WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
- COMMENT "Compiling HTML documentation"
-)
-
-add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/man/newtype.3"
- COMMAND "${DOCENV_DIR}/bin/sphinx-build"
- "-q"
- "-b"
- "man"
- "-E"
- "${CMAKE_CURRENT_SOURCE_DIR}/src"
- "${CMAKE_CURRENT_BINARY_DIR}/man"
- DEPENDS ${SOURCES}
- WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
- COMMENT "Compiling man page"
-)
-
-install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/singlehtml"
- TYPE DOC
- PATTERN ".doctrees" EXCLUDE
- PATTERN ".buildinfo" EXCLUDE
- PATTERN ".nojekyll" EXCLUDE
-)
-
-install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/man/"
- TYPE MAN
- PATTERN ".doctrees" EXCLUDE
-)
diff --git a/source/doc/requirements.txt b/source/doc/requirements.txt
deleted file mode 100644
index 47b0805..0000000
--- a/source/doc/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-sphinx~=7.0
diff --git a/source/doc/src/conf.py b/source/doc/src/conf.py
deleted file mode 100644
index a6e65de..0000000
--- a/source/doc/src/conf.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import os
-
-
-# -- Project information -----------------------------------------------------
-
-project = 'newtype'
-copyright = '2023, Felix Morgner'
-author = 'Felix Morgner'
-version = '2.0'
-release = '2.0.0'
-
-
-# -- General configuration ---------------------------------------------------
-
-master_doc = 'index'
-
-extensions = [
- 'sphinx.ext.todo',
- 'sphinx.ext.githubpages',
-]
-
-highlight_language = 'c++'
-
-pygments_style = 'tango'
-
-exclude_patterns = []
-
-numfig = True
-
-# -- Options for HTML output -------------------------------------------------
-
-html_theme = 'haiku'
-html_theme_options = {
-}
-
-# -- Options for manual page output -------------------------------------------------
-
-man_pages = [
- (
- "index",
- "newtype",
- "A library of types and functions to create strong type aliases",
- ["Felix Morgner <felix.morgner@gmail.com>"],
- 3,
- ),
-] \ No newline at end of file
diff --git a/source/doc/src/index.rst b/source/doc/src/index.rst
deleted file mode 100644
index 88925aa..0000000
--- a/source/doc/src/index.rst
+++ /dev/null
@@ -1,1271 +0,0 @@
-.. cpp:namespace-push:: nt
-
-.. |BaseTypeDoc| replace:: The type of the contained object
-.. |TagTypeDoc| replace:: A tag to uniquely identify an instance of :cpp:class:`nt::new_type`
-.. |DerivationClauseDoc| replace:: A (possibly empty) list of derivation tags as generated by :cpp:func:`nt::deriving`
-
-.. only:: html
-
- .. contents:: Table of Contents
- :depth: 5
-
-#############
-Documentation
-#############
-
-The ``newtype`` library provides types and functions to facilitate the creation of strong type aliases.
-
-Example Usage
-#############
-
-.. note::
-
- All examples shown in this section can be found in the directory :literal:`examples/src` within the source root.
-
-:ref:`new-type-usage-basic` below illustrates the basic usage of :cpp:class:`new_type`.
-In it, :cpp:class:`new_type` is used to create three new strong aliases :literal:`Width`, :literal:`Height`, and :literal:`Area`, all aliasing :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 is 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 others, is a common use case, ``newtype`` provides facilities to support automatic derivation of supporting functions.
-
-.. literalinclude:: ../../examples/src/basic_usage_with_show.cpp
- :emphasize-lines: 7,38
- :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` illustrates 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
- :emphasize-lines: 5,6,29,30,32
- :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.
-All declarations described in this section are found in the namespace :cpp:any:`nt`, unless noted otherwise.
-
-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`
-------------------------------------
-
-.. 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 newtype keyword in Haskell, this class template creates a new type that is layout equivalent to the underlying type.
- During creation of the of new strong type, features can be derived using :cpp:any:`nt::deriving`.
- Actual feature availability depends on the :cpp:any:`BaseType` chosen for :cpp:class:`new_type` instance.
- For example, deriving :cpp:any:`nt::Show` for a :cpp:class:`new_type` instance over a type not supporting output on a standard output stream, will not cause the instance to be output-streamable.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
-
- .. versionadded:: 1.0.0
-
- **Member Type Aliases**
-
- .. cpp:type:: base_type = BaseType
-
- .. cpp:type:: tag_type = TagType
-
- .. cpp:type:: derivation_clause_type = decltype(DerivationClause)
-
- .. cpp:type:: iterator = typename BaseType::iterator
-
- :enablement: This type alias is defined iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` has a member type :cpp:type:`iterator <new_type::base_type::iterator>` and the :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable`.
-
- .. versionadded:: 1.1.0
-
- .. cpp:type:: const_iterator = typename BaseType::const_iterator
-
- :enablement: This type alias is defined iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` has a member type :cpp:type:`const_iterator <new_type::base_type::const_iterator>` and the :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable`.
-
- .. versionadded:: 1.1.0
-
- .. cpp:type:: reverse_iterator = typename BaseType::reverse_iterator
-
- :enablement: This type alias is defined iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` has a member type :cpp:type:`reverse_iterator <new_type::base_type::reverse_iterator>` and the :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable`.
-
- .. versionadded:: 1.1.0
-
- .. cpp:type:: const_reverse_iterator = typename BaseType::const_reverse_iterator
-
- :enablement: This type alias is defined iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` has a member type :cpp:type:`const_reverse_iterator <new_type::base_type::const_reverse_iterator>` and the :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable`.
-
- .. versionadded:: 1.1.0
-
- **Static Data Members**
-
- .. cpp:var:: static derivation_clause_type constexpr derivation_clause = DerivationClause
-
- **Constructors**
-
- .. cpp:function:: constexpr new_type() noexcept(std::is_nothrow_default_constructible_v<base_type>)
-
- Construct a new instance of this :cpp:class:`new_type` by default constructing the contained object.
-
- :throws: Any exception thrown by the default constructor of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This constructor is noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow default-construtible*.
- :enablement: This constructor is defined as :cpp:expr:`= default` iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *default-construtible*.
- Otherwise, this constructor is declared as explicitely deleted.
-
- .. cpp:function:: constexpr new_type(new_type const & other) noexcept(std::is_nothrow_copy_constructible_v<base_type>)
-
- Construct a new instance of this :cpp:class:`new_type` by copy-constructing the contained object using the value contained by :cpp:any:`other`.
-
- :param other: An existing instance of this :cpp:class:`new_type`
- :throws: Any exception thrown by the copy-constructor of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow copy-construtible*.
- :enablement: 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.
-
- .. cpp:function:: constexpr new_type(new_type && other)
-
- Construct a new instance of this :cpp:class:`new_type` by move-constructing the contained object using the value contained by :literal:`other`.
-
- :param other: An existing instance of this :cpp:class:`new_type`
- :throws: Any exception thrown by the move-constructor of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow move-construtible*.
- :enablement: 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.
-
- .. cpp:function:: constexpr new_type(BaseType const & value)
-
- Construct a new instance of this :cpp:class:`new_type` by copy-constructing the contained object using :literal:`value`.
-
- :param value: An existing instance of this :cpp:class:`new_type`
- :throws: Any exception thrown by the copy-constructor of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow copy-construtible*.
- :enablement: 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.
-
- .. cpp:function:: constexpr new_type(BaseType && value)
-
- Construct a new instance of this :cpp:class:`new_type` by move-constructing the contained object using :literal:`value`.
-
- :param value: An existing instance of this :cpp:class:`new_type`
- :throws: Any exception thrown by the move-constructor of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This constructor shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow move-construtible*.
- :enablement: 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.
-
- **Assignment Operators**
-
- .. cpp:function:: constexpr new_type & operator=(new_type const & other)
-
- Copy the value of an existing instance of this :cpp:class:`new_type` and replace this instance's value
-
- :param other: An existing instance of this :cpp:class:`new_type`
- :throws: Any exception thrown by the copy-assignment operator of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This operator shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow copy-assignable*.
- :enablement: This operator shall be defined as :literal:`= default` iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *copy-assignable*.
- Otherwise, this operator shall be explicitely deleted.
-
- .. cpp:function:: constexpr new_type & operator=(new_type && other)
-
- Move the value of an existing instance of this :cpp:class:`new_type` and replace this instance's value
-
- :param other: An existing instance of this :cpp:class:`new_type`
- :throws: Any exception thrown by the move-assignment operator of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This operator shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow move-assignable*.
- :enablement: This operator shall be defined as :literal:`= default` iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *move-assignable*.
- Otherwise, this operator shall be explicitely deleted.
-
- **Accessors**
-
- .. cpp:function:: constexpr BaseType decay() const
-
- Retrieve a copy of the object contained by this :cpp:class:`new_type` object
-
- :throws: Any exception thrown by the copy-constructor of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This operator shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow copy-constructible*.
-
- .. cpp:function:: constexpr operator BaseType() const
-
- Retrieve a copy of the object contained by this :cpp:class:`new_type` object
-
- :throws: Any exception thrown by the copy-constructor of this :cpp:class:`new_type`'s :cpp:type:`base_type`.
- This operator shall be noexcept iff. this :cpp:class:`new_type`'s :cpp:type:`base_type` is *nothrow copy-constructible*.
- :explicit: This conversion operator shall be explicit unless this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`ImplicitConversion`.
-
- **Member Access Through Pointer**
-
- .. cpp:function:: constexpr BaseType operator->() noexcept
-
- Perform "member access through pointer" via a pointer to object contained by this :cpp:class:`new_type`
-
- :enablement: This operator shall be available iff. this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Indirection`
-
- .. cpp:function:: constexpr BaseType const * operator->() const noexcept
-
- Perform "member access through pointer" via a pointer to object contained by this :cpp:class:`new_type`
-
- :enablement: This operator shall be available iff. this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Indirection`
-
- **Iterators**
-
- .. cpp:function:: constexpr iterator begin()
-
- Get an iterator to the beginning of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`begin() <new_type::base_type::begin()>` that returns an instance of type :cpp:type:`iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator begin() const
-
- Get a constant iterator to the beginning of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`begin() const <new_type::base_type::begin()>` that returns an instance of type :cpp:type:`const_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator cbegin() const
-
- Get a constant iterator to the beginning of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`cbegin() const <new_type::base_type::cbegin()>` that returns an instance of type :cpp:type:`const_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator rbegin()
-
- Get a reverse iterator to the beginning of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`rbegin() <new_type::base_type::rbegin()>` that returns an instance of type :cpp:type:`reverse_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator rbegin() const
-
- Get a constant reverse iterator to the beginning of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`rbegin() const <new_type::base_type::rbegin()>` that returns an instance of type :cpp:type:`const_reverse_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator crbegin() const
-
- Get a constant reverse iterator to the beginning of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`crbegin() const <new_type::base_type::crbegin()>` that returns an instance of type :cpp:type:`const_reverse_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator end()
-
- Get an iterator beyond the end of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`end() <new_type::base_type::end()>` that returns an instance of type :cpp:type:`iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator end() const
-
- Get a constant iterator beyond the end of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`end() const <new_type::base_type::end()>` that returns an instance of type :cpp:type:`const_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator cend() const
-
- Get a constant iterator beyond the end of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`cend() const <new_type::base_type::cend()>` that returns an instance of type :cpp:type:`const_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator rend()
-
- Get a reverse iterator beyond the end of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`rend() <new_type::base_type::rend()>` that returns an instance of type :cpp:type:`reverse_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator rend() const
-
- Get a constant reverse iterator beyond the end of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`rend() const <new_type::base_type::rend()>` that returns an instance of type :cpp:type:`const_reverse_iterator`
-
- .. versionadded:: 1.1.0
-
- .. cpp:function:: constexpr iterator crend() const
-
- Get a constant reverse iterator beyond the end of the object contained by this :cpp:class:`new_type`
-
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <derivation_clause>` contains :cpp:var:`Iterable` and
- b) this :cpp:class:`new_type`'s :cpp:type:`base type <base_type>` has a non-static member function :cpp:func:`crend() const <new_type::base_type::crend()>` that returns an instance of type :cpp:type:`const_reverse_iterator`
-
- .. versionadded:: 1.1.0
-
-:literal:`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 & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Check two instances of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` for equality.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of the contained objects.
- :throws: Any exception thrown by the comparison operator of objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow equals-comparable*.
- :enablement: This operator shall be available iff. :cpp:type:`new_type::base_type` supports comparison using :literal:`==`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator==(new_type<BaseType, TagType, DerivationClause> const & lhs, BaseType const & rhs)
-
- Check an instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` for equality with an instance of :cpp:type:`BaseType`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of object contained by :literal:`lhs` with an object of the :cpp:type:`base type <new_type::base_type>`.
- :throws: Any exception thrown by the comparison of object contained by :literal:`lhs` with an object of the :cpp:type:`base type <new_type::base_type>`. This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow equals-comparable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports comparison using :literal:`==` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`EqBase`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator==(BaseType const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Check an instance of :cpp:type:`BaseType` for equality with an instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of an object of :cpp:type:`base type <new_type::base_type>` with the object contained by :literal:`rhs`.
- :throws: Any exception thrown by the comparison of an object of :cpp:type:`base type <new_type::base_type>` with the object contained by :literal:`rhs`. This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow equals-comparable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports comparison using :literal:`==` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`EqBase`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator!=(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Check two instances of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` for in-equality.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of the contained objects.
- :throws: Any exception thrown by the comparison operator of theobjects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow not-equals-comparable*.
- :enablement: This operator shall be available iff. :cpp:type:`new_type::base_type` supports comparison using :literal:`!=`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator!=(new_type<BaseType, TagType, DerivationClause> const & lhs, BaseType const & rhs)
-
- Check an instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` for in-equality with an instance of :cpp:type:`BaseType`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of the object contained by :literal:`lhs` with an object of the :cpp:type:`base type <new_type::base_type>`.
- :throws: Any exception thrown by the comparison of the object contained by :literal:`lhs` with an object of the :cpp:type:`base type <new_type::base_type>`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow not-equals-comparable*.
- :enablement: This operator shall be available iff.
-
- a) :cpp:type:`new_type::base_type` supports comparison using :literal:`!=` and
- b) the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`EqBase`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator!=(BaseType const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Check an instance of :cpp:type:`BaseType` for in-equality with an instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of an object of :cpp:type:`base type <new_type::base_type>` with the object contained by :literal:`rhs`.
- :throws: Any exception thrown by the comparison of an object of :cpp:type:`base type <new_type::base_type>` with the object contained by :literal:`rhs`. This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow not-equals-comparable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports comparison using :literal:`!=` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`EqBase`
-
- .. versionadded:: 1.0.0
-
-Relational Comparison Operators
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator<(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Compare two instances of the same :cpp:class:`new_type` using :literal:`<` (*less-than*).
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of the contained objects.
- :throws: Any exception thrown by the comparison operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow less-than-comparable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports comparison using :literal:`<` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Relational`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator>(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Compare two instances of the same :cpp:class:`new_type` using :literal:`>` (*greater-than*).
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of the contained objects.
- :throws: Any exception thrown by the comparison operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow greater-than-comparable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports comparison using :literal:`>` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Relational`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator<=(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Compare two instances of the same :cpp:class:`new_type` using :literal:`<=` (*less-than-equal*).
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of the contained objects.
- :throws: Any exception thrown by the comparison operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow less-than-equal-comparable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports comparison using :literal:`<=` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Relational`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr bool operator>=(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Compare two instances of the same :cpp:class:`new_type` using :literal:`>=` (*greater-than-equal*).
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the comparison
- :param rhs: The right-hand side of the comparison
- :returns: The value returned by the comparison of the contained objects.
- :throws: Any exception thrown by the comparison operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow greater-than-equal-comparable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports comparison using :literal:`>=` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Relational`
-
- .. versionadded:: 1.0.0
-
-Stream I/O 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> & out, new_type<BaseType, TagType, DerivationClause> const & value)
-
- Write an instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` to a standard :cpp:type:`ostream <std::ostream>`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :tparam CharType: The stream character type
- :tparam StreamTraits: The traits of the output stream
- :param out: The output stream
- :param value: A :cpp:class:`new_type` value to write to the output stream
- :returns: A reference to the output stream
- :throws: Any exception thrown by the stream-output operator of the object contained by :literal:`value`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow output-streamable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports being written to an output stream using :literal:`<<` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Show`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, \
- typename TagType, \
- auto DerivationClause, \
- typename CharType, \
- typename StreamTraits> \
- std::basic_istream<CharType, StreamTraits> & operator>>(std::basic_istream<CharType, StreamTraits> & in, new_type<BaseType, TagType, DerivationClause> & value)
-
- Read an instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` from a standard :cpp:type:`istream <std::istream>`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :tparam CharType: The stream character type
- :tparam StreamTraits: The traits of the input stream
- :param in: The input stream
- :param value: A :cpp:class:`new_type` value to be read from the output stream
- :returns: A reference to the input stream
- :throws: Any exception thrown by the stream-input operator of the object contained by :literal:`value`.
- This operator shall be noexcept iff. :cpp:type:`new_type::base_type` is *nothrow input-streamable*.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports being read from an input stream using :literal:`>>` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Read`
-
- .. versionadded:: 1.0.0
-
-Arithmetic Operators
-~~~~~~~~~~~~~~~~~~~~
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause> operator+(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Add two instances of the same :cpp:class:`new_type`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the addition
- :param rhs: The right-hand side of the addition
- :returns: A new instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` containing the result of applying :literal:`+` to the objects contained by :literal:`lhs` and :literal:`rhs`.
- :throws: Any exception thrown by the addition operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff.
-
- a. :cpp:type:`new_type::base_type` is *nothrow addable* and
- b. :cpp:type:`new_type::base_type` is *nothrow copy-constructible*
-
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports addition using :literal:`+` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Arithmetic`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause> & operator+=(new_type<BaseType, TagType, DerivationClause> & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Add two instances of the same :cpp:class:`new_type` by overwriting the first one.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the addition
- :param rhs: The right-hand side of the addition
- :returns: A reference to the first argument containing the value modified by applying :literal:`+=` to the objects contained by :literal:`lhs` and :literal:`rhs`.
- :throws: Any exception thrown by the addition-assignment operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff.
-
- a. :cpp:type:`new_type::base_type` is *nothrow add-assignable* and
- b. :cpp:type:`new_type::base_type` is *nothrow copy-constructible*
-
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports addition using :literal:`+=` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Arithmetic`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause> operator-(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Subtract two instances of the same :cpp:class:`new_type`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the subtraction
- :param rhs: The right-hand side of the subtraction
- :returns: A new instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` containing the result of applying :literal:`-` to the objects contained by :literal:`lhs` and :literal:`rhs`.
- :throws: Any exception thrown by the subtraction operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff.
-
- a. :cpp:type:`new_type::base_type` is *nothrow subtractable* and
- b. :cpp:type:`new_type::base_type` is *nothrow copy-constructible*
-
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports subtraction using :literal:`-` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Arithmetic`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause> & operator-=(new_type<BaseType, TagType, DerivationClause> & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Subtract two instances of the same :cpp:class:`new_type` by overwriting the first one.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the subtraction
- :param rhs: The right-hand side of the subtraction
- :returns: A reference to the first argument containing the value modified by applying :literal:`-=` to the objects contained by :literal:`lhs` and :literal:`rhs`.
- :throws: Any exception thrown by the subtraction-assignment operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff.
-
- a. :cpp:type:`new_type::base_type` is *nothrow subtract-assignable* and
- b. :cpp:type:`new_type::base_type` is *nothrow copy-constructible*
-
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports subtraction using :literal:`-=` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Arithmetic`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause> operator*(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Multiply two instances of the same :cpp:class:`new_type`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the multiplication
- :param rhs: The right-hand side of the multiplication
- :returns: A new instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` containing the result of applying :literal:`*` to the objects contained by :literal:`lhs` and :literal:`rhs`.
- :throws: Any exception thrown by the multiplication operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff.
-
- a. :cpp:type:`new_type::base_type` is *nothrow multipliable* and
- b. :cpp:type:`new_type::base_type` is *nothrow copy-constructible*
-
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports multiplication using :literal:`*` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Arithmetic`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause> & operator*=(new_type<BaseType, TagType, DerivationClause> & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Multiply two instances of the same :cpp:class:`new_type` by overwriting the first one.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the multiplication
- :param rhs: The right-hand side of the multiplication
- :returns: A reference to the first argument containing the value modified by applying :literal:`*=` to the objects contained by :literal:`lhs` and :literal:`rhs`.
- :throws: Any exception thrown by the multiplication-assignment operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff.
-
- a. :cpp:type:`new_type::base_type` is *nothrow multiply-assignable* and
- b. :cpp:type:`new_type::base_type` is *nothrow copy-constructible*
-
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports multiplication using :literal:`*=` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Arithmetic`
-
- .. versionadded:: 1.0.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause> operator/(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Divide two instances of the same :cpp:class:`new_type`.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the division
- :param rhs: The right-hand side of the division
- :returns: A new instance of :cpp:class:`new_type\<BaseType, TagType, DerivationClause>` containing the result of applying :literal:`/` to the objects contained by :literal:`lhs` and :literal:`rhs`.
- :throws: Any exception thrown by the division operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff.
-
- a. :cpp:type:`new_type::base_type` is *nothrow dividable* and
- b. :cpp:type:`new_type::base_type` is *nothrow copy-constructible*
-
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports division using :literal:`/` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Arithmetic`
-
- .. versionadded:: 1.0.0
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause> & operator/=(new_type<BaseType, TagType, DerivationClause> & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)
-
- Divide two instances of the same :cpp:class:`new_type` by overwriting the first one.
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param lhs: The left-hand side of the division
- :param rhs: The right-hand side of the division
- :returns: A reference to the first argument containing the value modified by applying :literal:`/=` to the objects contained by :literal:`lhs` and :literal:`rhs`.
- :throws: Any exception thrown by the division-assignment operator of the objects contained by :literal:`lhs` and :literal:`rhs`.
- This operator shall be noexcept iff.
-
- a. :cpp:type:`new_type::base_type` is *nothrow divide-assignable* and
- b. :cpp:type:`new_type::base_type` is *nothrow copy-constructible*
-
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`new_type::base_type` supports division using :literal:`/=` and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Arithmetic`
-
- .. versionadded:: 1.0.0
-
-Iterators
-~~~~~~~~~
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::iterator begin(new_type<BaseType, TagType, DerivationClause> & obj)
-
- Get an iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator to the begining of the object of contained by :literal:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`begin(BaseType &)` that returns an instance of type :cpp:type:`new_type::iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::const_iterator begin(new_type<BaseType, TagType, DerivationClause> const & obj)
-
- Get a constant iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator to the begining of the object of contained by :cpp:var:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`begin(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::const_iterator cbegin(new_type<BaseType, TagType, DerivationClause> const & obj)
-
- Get a constant iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator to the begining of the object of contained by :cpp:var:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`cbegin(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::reverse_iterator rbegin(new_type<BaseType, TagType, DerivationClause> & obj)
-
- Get a reverse iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator to the begining of the object of contained by :literal:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`rbegin(BaseType &)` that returns an instance of type :cpp:type:`new_type::reverse_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::const_reverse_iterator rbegin(new_type<BaseType, TagType, DerivationClause> const & obj)
-
- Get a constant reverse iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator to the begining of the object of contained by :cpp:var:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`rbegin(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_reverse_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::const_reverse_iterator crbegin(new_type<BaseType, TagType, DerivationClause> const & obj)
-
- Get a constant reverse iterator to the beginning of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator to the begining of the object of contained by :cpp:var:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`crbegin(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_reverse_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::iterator end(new_type<BaseType, TagType, DerivationClause> & obj)
-
- Get an iterator beyond the end of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator beyond the end of the object of contained by :literal:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`end(BaseType &)` that returns an instance of type :cpp:type:`new_type::iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::const_iterator end(new_type<BaseType, TagType, DerivationClause> const & obj)
-
- Get a constant iterator beyond the end of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator beyond the end of the object of contained by :cpp:var:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`end(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::const_iterator cend(new_type<BaseType, TagType, DerivationClause> const & obj)
-
- Get a constant iterator beyond the end of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator beyond the end of the object of contained by :cpp:var:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`cend(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::reverse_iterator rend(new_type<BaseType, TagType, DerivationClause> & obj)
-
- Get a reverse iterator beyond the end of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator beyond the end of the object of contained by :literal:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`rend(BaseType &)` that returns an instance of type :cpp:type:`new_type::reverse_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::const_reverse_iterator rend(new_type<BaseType, TagType, DerivationClause> const & obj)
-
- Get a constant reverse iterator beyond the end of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator beyond the end of the object of contained by :cpp:var:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`rend(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_reverse_iterator`
-
- .. versionadded:: 1.1.0
-
-.. cpp:function:: template<typename BaseType, typename TagType, auto DerivationClause> \
- constexpr new_type<BaseType, TagType, DerivationClause>::const_reverse_iterator crend(new_type<BaseType, TagType, DerivationClause> const & obj)
-
- Get a constant reverse iterator beyond the end of the object contained by an instance of :cpp:class:`new_type`
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
- :param obj: The object to retrieve the iterator from
- :returns: An iterator beyond the end of the object of contained by :cpp:var:`obj`.
- :throws: Any exception
- :enablement: This function shall be available iff.
-
- a) this :cpp:class:`new_type`'s :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Iterable` and
- b) for the :cpp:class:`new_type`'s :cpp:type:`base type <BaseType>` exists a namespace-level function :literal:`crend(BaseType const &)` that returns an instance of type :cpp:type:`new_type::const_reverse_iterator`
-
- .. versionadded:: 1.1.0
-
-:cpp:class:`std::hash` Support
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. cpp:namespace-pop::
-
-.. cpp:class:: template<typename BaseType, typename TagType, auto DerivationClause> \
- std::hash<nt::new_type<BaseType, TagType, DerivationClause>>
-
- :tparam BaseType: |BaseTypeDoc|
- :tparam TagType: |TagTypeDoc|
- :tparam DerivationClause: |DerivationClauseDoc|
-
- Hash an instance of :cpp:class:`new_type` using the hash implementation of the :cpp:type:`base type <BaseType>`.
-
- .. cpp:function:: constexpr std::size operator()(nt::new_type<BaseType, TagType, DerivationClause> const & value) const
-
- :param value: A :cpp:class:`nt::new_type` value to be hashed
- :returns: The result of applying :cpp:class:`std::hash` to the object contained by :literal:`value`
- :throws: Any exception thrown by the call operator of the specialization of :cpp:class`std::hash` for the type of the object contained by :literal:`value`.
- :enablement: This operator shall be available iff.
-
- a. :cpp:type:`nt::new_type::base_type` is hashable and
- b. the :cpp:var:`derivation clause <DerivationClause>` contains :cpp:var:`Hash <nt::Hash>`.
-
- .. versionadded:: 1.0.0
-
-.. cpp:namespace-push:: nt
-
-Header :literal:`<newtype/derivable.hpp>`
-=========================================
-
-This header defines the alias template :cpp:type:`derivable` as well as the set of standard derivation tags.
-
-Class template :cpp:type:`derivable`
-------------------------------------
-
-.. cpp:class:: template<typename NameTag> \
- derivable
-
- :tparam NameTag: A tag uniquely identifing a specific derivation tag
-
- .. versionadded:: 1.0.0
-
-.. _sec-standard-derivation-tags:
-
-Standard derivation tags
-------------------------
-
-.. cpp:var:: auto constexpr Arithmetic = derivable<class arithmetic_tag>{}
-
- This tag enables the derivation of the following arithmetic operators:
-
- * :cpp:func:`operator+(new_type const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr new_type<BaseType, TagType, DerivationClause> operator+(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)>`
- * :cpp:func:`operator-(new_type const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr new_type<BaseType, TagType, DerivationClause> operator-(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)>`
- * :cpp:func:`operator*(new_type const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr new_type<BaseType, TagType, DerivationClause> operator*(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)>`
- * :cpp:func:`operator/(new_type const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr new_type<BaseType, TagType, DerivationClause> operator/(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)>`
- * :cpp:func:`operator+=(new_type &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr new_type<BaseType, TagType, DerivationClause> & operator+=(new_type<BaseType, TagType, DerivationClause> & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)>`
- * :cpp:func:`operator-=(new_type &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr new_type<BaseType, TagType, DerivationClause> & operator-=(new_type<BaseType, TagType, DerivationClause> & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)>`
- * :cpp:func:`operator*=(new_type &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr new_type<BaseType, TagType, DerivationClause> & operator*=(new_type<BaseType, TagType, DerivationClause> & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)>`
- * :cpp:func:`operator/=(new_type &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr new_type<BaseType, TagType, DerivationClause> & operator/=(new_type<BaseType, TagType, DerivationClause> & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs)>`
-
- .. versionadded:: 1.0.0
-
-.. cpp:var:: auto constexpr EqBase = derivable<class eq_base_tag>{}
-
- This tag enables the derivation of following "equality comparison with base type" operators:
-
- * :cpp:func:`operator==(BaseType const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr bool nt::operator==(BaseType const &, new_type<BaseType, TagType, DerivationClause> const &)>`
- * :cpp:func:`operator==(new_type const &, BaseType const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr bool nt::operator==(new_type<BaseType, TagType, DerivationClause> const &, BaseType const &)>`
- * :cpp:func:`operator!=(BaseType const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr bool nt::operator!=(BaseType const &, new_type<BaseType, TagType, DerivationClause> const &)>`
- * :cpp:func:`operator!=(new_type const &, BaseType const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr bool nt::operator!=(new_type<BaseType, TagType, DerivationClause> const &, BaseType const &)>`
-
- By virtue of its nature, deriving this feature compromises the strength of the given :cpp:class:`new_type`.
-
- .. versionadded:: 1.0.0
-
-.. cpp:var:: auto constexpr ImplicitConversion = derivable<class implicit_conversion_tag>{}
-
- This tag enables the derivation of the implicit "conversion to base type" operator.
- By virtue of its nature, deriving this feature compromises the strength of the given :cpp:class:`new_type`.
-
- .. versionadded:: 1.0.0
-
-.. cpp:var:: auto constexpr Hash = derivable<class hash_tag>{}
-
- This tag enables the derivation of a specialization of :cpp:class:`std::hash`
-
- .. versionadded:: 1.0.0
-
-.. cpp:var:: auto constexpr Indirection = derivable<class indirection_tag>{}
-
- This tag enables the derivation of the "member access through pointer" operator :cpp:func:`operator->() <constexpr BaseType new_type::operator->()()>` (both in :literal:`const` and non-:literal:`const` variants).
-
- .. versionadded:: 1.0.0
-
-.. cpp:var:: auto constexpr Iterable = derivable<class iterable_tag>{}
-
- This tag enables the derivation of the following "standard iterator functions":
-
- * :cpp:func:`begin() <constexpr typename BaseType::iterator new_type::begin()>`
- * :cpp:func:`begin() const <constexpr typename BaseType::iterator new_type::begin() const>`
-
- .. versionadded:: 1.1.0
-
-.. cpp:var:: auto constexpr Read = derivable<class read_tag>{}
-
- This tag enables the derivation of the "stream output" :cpp:func:`operator\<\<(std::basic_ostream &, new_type const &) <operator<<>`
-
- .. versionadded:: 1.0.0
-
-.. cpp:var:: auto constexpr Relational = derivable<class relational_tag>{}
-
- This tag enables the derivation of the following relational operators:
-
- * :cpp:func:`operator\<(new_type const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr bool operator<(new_type<BaseType, TagType, DerivationClause> const &, new_type<BaseType, TagType, DerivationClause> const &)>`
- * :cpp:func:`operator>(new_type const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr bool operator>(new_type<BaseType, TagType, DerivationClause> const &, new_type<BaseType, TagType, DerivationClause> const &)>`
- * :cpp:func:`operator\<=(new_type const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr bool operator<=(new_type<BaseType, TagType, DerivationClause> const &, new_type<BaseType, TagType, DerivationClause> const &)>`
- * :cpp:func:`operator>=(new_type const &, new_type const &) <template\<typename BaseType, typename TagType, auto DerivationClause> constexpr bool operator>=(new_type<BaseType, TagType, DerivationClause> const &, new_type<BaseType, TagType, DerivationClause> const &)>`
-
- .. versionadded:: 1.0.0
-
-.. cpp:var:: auto constexpr Show = derivable<class show_tag>{}
-
- This tag enables the derivation of the "stream input" :cpp:func:`operator>>(std::basic_istream &, new_type &) <operator>>>`
-
- .. versionadded:: 1.0.0
-
-Header :literal:`<newtype/deriving.hpp>`
-========================================
-
-This header contains the definition of the function template :cpp:func:`deriving`.
-
-Function template :cpp:func:`deriving`
---------------------------------------
-
-.. cpp:function:: template<typename... DerivableTags> \
- constexpr derivation_clause<DerivableTags...> deriving(derivable<DerivableTags>... features) noexcept
-
- This function can be used to create a new :cpp:class:`derivation_clause` for use in the definitions of instances of :cpp:class:`new_type`.
-
- .. versionadded:: 1.0.0
-
- .. seealso:: :ref:`sec-standard-derivation-tags` for a list of standard derivation tags
-
-Header :literal:`<newtype/derivation_clause.hpp>`
-=================================================
-
-This header contains the definition of the class template :cpp:class:`derivation_clause`
-
-Class template :cpp:class:`derivation_clause`
----------------------------------------------
-
-.. cpp:class:: template<typename... DerivableTags> \
- derivation_clause
-
- Derivation clauses are used by :cpp:class:`new_type` to allow users to specify a set of automatically derived support functions.
-
- :tparam DerivableTags: A (potentially empty) list of tag types identifying the contained derivations
-
- .. versionadded:: 1.0.0
-
- **Constructors**
-
- .. cpp:function:: constexpr derivation_clause(derivable<DerivableTags>...) noexcept
-
- Construct a new derivations clause containing the given derivations
-
- **Evaluation Functions**
-
- .. cpp:function:: template<typename DerivableTag> \
- constexpr bool operator()(derivable<DerivableTag>) const noexcept
-
- Check if this :cpp:class:`derivation clause <derivation_clause>` contains the given derivation
-
- :tparam DerivableTag: A tag uniquely identifying a derivation
-
- .. cpp:function:: template<typename DerivableTag, typename... RemainingDerivableTags> \
- constexpr bool operator()(derivable<DerivableTag>, derivable<RemainingDerivableTags>...) const noexcept
-
- Check if this :cpp:class:`derivation clause <derivation_clause>` contains **all** of the given derivations
-
- :tparam DerivableTag: A tag uniquely identifying a derivation
- :tparam RemainingDerivableTags: A list of tags uniquely identifying a list of derivations
-
- **Equality Comparison Operators**
-
- .. cpp:function:: template<typename... OtherDerivableTags> \
- constexpr bool operator==(derivation_clause<OtherDerivableTags...> other) const noexcept
-
- Check if this :cpp:class:`derivation clause <derivation_clause>` is identical to the one represented by :cpp:any:`other`.
- Two derivation clauses are considered equal iff. both contain the same derivations irrespective of their order.
-
- :tparam OtherDerivableTags: A (potentialy empty) list of tags uniquely identifying a list of derivations
- :param other: An existing :cpp:class:`derivation clause <derivation_clause>`
-
- .. cpp:function:: template<typename... OtherDerivableTags> \
- constexpr bool operator!=(derivation_clause<OtherDerivableTags...> other) const noexcept
-
- Check if this :cpp:class:`derivation clause <derivation_clause>` is different from the one represented by :cpp:any:`other`.
- Two derivation clauses are considered different iff. one contains at least one derivation not contained by the other.
-
- :tparam OtherDerivableTags: A (potentialy empty) list of tags uniquely identifying a list of derivations
- :param other: An existing :cpp:class:`derivation clause <derivation_clause>`
-
- **Relational Comparison Operators**
-
- .. cpp:function:: template<typename... OtherDerivableTags> \
- constexpr bool operator<(derivation_clause<OtherDerivableTags...> other) const noexcept
-
- Check if this :cpp:class:`derivation clause <derivation_clause>` is a subset of the one represented by :cpp:any:`other`.
- One :cpp:class:`derivation clause <derivation_clause>` is considered to be a subset of another iff. the list of derivations of this instance forms a proper subset of the list of derivations of the other.
-
- :tparam OtherDerivableTags: A (potentialy empty) list of tags uniquely identifying a list of derivations
- :param other: An existing :cpp:class:`derivation clause <derivation_clause>`
-
- .. cpp:function:: template<typename... OtherDerivableTags> \
- constexpr bool operator>(derivation_clause<OtherDerivableTags...> other) const noexcept
-
- Check if this :cpp:class:`derivation clause <derivation_clause>` is a superset of the one represented by :cpp:any:`other`.
- One :cpp:class:`derivation clause <derivation_clause>` is considered to be a superset of another iff. the list of derivations of this instance forms a proper superset of the list of derivations of the other.
-
- :tparam OtherDerivableTags: A (potentialy empty) list of tags uniquely identifying a list of derivations
- :param other: An existing :cpp:class:`derivation clause <derivation_clause>`
-
- .. cpp:function:: template<typename... OtherDerivableTags> \
- constexpr bool operator<=(derivation_clause<OtherDerivableTags...> other) const noexcept
-
- Check if this :cpp:class:`derivation clause <derivation_clause>` is either identical to or a subset of the one represented by :cpp:any:`other`.
- One :cpp:class:`derivation clause <derivation_clause>` is considered to be identical to another iff. the list of derivations of this instance is identical to the list of derivations of the other.
- One :cpp:class:`derivation clause <derivation_clause>` is considered to be a subset of another iff. the list of derivations of this instance forms a proper subset of the list of derivations of the other.
-
- :tparam OtherDerivableTags: A (potentialy empty) list of tags uniquely identifying a list of derivations
- :param other: An existing :cpp:class:`derivation clause <derivation_clause>`
-
- .. cpp:function:: template<typename... OtherDerivableTags> \
- constexpr bool operator>=(derivation_clause<OtherDerivableTags...> other) const noexcept
-
- Check if this :cpp:class:`derivation clause <derivation_clause>` is either identical to or a superset of the one represented by :cpp:any:`other`.
- One :cpp:class:`derivation clause <derivation_clause>` is considered to be identical to another iff. the list of derivations of this instance is identical to the list of derivations of the other.
- One :cpp:class:`derivation clause <derivation_clause>` is considered to be a superset of another iff. the list of derivations of this instance forms a proper superset of the list of derivations of the other.
-
- :tparam OtherDerivableTags: A (potentialy empty) list of tags uniquely identifying a list of derivations
- :param other: An existing :cpp:class:`derivation clause <derivation_clause>`
diff --git a/source/examples/CMakeLists.txt b/source/examples/CMakeLists.txt
deleted file mode 100644
index 73d961e..0000000
--- a/source/examples/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-file(GLOB SOURCES
- RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
- CONFIGURE_DEPENDS
- "src/*.cpp"
-)
-
-foreach(EXAMPLE IN LISTS SOURCES)
- get_filename_component(NAME "${EXAMPLE}" NAME_WE)
- add_executable("ex_${NAME}" "${EXAMPLE}")
- target_link_libraries("ex_${NAME}" "newtype::newtype")
-endforeach()
-
-install(DIRECTORY "src/"
- TYPE DOC
-)
diff --git a/source/examples/src/basic_usage.cpp b/source/examples/src/basic_usage.cpp
deleted file mode 100644
index 35d1d2c..0000000
--- a/source/examples/src/basic_usage.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <newtype/newtype.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/source/examples/src/basic_usage_with_read.cpp b/source/examples/src/basic_usage_with_read.cpp
deleted file mode 100644
index 531a8e3..0000000
--- a/source/examples/src/basic_usage_with_read.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <newtype/newtype.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/source/examples/src/basic_usage_with_show.cpp b/source/examples/src/basic_usage_with_show.cpp
deleted file mode 100644
index 9e4d985..0000000
--- a/source/examples/src/basic_usage_with_show.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <newtype/newtype.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/source/lib/CMakeLists.txt b/source/lib/CMakeLists.txt
deleted file mode 100644
index 0219803..0000000
--- a/source/lib/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-add_library("${PROJECT_NAME}" INTERFACE)
-
-target_include_directories("${PROJECT_NAME}" INTERFACE
- "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
- "$<INSTALL_INTERFACE:include>"
-)
-
-target_compile_features("${PROJECT_NAME}" INTERFACE
- "cxx_std_20"
-)
-
-install(DIRECTORY "include/"
- TYPE INCLUDE
-)
-
-add_library("${PROJECT_NAME}::${PROJECT_NAME}" ALIAS "${PROJECT_NAME}")
diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp
deleted file mode 100644
index fecaf2c..0000000
--- a/source/lib/include/newtype/newtype.hpp
+++ /dev/null
@@ -1,753 +0,0 @@
-#ifndef NEWTYPE_NEWTYPE_HPP
-#define NEWTYPE_NEWTYPE_HPP
-
-#include <algorithm>
-#include <compare>
-#include <functional>
-#include <istream>
-#include <ostream>
-#include <type_traits>
-#include <utility>
-
-namespace nt
-{
- inline namespace lib
- {
- constexpr struct
- {
- int const major;
- int const minor;
- int const patch;
-
- char const * const name;
- } version{
- .major = 2,
- .minor = 0,
- .patch = 0,
- .name = "Brynn",
- };
-
- } // namespace lib
-
- namespace impl
- {
- inline namespace storage
- {
- template<typename T>
- struct new_type_storage
- {
- T m_value;
- };
- } // namespace storage
-
- inline namespace member_types
- {
-
- template<typename T, bool = false, typename = std::void_t<>>
- struct new_type_iterator : new_type_storage<T>
- {
- };
-
- template<typename T>
- struct new_type_iterator<T, true, std::void_t<typename T::iterator>> : new_type_storage<T>
- {
- using iterator = typename T::iterator;
- };
-
-#define NEWTYPE_MAKE_ITERATOR_BASE(NAME, BASE) \
- template<typename T, bool Enabled = false, typename = std::void_t<>> \
- struct new_type_##NAME : new_type_##BASE<T, Enabled> \
- { \
- }; \
- template<typename T> \
- struct new_type_##NAME<T, true, std::void_t<typename T::NAME>> : new_type_##BASE<T, true> \
- { \
- using NAME = typename T::NAME; \
- };
-
- NEWTYPE_MAKE_ITERATOR_BASE(const_iterator, iterator)
- NEWTYPE_MAKE_ITERATOR_BASE(reverse_iterator, const_iterator)
- NEWTYPE_MAKE_ITERATOR_BASE(const_reverse_iterator, reverse_iterator)
-#undef NEWTYPE_MAKE_ITERATOR_BASE
-
- template<typename T, bool Enabled>
- struct new_type_iterator_types : new_type_const_reverse_iterator<T, Enabled>
- {
- };
-
- } // namespace member_types
-
- } // namespace impl
-
- namespace concepts
- {
-
- inline namespace arithmetic
- {
-#define NEWTYPE_MAKE_ARITHMETIC_CONCEPT(NAME, OPERATOR, REF) \
- template<typename SubjectType> \
- concept NAME = requires(SubjectType lhs, SubjectType rhs) { \
- { \
- lhs OPERATOR rhs \
- } -> std::same_as<SubjectType REF>; \
- }; \
- template<typename SubjectType> \
- concept nothrow_##NAME = requires(SubjectType lhs, SubjectType rhs) { \
- requires NAME<SubjectType>; \
- { \
- lhs OPERATOR rhs \
- } noexcept; \
- };
-
- NEWTYPE_MAKE_ARITHMETIC_CONCEPT(addable, +, /*no-ref*/)
- NEWTYPE_MAKE_ARITHMETIC_CONCEPT(divisible, /, /*no-ref*/)
- NEWTYPE_MAKE_ARITHMETIC_CONCEPT(multipliable, *, /*no-ref*/)
- NEWTYPE_MAKE_ARITHMETIC_CONCEPT(subtractable, -, /*no-ref*/)
- NEWTYPE_MAKE_ARITHMETIC_CONCEPT(compound_addable, +=, &)
- NEWTYPE_MAKE_ARITHMETIC_CONCEPT(compound_divisible, /=, &)
- NEWTYPE_MAKE_ARITHMETIC_CONCEPT(compound_multipliable, *=, &)
- NEWTYPE_MAKE_ARITHMETIC_CONCEPT(compound_subtractable, -=, &)
-#undef NEWTYPE_MAKE_ARITHMETIC_CONCEPT
- } // namespace arithmetic
-
- inline namespace comparability
- {
-
- template<typename SubjectType>
- concept nothrow_three_way_comparable = requires(SubjectType lhs, SubjectType rhs) {
- requires std::three_way_comparable<SubjectType>;
- {
- lhs <=> rhs
- } noexcept;
- };
-
- template<typename SubjectType>
- concept equality_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs == rhs
- } -> std::convertible_to<bool>;
- };
-
- template<typename SubjectType>
- concept nothrow_equality_comparable = requires(SubjectType lhs, SubjectType rhs) {
- requires equality_comparable<SubjectType>;
- {
- lhs == rhs
- } noexcept;
- };
-
- template<typename SubjectType>
- concept inequality_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs != rhs
- } -> std::convertible_to<bool>;
- };
-
- template<typename SubjectType>
- concept nothrow_inequality_comparable = requires(SubjectType lhs, SubjectType rhs) {
- requires inequality_comparable<SubjectType>;
- {
- lhs != rhs
- } noexcept;
- };
-
- template<typename SubjectType>
- concept less_than_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs < rhs
- } -> std::convertible_to<bool>;
- };
-
- template<typename SubjectType>
- concept nothrow_less_than_comparable = requires(SubjectType lhs, SubjectType rhs) {
- requires less_than_comparable<SubjectType>;
- {
- lhs < rhs
- } noexcept;
- };
-
- template<typename SubjectType>
- concept less_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs <= rhs
- } -> std::convertible_to<bool>;
- };
-
- template<typename SubjectType>
- concept nothrow_less_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) {
- requires less_than_equal_comparable<SubjectType>;
- {
- lhs <= rhs
- } noexcept;
- };
-
- template<typename SubjectType>
- concept greater_than_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs > rhs
- } -> std::convertible_to<bool>;
- };
-
- template<typename SubjectType>
- concept nothrow_greater_than_comparable = requires(SubjectType lhs, SubjectType rhs) {
- requires greater_than_comparable<SubjectType>;
- {
- lhs > rhs
- } noexcept;
- };
-
- template<typename SubjectType>
- concept greater_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs >= rhs
- } -> std::convertible_to<bool>;
- };
-
- template<typename SubjectType>
- concept nothrow_greater_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) {
- requires greater_than_equal_comparable<SubjectType>;
- {
- lhs >= rhs
- } noexcept;
- };
-
- } // namespace comparability
-
- inline namespace iostreamable
- {
-
- template<typename SubjectType, typename CharType, typename StreamTraits>
- concept input_streamable = requires(SubjectType subject) {
- {
- std::declval<std::basic_istream<CharType, StreamTraits> &>() >> subject
- } -> std::same_as<std::basic_istream<CharType, StreamTraits> &>;
- };
-
- template<typename SubjectType, typename CharType, typename StreamTraits>
- concept nothrow_input_streamable = requires(SubjectType subject) {
- requires input_streamable<SubjectType, CharType, StreamTraits>;
- {
- std::declval<std::basic_istream<CharType, StreamTraits> &>() >> subject
- } noexcept;
- };
-
- template<typename SubjectType, typename CharType, typename StreamTraits>
- concept output_streamable = requires(SubjectType subject) {
- {
- std::declval<std::basic_ostream<CharType, StreamTraits> &>() << subject
- } -> std::same_as<std::basic_ostream<CharType, StreamTraits> &>;
- };
-
- template<typename SubjectType, typename CharType, typename StreamTraits>
- concept nothrow_output_streamable = requires(SubjectType subject) {
- requires output_streamable<SubjectType, CharType, StreamTraits>;
- {
- std::declval<std::basic_ostream<CharType, StreamTraits> &>() << subject
- } noexcept;
- };
-
- } // namespace iostreamable
-
- inline namespace iterable
- {
-
- template<typename SubjectType>
- concept free_begin = requires(SubjectType & subject) {
- typename SubjectType::iterator;
- {
- begin(subject)
- } -> std::same_as<typename SubjectType::iterator>;
- };
-
- template<typename SubjectType>
- concept const_free_begin = requires(SubjectType const & subject) {
- typename SubjectType::const_iterator;
- {
- begin(subject)
- } -> std::same_as<typename SubjectType::const_iterator>;
- };
-
- template<typename SubjectType>
- concept member_begin = requires(SubjectType & subject) {
- typename SubjectType::iterator;
- {
- subject.begin()
- } -> std::same_as<typename SubjectType::iterator>;
- };
-
- template<typename SubjectType>
- concept const_member_begin = requires(SubjectType const & subject) {
- typename SubjectType::const_iterator;
- {
- subject.begin()
- } -> std::same_as<typename SubjectType::const_iterator>;
- };
-
- template<typename SubjectType>
- concept beginnable = free_begin<SubjectType> || member_begin<SubjectType>;
-
- template<typename SubjectType>
- concept const_beginnable = const_free_begin<SubjectType> || const_member_begin<SubjectType>;
-
- template<typename SubjectType>
- concept free_cbegin = requires(SubjectType const & subject) {
- typename SubjectType::const_iterator;
- {
- cbegin(subject)
- } -> std::same_as<typename SubjectType::const_iterator>;
- };
-
- template<typename SubjectType>
- concept member_cbegin = requires(SubjectType const & subject) {
- typename SubjectType::const_iterator;
- {
- subject.cbegin()
- } -> std::same_as<typename SubjectType::const_iterator>;
- };
-
- template<typename SubjectType>
- concept cbeginnable = free_cbegin<SubjectType> || member_cbegin<SubjectType>;
-
- template<typename SubjectType>
- concept free_rbegin = requires(SubjectType & subject) {
- typename SubjectType::reverse_iterator;
- {
- rbegin(subject)
- } -> std::same_as<typename SubjectType::reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept const_free_rbegin = requires(SubjectType const & subject) {
- typename SubjectType::const_reverse_iterator;
- {
- rbegin(subject)
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept member_rbegin = requires(SubjectType & subject) {
- typename SubjectType::reverse_iterator;
- {
- subject.rbegin()
- } -> std::same_as<typename SubjectType::reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept const_member_rbegin = requires(SubjectType const & subject) {
- typename SubjectType::const_reverse_iterator;
- {
- subject.rbegin()
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept rbeginnable = free_rbegin<SubjectType> || member_rbegin<SubjectType>;
-
- template<typename SubjectType>
- concept const_rbeginnable = const_free_rbegin<SubjectType> || const_member_rbegin<SubjectType>;
-
- template<typename SubjectType>
- concept free_crbegin = requires(SubjectType const & subject) {
- typename SubjectType::const_reverse_iterator;
- {
- crbegin(subject)
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept member_crbegin = requires(SubjectType const & subject) {
- typename SubjectType::const_reverse_iterator;
- {
- subject.crbegin()
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept crbeginnable = free_crbegin<SubjectType> || member_crbegin<SubjectType>;
-
- template<typename SubjectType>
- concept free_end = requires(SubjectType & subject) {
- typename SubjectType::iterator;
- {
- end(subject)
- } -> std::same_as<typename SubjectType::iterator>;
- };
-
- template<typename SubjectType>
- concept const_free_end = requires(SubjectType const & subject) {
- typename SubjectType::const_iterator;
- {
- end(subject)
- } -> std::same_as<typename SubjectType::const_iterator>;
- };
-
- template<typename SubjectType>
- concept member_end = requires(SubjectType & subject) {
- typename SubjectType::iterator;
- {
- subject.end()
- } -> std::same_as<typename SubjectType::iterator>;
- };
-
- template<typename SubjectType>
- concept const_member_end = requires(SubjectType const & subject) {
- typename SubjectType::const_iterator;
- {
- subject.end()
- } -> std::same_as<typename SubjectType::const_iterator>;
- };
-
- template<typename SubjectType>
- concept endable = free_end<SubjectType> || member_end<SubjectType>;
-
- template<typename SubjectType>
- concept const_endable = const_free_end<SubjectType> || const_member_end<SubjectType>;
-
- template<typename SubjectType>
- concept free_cend = requires(SubjectType const & subject) {
- typename SubjectType::const_iterator;
- {
- cend(subject)
- } -> std::same_as<typename SubjectType::const_iterator>;
- };
-
- template<typename SubjectType>
- concept member_cend = requires(SubjectType const & subject) {
- typename SubjectType::const_iterator;
- {
- subject.cend()
- } -> std::same_as<typename SubjectType::const_iterator>;
- };
-
- template<typename SubjectType>
- concept cendable = free_cend<SubjectType> || member_cend<SubjectType>;
-
- template<typename SubjectType>
- concept free_rend = requires(SubjectType & subject) {
- typename SubjectType::reverse_iterator;
- {
- rend(subject)
- } -> std::same_as<typename SubjectType::reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept const_free_rend = requires(SubjectType const & subject) {
- typename SubjectType::const_reverse_iterator;
- {
- rend(subject)
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept member_rend = requires(SubjectType & subject) {
- typename SubjectType::reverse_iterator;
- {
- subject.rend()
- } -> std::same_as<typename SubjectType::reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept const_member_rend = requires(SubjectType const & subject) {
- typename SubjectType::const_reverse_iterator;
- {
- subject.rend()
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept rendable = free_rend<SubjectType> || member_rend<SubjectType>;
-
- template<typename SubjectType>
- concept const_rendable = const_free_rend<SubjectType> || const_member_rend<SubjectType>;
-
- template<typename SubjectType>
- concept free_crend = requires(SubjectType const & subject) {
- typename SubjectType::const_reverse_iterator;
- {
- crend(subject)
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept member_crend = requires(SubjectType const & subject) {
- typename SubjectType::const_reverse_iterator;
- {
- subject.crend()
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
- };
-
- template<typename SubjectType>
- concept crendable = free_crend<SubjectType> || member_crend<SubjectType>;
- } // namespace iterable
-
- inline namespace standard_extensions
- {
-
- template<typename SubjectType>
- concept hashable = requires(SubjectType subject) {
- {
- std::hash<SubjectType>{}(subject)
- } -> std::convertible_to<std::size_t>;
- };
-
- }
-
- } // namespace concepts
-
- template<typename DerivableTag>
- struct derivable final
- {
- using tag_type = DerivableTag;
- };
-
- inline namespace derivables
- {
-
- auto constexpr Arithmetic = derivable<struct arithmetic_tag>{};
- auto constexpr EqBase = derivable<struct eq_base_tag>{};
- auto constexpr Hash = derivable<struct hash_tag>{};
- auto constexpr ImplicitConversion = derivable<struct implicit_conversion_tag>{};
- auto constexpr Indirection = derivable<struct indirection_tag>{};
- auto constexpr Iterable = derivable<struct iterable_tag>{};
- auto constexpr Read = derivable<struct read_tag>{};
- auto constexpr Relational = derivable<struct relational_tag>{};
- auto constexpr Show = derivable<struct show_tag>{};
- auto constexpr ThreewayCompare = derivable<struct threeway_compare_tag>{};
-
- } // namespace derivables
-
- template<typename... DerivableTags>
- struct derivation_clause
- {
- template<auto Needle>
- using derives_one = std::disjunction<std::is_same<typename decltype(Needle)::tag_type, DerivableTags>...>;
-
- template<auto... Needles>
- using derives = std::conjunction<derives_one<Needles>...>;
-
- constexpr derivation_clause(derivable<DerivableTags>...) noexcept
- {
- }
- };
-
- template<typename DerivationClause, auto... Features>
- concept derives = requires(DerivationClause clause) { requires DerivationClause::template derives<Features...>::value; };
-
- template<typename DerivationClause, auto... Features>
- concept doesnt_derive = !derives<DerivationClause, Features...>;
-
- template<typename... DerivableTags>
- auto constexpr deriving(derivable<DerivableTags>... features) noexcept -> derivation_clause<DerivableTags...>
- {
- return {features...};
- }
-
- template<typename BaseType, typename TagType, auto DerivationClause = deriving()>
- class new_type : public impl::new_type_iterator_types<BaseType, nt::derives<decltype(DerivationClause), nt::Iterable>>
- {
- static_assert(!std::is_reference_v<BaseType>, "The base type must not be a reference type");
- static_assert(!std::is_void_v<std::remove_cv_t<BaseType>>, "The base type must not be possibly cv-qualified void");
- static_assert(!derives<decltype(DerivationClause), nt::Relational, nt::ThreewayCompare>,
- "Cannot derive both nt::Relational and nt::ThreewayCompare at the same time.");
-
- using super = impl::new_type_iterator_types<BaseType, nt::derives<decltype(DerivationClause), nt::Iterable>>;
-
- public:
- using base_type = BaseType;
- using tag_type = TagType;
- using derivation_clause_type = decltype(DerivationClause);
-
- auto constexpr static derivation_clause = DerivationClause;
-
- constexpr new_type() noexcept(std::is_nothrow_default_constructible_v<BaseType>)
- requires std::constructible_from<BaseType>
- = default;
-
- constexpr new_type(new_type const &) noexcept(std::is_nothrow_copy_constructible_v<BaseType>)
- requires std::copy_constructible<BaseType>
- = default;
-
- constexpr new_type(new_type &&) noexcept(std::is_nothrow_move_constructible_v<BaseType>)
- requires std::move_constructible<BaseType>
- = default;
-
- constexpr new_type(BaseType const & base) noexcept(std::is_nothrow_copy_constructible_v<BaseType>)
- requires std::copy_constructible<BaseType>
- : super{base}
- {
- }
-
- constexpr new_type(BaseType && base) noexcept(std::is_nothrow_move_constructible_v<BaseType>)
- requires std::move_constructible<BaseType>
- : super{std::move(base)}
- {
- }
-
- auto constexpr operator=(new_type const &) noexcept(std::is_nothrow_copy_assignable_v<BaseType>) -> new_type & = default;
- auto constexpr operator=(new_type &&) noexcept(std::is_nothrow_move_assignable_v<BaseType>) -> new_type & = default;
-
- auto constexpr decay() const noexcept(std::is_nothrow_copy_constructible_v<BaseType>) -> BaseType
- {
- return this->m_value;
- }
-
- template<typename DerivationClauseT = decltype(DerivationClause)>
- constexpr operator base_type() const noexcept(std::is_nothrow_copy_constructible_v<base_type>)
- requires(nt::derives<DerivationClauseT, nt::ImplicitConversion>)
- {
- return decay();
- }
-
- template<typename DerivationClauseT = decltype(DerivationClause)>
- explicit constexpr operator base_type() const noexcept(std::is_nothrow_copy_constructible_v<base_type>)
- requires(nt::doesnt_derive<DerivationClauseT, nt::ImplicitConversion>)
- {
- return decay();
- }
-
- template<typename CharType, typename StreamTraits, nt::concepts::input_streamable<CharType, StreamTraits> BaseTypeT = BaseType>
- auto friend operator>>(std::basic_istream<CharType, StreamTraits> & in,
- new_type & obj) noexcept(nt::concepts::nothrow_input_streamable<BaseTypeT, CharType, StreamTraits>)
- -> std::basic_istream<CharType, StreamTraits> &
- requires nt::derives<decltype(DerivationClause), nt::Read>
- {
- return in >> obj.m_value;
- }
-
- template<typename CharType, typename StreamTraits, nt::concepts::output_streamable<CharType, StreamTraits> BaseTypeT = BaseType>
- auto friend operator<<(std::basic_ostream<CharType, StreamTraits> & out,
- new_type const & obj) noexcept(nt::concepts::nothrow_output_streamable<BaseType, CharType, StreamTraits>)
- -> std::basic_ostream<CharType, StreamTraits> &
- requires nt::derives<decltype(DerivationClause), nt::Show>
- {
- return out << obj.m_value;
- }
-
- // THREE-WAY ORDER AND EQUAL
-
- auto constexpr operator<=>(new_type const & rhs) const noexcept(nt::concepts::nothrow_three_way_comparable<BaseType>)
- requires(std::three_way_comparable<BaseType> && nt::derives<derivation_clause_type, nt::ThreewayCompare>)
- {
- return decay() <=> rhs.decay();
- }
-
- auto constexpr operator==(new_type const & rhs) const -> bool
- requires(nt::concepts::equality_comparable<BaseType> && nt::derives<derivation_clause_type, nt::ThreewayCompare>)
- {
- return decay() == rhs.decay();
- }
-
- // NOT THREE-WAY EQUAL
-
- auto constexpr operator==(new_type const & rhs) const noexcept(nt::concepts::nothrow_equality_comparable<BaseType>) -> bool
- requires(nt::concepts::equality_comparable<BaseType> && nt::doesnt_derive<derivation_clause_type, nt::ThreewayCompare>)
- {
- return decay() == rhs.decay();
- }
-
- // BASE EQUAL
-
- auto constexpr operator==(BaseType const & rhs) const noexcept(nt::concepts::nothrow_equality_comparable<BaseType>) -> bool
- requires(nt::concepts::equality_comparable<BaseType> && nt::derives<derivation_clause_type, nt::EqBase>)
- {
- return decay() == rhs;
- }
-
- // NOT THREE-WAY EQUAL
-
- auto constexpr operator!=(new_type const & rhs) const noexcept(nt::concepts::nothrow_inequality_comparable<BaseType>) -> bool
- requires(nt::concepts::inequality_comparable<BaseType> && nt::doesnt_derive<derivation_clause_type, nt::ThreewayCompare>)
- {
- return decay() != rhs.decay();
- }
-
-#define NEWTYPE_MAKE_LOGICAL_OPERATOR(OPERATOR, CONCEPT) \
- auto constexpr operator OPERATOR(new_type const & rhs) const noexcept(nt::concepts::nothrow_##CONCEPT##_comparable<BaseType>) -> bool \
- requires(nt::concepts::CONCEPT##_comparable<BaseType> && nt::doesnt_derive<derivation_clause_type, nt::ThreewayCompare> && \
- nt::derives<derivation_clause_type, nt::Relational>) \
- { \
- return decay() OPERATOR rhs.decay(); \
- }
-
- NEWTYPE_MAKE_LOGICAL_OPERATOR(<, less_than)
- NEWTYPE_MAKE_LOGICAL_OPERATOR(<=, less_than_equal)
- NEWTYPE_MAKE_LOGICAL_OPERATOR(>, greater_than)
- NEWTYPE_MAKE_LOGICAL_OPERATOR(>=, greater_than_equal)
-#undef NEWTYPE_MAKE_LOGICAL_OPERATOR
-
-#define NEWTYPE_MAKE_ARITHMETIC_OPERATOR(OPERATOR, CONCEPT) \
- auto constexpr operator OPERATOR(new_type const & rhs) const noexcept(nt::concepts::nothrow_##CONCEPT<BaseType>) -> new_type \
- requires(nt::concepts::CONCEPT<BaseType> && nt::derives<derivation_clause_type, nt::Arithmetic>) \
- { \
- return {decay() OPERATOR rhs.decay()}; \
- } \
- auto constexpr operator OPERATOR##=(new_type const & rhs) const noexcept(nt::concepts::nothrow_compound_##CONCEPT<BaseType>) -> new_type & \
- requires(nt::concepts::compound_##CONCEPT<BaseType> && nt::derives<derivation_clause_type, nt::Arithmetic>) { \
- return this->m_value OPERATOR## = rhs.decay(), *this; \
- };
-
- NEWTYPE_MAKE_ARITHMETIC_OPERATOR(+, addable)
- NEWTYPE_MAKE_ARITHMETIC_OPERATOR(-, subtractable)
- NEWTYPE_MAKE_ARITHMETIC_OPERATOR(*, multipliable)
- NEWTYPE_MAKE_ARITHMETIC_OPERATOR(/, divisible)
-#undef NEWTYPE_MAKE_ARITHMETIC_OPERATOR
-
-#define NEWTYPE_MAKE_ITERATOR_FACTORY_HELPER(NAME, QUALIFICATION, ITERATOR) \
- template<nt::concepts::free_##NAME BaseTypeT = BaseType> \
- auto constexpr friend NAME(new_type QUALIFICATION & obj) -> new_type<BaseTypeT, TagType, DerivationClause>::ITERATOR \
- requires nt::derives<decltype(DerivationClause), nt::Iterable> \
- { \
- using std::NAME; \
- return NAME(obj.m_value); \
- } \
- template<nt::concepts::member_##NAME BaseTypeT = BaseType> \
- auto constexpr NAME() QUALIFICATION->new_type<BaseTypeT, TagType, DerivationClause>::ITERATOR \
- requires nt::derives<derivation_clause_type, nt::Iterable> \
- { \
- return this->m_value.NAME(); \
- }
-
-#define NEWTYPE_MAKE_ITERATOR_FACTORY(NAME, ITERATOR) \
- NEWTYPE_MAKE_ITERATOR_FACTORY_HELPER(NAME, /*non-const*/, ITERATOR) \
- NEWTYPE_MAKE_ITERATOR_FACTORY_HELPER(NAME, const, const_##ITERATOR) \
- NEWTYPE_MAKE_ITERATOR_FACTORY_HELPER(c##NAME, const, const_##ITERATOR)
-
- NEWTYPE_MAKE_ITERATOR_FACTORY(begin, iterator)
- NEWTYPE_MAKE_ITERATOR_FACTORY(rbegin, reverse_iterator)
- NEWTYPE_MAKE_ITERATOR_FACTORY(end, iterator)
- NEWTYPE_MAKE_ITERATOR_FACTORY(rend, reverse_iterator)
-#undef NEWTYPE_MAKE_ITERATOR_FACTORY
-#undef NEWTYPE_MAKE_ITERATOR_FACTORY_HELPER
-
- // INDIRECTION
-
- // template<typename DerivationClauseT = decltype(DerivationClause)>
- // requires(nt::derives<DerivationClauseT, nt::Indirection>)
- // auto constexpr operator->() noexcept -> BaseType *
- // {
- // return std::addressof(this->m_value);
- // }
-
- // template<typename DerivationClauseT = decltype(DerivationClause)>
- // requires(nt::derives<DerivationClauseT, nt::Indirection>)
- // auto constexpr operator->() const noexcept -> BaseType const *
- // {
- // return std::addressof(this->m_value);
- // }
- };
-
-} // namespace nt
-
-namespace std
-{
- template<nt::concepts::hashable BaseType, typename TagType, nt::derives<nt::Hash> auto DerivationClause>
- struct hash<nt::new_type<BaseType, TagType, DerivationClause>>
- {
- auto constexpr operator()(nt::new_type<BaseType, TagType, DerivationClause> const & object) const
- {
- return std::hash<BaseType>{}(object.decay());
- }
- };
-} // namespace std
-
-#endif
diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt
deleted file mode 100644
index 47b8331..0000000
--- a/source/tests/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-find_package("Catch2" "3.1"
- COMPONENTS "Catch2WithMain"
- REQUIRED
-)
-
-include("CTest")
-include("Catch")
-
-file(GLOB SOURCES
- RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
- CONFIGURE_DEPENDS
- "src/*.cpp"
-)
-
-
-add_executable("${PROJECT_NAME}_tests"
- ${SOURCES}
-)
-
-target_link_libraries("${PROJECT_NAME}_tests"
- "${PROJECT_NAME}::${PROJECT_NAME}"
- "Catch2::Catch2WithMain"
-)
-
-target_compile_options("${PROJECT_NAME}_tests" PRIVATE
- "$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall>"
- "$<$<CXX_COMPILER_ID:GNU,Clang>:-Wextra>"
- "$<$<CXX_COMPILER_ID:GNU,Clang>:-Werror>"
- "$<$<CXX_COMPILER_ID:GNU,Clang>:-pedantic-errors>"
- "$<$<CXX_COMPILER_ID:GNU>:-fconcepts-diagnostics-depth=5>"
-)
-
-catch_discover_tests("${PROJECT_NAME}_tests")
diff --git a/source/tests/src/arithmetic.cpp b/source/tests/src/arithmetic.cpp
deleted file mode 100644
index 30c243f..0000000
--- a/source/tests/src/arithmetic.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_test_macros.hpp>
-
-#include <type_traits>
-
-SCENARIO("Addition", "[arithmetic]")
-{
- struct addable_type
- {
- auto constexpr operator+(addable_type const &) const -> addable_type
- {
- return {};
- };
- };
-
- GIVEN("A new_type instance not deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag>;
-
- THEN("it is not addable")
- {
- STATIC_REQUIRE(!nt::concepts::addable<type_alias>);
- }
- }
-
- GIVEN("A new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is addable")
- {
- STATIC_REQUIRE(nt::concepts::addable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-addable class type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<void *, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is not addable")
- {
- STATIC_REQUIRE(!nt::concepts::addable<addable_type> == nt::concepts::addable<type_alias>);
- }
- }
-
- GIVEN("A new_type over an addable class type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<addable_type, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is addable")
- {
- STATIC_REQUIRE(nt::concepts::addable<addable_type> == nt::concepts::addable<type_alias>);
- }
- }
-
- GIVEN("A new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("addition produces the same type")
- {
- STATIC_REQUIRE(std::is_same_v<type_alias, decltype(std::declval<type_alias const &>() + std::declval<type_alias const &>())>);
- }
- }
-
- GIVEN("Two objects of a new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
- auto lhs = type_alias{24};
- auto rhs = type_alias{18};
-
- THEN("addition produces the correct result with respect to the base type")
- {
- REQUIRE((lhs + rhs).decay() == 24 + 18);
- }
- }
-}
-
-SCENARIO("Subtraction", "[arithmetic]")
-{
- struct subtractable_type
- {
- auto constexpr operator-(subtractable_type const &) const -> subtractable_type
- {
- return {};
- };
- };
-
- GIVEN("A new_type not deriving nt::arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag>;
-
- THEN("it is not subtractable")
- {
- STATIC_REQUIRE(!nt::concepts::subtractable<type_alias>);
- }
- }
-
- GIVEN("A new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is subtractable")
- {
- STATIC_REQUIRE(nt::concepts::subtractable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-subtractable class type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<void *, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is not addable")
- {
- STATIC_REQUIRE(!nt::concepts::subtractable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a subtractable class type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<subtractable_type, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is subtractable")
- {
- STATIC_REQUIRE(nt::concepts::subtractable<type_alias>);
- }
- }
-
- GIVEN("A new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("subtraction produces the same type")
- {
- STATIC_REQUIRE(std::is_same_v<type_alias, decltype(std::declval<type_alias const &>() - std::declval<type_alias const &>())>);
- }
- }
-
- GIVEN("Two objects of a new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
- auto lhs = type_alias{24};
- auto rhs = type_alias{18};
-
- THEN("subtraction produces the correct result with respect to the base type")
- {
- REQUIRE((lhs - rhs).decay() == 24 - 18);
- }
- }
-}
-
-SCENARIO("Multiplication", "[arithmetic]")
-{
- struct multipliable_type
- {
- auto constexpr operator*(multipliable_type const &) const -> multipliable_type
- {
- return {};
- };
- };
-
- GIVEN("A new_type not deriving nt::arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag>;
-
- THEN("it is not multipliable")
- {
- STATIC_REQUIRE(!nt::concepts::multipliable<type_alias>);
- }
- }
-
- GIVEN("A new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is multipliable")
- {
- STATIC_REQUIRE(nt::concepts::multipliable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-multipliable class type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<void *, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is not multipliable")
- {
- STATIC_REQUIRE(!nt::concepts::multipliable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a multipliable class type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<multipliable_type, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is multipliable")
- {
- STATIC_REQUIRE(nt::concepts::multipliable<type_alias>);
- }
- }
-
- GIVEN("A new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("multiplication produces the same type")
- {
- STATIC_REQUIRE(std::is_same_v<type_alias, decltype(std::declval<type_alias const &>() * std::declval<type_alias const &>())>);
- }
- }
-
- GIVEN("Two objects of a new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
- auto lhs = type_alias{24};
- auto rhs = type_alias{18};
-
- THEN("multiplication produces the correct result with respect to the base type")
- {
- REQUIRE((lhs * rhs).decay() == 24 * 18);
- }
- }
-}
-
-SCENARIO("Division", "[arithmetic]")
-{
- struct dividable_type
- {
- auto constexpr operator/(dividable_type const &) const -> dividable_type
- {
- return {};
- };
- };
-
- GIVEN("A new_type not deriving nt::arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag>;
-
- THEN("it is not divisible")
- {
- STATIC_REQUIRE(!nt::concepts::divisible<type_alias>);
- }
- }
-
- GIVEN("A new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is divisible")
- {
- STATIC_REQUIRE(nt::concepts::divisible<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-divisible class type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<void *, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is not divisible")
- {
- STATIC_REQUIRE(!nt::concepts::divisible<type_alias>);
- }
- }
-
- GIVEN("A new_type over a divisible class type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<dividable_type, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("it is divisible")
- {
- STATIC_REQUIRE(nt::concepts::divisible<type_alias>);
- }
- }
-
- GIVEN("A new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
-
- THEN("division produces the same type")
- {
- STATIC_REQUIRE(std::is_same_v<type_alias, decltype(std::declval<type_alias const &>() / std::declval<type_alias const &>())>);
- }
- }
-
- GIVEN("Two objects of a new_type deriving nt::Arithmetic")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Arithmetic)>;
- auto lhs = type_alias{30};
- auto rhs = type_alias{15};
-
- THEN("division produces the correct result with respect to the base type")
- {
- REQUIRE((lhs / rhs).decay() == 30 / 15);
- }
- }
-}
diff --git a/source/tests/src/constructors.cpp b/source/tests/src/constructors.cpp
deleted file mode 100644
index b866f2e..0000000
--- a/source/tests/src/constructors.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_template_test_macros.hpp>
-#include <catch2/catch_test_macros.hpp>
-
-#include <type_traits>
-
-using fundamental_types = std::tuple<bool,
- char,
- unsigned char,
- signed char,
- wchar_t,
- char16_t,
- char32_t,
- short,
- unsigned short,
- int,
- unsigned int,
- long,
- unsigned long,
- long long,
- unsigned long long,
- float,
- double,
- long double>;
-
-TEMPLATE_LIST_TEST_CASE("Scenario: Construction from Fundamental Types", "[construction]", fundamental_types)
-{
- GIVEN("A new_type over a fundamental type")
- {
- using type_alias = nt::new_type<TestType, struct tag>;
-
- THEN("objects of it can be constructed from the fundamental type")
- {
- STATIC_REQUIRE(std::is_constructible_v<type_alias, TestType>);
- }
- }
-}
-
-SCENARIO("Default Construction", "[construction]")
-{
- struct not_default_constructible
- {
- not_default_constructible() = delete;
- };
-
- GIVEN("A new_type over a default-constructible type")
- {
- using type_alias = nt::new_type<int, struct tag>;
- static_assert(std::is_default_constructible_v<type_alias::base_type>);
-
- THEN("it is default-constructible")
- {
- STATIC_REQUIRE(std::is_default_constructible_v<type_alias>);
- }
- }
-
- GIVEN("A new_type over a type that is not default-constructible")
- {
- using type_alias = nt::new_type<not_default_constructible, struct tag>;
- static_assert(!std::is_default_constructible_v<type_alias::base_type>);
-
- THEN("it is not default-constructible")
- {
- STATIC_REQUIRE_FALSE(std::is_default_constructible_v<type_alias>);
- }
- }
-}
-
-SCENARIO("Copy Construction", "[construction]")
-{
- struct not_copy_constructible
- {
- not_copy_constructible() = default;
- not_copy_constructible(not_copy_constructible const &) = delete;
- not_copy_constructible(not_copy_constructible &&) = default;
- auto operator=(not_copy_constructible const &) -> not_copy_constructible & = default;
- auto operator=(not_copy_constructible &&) -> not_copy_constructible & = default;
- };
-
- GIVEN("A new_type over a copy-constructible type")
- {
- using type_alias = nt::new_type<int, struct tag>;
- static_assert(std::is_copy_constructible_v<type_alias::base_type>);
-
- THEN("it is copy-constructible")
- {
- STATIC_REQUIRE(std::is_copy_constructible_v<type_alias>);
- }
- }
-
- GIVEN("A new_type over a type that is not copy-constructible")
- {
- using type_alias = nt::new_type<not_copy_constructible, struct tag>;
- static_assert(!std::is_copy_constructible_v<type_alias::base_type>);
-
- THEN("it is not copy-constructible")
- {
- STATIC_REQUIRE_FALSE(std::is_copy_constructible_v<type_alias>);
- }
- }
-}
diff --git a/source/tests/src/conversion.cpp b/source/tests/src/conversion.cpp
deleted file mode 100644
index e7ce51c..0000000
--- a/source/tests/src/conversion.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_template_test_macros.hpp>
-#include <catch2/catch_test_macros.hpp>
-#include <catch2/generators/catch_generators_all.hpp>
-
-#include <string>
-#include <type_traits>
-#include <vector>
-
-using test_types = std::tuple<bool, char, int, double, std::string>;
-
-TEMPLATE_LIST_TEST_CASE("Scenario: Implicit Conversions", "[conversion]", test_types)
-{
- GIVEN("A new_type not deriving nt::ImplicitConversion")
- {
- using type_alias = nt::new_type<TestType, struct conversion_test>;
-
- THEN("it is not implicitly convertible to the base type")
- {
- STATIC_REQUIRE(!std::is_convertible_v<type_alias, TestType>);
- }
- }
-
- GIVEN("A new_type deriving nt::ImplicitConversion")
- {
- using type_alias = nt::new_type<TestType, struct conversion_test, deriving(nt::ImplicitConversion)>;
-
- THEN("it is implicitly convertible to the base type")
- {
- STATIC_REQUIRE(std::is_convertible_v<type_alias, TestType>);
- }
- }
-}
-
-TEMPLATE_LIST_TEST_CASE("Scenario: Decay", "[conversion]", test_types)
-{
- GIVEN("Any new_type")
- {
- using type_alias = nt::new_type<TestType, struct conversion_test>;
-
- THEN("it's decay() member function returns a value of the base type")
- {
- STATIC_REQUIRE(std::is_same_v<TestType, decltype(std::declval<type_alias>().decay())>);
- }
- }
-
- GIVEN("Any new_type")
- {
- using type_alias = nt::new_type<TestType, struct conversion_test>;
-
- WHEN("an object of that type is constructed")
- {
- auto integral_value = GENERATE(take(64, random(0, 127)));
- auto value = [integral_value] {
- if constexpr (std::is_same_v<std::string, TestType>)
- {
- return std::to_string(integral_value);
- }
- else
- {
- return static_cast<TestType>(integral_value);
- }
- }();
- auto obj = type_alias{value};
-
- THEN("it's decay() member function return the underlying value")
- {
- REQUIRE(obj.decay() == value);
- }
- }
- }
-}
-
-SCENARIO("Nothrow Decay")
-{
- struct strange_type
- {
- strange_type(strange_type const &) noexcept(false)
- {
- }
- };
-
- GIVEN("A new_type over a nothrow-copyable type")
- {
- using type_alias = nt::new_type<int, struct conversion_test>;
-
- THEN("the decay member function is nothrow-invokable")
- {
- STATIC_REQUIRE(noexcept(std::declval<type_alias>().decay()));
- }
- }
-
- GIVEN("A new_type over a non-nothrow-copyable type")
- {
- using type_alias = nt::new_type<strange_type, struct conversion_test>;
-
- THEN("the decay member function is not nothrow-invokable")
- {
- STATIC_REQUIRE(!noexcept(std::declval<type_alias>().decay()));
- }
- }
-}
-
-SCENARIO("Nothrow Conversion")
-{
- struct strange_type
- {
- strange_type(strange_type const &) noexcept(false)
- {
- }
- };
-
- GIVEN("A new_type over a nothrow-copy-constructible type")
- {
- using type_alias = nt::new_type<int, struct conversion_test>;
-
- THEN("the decay member function is nothrow-invokable")
- {
- STATIC_REQUIRE(noexcept(std::declval<type_alias>().operator int()));
- }
- }
-
- GIVEN("A new_type over a non-nothrow-copy-constructible type")
- {
- using type_alias = nt::new_type<strange_type, struct conversion_test>;
-
- THEN("the decay member function is not nothrow-invokable")
- {
- STATIC_REQUIRE(!noexcept(std::declval<type_alias>().operator strange_type()));
- }
- }
-}
diff --git a/source/tests/src/derivation_clause.cpp b/source/tests/src/derivation_clause.cpp
deleted file mode 100644
index 78bd3d4..0000000
--- a/source/tests/src/derivation_clause.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_test_macros.hpp>
-
-#include <string>
-
-SCENARIO("Derivation Clause", "[infrastructure]")
-{
- GIVEN("An empty derivation clause")
- {
- auto clause = nt::deriving();
-
- THEN("it doesn't contain any derivable")
- {
- STATIC_REQUIRE_FALSE(nt::derives<decltype(clause), nt::Show>);
- }
- }
-
- GIVEN("A derivation clause containing only nt::Show")
- {
- auto clause = deriving(nt::Show);
-
- THEN("it doesn't contain nt::EqBase")
- {
- STATIC_REQUIRE_FALSE(nt::derives<decltype(clause), nt::EqBase>);
- }
-
- THEN("it contains nt::Show")
- {
- STATIC_REQUIRE(nt::derives<decltype(clause), nt::Show>);
- }
- }
-
- GIVEN("A derivation clause containing only nt::Show and nt::EqBase")
- {
- auto clause = deriving(nt::Show, nt::EqBase);
-
- THEN("it contains nt::EqBase")
- {
- STATIC_REQUIRE(nt::derives<decltype(clause), nt::EqBase>);
- }
-
- THEN("it contains nt::Show")
- {
- STATIC_REQUIRE(nt::derives<decltype(clause), nt::Show>);
- }
-
- THEN("it contains both nt::Show and nt::EqBase")
- {
- STATIC_REQUIRE(nt::derives<decltype(clause), nt::Show, nt::EqBase>);
- }
-
- THEN("it does not contain nt::Arithmetic")
- {
- STATIC_REQUIRE_FALSE(nt::derives<decltype(clause), nt::Arithmetic>);
- }
-
- THEN("it does not contain both nt::Arithmetic and nt::Show")
- {
- STATIC_REQUIRE_FALSE(nt::derives<decltype(clause), nt::Arithmetic, nt::Show>);
- }
- }
-}
diff --git a/source/tests/src/equality_comparison.cpp b/source/tests/src/equality_comparison.cpp
deleted file mode 100644
index e0be7f9..0000000
--- a/source/tests/src/equality_comparison.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_test_macros.hpp>
-
-#include <string>
-#include <type_traits>
-#include <utility>
-
-SCENARIO("Equality Comparison", "[compare]")
-{
- GIVEN("A new_type over an equality comparable type")
- {
- using type_alias = nt::new_type<int, struct tag>;
-
- THEN("two objects of it with the same value compare equal")
- {
- REQUIRE(type_alias{42} == type_alias{42});
- }
-
- THEN("two objects of it with the same value do not compare not-equal")
- {
- REQUIRE_FALSE(type_alias{42} != type_alias{42});
- }
-
- THEN("two object of it with different values do not compare equal")
- {
- REQUIRE_FALSE(type_alias{42} == type_alias{43});
- }
-
- THEN("two object of it with different values compare not-equal")
- {
- REQUIRE(type_alias{42} != type_alias{43});
- }
-
- THEN("equality comparison returns bool")
- {
- STATIC_REQUIRE(std::is_same_v<bool, decltype(std::declval<type_alias>() == std::declval<type_alias>())>);
- }
-
- THEN("inequality comparison returns bool")
- {
- STATIC_REQUIRE(std::is_same_v<bool, decltype(std::declval<type_alias>() != std::declval<type_alias>())>);
- }
- }
-
- GIVEN("A new_type deriving nt::EqBase")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::EqBase)>;
-
- THEN("an instance of it compares equal to the equivalent base type value")
- {
- REQUIRE(type_alias{42} == 42);
- }
-
- THEN("an instance of it comapres not-equal to a different base type value")
- {
- REQUIRE(type_alias{42} != 43);
- }
- }
-
- GIVEN("A new_type over a nothrow-comparable type")
- {
- using type_alias = nt::new_type<int, struct tag>;
-
- static_assert(nt::concepts::nothrow_equality_comparable<type_alias::base_type>);
- static_assert(nt::concepts::nothrow_inequality_comparable<type_alias::base_type>);
-
- THEN("it is nothrow-equality-comparable")
- {
- STATIC_REQUIRE(nt::concepts::nothrow_equality_comparable<type_alias>);
- }
-
- THEN("it is nothrow-inequality-comparable")
- {
- STATIC_REQUIRE(nt::concepts::nothrow_inequality_comparable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-nothrow-comparable type")
- {
- struct not_nothrow_comparable
- {
- auto operator==(not_nothrow_comparable) const noexcept(false) -> bool;
- auto operator!=(not_nothrow_comparable) const noexcept(false) -> bool;
- };
-
- using type_alias = nt::new_type<not_nothrow_comparable, struct tag>;
-
- static_assert(!nt::concepts::nothrow_equality_comparable<type_alias::base_type>);
- static_assert(!nt::concepts::nothrow_inequality_comparable<type_alias::base_type>);
-
- THEN("it is not nothrow-equality-comparable")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::nothrow_equality_comparable<type_alias>);
- }
-
- THEN("it is not nothrow-inequality-comparable")
- {
- STATIC_REQUIRE_FALSE(noexcept(std::declval<type_alias>() != std::declval<type_alias>()));
- }
- }
-}
diff --git a/source/tests/src/hash.cpp b/source/tests/src/hash.cpp
deleted file mode 100644
index 94f252f..0000000
--- a/source/tests/src/hash.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_template_test_macros.hpp>
-#include <catch2/catch_test_macros.hpp>
-
-#include <string>
-#include <unordered_map>
-
-TEMPLATE_TEST_CASE("Hash", "[hash]", std::string, int)
-{
- GIVEN("A new_type not deriving nt::Hash")
- {
- using type_alias = nt::new_type<TestType, struct tag>;
- static_assert(nt::concepts::hashable<typename type_alias::base_type>);
-
- THEN("it is not hashable")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::hashable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a hashable type deriving nt::Hash")
- {
- using type_alias = nt::new_type<TestType, struct tag, deriving(nt::Hash)>;
- static_assert(nt::concepts::hashable<typename type_alias::base_type>);
-
- THEN("it is hashable")
- {
- STATIC_REQUIRE(nt::concepts::hashable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-hashable type deriving nt::Hash")
- {
- struct non_hashable
- {
- };
- using type_alias = nt::new_type<non_hashable, struct tag, deriving(nt::Hash)>;
- static_assert(!nt::concepts::hashable<typename type_alias::base_type>);
-
- THEN("it is not hashable")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::hashable<type_alias>);
- }
- }
-
- GIVEN("A hashable new_type")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Hash)>;
- static_assert(nt::concepts::hashable<typename type_alias::base_type>);
-
- THEN("it can be used a the key in an unordered_map")
- {
- auto map = std::unordered_map<type_alias, int>{};
- map[type_alias{42}] = 43;
- REQUIRE(map[type_alias{42}] == 43);
- }
- }
-}
diff --git a/source/tests/src/io_operators.cpp b/source/tests/src/io_operators.cpp
deleted file mode 100644
index f7f8f29..0000000
--- a/source/tests/src/io_operators.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_test_macros.hpp>
-
-#include <iosfwd>
-#include <sstream>
-#include <string>
-#include <type_traits>
-#include <utility>
-
-inline namespace traits_extensions
-{
-
- template<typename T, typename = void>
- struct has_stream_input : std::false_type
- {
- };
-
- template<typename T>
- struct has_stream_input<T, std::void_t<decltype(std::declval<std::istream &>() >> std::declval<T &>())>> : std::true_type
- {
- };
-
- template<typename T>
- auto constexpr has_stream_input_v = has_stream_input<T>::value;
-
- template<typename T, typename = void>
- struct has_stream_output : std::false_type
- {
- };
-
- template<typename T>
- struct has_stream_output<T, std::void_t<decltype(std::declval<std::ostream &>() << std::declval<T &>())>> : std::true_type
- {
- };
-
- template<typename T>
- auto constexpr has_stream_output_v = has_stream_output<T>::value;
-
-} // namespace traits_extensions
-
-SCENARIO("Stream Input")
-{
- GIVEN("A new_type over a stream-inputtable type deriving nt::Read")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Read)>;
- static_assert(has_stream_input_v<type_alias::base_type>);
-
- THEN("it has the stream input operator")
- {
- STATIC_REQUIRE(has_stream_input_v<type_alias>);
- }
-
- THEN("an instance of it can be read from an std::istream")
- {
- auto obj = type_alias{};
- auto str = std::istringstream{"42"};
-
- str >> obj;
-
- REQUIRE(obj.decay() == 42);
- }
- }
-
- GIVEN("A new_type over a non-stream-inputtable type deriving nt::Read")
- {
- using type_alias = nt::new_type<std::istream, struct tag, deriving(nt::Read)>;
- static_assert(!has_stream_input_v<type_alias::base_type>);
-
- THEN("it does not have the input operator")
- {
- STATIC_REQUIRE(!has_stream_input_v<type_alias>);
- }
- }
-}
-
-SCENARIO("Stream Output")
-{
- GIVEN("A new_type over a stream-outputtable type deriving nt::Show")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Show)>;
- static_assert(has_stream_output_v<type_alias::base_type>);
-
- THEN("it has the stream output operator")
- {
- STATIC_REQUIRE(has_stream_output_v<type_alias>);
- }
-
- THEN("an instance of it can be written to an std::ostream")
- {
- auto obj = type_alias{42};
- auto str = std::ostringstream{};
-
- str << obj;
-
- REQUIRE(str.str() == "42");
- }
- }
-
- GIVEN("A new_type over a non-stream-outputtable type deriving nt::Show")
- {
- using type_alias = nt::new_type<std::istream, struct tag, deriving(nt::Show)>;
- static_assert(!has_stream_output_v<type_alias::base_type>);
-
- THEN("it does not have the output operator")
- {
- STATIC_REQUIRE(!has_stream_output_v<type_alias>);
- }
- }
-}
diff --git a/source/tests/src/iterable.cpp b/source/tests/src/iterable.cpp
deleted file mode 100644
index 85b7edc..0000000
--- a/source/tests/src/iterable.cpp
+++ /dev/null
@@ -1,1060 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_test_macros.hpp>
-
-#include <algorithm>
-#include <array>
-#include <iterator>
-#include <numeric>
-
-namespace iterable_types
-{
-
- struct with_member
- {
- using iterator = char *;
- using const_iterator = char const *;
- using reverse_iterator = std::reverse_iterator<iterator>;
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
- auto constexpr begin() -> iterator;
- auto constexpr begin() const -> const_iterator;
- auto constexpr cbegin() const -> const_iterator;
- auto constexpr rbegin() -> reverse_iterator;
- auto constexpr rbegin() const -> const_reverse_iterator;
- auto constexpr crbegin() const -> const_reverse_iterator;
-
- auto constexpr end() -> iterator;
- auto constexpr end() const -> const_iterator;
- auto constexpr cend() const -> const_iterator;
- auto constexpr rend() -> reverse_iterator;
- auto constexpr rend() const -> const_reverse_iterator;
- auto constexpr crend() const -> const_reverse_iterator;
- };
-
- struct with_free
- {
- using iterator = char *;
- using const_iterator = char const *;
- using reverse_iterator = std::reverse_iterator<iterator>;
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- };
-
- auto constexpr begin(with_free &) -> with_free::iterator;
- auto constexpr begin(with_free const &) -> with_free::const_iterator;
- auto constexpr cbegin(with_free const &) -> with_free::const_iterator;
- auto constexpr rbegin(with_free &) -> with_free::reverse_iterator;
- auto constexpr rbegin(with_free const &) -> with_free::const_reverse_iterator;
- auto constexpr crbegin(with_free const &) -> with_free::const_reverse_iterator;
- auto constexpr end(with_free &) -> with_free::iterator;
- auto constexpr end(with_free const &) -> with_free::const_iterator;
- auto constexpr cend(with_free const &) -> with_free::const_iterator;
- auto constexpr rend(with_free &) -> with_free::reverse_iterator;
- auto constexpr rend(with_free const &) -> with_free::const_reverse_iterator;
- auto constexpr crend(with_free const &) -> with_free::const_reverse_iterator;
-
-} // namespace iterable_types
-
-SCENARIO("Iterators", "[iterators]")
-{
- GIVEN("A new_type over a non-iterable base type not deriving nt::Iterable")
- {
- using type_alias = nt::new_type<int, struct tag>;
- static_assert(!nt::concepts::beginnable<type_alias::base_type>);
- static_assert(!nt::concepts::beginnable<type_alias::base_type const>);
- static_assert(!nt::concepts::cbeginnable<type_alias::base_type>);
- static_assert(!nt::concepts::rbeginnable<type_alias::base_type>);
- static_assert(!nt::concepts::rbeginnable<type_alias::base_type const>);
- static_assert(!nt::concepts::crbeginnable<type_alias::base_type>);
- static_assert(!nt::concepts::endable<type_alias::base_type>);
- static_assert(!nt::concepts::endable<type_alias::base_type const>);
- static_assert(!nt::concepts::cendable<type_alias::base_type>);
- static_assert(!nt::concepts::rendable<type_alias::base_type>);
- static_assert(!nt::concepts::rendable<type_alias::base_type const>);
- static_assert(!nt::concepts::crendable<type_alias::base_type>);
-
- THEN("it has no begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::beginnable<type_alias>);
- }
-
- THEN("it has no constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::beginnable<type_alias const>);
- }
-
- THEN("it has no cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::cbeginnable<type_alias>);
- }
-
- THEN("it has no rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable<type_alias>);
- }
-
- THEN("it has no constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable<type_alias const>);
- }
-
- THEN("it has no crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::crbeginnable<type_alias>);
- }
-
- THEN("it has no end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::endable<type_alias>);
- }
-
- THEN("it has no constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::endable<type_alias const>);
- }
-
- THEN("it has no cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::cendable<type_alias>);
- }
-
- THEN("it has no rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rendable<type_alias>);
- }
-
- THEN("it has no constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rendable<type_alias const>);
- }
-
- THEN("it has no crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::crendable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-iterable base type deriving nt::Iterable")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>;
- static_assert(!nt::concepts::beginnable<type_alias::base_type>);
- static_assert(!nt::concepts::beginnable<type_alias::base_type const>);
- static_assert(!nt::concepts::cbeginnable<type_alias::base_type>);
- static_assert(!nt::concepts::rbeginnable<type_alias::base_type>);
- static_assert(!nt::concepts::rbeginnable<type_alias::base_type const>);
- static_assert(!nt::concepts::crbeginnable<type_alias::base_type>);
- static_assert(!nt::concepts::endable<type_alias::base_type>);
- static_assert(!nt::concepts::endable<type_alias::base_type const>);
- static_assert(!nt::concepts::cendable<type_alias::base_type>);
- static_assert(!nt::concepts::rendable<type_alias::base_type>);
- static_assert(!nt::concepts::rendable<type_alias::base_type const>);
- static_assert(!nt::concepts::crendable<type_alias::base_type>);
-
- THEN("it has no begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::beginnable<type_alias>);
- }
-
- THEN("it has no constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::beginnable<type_alias const>);
- }
-
- THEN("it has no cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::cbeginnable<type_alias>);
- }
-
- THEN("it has no rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable<type_alias>);
- }
-
- THEN("it has no constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable<type_alias const>);
- }
-
- THEN("it has no crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::crbeginnable<type_alias>);
- }
-
- THEN("it has no end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::endable<type_alias>);
- }
-
- THEN("it has no constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::endable<type_alias const>);
- }
-
- THEN("it has no cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::cendable<type_alias>);
- }
-
- THEN("it has no rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rendable<type_alias>);
- }
-
- THEN("it has no constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rendable<type_alias const>);
- }
-
- THEN("it has no crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::crendable<type_alias>);
- }
- }
-
- GIVEN("A new_type over an iterable base type not deriving nt::Iterable")
- {
- using type_alias = nt::new_type<std::array<int, 1>, struct tag>;
- static_assert(nt::concepts::beginnable<type_alias::base_type>);
- static_assert(nt::concepts::const_beginnable<type_alias::base_type>);
- static_assert(nt::concepts::cbeginnable<type_alias::base_type>);
- static_assert(nt::concepts::rbeginnable<type_alias::base_type>);
- static_assert(nt::concepts::const_rbeginnable<type_alias::base_type>);
- static_assert(nt::concepts::crbeginnable<type_alias::base_type>);
- static_assert(nt::concepts::endable<type_alias::base_type>);
- static_assert(nt::concepts::const_endable<type_alias::base_type>);
- static_assert(nt::concepts::cendable<type_alias::base_type>);
- static_assert(nt::concepts::rendable<type_alias::base_type>);
- static_assert(nt::concepts::const_rendable<type_alias::base_type>);
- static_assert(nt::concepts::crendable<type_alias::base_type>);
-
- THEN("it has no begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::beginnable<type_alias>);
- }
-
- THEN("it has no constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::beginnable<type_alias const>);
- }
-
- THEN("it has no cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::cbeginnable<type_alias>);
- }
-
- THEN("it has no rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable<type_alias>);
- }
-
- THEN("it has no constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable<type_alias const>);
- }
-
- THEN("it has no crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::crbeginnable<type_alias>);
- }
-
- THEN("it has no end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::endable<type_alias>);
- }
-
- THEN("it has no constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::endable<type_alias const>);
- }
-
- THEN("it has no cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::cendable<type_alias>);
- }
-
- THEN("it has no rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rendable<type_alias>);
- }
-
- THEN("it has no constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::rendable<type_alias const>);
- }
-
- THEN("it has no crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::crendable<type_alias>);
- }
- }
-
- GIVEN("A new_type over an iterable base type deriving nt::Iterable")
- {
- using type_alias = nt::new_type<std::array<int, 1>, struct tag, deriving(nt::Iterable)>;
- static_assert(nt::concepts::beginnable<type_alias::base_type>);
- static_assert(nt::concepts::const_beginnable<type_alias::base_type>);
- static_assert(nt::concepts::cbeginnable<type_alias::base_type>);
- static_assert(nt::concepts::rbeginnable<type_alias::base_type>);
- static_assert(nt::concepts::const_rbeginnable<type_alias::base_type>);
- static_assert(nt::concepts::crbeginnable<type_alias::base_type>);
- static_assert(nt::concepts::endable<type_alias::base_type>);
- static_assert(nt::concepts::const_endable<type_alias::base_type>);
- static_assert(nt::concepts::cendable<type_alias::base_type>);
- static_assert(nt::concepts::rendable<type_alias::base_type>);
- static_assert(nt::concepts::const_rendable<type_alias::base_type>);
- static_assert(nt::concepts::crendable<type_alias::base_type>);
-
- THEN("it has begin")
- {
- STATIC_REQUIRE(nt::concepts::beginnable<type_alias>);
- }
-
- THEN("it has constant begin")
- {
- STATIC_REQUIRE(nt::concepts::const_beginnable<type_alias>);
- }
-
- THEN("it has cbegin")
- {
- STATIC_REQUIRE(nt::concepts::cbeginnable<type_alias>);
- }
-
- THEN("it has rbegin")
- {
- STATIC_REQUIRE(nt::concepts::rbeginnable<type_alias>);
- }
-
- THEN("it has constant rbegin")
- {
- STATIC_REQUIRE(nt::concepts::const_rbeginnable<type_alias>);
- }
-
- THEN("it has crbegin")
- {
- STATIC_REQUIRE(nt::concepts::crbeginnable<type_alias>);
- }
-
- THEN("it has end")
- {
- STATIC_REQUIRE(nt::concepts::endable<type_alias>);
- }
-
- THEN("it has constant end")
- {
- STATIC_REQUIRE(nt::concepts::const_endable<type_alias>);
- }
-
- THEN("it has cend")
- {
- STATIC_REQUIRE(nt::concepts::cendable<type_alias>);
- }
-
- THEN("it has rend")
- {
- STATIC_REQUIRE(nt::concepts::rendable<type_alias>);
- }
-
- THEN("it has constant rend")
- {
- STATIC_REQUIRE(nt::concepts::const_rendable<type_alias>);
- }
-
- THEN("it has crend")
- {
- STATIC_REQUIRE(nt::concepts::crendable<type_alias>);
- }
- }
-}
-
-SCENARIO("Iterators (member)", "[iterators]")
-{
- GIVEN("A new_type over a non-iterable base type not deriving nt::Iterable")
- {
- using type_alias = nt::new_type<int, struct tag>;
- static_assert(!nt::concepts::member_begin<type_alias::base_type>);
- static_assert(!nt::concepts::const_member_begin<type_alias::base_type>);
- static_assert(!nt::concepts::member_cbegin<type_alias::base_type>);
- static_assert(!nt::concepts::member_rbegin<type_alias::base_type>);
- static_assert(!nt::concepts::const_member_rbegin<type_alias::base_type>);
- static_assert(!nt::concepts::member_crbegin<type_alias::base_type>);
- static_assert(!nt::concepts::member_end<type_alias::base_type>);
- static_assert(!nt::concepts::const_member_end<type_alias::base_type>);
- static_assert(!nt::concepts::member_cend<type_alias::base_type>);
- static_assert(!nt::concepts::member_rend<type_alias::base_type>);
- static_assert(!nt::concepts::const_member_rend<type_alias::base_type>);
- static_assert(!nt::concepts::member_crend<type_alias::base_type>);
-
- THEN("it has no member begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_begin<type_alias>);
- }
-
- THEN("it has no member constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_begin<type_alias const>);
- }
-
- THEN("it has no member cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_cbegin<type_alias>);
- }
-
- THEN("it has no member rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin<type_alias>);
- }
-
- THEN("it has no member constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin<type_alias const>);
- }
-
- THEN("it has no member crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_crbegin<type_alias>);
- }
-
- THEN("it has no member end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_end<type_alias>);
- }
-
- THEN("it has no member constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_end<type_alias const>);
- }
-
- THEN("it has no member cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_cend<type_alias>);
- }
-
- THEN("it has no member rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rend<type_alias>);
- }
-
- THEN("it has no member constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rend<type_alias const>);
- }
-
- THEN("it has no member crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_crend<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-iterable base type deriving nt::Iterable")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>;
- static_assert(!nt::concepts::member_begin<type_alias::base_type>);
- static_assert(!nt::concepts::const_member_begin<type_alias::base_type>);
- static_assert(!nt::concepts::member_cbegin<type_alias::base_type>);
- static_assert(!nt::concepts::member_rbegin<type_alias::base_type>);
- static_assert(!nt::concepts::const_member_rbegin<type_alias::base_type>);
- static_assert(!nt::concepts::member_crbegin<type_alias::base_type>);
- static_assert(!nt::concepts::member_end<type_alias::base_type>);
- static_assert(!nt::concepts::const_member_end<type_alias::base_type>);
- static_assert(!nt::concepts::member_cend<type_alias::base_type>);
- static_assert(!nt::concepts::member_rend<type_alias::base_type>);
- static_assert(!nt::concepts::const_member_rend<type_alias::base_type>);
- static_assert(!nt::concepts::member_crend<type_alias::base_type>);
-
- THEN("it has no member begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_begin<type_alias>);
- }
-
- THEN("it has no member constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_begin<type_alias const>);
- }
-
- THEN("it has no member cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_cbegin<type_alias>);
- }
-
- THEN("it has no member rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin<type_alias>);
- }
-
- THEN("it has no member constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin<type_alias const>);
- }
-
- THEN("it has no member crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_crbegin<type_alias>);
- }
-
- THEN("it has no member end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_end<type_alias>);
- }
-
- THEN("it has no member constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_end<type_alias const>);
- }
-
- THEN("it has no member cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_cend<type_alias>);
- }
-
- THEN("it has no member rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rend<type_alias>);
- }
-
- THEN("it has no member constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rend<type_alias const>);
- }
-
- THEN("it has no member crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_crend<type_alias>);
- }
- }
-
- GIVEN("A new_type over an iterable base type not deriving nt::Iterable")
- {
- using type_alias = nt::new_type<std::array<int, 1>, struct tag>;
- static_assert(nt::concepts::member_begin<type_alias::base_type>);
- static_assert(nt::concepts::const_member_begin<type_alias::base_type>);
- static_assert(nt::concepts::member_cbegin<type_alias::base_type>);
- static_assert(nt::concepts::member_rbegin<type_alias::base_type>);
- static_assert(nt::concepts::const_member_rbegin<type_alias::base_type>);
- static_assert(nt::concepts::member_crbegin<type_alias::base_type>);
- static_assert(nt::concepts::member_end<type_alias::base_type>);
- static_assert(nt::concepts::const_member_end<type_alias::base_type>);
- static_assert(nt::concepts::member_cend<type_alias::base_type>);
- static_assert(nt::concepts::member_rend<type_alias::base_type>);
- static_assert(nt::concepts::const_member_rend<type_alias::base_type>);
- static_assert(nt::concepts::member_crend<type_alias::base_type>);
-
- THEN("it has no member begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_begin<type_alias>);
- }
-
- THEN("it has no member constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_begin<type_alias const>);
- }
-
- THEN("it has no member cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_cbegin<type_alias>);
- }
-
- THEN("it has no member rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin<type_alias>);
- }
-
- THEN("it has no member constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin<type_alias const>);
- }
-
- THEN("it has no member crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_crbegin<type_alias>);
- }
-
- THEN("it has no member end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_end<type_alias>);
- }
-
- THEN("it has no member constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_end<type_alias const>);
- }
-
- THEN("it has no member cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_cend<type_alias>);
- }
-
- THEN("it has no member rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rend<type_alias>);
- }
-
- THEN("it has no member constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_rend<type_alias const>);
- }
-
- THEN("it has no member crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::member_crend<type_alias>);
- }
- }
-
- GIVEN("A new_type over an iterable base type deriving nt::Iterable")
- {
- using type_alias = nt::new_type<std::array<int, 1>, struct tag, deriving(nt::Iterable)>;
- static_assert(nt::concepts::member_begin<type_alias::base_type>);
- static_assert(nt::concepts::const_member_begin<type_alias::base_type>);
- static_assert(nt::concepts::member_cbegin<type_alias::base_type>);
- static_assert(nt::concepts::member_rbegin<type_alias::base_type>);
- static_assert(nt::concepts::const_member_rbegin<type_alias::base_type>);
- static_assert(nt::concepts::member_crbegin<type_alias::base_type>);
- static_assert(nt::concepts::member_end<type_alias::base_type>);
- static_assert(nt::concepts::const_member_end<type_alias::base_type>);
- static_assert(nt::concepts::member_cend<type_alias::base_type>);
- static_assert(nt::concepts::member_rend<type_alias::base_type>);
- static_assert(nt::concepts::const_member_rend<type_alias::base_type>);
- static_assert(nt::concepts::member_crend<type_alias::base_type>);
-
- THEN("it has member begin")
- {
- STATIC_REQUIRE(nt::concepts::member_begin<type_alias>);
- }
-
- THEN("it has member constant begin")
- {
- STATIC_REQUIRE(nt::concepts::const_member_begin<type_alias>);
- }
-
- THEN("it has member cbegin")
- {
- STATIC_REQUIRE(nt::concepts::member_cbegin<type_alias>);
- }
-
- THEN("it has member rbegin")
- {
- STATIC_REQUIRE(nt::concepts::member_rbegin<type_alias>);
- }
-
- THEN("it has member constant rbegin")
- {
- STATIC_REQUIRE(nt::concepts::const_member_rbegin<type_alias>);
- }
-
- THEN("it has member crbegin")
- {
- STATIC_REQUIRE(nt::concepts::member_crbegin<type_alias>);
- }
-
- THEN("it has member end")
- {
- STATIC_REQUIRE(nt::concepts::member_end<type_alias>);
- }
-
- THEN("it has member constant end")
- {
- STATIC_REQUIRE(nt::concepts::const_member_end<type_alias>);
- }
-
- THEN("it has member cend")
- {
- STATIC_REQUIRE(nt::concepts::member_cend<type_alias>);
- }
-
- THEN("it has member rend")
- {
- STATIC_REQUIRE(nt::concepts::member_rend<type_alias>);
- }
-
- THEN("it has member constant rend")
- {
- STATIC_REQUIRE(nt::concepts::const_member_rend<type_alias>);
- }
-
- THEN("it has member crend")
- {
- STATIC_REQUIRE(nt::concepts::member_crend<type_alias>);
- }
- }
-}
-
-SCENARIO("Iterators (free)", "[iterators]")
-{
- GIVEN("A new_type over a non-iterable base type not deriving nt::Iterable")
- {
- using type_alias = nt::new_type<int, struct tag>;
- static_assert(!nt::concepts::free_begin<type_alias::base_type>);
- static_assert(!nt::concepts::const_free_begin<type_alias::base_type>);
- static_assert(!nt::concepts::free_cbegin<type_alias::base_type>);
- static_assert(!nt::concepts::free_rbegin<type_alias::base_type>);
- static_assert(!nt::concepts::const_free_rbegin<type_alias::base_type>);
- static_assert(!nt::concepts::free_crbegin<type_alias::base_type>);
- static_assert(!nt::concepts::free_end<type_alias::base_type>);
- static_assert(!nt::concepts::const_free_end<type_alias::base_type>);
- static_assert(!nt::concepts::free_cend<type_alias::base_type>);
- static_assert(!nt::concepts::free_rend<type_alias::base_type>);
- static_assert(!nt::concepts::const_free_rend<type_alias::base_type>);
- static_assert(!nt::concepts::free_crend<type_alias::base_type>);
-
- THEN("it has no free begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_begin<type_alias>);
- }
-
- THEN("it has no free constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::const_free_begin<type_alias>);
- }
-
- THEN("it has no free cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_cbegin<type_alias>);
- }
-
- THEN("it has no free rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_rbegin<type_alias>);
- }
-
- THEN("it has no free constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::const_free_rbegin<type_alias>);
- }
-
- THEN("it has no free crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_crbegin<type_alias>);
- }
-
- THEN("it has no free end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_end<type_alias>);
- }
-
- THEN("it has no free constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::const_free_end<type_alias>);
- }
-
- THEN("it has no free cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_cend<type_alias>);
- }
-
- THEN("it has no free rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_rend<type_alias>);
- }
-
- THEN("it has no free constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::const_free_rend<type_alias>);
- }
-
- THEN("it has no free crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_crend<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-iterable base type deriving nt::Iterable")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Iterable)>;
- static_assert(!nt::concepts::free_begin<type_alias::base_type>);
- static_assert(!nt::concepts::const_free_begin<type_alias::base_type>);
- static_assert(!nt::concepts::free_cbegin<type_alias::base_type>);
- static_assert(!nt::concepts::free_rbegin<type_alias::base_type>);
- static_assert(!nt::concepts::const_free_rbegin<type_alias::base_type>);
- static_assert(!nt::concepts::free_crbegin<type_alias::base_type>);
- static_assert(!nt::concepts::free_end<type_alias::base_type>);
- static_assert(!nt::concepts::const_free_end<type_alias::base_type>);
- static_assert(!nt::concepts::free_cend<type_alias::base_type>);
- static_assert(!nt::concepts::free_rend<type_alias::base_type>);
- static_assert(!nt::concepts::const_free_rend<type_alias::base_type>);
- static_assert(!nt::concepts::free_crend<type_alias::base_type>);
-
- THEN("it has no free begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_begin<type_alias>);
- }
-
- THEN("it has no free constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::const_free_begin<type_alias>);
- }
-
- THEN("it has no free cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_cbegin<type_alias>);
- }
-
- THEN("it has no free rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_rbegin<type_alias>);
- }
-
- THEN("it has no free constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::const_free_rbegin<type_alias>);
- }
-
- THEN("it has no free crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_crbegin<type_alias>);
- }
-
- THEN("it has no free end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_end<type_alias>);
- }
-
- THEN("it has no free constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::const_free_end<type_alias>);
- }
-
- THEN("it has no free cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_cend<type_alias>);
- }
-
- THEN("it has no free rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_rend<type_alias>);
- }
-
- THEN("it has no free constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::const_free_rend<type_alias>);
- }
-
- THEN("it has no free crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_crend<type_alias>);
- }
- }
-
- GIVEN("A new_type over an iterable base type not deriving nt::Iterable")
- {
- using type_alias = nt::new_type<std::array<int, 1>, struct tag>;
- static_assert(nt::concepts::free_begin<type_alias::base_type>);
- static_assert(nt::concepts::const_free_begin<type_alias::base_type>);
- static_assert(nt::concepts::free_cbegin<type_alias::base_type>);
- static_assert(nt::concepts::free_rbegin<type_alias::base_type>);
- static_assert(nt::concepts::const_free_rbegin<type_alias::base_type>);
- static_assert(nt::concepts::free_crbegin<type_alias::base_type>);
- static_assert(nt::concepts::free_end<type_alias::base_type>);
- static_assert(nt::concepts::const_free_end<type_alias::base_type>);
- static_assert(nt::concepts::free_cend<type_alias::base_type>);
- static_assert(nt::concepts::free_rend<type_alias::base_type>);
- static_assert(nt::concepts::const_free_rend<type_alias::base_type>);
- static_assert(nt::concepts::free_crend<type_alias::base_type>);
-
- THEN("it has no free begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_begin<type_alias>);
- }
-
- THEN("it has no free constant begin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_begin<type_alias const>);
- }
-
- THEN("it has no free cbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_cbegin<type_alias>);
- }
-
- THEN("it has no free rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_rbegin<type_alias>);
- }
-
- THEN("it has no free constant rbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_rbegin<type_alias const>);
- }
-
- THEN("it has no free crbegin")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_crbegin<type_alias>);
- }
-
- THEN("it has no free end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_end<type_alias>);
- }
-
- THEN("it has no free constant end")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_end<type_alias const>);
- }
-
- THEN("it has no free cend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_cend<type_alias>);
- }
-
- THEN("it has no free rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_rend<type_alias>);
- }
-
- THEN("it has no free constant rend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_rend<type_alias const>);
- }
-
- THEN("it has no free crend")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::free_crend<type_alias>);
- }
- }
-
- GIVEN("A new_type over an iterable base type deriving nt::Iterable")
- {
- using type_alias = nt::new_type<std::array<int, 1>, struct tag, deriving(nt::Iterable)>;
- static_assert(nt::concepts::free_begin<type_alias::base_type>);
- static_assert(nt::concepts::const_free_begin<type_alias::base_type>);
- static_assert(nt::concepts::free_cbegin<type_alias::base_type>);
- static_assert(nt::concepts::free_rbegin<type_alias::base_type>);
- static_assert(nt::concepts::const_free_rbegin<type_alias::base_type>);
- static_assert(nt::concepts::free_crbegin<type_alias::base_type>);
- static_assert(nt::concepts::free_end<type_alias::base_type>);
- static_assert(nt::concepts::const_free_end<type_alias::base_type>);
- static_assert(nt::concepts::free_cend<type_alias::base_type>);
- static_assert(nt::concepts::free_rend<type_alias::base_type>);
- static_assert(nt::concepts::const_free_rend<type_alias::base_type>);
- static_assert(nt::concepts::free_crend<type_alias::base_type>);
-
- THEN("it has free begin")
- {
- STATIC_REQUIRE(nt::concepts::free_begin<type_alias>);
- }
-
- THEN("it has free constant begin")
- {
- STATIC_REQUIRE(nt::concepts::const_free_begin<type_alias>);
- }
-
- THEN("it has free cbegin")
- {
- STATIC_REQUIRE(nt::concepts::free_cbegin<type_alias>);
- }
-
- THEN("it has free rbegin")
- {
- STATIC_REQUIRE(nt::concepts::free_rbegin<type_alias>);
- }
-
- THEN("it has free constant rbegin")
- {
- STATIC_REQUIRE(nt::concepts::const_free_rbegin<type_alias>);
- }
-
- THEN("it has free crbegin")
- {
- STATIC_REQUIRE(nt::concepts::free_crbegin<type_alias>);
- }
-
- THEN("it has free end")
- {
- STATIC_REQUIRE(nt::concepts::free_end<type_alias>);
- }
-
- THEN("it has free constant end")
- {
- STATIC_REQUIRE(nt::concepts::const_free_end<type_alias>);
- }
-
- THEN("it has free cend")
- {
- STATIC_REQUIRE(nt::concepts::free_cend<type_alias>);
- }
-
- THEN("it has free rend")
- {
- STATIC_REQUIRE(nt::concepts::free_rend<type_alias>);
- }
-
- THEN("it has free constant rend")
- {
- STATIC_REQUIRE(nt::concepts::const_free_rend<type_alias>);
- }
-
- THEN("it has free crend")
- {
- STATIC_REQUIRE(nt::concepts::free_crend<type_alias>);
- }
- }
-}
-
-SCENARIO("Iterator Semantics", "[iterators]")
-{
- GIVEN("An iterable new_type")
- {
- using type_alias = nt::new_type<std::array<int, 3>, struct tag, deriving(nt::Iterable)>;
-
- THEN("a non-const object can be used in value range-based for")
- {
- auto obj = type_alias{{1, 2, 3}};
- auto res = 0;
- for (auto e : obj)
- {
- res += e;
- }
- REQUIRE(res == 6);
- }
-
- THEN("a const object can be used in value range-based for")
- {
- auto const obj = type_alias{{1, 2, 3}};
- auto res = 0;
- for (auto e : obj)
- {
- res += e;
- }
- REQUIRE(res == 6);
- }
-
- THEN("a non-const object can be used in reference range-based for")
- {
- auto obj = type_alias{{1, 2, 3}};
- auto res = 0;
- for (auto & e : obj)
- {
- res += e;
- }
- REQUIRE(res == 6);
- }
-
- THEN("a const object can be used in const-reference range-based for")
- {
- auto const obj = type_alias{{1, 2, 3}};
- auto res = 0;
- for (auto const & e : obj)
- {
- res += e;
- }
- REQUIRE(res == 6);
- }
-
- THEN("using an instance of it in an STL algorithm yields the same results as using an instance of the base type")
- {
- auto const base_obj = type_alias::base_type{{1, 2, 3}};
- auto const nt_obj = type_alias{base_obj};
-
- auto base_res = std::accumulate(begin(base_obj), end(base_obj), 0);
- auto nt_res = std::accumulate(begin(nt_obj), end(nt_obj), 0);
-
- REQUIRE(nt_res == base_res);
- }
-
- THEN("iterating over an instance yields the same elements in the same order as iterating over an instance of the base type")
- {
- auto const base_obj = type_alias::base_type{{1, 2, 3}};
- auto const nt_obj = type_alias{base_obj};
-
- REQUIRE(std::equal(cbegin(nt_obj), cend(nt_obj), cbegin(base_obj), cend(base_obj)));
- }
- }
-}
diff --git a/source/tests/src/relational_operators.cpp b/source/tests/src/relational_operators.cpp
deleted file mode 100644
index e852957..0000000
--- a/source/tests/src/relational_operators.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_test_macros.hpp>
-
-#include <istream>
-#include <string>
-#include <type_traits>
-#include <utility>
-
-SCENARIO("Relational Operator Availability")
-{
- GIVEN("A new_type over a relationally comparable type not deriving nt::Relational")
- {
- using type_alias = nt::new_type<int, struct tag>;
- static_assert(nt::concepts::less_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::less_than_equal_comparable<type_alias::base_type>);
- static_assert(nt::concepts::greater_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::greater_than_equal_comparable<type_alias::base_type>);
-
- THEN("it does not have <")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::less_than_comparable<type_alias>);
- }
-
- THEN("it does not have <=")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::less_than_equal_comparable<type_alias>);
- }
-
- THEN("it does not have >")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::greater_than_comparable<type_alias>);
- }
-
- THEN("it does not have >=")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::greater_than_equal_comparable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a relationally comparable type deriving nt::Relational")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Relational)>;
- static_assert(nt::concepts::less_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::less_than_equal_comparable<type_alias::base_type>);
- static_assert(nt::concepts::greater_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::greater_than_equal_comparable<type_alias::base_type>);
-
- THEN("it does have <")
- {
- STATIC_REQUIRE(nt::concepts::less_than_comparable<type_alias>);
- }
-
- THEN("it does have <=")
- {
- STATIC_REQUIRE(nt::concepts::less_than_equal_comparable<type_alias>);
- }
-
- THEN("it does have >")
- {
- STATIC_REQUIRE(nt::concepts::greater_than_comparable<type_alias>);
- }
-
- THEN("it does have >=")
- {
- STATIC_REQUIRE(nt::concepts::greater_than_equal_comparable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a type that is not relationally comparable not deriving nt::Relational")
- {
- using type_alias = nt::new_type<std::istream, struct tag>;
- static_assert(!nt::concepts::less_than_comparable<type_alias::base_type>);
- static_assert(!nt::concepts::less_than_equal_comparable<type_alias::base_type>);
- static_assert(!nt::concepts::greater_than_comparable<type_alias::base_type>);
- static_assert(!nt::concepts::greater_than_equal_comparable<type_alias::base_type>);
-
- THEN("it does not have <")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::less_than_comparable<type_alias>);
- }
-
- THEN("it does not have <=")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::less_than_equal_comparable<type_alias>);
- }
-
- THEN("it does not have >")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::greater_than_comparable<type_alias>);
- }
-
- THEN("it does not have >=")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::greater_than_equal_comparable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a type that is not relationally comparable deriving nt::Relational")
- {
- using type_alias = nt::new_type<std::istream, struct tag, deriving(nt::Relational)>;
- static_assert(!nt::concepts::less_than_comparable<type_alias::base_type>);
- static_assert(!nt::concepts::less_than_equal_comparable<type_alias::base_type>);
- static_assert(!nt::concepts::greater_than_comparable<type_alias::base_type>);
- static_assert(!nt::concepts::greater_than_equal_comparable<type_alias::base_type>);
-
- THEN("it does not have <")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::less_than_comparable<type_alias>);
- }
-
- THEN("it does not have <=")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::less_than_equal_comparable<type_alias>);
- }
-
- THEN("it does not have >")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::greater_than_comparable<type_alias>);
- }
-
- THEN("it does not have >=")
- {
- STATIC_REQUIRE_FALSE(nt::concepts::greater_than_equal_comparable<type_alias>);
- }
- }
-}
-
-SCENARIO("Relational Comparisons")
-{
- GIVEN("A new_type over a relationally comparable type deriving nt::Relational")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Relational)>;
- static_assert(nt::concepts::less_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::less_than_equal_comparable<type_alias::base_type>);
- static_assert(nt::concepts::greater_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::greater_than_equal_comparable<type_alias::base_type>);
-
- THEN("comparing two instances using < yields the same result as it does for the base type")
- {
- REQUIRE((type_alias{1} < type_alias{2}) == (1 < 2));
- REQUIRE((type_alias{2} < type_alias{1}) == (2 < 1));
- }
-
- THEN("comparing two instances using <= yields the same result as it does for the base type")
- {
- REQUIRE((type_alias{1} <= type_alias{2}) == (1 <= 2));
- REQUIRE((type_alias{2} <= type_alias{1}) == (2 <= 1));
- }
-
- THEN("comparing two instances using > yields the same result as it does for the base type")
- {
- REQUIRE((type_alias{1} > type_alias{2}) == (1 > 2));
- REQUIRE((type_alias{2} > type_alias{1}) == (2 > 1));
- }
-
- THEN("comparing two instances using >= yields the same result as it does for the base type")
- {
- REQUIRE((type_alias{1} >= type_alias{2}) == (1 >= 2));
- REQUIRE((type_alias{2} >= type_alias{1}) == (2 >= 1));
- }
- }
-}
-
-SCENARIO("Nothrow Relational Comparison")
-{
- GIVEN("A new_type over a nothrow relationally comparable type deriving nt::Relational")
- {
- using type_alias = nt::new_type<int, struct tag, deriving(nt::Relational)>;
- static_assert(nt::concepts::nothrow_less_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::nothrow_less_than_equal_comparable<type_alias::base_type>);
- static_assert(nt::concepts::nothrow_greater_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::nothrow_greater_than_equal_comparable<type_alias::base_type>);
-
- THEN("it is nothrow-comparable using < ")
- {
- STATIC_REQUIRE(nt::concepts::nothrow_less_than_comparable<type_alias>);
- }
-
- THEN("it is nothrow-comparable using <= ")
- {
- STATIC_REQUIRE(nt::concepts::nothrow_less_than_equal_comparable<type_alias>);
- }
-
- THEN("it is nothrow-comparable using > ")
- {
- STATIC_REQUIRE(nt::concepts::nothrow_greater_than_comparable<type_alias>);
- }
-
- THEN("it is nothrow-comparable using >= ")
- {
- STATIC_REQUIRE(nt::concepts::nothrow_greater_than_equal_comparable<type_alias>);
- }
- }
-
- GIVEN("A new_type over a non-nothrow relationally comparable type deriving nt::Relational")
- {
- struct strange_type
- {
- auto constexpr operator<(strange_type const &) const noexcept(false) -> bool
- {
- return false;
- }
- auto constexpr operator>(strange_type const &) const noexcept(false) -> bool
- {
- return false;
- }
- auto constexpr operator<=(strange_type const &) const noexcept(false) -> bool
- {
- return false;
- }
- auto constexpr operator>=(strange_type const &) const noexcept(false) -> bool
- {
- return false;
- }
- };
-
- using type_alias = nt::new_type<strange_type, struct tag, deriving(nt::Relational)>;
- static_assert(nt::concepts::less_than_comparable<type_alias::base_type> &&
- !nt::concepts::nothrow_less_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::less_than_equal_comparable<type_alias::base_type> &&
- !nt::concepts::nothrow_less_than_equal_comparable<type_alias::base_type>);
- static_assert(nt::concepts::greater_than_comparable<type_alias::base_type> &&
- !nt::concepts::nothrow_greater_than_comparable<type_alias::base_type>);
- static_assert(nt::concepts::greater_than_equal_comparable<type_alias::base_type> &&
- !nt::concepts::nothrow_greater_than_equal_comparable<type_alias::base_type>);
-
- THEN("it is not nothrow-comparable using < ")
- {
- STATIC_REQUIRE(nt::concepts::less_than_comparable<type_alias> && !nt::concepts::nothrow_less_than_comparable<type_alias>);
- }
-
- THEN("it is not nothrow-comparable using <= ")
- {
- STATIC_REQUIRE(nt::concepts::less_than_equal_comparable<type_alias> && !nt::concepts::nothrow_less_than_equal_comparable<type_alias>);
- }
-
- THEN("it is not nothrow-comparable using > ")
- {
- STATIC_REQUIRE(nt::concepts::greater_than_comparable<type_alias> && !nt::concepts::nothrow_greater_than_comparable<type_alias>);
- }
-
- THEN("it is not nothrow-comparable using >= ")
- {
- STATIC_REQUIRE(nt::concepts::greater_than_equal_comparable<type_alias> &&
- !nt::concepts::nothrow_greater_than_equal_comparable<type_alias>);
- }
- }
-}
diff --git a/source/tests/src/threeway_comparison.cpp b/source/tests/src/threeway_comparison.cpp
deleted file mode 100644
index 45a36af..0000000
--- a/source/tests/src/threeway_comparison.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "newtype/newtype.hpp"
-
-#include <catch2/catch_template_test_macros.hpp>
-#include <catch2/catch_test_macros.hpp>
-
-#include <compare>
-#include <string>
-#include <vector>
-
-TEMPLATE_TEST_CASE("Scenario: Three-way Comparison", "[comparison]", int, std::string, std::vector<double>)
-{
- GIVEN("A new_type over a <=> comparable base type deriving nt::ThreewayCompare")
- {
- using type_alias = nt::new_type<TestType, struct tag, deriving(nt::ThreewayCompare)>;
- static_assert(std::three_way_comparable<TestType>);
-
- THEN("it is equality-comparable")
- {
- STATIC_REQUIRE(nt::concepts::equality_comparable<type_alias>);
- }
-
- THEN("it is inequality-comparable")
- {
- STATIC_REQUIRE(nt::concepts::inequality_comparable<type_alias>);
- }
-
- THEN("it is three-way comparable")
- {
- STATIC_REQUIRE(std::three_way_comparable<type_alias>);
- }
-
- THEN("it is less-than comparable")
- {
- STATIC_REQUIRE(nt::concepts::less_than_comparable<type_alias>);
- }
-
- THEN("it is less-than-equal comparable")
- {
- STATIC_REQUIRE(nt::concepts::greater_than_equal_comparable<type_alias>);
- }
-
- THEN("it is greater-than comparable")
- {
- STATIC_REQUIRE(nt::concepts::less_than_comparable<type_alias>);
- }
-
- THEN("it is greater-than-equal comparable")
- {
- STATIC_REQUIRE(nt::concepts::greater_than_equal_comparable<type_alias>);
- }
- }
-} \ No newline at end of file