From 440d47cae6431de3332ac934b6056a970cc1a0d7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 26 Feb 2025 11:24:59 +0100 Subject: build: remove conan --- .conan/profiles/gnu | 4 - .conan/profiles/std | 4 - .github/FUNDING.yml | 1 - .vscode/c_cpp_properties.json | 16 - .vscode/settings.json | 8 +- CMakeLists.txt | 19 + CMakePresets.json | 30 + conanfile.py | 65 -- doc/.gitignore | 2 + doc/CMakeLists.txt | 81 ++ doc/requirements.txt | 1 + doc/src/conf.py | 48 + doc/src/index.rst | 1271 +++++++++++++++++++++++++ examples/CMakeLists.txt | 15 + examples/src/basic_usage.cpp | 39 + examples/src/basic_usage_with_read.cpp | 37 + examples/src/basic_usage_with_show.cpp | 39 + lib/CMakeLists.txt | 16 + lib/include/newtype/newtype.hpp | 753 +++++++++++++++ source/CMakeLists.txt | 19 - source/doc/.gitignore | 2 - source/doc/CMakeLists.txt | 81 -- source/doc/requirements.txt | 1 - source/doc/src/conf.py | 48 - source/doc/src/index.rst | 1271 ------------------------- source/examples/CMakeLists.txt | 15 - source/examples/src/basic_usage.cpp | 39 - source/examples/src/basic_usage_with_read.cpp | 37 - source/examples/src/basic_usage_with_show.cpp | 39 - source/lib/CMakeLists.txt | 16 - source/lib/include/newtype/newtype.hpp | 753 --------------- source/tests/CMakeLists.txt | 33 - source/tests/src/arithmetic.cpp | 297 ------ source/tests/src/constructors.cpp | 102 -- source/tests/src/conversion.cpp | 133 --- source/tests/src/derivation_clause.cpp | 63 -- source/tests/src/equality_comparison.cpp | 102 -- source/tests/src/hash.cpp | 59 -- source/tests/src/io_operators.cpp | 110 --- source/tests/src/iterable.cpp | 1060 --------------------- source/tests/src/relational_operators.cpp | 249 ----- source/tests/src/threeway_comparison.cpp | 52 - test_package/.gitignore | 1 - test_package/CMakeLists.txt | 13 - test_package/conanfile.py | 21 - test_package/main.cpp | 11 - tests/CMakeLists.txt | 33 + tests/src/arithmetic.cpp | 297 ++++++ tests/src/constructors.cpp | 102 ++ tests/src/conversion.cpp | 133 +++ tests/src/derivation_clause.cpp | 63 ++ tests/src/equality_comparison.cpp | 102 ++ tests/src/hash.cpp | 59 ++ tests/src/io_operators.cpp | 110 +++ tests/src/iterable.cpp | 1060 +++++++++++++++++++++ tests/src/relational_operators.cpp | 249 +++++ tests/src/threeway_comparison.cpp | 52 + 57 files changed, 4614 insertions(+), 4722 deletions(-) delete mode 100644 .conan/profiles/gnu delete mode 100644 .conan/profiles/std delete mode 100644 .github/FUNDING.yml delete mode 100644 .vscode/c_cpp_properties.json create mode 100644 CMakeLists.txt create mode 100644 CMakePresets.json delete mode 100644 conanfile.py create mode 100644 doc/.gitignore create mode 100644 doc/CMakeLists.txt create mode 100644 doc/requirements.txt create mode 100644 doc/src/conf.py create mode 100644 doc/src/index.rst create mode 100644 examples/CMakeLists.txt create mode 100644 examples/src/basic_usage.cpp create mode 100644 examples/src/basic_usage_with_read.cpp create mode 100644 examples/src/basic_usage_with_show.cpp create mode 100644 lib/CMakeLists.txt create mode 100644 lib/include/newtype/newtype.hpp delete mode 100644 source/CMakeLists.txt delete mode 100644 source/doc/.gitignore delete mode 100644 source/doc/CMakeLists.txt delete mode 100644 source/doc/requirements.txt delete mode 100644 source/doc/src/conf.py delete mode 100644 source/doc/src/index.rst delete mode 100644 source/examples/CMakeLists.txt delete mode 100644 source/examples/src/basic_usage.cpp delete mode 100644 source/examples/src/basic_usage_with_read.cpp delete mode 100644 source/examples/src/basic_usage_with_show.cpp delete mode 100644 source/lib/CMakeLists.txt delete mode 100644 source/lib/include/newtype/newtype.hpp delete mode 100644 source/tests/CMakeLists.txt delete mode 100644 source/tests/src/arithmetic.cpp delete mode 100644 source/tests/src/constructors.cpp delete mode 100644 source/tests/src/conversion.cpp delete mode 100644 source/tests/src/derivation_clause.cpp delete mode 100644 source/tests/src/equality_comparison.cpp delete mode 100644 source/tests/src/hash.cpp delete mode 100644 source/tests/src/io_operators.cpp delete mode 100644 source/tests/src/iterable.cpp delete mode 100644 source/tests/src/relational_operators.cpp delete mode 100644 source/tests/src/threeway_comparison.cpp delete mode 100644 test_package/.gitignore delete mode 100644 test_package/CMakeLists.txt delete mode 100644 test_package/conanfile.py delete mode 100644 test_package/main.cpp create mode 100644 tests/CMakeLists.txt create mode 100644 tests/src/arithmetic.cpp create mode 100644 tests/src/constructors.cpp create mode 100644 tests/src/conversion.cpp create mode 100644 tests/src/derivation_clause.cpp create mode 100644 tests/src/equality_comparison.cpp create mode 100644 tests/src/hash.cpp create mode 100644 tests/src/io_operators.cpp create mode 100644 tests/src/iterable.cpp create mode 100644 tests/src/relational_operators.cpp create mode 100644 tests/src/threeway_comparison.cpp diff --git a/.conan/profiles/gnu b/.conan/profiles/gnu deleted file mode 100644 index eb91651..0000000 --- a/.conan/profiles/gnu +++ /dev/null @@ -1,4 +0,0 @@ -include(default) - -[settings] -compiler.cppstd=gnu20 \ No newline at end of file diff --git a/.conan/profiles/std b/.conan/profiles/std deleted file mode 100644 index dedc2a6..0000000 --- a/.conan/profiles/std +++ /dev/null @@ -1,4 +0,0 @@ -include(default) - -[settings] -compiler.cppstd=20 \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 77f52dd..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -github: fmorgner diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 2091cd3..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/source/lib/include" - ], - "defines": [], - "compilerPath": "/usr/bin/g++", - "cppStandard": "c++20", - "intelliSenseMode": "gcc-x64", - "configurationProvider": "ms-vscode.cmake-tools" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 72ff434..f9b4fe7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,20 +2,18 @@ // CMake Configuration "cmake.configureOnOpen": true, "cmake.useCMakePresets": "always", - "cmake.sourceDirectory": "${workspaceFolder}/source", // C++ Configuration "[cpp]": { "editor.formatOnSave": true }, "C_Cpp.autoAddFileAssociations": false, - "C_Cpp.intelliSenseEngine": "default", - "C_Cpp.errorSquiggles": "enabled", - "C_Cpp.autocomplete": "default", + "C_Cpp.intelliSenseEngine": "disabled", + "C_Cpp.errorSquiggles": "disabled", + "C_Cpp.autocomplete": "disabled", // RST Configuration "[python]": { "editor.defaultFormatter": "ms-python.black-formatter" }, - "esbonio.sphinx.confDir": "${workspaceFolder}/doc/src" } diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..36b5b62 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +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/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..da73733 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,30 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 25, + "patch": 0 + }, + "configurePresets": [ + { + "name": "default", + "generator": "Ninja Multi-Config", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_CONFIGURATION_TYPES": "Debug;MinSizeRel" + } + } + ], + "buildPresets": [ + { + "name": "debug", + "configurePreset": "default", + "configuration": "Debug" + }, + { + "name": "release", + "configurePreset": "default", + "configuration": "MinSizeRel" + } + ] +} \ No newline at end of file diff --git a/conanfile.py b/conanfile.py deleted file mode 100644 index 222ac72..0000000 --- a/conanfile.py +++ /dev/null @@ -1,65 +0,0 @@ -from conan import ConanFile -from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout -from conan.tools.build import check_min_cppstd - - -class NewtypeConan(ConanFile): - name = "newtype" - version = "2.0.0" - license = "BSD-3-Clause" - description = "A library of types and functions to create strong type aliases" - url = "https://github.com/fmorgner/newtype" - - settings = ("os", "arch", "compiler", "build_type") - - scm = { - "type": "git", - "url": "auto", - "revision": "auto" - } - - generators = [ - "CMakeDeps" - ] - - exports_sources = [ - "source/*", - "test_package/*", - "LICENSE", - ] - - def build(self): - cmake = CMake(self) - cmake.configure() - if not self.conf.get("tools.build:skip_test", default=False): - cmake.build() - cmake.test() - - def build_requirements(self): - self.tool_requires("cmake/[>3.25]") - self.tool_requires("ninja/[>1.11]") - self.test_requires("catch2/[>3.3]") - - def generate(self): - toolchain = CMakeToolchain(self, generator="Ninja Multi-Config") - toolchain.variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = True - toolchain.variables["PROJECT_VERSION"] = self.version - toolchain.variables["PROJECT_DESCRIPTION"] = self.description - toolchain.generate() - - def layout(self): - cmake_layout(self, generator="Ninja Multi-Config", src_folder="source") - - def package(self): - cmake = CMake(self) - cmake.install() - - def package_id(self): - self.info.clear() - - def package_info(self): - self.cpp_info.bindirs = [] - self.cpp_info.libdirs = [] - - def validate(self): - check_min_cppstd(self, 20) diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..ee826c1 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,2 @@ +Pipfile +Pipfile.lock diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000..7a9e27d --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,81 @@ +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/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 0000000..47b0805 --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1 @@ +sphinx~=7.0 diff --git a/doc/src/conf.py b/doc/src/conf.py new file mode 100644 index 0000000..a6e65de --- /dev/null +++ b/doc/src/conf.py @@ -0,0 +1,48 @@ +# -*- 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 "], + 3, + ), +] \ No newline at end of file diff --git a/doc/src/index.rst b/doc/src/index.rst new file mode 100644 index 0000000..88925aa --- /dev/null +++ b/doc/src/index.rst @@ -0,0 +1,1271 @@ +.. 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:`` +======================================== + +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 \ + 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 ` and the :cpp:var:`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 ` and the :cpp:var:`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 ` and the :cpp:var:`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 ` and the :cpp:var:`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) + + 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) + + 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 ` 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 ` 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 ` 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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`begin() const ` 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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`cbegin() const ` 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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`rbegin() const ` 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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`crbegin() const ` 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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`end() const ` 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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`cend() const ` 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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`rend() const ` 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 ` contains :cpp:var:`Iterable` and + b) this :cpp:class:`new_type`'s :cpp:type:`base type ` has a non-static member function :cpp:func:`crend() const ` 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 \ + constexpr bool operator==(new_type const & lhs, new_type const & rhs) + + Check two instances of :cpp:class:`new_type\` 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 \ + constexpr bool operator==(new_type const & lhs, BaseType const & rhs) + + Check an instance of :cpp:class:`new_type\` 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 `. + :throws: Any exception thrown by the comparison of object contained by :literal:`lhs` with an object of the :cpp: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 ` contains :cpp:var:`EqBase` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr bool operator==(BaseType const & lhs, new_type const & rhs) + + Check an instance of :cpp:type:`BaseType` for equality with an instance of :cpp:class:`new_type\`. + + :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 ` with the object contained by :literal:`rhs`. + :throws: Any exception thrown by the comparison of an object of :cpp: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 ` contains :cpp:var:`EqBase` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr bool operator!=(new_type const & lhs, new_type const & rhs) + + Check two instances of :cpp:class:`new_type\` 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 \ + constexpr bool operator!=(new_type const & lhs, BaseType const & rhs) + + Check an instance of :cpp:class:`new_type\` 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 `. + :throws: Any exception thrown by the comparison of the object contained by :literal:`lhs` with an object of the :cpp: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 ` contains :cpp:var:`EqBase` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr bool operator!=(BaseType const & lhs, new_type const & rhs) + + Check an instance of :cpp:type:`BaseType` for in-equality with an instance of :cpp:class:`new_type\`. + + :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 ` with the object contained by :literal:`rhs`. + :throws: Any exception thrown by the comparison of an object of :cpp: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 ` contains :cpp:var:`EqBase` + + .. versionadded:: 1.0.0 + +Relational Comparison Operators +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. cpp:function:: template \ + constexpr bool operator<(new_type const & lhs, new_type 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 ` contains :cpp:var:`Relational` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr bool operator>(new_type const & lhs, new_type 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 ` contains :cpp:var:`Relational` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr bool operator<=(new_type const & lhs, new_type 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 ` contains :cpp:var:`Relational` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr bool operator>=(new_type const & lhs, new_type 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 ` contains :cpp:var:`Relational` + + .. versionadded:: 1.0.0 + +Stream I/O Operators +~~~~~~~~~~~~~~~~~~~~ + +.. cpp:function:: template \ + std::basic_ostream & operator<<(std::basic_ostream & out, new_type const & value) + + Write an instance of :cpp:class:`new_type\` to a standard :cpp:type:`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 ` contains :cpp:var:`Show` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + std::basic_istream & operator>>(std::basic_istream & in, new_type & value) + + Read an instance of :cpp:class:`new_type\` from a standard :cpp:type:`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 ` contains :cpp:var:`Read` + + .. versionadded:: 1.0.0 + +Arithmetic Operators +~~~~~~~~~~~~~~~~~~~~ + +.. cpp:function:: template \ + constexpr new_type operator+(new_type const & lhs, new_type 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\` 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 ` contains :cpp:var:`Arithmetic` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr new_type & operator+=(new_type & lhs, new_type 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 ` contains :cpp:var:`Arithmetic` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr new_type operator-(new_type const & lhs, new_type 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\` 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 ` contains :cpp:var:`Arithmetic` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr new_type & operator-=(new_type & lhs, new_type 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 ` contains :cpp:var:`Arithmetic` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr new_type operator*(new_type const & lhs, new_type 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\` 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 ` contains :cpp:var:`Arithmetic` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr new_type & operator*=(new_type & lhs, new_type 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 ` contains :cpp:var:`Arithmetic` + + .. versionadded:: 1.0.0 + +.. cpp:function:: template \ + constexpr new_type operator/(new_type const & lhs, new_type 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\` 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 ` contains :cpp:var:`Arithmetic` + + .. versionadded:: 1.0.0 +.. cpp:function:: template \ + constexpr new_type & operator/=(new_type & lhs, new_type 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 ` contains :cpp:var:`Arithmetic` + + .. versionadded:: 1.0.0 + +Iterators +~~~~~~~~~ + +.. cpp:function:: template \ + constexpr new_type::iterator begin(new_type & 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 ` contains :cpp:var:`Iterable` and + b) for the :cpp:class:`new_type`'s :cpp:type:`base type ` 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 \ + constexpr new_type::const_iterator begin(new_type 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 ` contains :cpp:var:`Iterable` and + b) for the :cpp:class:`new_type`'s :cpp:type:`base type ` 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 \ + constexpr new_type::const_iterator cbegin(new_type 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`'