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