CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
NamedType.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include <tuple>
11#include <type_traits>
12#include <utility>
13
14namespace CeresEngine {
15
16 template<typename T> using IsNotReference = typename std::enable_if<!std::is_reference<T>::value, void>::type;
17
18 template<typename T, template<typename> class CRTPType> struct CRTP {
19 constexpr T& getUnderlying() { return static_cast<T&>(*this); }
20 constexpr T const& getUnderlying() const { return static_cast<T const&>(*this); }
21 };
22
23 template<typename T, typename Parameter, template<typename> class... Skills> class NamedType : public Skills<NamedType<T, Parameter, Skills...>>... {
24 public:
26 using ReferenceType = NamedType<T&, Parameter, Skills...>;
27
29
30 // constructor
31 NamedType() = default;
32
33 explicit constexpr NamedType(T const& value) noexcept(std::is_nothrow_copy_constructible<T>::value) : raw(value) {}
34
35 template<typename TType = T, typename = IsNotReference<TType>>
36 explicit constexpr NamedType(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value) : raw(std::move(value)) {}
37
38 // get
39 [[nodiscard]] constexpr T& get() noexcept { return raw; }
40 [[nodiscard]] constexpr std::remove_reference_t<T> const& get() const noexcept { return raw; }
41
42 // conversions
43 operator ReferenceType() { return ReferenceType(raw); }
44 };
45
46 template<template<typename T> class StrongType, typename T> constexpr StrongType<T> make_named(T const& value) { return StrongType<T>(value); }
47
48 namespace details {
49 template<class F, class... Ts> struct AnyOrderCallable {
51 template<class... Us> auto operator()(Us&&... args) const {
52 static_assert(sizeof...(Ts) == sizeof...(Us), "Passing wrong number of arguments");
53 auto x = std::make_tuple(std::forward<Us>(args)...);
54 return f(std::move(std::get<Ts>(x))...);
55 }
56 };
57 } //namespace details
58
59 template<typename T> struct PreIncrementable : CRTP<T, PreIncrementable> {
60 constexpr T& operator++() {
61 ++this->getUnderlying().get();
62 return this->getUnderlying();
63 }
64 };
65
66 template<typename T> struct PostIncrementable : CRTP<T, PostIncrementable> {
67 constexpr T operator++(int) { return T(this->getUnderlying().get()++); }
68 };
69
70 template<typename T> struct PreDecrementable : CRTP<T, PreDecrementable> {
71 constexpr T& operator--() {
72 --this->getUnderlying().get();
73 return this->getUnderlying();
74 }
75 };
76
77 template<typename T> struct PostDecrementable : CRTP<T, PostDecrementable> {
78 constexpr T operator--(int) { return T(this->getUnderlying().get()--); }
79 };
80
81 template<typename T> struct BinaryAddable : CRTP<T, BinaryAddable> {
82 [[nodiscard]] constexpr T operator+(T const& other) const { return T(this->getUnderlying().get() + other.get()); }
83 constexpr T& operator+=(T const& other) {
84 this->getUnderlying().get() += other.get();
85 return this->getUnderlying();
86 }
87 };
88
89 template<typename T> struct UnaryAddable : CRTP<T, UnaryAddable> {
90 [[nodiscard]] constexpr T operator+() const { return T(+this->getUnderlying().get()); }
91 };
92
93 template<typename T> struct Addable : BinaryAddable<T>, UnaryAddable<T> {
96 };
97
98 template<typename T> struct BinarySubtractable : CRTP<T, BinarySubtractable> {
99 [[nodiscard]] constexpr T operator-(T const& other) const { return T(this->getUnderlying().get() - other.get()); }
100 constexpr T& operator-=(T const& other) {
101 this->getUnderlying().get() -= other.get();
102 return this->getUnderlying();
103 }
104 };
105
106 template<typename T> struct UnarySubtractable : CRTP<T, UnarySubtractable> {
107 [[nodiscard]] constexpr T operator-() const { return T(-this->getUnderlying().get()); }
108 };
109
110 template<typename T> struct Subtractable : BinarySubtractable<T>, UnarySubtractable<T> {
113 };
114
115 template<typename T> struct Multiplicable : CRTP<T, Multiplicable> {
116 [[nodiscard]] constexpr T operator*(T const& other) const { return T(this->getUnderlying().get() * other.get()); }
117 constexpr T& operator*=(T const& other) {
118 this->getUnderlying().get() *= other.get();
119 return this->getUnderlying();
120 }
121 };
122
123 template<typename T> struct Divisible : CRTP<T, Divisible> {
124 [[nodiscard]] constexpr T operator/(T const& other) const { return T(this->getUnderlying().get() / other.get()); }
125 constexpr T& operator/=(T const& other) {
126 this->getUnderlying().get() /= other.get();
127 return this->getUnderlying();
128 }
129 };
130
131 template<typename T> struct Modulable : CRTP<T, Modulable> {
132 [[nodiscard]] constexpr T operator%(T const& other) const { return T(this->getUnderlying().get() % other.get()); }
133 constexpr T& operator%=(T const& other) {
134 this->getUnderlying().get() %= other.get();
135 return this->getUnderlying();
136 }
137 };
138
139 template<typename T> struct BitwiseInvertable : CRTP<T, BitwiseInvertable> {
140 [[nodiscard]] constexpr T operator~() const { return T(~this->getUnderlying().get()); }
141 };
142
143 template<typename T> struct BitwiseAndable : CRTP<T, BitwiseAndable> {
144 [[nodiscard]] constexpr T operator&(T const& other) const { return T(this->getUnderlying().get() & other.get()); }
145 constexpr T& operator&=(T const& other) {
146 this->getUnderlying().get() &= other.get();
147 return this->getUnderlying();
148 }
149 };
150
151 template<typename T> struct BitwiseOrable : CRTP<T, BitwiseOrable> {
152 [[nodiscard]] constexpr T operator|(T const& other) const { return T(this->getUnderlying().get() | other.get()); }
153 constexpr T& operator|=(T const& other) {
154 this->getUnderlying().get() |= other.get();
155 return this->getUnderlying();
156 }
157 };
158
159 template<typename T> struct BitwiseXorable : CRTP<T, BitwiseXorable> {
160 [[nodiscard]] constexpr T operator^(T const& other) const { return T(this->getUnderlying().get() ^ other.get()); }
161 constexpr T& operator^=(T const& other) {
162 this->getUnderlying().get() ^= other.get();
163 return this->getUnderlying();
164 }
165 };
166
167 template<typename T> struct BitwiseLeftShiftable : CRTP<T, BitwiseLeftShiftable> {
168 [[nodiscard]] constexpr T operator<<(T const& other) const { return T(this->getUnderlying().get() << other.get()); }
169 constexpr T& operator<<=(T const& other) {
170 this->getUnderlying().get() <<= other.get();
171 return this->getUnderlying();
172 }
173 };
174
175 template<typename T> struct BitwiseRightShiftable : CRTP<T, BitwiseRightShiftable> {
176 [[nodiscard]] constexpr T operator>>(T const& other) const { return T(this->getUnderlying().get() >> other.get()); }
177 constexpr T& operator>>=(T const& other) {
178 this->getUnderlying().get() >>= other.get();
179 return this->getUnderlying();
180 }
181 };
182
183 template<typename T> struct ComparableTrait : CRTP<T, ComparableTrait> {
184 [[nodiscard]] constexpr bool operator<(ComparableTrait<T> const& other) const { return this->getUnderlying().get() < other.getUnderlying().get(); }
185 [[nodiscard]] constexpr bool operator>(ComparableTrait<T> const& other) const { return other.getUnderlying().get() < this->getUnderlying().get(); }
186 [[nodiscard]] constexpr bool operator<=(ComparableTrait<T> const& other) const { return !(other < *this); }
187 [[nodiscard]] constexpr bool operator>=(ComparableTrait<T> const& other) const { return !(*this < other); }
188 [[nodiscard]] constexpr bool operator==(ComparableTrait<T> const& other) const { return !(*this < other) && !(other < *this); }
189 [[nodiscard]] constexpr bool operator!=(ComparableTrait<T> const& other) const { return !(*this == other); }
190 };
191
192 template<typename T> struct Dereferencable;
193
194 template<typename T, typename Parameter, template<typename> class... Skills>
195 struct Dereferencable<NamedType<T, Parameter, Skills...>> : CRTP<NamedType<T, Parameter, Skills...>, Dereferencable> {
196 [[nodiscard]] constexpr T& operator*() & { return this->getUnderlying().get(); }
197 [[nodiscard]] constexpr std::remove_reference_t<T> const& operator*() const& { return this->getUnderlying().get(); }
198 };
199
200 template<typename Destination> struct ImplicitlyConvertibleTo {
201 template<typename T> struct templ : CRTP<T, templ> {
202 [[nodiscard]] constexpr operator Destination() const { return this->getUnderlying().get(); }
203 };
204 };
205
206 template<typename T> struct Printable : CRTP<T, Printable> {
207 static constexpr bool is_printable = true;
208
209 void print(std::ostream& os) const { os << this->getUnderlying().get(); }
210 };
211
212 template<typename T, typename Parameter, template<typename> class... Skills>
213 typename std::enable_if<NamedType<T, Parameter, Skills...>::is_printable, std::ostream&>::type operator<<(std::ostream& os,
215 object.print(os);
216 return os;
217 }
218
219 template<typename T> struct HashableTrait { static constexpr bool is_hashable = true; };
220
221 template<typename NamedType_> struct FunctionCallable;
222
223 template<typename T, typename Parameter, template<typename> class... Skills>
224 struct FunctionCallable<NamedType<T, Parameter, Skills...>> : CRTP<NamedType<T, Parameter, Skills...>, FunctionCallable> {
225 [[nodiscard]] constexpr operator T const&() const { return this->getUnderlying().get(); }
226 [[nodiscard]] constexpr operator T&() { return this->getUnderlying().get(); }
227 };
228
229 template<typename NamedType_> struct MethodCallable;
230
231 template<typename T, typename Parameter, template<typename> class... Skills>
232 struct MethodCallable<NamedType<T, Parameter, Skills...>> : CRTP<NamedType<T, Parameter, Skills...>, MethodCallable> {
233 [[nodiscard]] constexpr std::remove_reference_t<T> const* operator->() const { return std::addressof(this->getUnderlying().get()); }
234 [[nodiscard]] constexpr std::remove_reference_t<T>* operator->() { return std::addressof(this->getUnderlying().get()); }
235 };
236
237 template<typename NamedType_> struct Callable : FunctionCallable<NamedType_>, MethodCallable<NamedType_> {};
238
239 template<typename T> struct Incrementable : PreIncrementable<T>, PostIncrementable<T> {
242 };
243
244 template<typename T> struct Decrementable : PreDecrementable<T>, PostDecrementable<T> {
247 };
248
249 template<typename T>
251 Decrementable<T>,
252 Addable<T>,
253 Subtractable<T>,
254 Multiplicable<T>,
255 Divisible<T>,
256 Modulable<T>,
259 BitwiseOrable<T>,
264 Printable<T>,
265 HashableTrait<T> {};
266
267} // namespace CeresEngine
268
269template<typename T, typename Parameter, template<typename> class... Skills> struct std::hash<CeresEngine::NamedType<T, Parameter, Skills...>> {
270 using NamedType = CeresEngine::NamedType<T, Parameter, Skills...>;
271 using checkIfHashable = typename std::enable_if<NamedType::is_hashable, void>::type;
272
273 size_t operator()(CeresEngine::NamedType<T, Parameter, Skills...> const& x) const noexcept {
274 static_assert(noexcept(std::hash<T>()(x.get())), "hash fuction should not throw");
275
276 return std::hash<T>()(x.get());
277 }
278};
Definition NamedType.hpp:23
constexpr NamedType(T &&value) noexcept(std::is_nothrow_move_constructible< T >::value)
Definition NamedType.hpp:36
T raw
Definition NamedType.hpp:28
constexpr T & get() noexcept
Definition NamedType.hpp:39
NamedType< T &, Parameter, Skills... > ReferenceType
Definition NamedType.hpp:26
constexpr std::remove_reference_t< T > const & get() const noexcept
Definition NamedType.hpp:40
constexpr NamedType(T const &value) noexcept(std::is_nothrow_copy_constructible< T >::value)
Definition NamedType.hpp:33
T UnderlyingType
Definition NamedType.hpp:25
Definition Application.hpp:19
decltype(auto) get(BezierPath::Element &element) noexcept
Decomposes a bezier path element.
Definition BezierPath.hpp:723
constexpr Byte operator<<(const Byte arg, const _IntType shift) noexcept
Definition DataTypes.hpp:44
auto move(Vector3 position)
Moves a entity to the given position.
Definition Helpers.hpp:22
@ Destination
Specifies that the buffer can be used as the destination of a transfer command.
typename std::enable_if<!std::is_reference< T >::value, void >::type IsNotReference
Definition NamedType.hpp:16
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
constexpr StrongType< T > make_named(T const &value)
Definition NamedType.hpp:46
Definition Span.hpp:668
Definition NamedType.hpp:93
Definition NamedType.hpp:265
Definition NamedType.hpp:81
constexpr T operator+(T const &other) const
Definition NamedType.hpp:82
constexpr T & operator+=(T const &other)
Definition NamedType.hpp:83
Definition NamedType.hpp:98
constexpr T & operator-=(T const &other)
Definition NamedType.hpp:100
constexpr T operator-(T const &other) const
Definition NamedType.hpp:99
Definition NamedType.hpp:143
constexpr T operator&(T const &other) const
Definition NamedType.hpp:144
constexpr T & operator&=(T const &other)
Definition NamedType.hpp:145
Definition NamedType.hpp:139
constexpr T operator~() const
Definition NamedType.hpp:140
Definition NamedType.hpp:167
constexpr T operator<<(T const &other) const
Definition NamedType.hpp:168
constexpr T & operator<<=(T const &other)
Definition NamedType.hpp:169
Definition NamedType.hpp:151
constexpr T operator|(T const &other) const
Definition NamedType.hpp:152
constexpr T & operator|=(T const &other)
Definition NamedType.hpp:153
Definition NamedType.hpp:175
constexpr T & operator>>=(T const &other)
Definition NamedType.hpp:177
constexpr T operator>>(T const &other) const
Definition NamedType.hpp:176
Definition NamedType.hpp:159
constexpr T operator^(T const &other) const
Definition NamedType.hpp:160
constexpr T & operator^=(T const &other)
Definition NamedType.hpp:161
Definition NamedType.hpp:18
constexpr T const & getUnderlying() const
Definition NamedType.hpp:20
constexpr T & getUnderlying()
Definition NamedType.hpp:19
Definition NamedType.hpp:237
Definition NamedType.hpp:183
constexpr bool operator>(ComparableTrait< T > const &other) const
Definition NamedType.hpp:185
constexpr bool operator<=(ComparableTrait< T > const &other) const
Definition NamedType.hpp:186
constexpr bool operator!=(ComparableTrait< T > const &other) const
Definition NamedType.hpp:189
constexpr bool operator<(ComparableTrait< T > const &other) const
Definition NamedType.hpp:184
constexpr bool operator>=(ComparableTrait< T > const &other) const
Definition NamedType.hpp:187
constexpr bool operator==(ComparableTrait< T > const &other) const
Definition NamedType.hpp:188
Definition NamedType.hpp:244
constexpr std::remove_reference_t< T > const & operator*() const &
Definition NamedType.hpp:197
constexpr T & operator*() &
Definition NamedType.hpp:196
Definition NamedType.hpp:192
Definition NamedType.hpp:123
constexpr T operator/(T const &other) const
Definition NamedType.hpp:124
constexpr T & operator/=(T const &other)
Definition NamedType.hpp:125
Definition NamedType.hpp:221
Definition NamedType.hpp:219
static constexpr bool is_hashable
Definition NamedType.hpp:219
Definition NamedType.hpp:200
Definition NamedType.hpp:239
constexpr std::remove_reference_t< T > * operator->()
Definition NamedType.hpp:234
constexpr std::remove_reference_t< T > const * operator->() const
Definition NamedType.hpp:233
Definition NamedType.hpp:229
Definition NamedType.hpp:131
constexpr T & operator%=(T const &other)
Definition NamedType.hpp:133
constexpr T operator%(T const &other) const
Definition NamedType.hpp:132
Definition NamedType.hpp:115
constexpr T operator*(T const &other) const
Definition NamedType.hpp:116
constexpr T & operator*=(T const &other)
Definition NamedType.hpp:117
Definition NamedType.hpp:77
constexpr T operator--(int)
Definition NamedType.hpp:78
Definition NamedType.hpp:66
constexpr T operator++(int)
Definition NamedType.hpp:67
Definition NamedType.hpp:70
constexpr T & operator--()
Definition NamedType.hpp:71
Definition NamedType.hpp:59
constexpr T & operator++()
Definition NamedType.hpp:60
Definition NamedType.hpp:206
void print(std::ostream &os) const
Definition NamedType.hpp:209
static constexpr bool is_printable
Definition NamedType.hpp:207
Definition NamedType.hpp:110
Definition NamedType.hpp:89
constexpr T operator+() const
Definition NamedType.hpp:90
Definition NamedType.hpp:106
constexpr T operator-() const
Definition NamedType.hpp:107
Definition NamedType.hpp:49
auto operator()(Us &&... args) const
Definition NamedType.hpp:51
F f
Definition NamedType.hpp:50