OGS
StrongType.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <concepts>
7#include <utility>
8
9namespace BaseLib
10{
16template <typename T, typename Tag>
18{
19 static_assert(
20 !std::is_reference_v<T>,
21 "The underlying type must not be a reference. This struct is not "
22 "designed for references. If its design should be extended to also "
23 "cover references make sure to unit test it thoroughly. In this case "
24 "also consider the implications for the overall usage of StrongType in "
25 "the code, e.g., StrongType<int, struct Tag> and StrongType<int&, "
26 "struct Tag> are not related to each other by any inheritance "
27 "relation, but are completely different types, and in particular "
28 "cannot be passed to functions expecting a value/reference of the "
29 "other type. Therefore, allowing references as underlying types might "
30 "have adverse effect on \"large scale\" API design.");
31
32 static_assert(
33 std::default_initializable<T>,
34 "The underlying type must be default initializable. This struct is "
35 "designed for \"general purpose\" underlying types such as numbers or "
36 "matrices, which are usually default constructible. If you need "
37 "support for non-default-constuctible underlying types, make sure you "
38 "test your extension of the current implementation thoroughly.");
39
40 constexpr StrongType() noexcept(std::is_nothrow_default_constructible_v<T>)
41 : value_{} // "zero initialization"
42 {
43 }
44
45 constexpr explicit StrongType(T const& value) noexcept(
46 std::is_nothrow_copy_constructible_v<T>)
47 : value_{value}
48 {
49 }
50
51 constexpr explicit StrongType(T&& value) noexcept(
52 std::is_nothrow_move_constructible_v<T>)
53 : value_{std::move(value)}
54 {
55 }
56
59 [[nodiscard]] constexpr T& operator()() noexcept { return this->value_; }
60 [[nodiscard]] constexpr T const& operator()() const noexcept
61 {
62 return value_;
63 }
64
67 [[nodiscard]] constexpr T& operator*() noexcept { return this->value_; }
68 [[nodiscard]] constexpr T const& operator*() const noexcept
69 {
70 return value_;
71 }
72
74 [[nodiscard]] constexpr T* operator->() noexcept { return &this->value_; }
75 [[nodiscard]] constexpr T const* operator->() const noexcept
76 {
77 return &value_;
78 }
79
80private:
82};
83} // namespace BaseLib
constexpr T const * operator->() const noexcept
Definition StrongType.h:75
constexpr StrongType() noexcept(std::is_nothrow_default_constructible_v< T >)
Definition StrongType.h:40
constexpr T * operator->() noexcept
Value access.
Definition StrongType.h:74
constexpr StrongType(T &&value) noexcept(std::is_nothrow_move_constructible_v< T >)
Definition StrongType.h:51
constexpr StrongType(T const &value) noexcept(std::is_nothrow_copy_constructible_v< T >)
Definition StrongType.h:45
constexpr T & operator*() noexcept
Definition StrongType.h:67
constexpr T & operator()() noexcept
Definition StrongType.h:59
constexpr T const & operator*() const noexcept
Definition StrongType.h:68
constexpr T const & operator()() const noexcept
Definition StrongType.h:60