MostlyHarmless 0.0.1
 
Loading...
Searching...
No Matches
marvin_PropagateConst.h
Go to the documentation of this file.
1// ========================================================================================================
2// _______ _______ ______ ___ ___ _______ _______
3// | | | _ | __ \ | |_ _| | |
4// | | | < | |_| |_| |
5// |__|_|__|___|___|___|__|\_____/|_______|__|____|
6//
7// This file is part of the Marvin open source library and is licensed under the terms of the MIT License.
8//
9// ========================================================================================================
10
11#ifndef SLMADSP_PROPAGATECONST_H
12#define SLMADSP_PROPAGATECONST_H
14#include <algorithm>
15#include <cstddef>
16#include <memory>
17#include <type_traits>
18
19namespace marvin::library {
26 template <typename T>
27 requires SmartPointerType<T> || std::is_pointer_v<T>
29 using element_type = typename std::pointer_traits<T>::element_type;
30 template <class U>
31 struct is_specialisation : std::false_type {};
32 template <class U>
33 struct is_specialisation<PropagateConst<U>> : std::true_type {};
34
35 static constexpr bool isConvertibleOrPointer = requires(T a) {
36 std::is_pointer_v<T> || std::is_convertible_v<T, element_type*>;
37 };
38
39 public:
43 constexpr PropagateConst() = default;
48 constexpr PropagateConst(PropagateConst&& p) = default;
49
54 template <class U>
55 requires std::is_constructible<T, U>::value && std::is_convertible<U, T>::value
56 constexpr PropagateConst(PropagateConst<U>&& pu) : m_underlying(std::move(pu)) {
57 }
58
63 template <class U>
64 requires std::is_constructible<T, U>::value && (!std::is_convertible<U, T>::value)
65 explicit constexpr PropagateConst(PropagateConst<U>&& pu) : m_underlying(std::move(pu)) {
66 }
67
72 template <class U>
73 requires std::is_constructible<T, U>::value && (!is_specialisation<std::decay_t<U>>::value)
74 constexpr PropagateConst(U&& u) : m_underlying(std::forward<U>(u)) {
75 }
76
81 template <class U>
82 requires std::is_constructible<T, U>::value && (!is_specialisation<std::decay_t<U>>::value) && (!std::is_convertible<U, T>::value)
83 explicit constexpr PropagateConst(U&& u) : m_underlying(std::forward<U>(u)) {
84 }
85
89 constexpr PropagateConst& operator=(PropagateConst&&) = default;
90
91
97 template <class U>
98 requires std::is_convertible<U, T>::value
100 m_underlying = std::move(pu);
101 return *this;
102 }
103
109 template <class U>
110 requires std::is_convertible<U, T>::value && (!is_specialisation<std::decay_t<U>>::value)
111 constexpr PropagateConst& operator=(U&& u) {
112 m_underlying = std::forward<U>(u);
113 return *this;
114 }
115
119 PropagateConst& operator=(const PropagateConst& other) = delete;
120
125 constexpr void swap(PropagateConst& pt) noexcept {
126 std::swap(m_underlying, pt.m_underlying);
127 }
128
133 constexpr element_type* get() {
134 if constexpr (isSmartPointer) {
135 return m_underlying.get();
136 } else {
137 return m_underlying;
138 }
139 }
140
141
146 constexpr const element_type* get() const {
147 if constexpr (isSmartPointer) {
148 return m_underlying.get();
149 } else {
150 return m_underlying;
151 }
152 }
153
154
159 constexpr explicit operator bool() const {
160 return m_underlying != nullptr;
161 }
162
163
168 constexpr element_type& operator*() {
169 return *get();
170 }
171
176 constexpr const element_type& operator*() const {
177 return *get();
178 }
179
184 constexpr element_type* operator->() {
185 return get();
186 }
187
192 constexpr const element_type* operator->() const {
193 return get();
194 }
195
200 constexpr operator element_type*()
201 requires isConvertibleOrPointer
202 {
203 return get();
204 }
205
210 constexpr operator const element_type*()
211 requires isConvertibleOrPointer
212 {
213 return get();
214 }
215
216
217 private:
218 static constexpr bool isSmartPointer = requires(T a) {
219 a.get(); // Require that .get is a valid thing..
220 };
221
222
223 template <class U>
224 friend constexpr bool operator==(const PropagateConst<U>&, std::nullptr_t);
225 template <class U>
226 friend constexpr bool operator==(std::nullptr_t, const PropagateConst<U>&);
227 template <class U>
228 friend constexpr bool operator!=(const PropagateConst<U>&, std::nullptr_t);
229 template <class U>
230 friend constexpr bool operator!=(std::nullptr_t, const PropagateConst<U>&);
231 template <class U>
232 friend constexpr bool operator==(const PropagateConst<T>&, const PropagateConst<U>&);
233 template <class U>
234 friend constexpr bool operator!=(const PropagateConst<T>&, const PropagateConst<U>&);
235 template <class U>
236 friend constexpr bool operator<(const PropagateConst<T>&, const PropagateConst<U>&);
237 template <class U>
238 friend constexpr bool operator>(const PropagateConst<T>&, const PropagateConst<U>&);
239 template <class U>
240 friend constexpr bool operator<=(const PropagateConst<T>&, const PropagateConst<U>&);
241 template <class U>
242 friend constexpr bool operator>=(const PropagateConst<T>&, const PropagateConst<U>&);
243 template <class U>
244 friend constexpr bool operator==(const PropagateConst<T>&, const U&);
245 template <class U>
246 friend constexpr bool operator!=(const PropagateConst<T>&, const U&);
247 template <class U>
248 friend constexpr bool operator==(const T&, const PropagateConst<U>&);
249 template <class U>
250 friend constexpr bool operator!=(const T&, const PropagateConst<U>&);
251 template <class U>
252 friend constexpr bool operator<(const PropagateConst<T>&, const U&);
253 template <class U>
254 friend constexpr bool operator>(const PropagateConst<T>&, const U&);
255 template <class U>
256 friend constexpr bool operator<=(const PropagateConst<T>&, const U&);
257 template <class U>
258 friend constexpr bool operator>=(const PropagateConst<T>&, const U&);
259 template <class U>
260 friend constexpr bool operator<(const T&, const PropagateConst<U>&);
261 template <class U>
262 friend constexpr bool operator>(const T&, const PropagateConst<U>&);
263 template <class U>
264 friend constexpr bool operator<=(const T&, const PropagateConst<U>&);
265 template <class U>
266 friend constexpr bool operator>=(const T&, const PropagateConst<U>&);
267 T m_underlying;
268 };
269
270 template <class T>
271 constexpr bool operator==(const PropagateConst<T>& pt, std::nullptr_t) {
272 return pt.m_underlying == nullptr;
273 }
274
275 template <class T>
276 constexpr bool operator==(std::nullptr_t, const PropagateConst<T>& pt) {
277 return nullptr == pt.m_underlying;
278 }
279 template <class T>
280 constexpr bool operator!=(const PropagateConst<T>& pt, std::nullptr_t) {
281 return pt.m_underlying != nullptr;
282 }
283
284 template <class T>
285 constexpr bool operator!=(std::nullptr_t, const PropagateConst<T>& pt) {
286 return nullptr != pt.m_underlying;
287 }
288
289 template <class T, class U>
290 constexpr bool operator==(const PropagateConst<T>& pt, const PropagateConst<U>& pu) {
291 return pt.m_underlying == pu.m_underlying;
292 }
293
294 template <class T, class U>
295 constexpr bool operator!=(const PropagateConst<T>& pt, const PropagateConst<U>& pu) {
296 return pt.m_underlying != pu.m_underlying;
297 }
298
299 template <class T, class U>
300 constexpr bool operator<(const PropagateConst<T>& pt, const PropagateConst<U>& pu) {
301 return pt.m_underlying < pu.m_underlying;
302 }
303
304 template <class T, class U>
305 constexpr bool operator>(const PropagateConst<T>& pt, const PropagateConst<U>& pu) {
306 return pt.m_underlying > pu.m_underlying;
307 }
308
309 template <class T, class U>
310 constexpr bool operator<=(const PropagateConst<T>& pt, const PropagateConst<U>& pu) {
311 return pt.m_underlying <= pu.m_underlying;
312 }
313
314 template <class T, class U>
315 constexpr bool operator>=(const PropagateConst<T>& pt, const PropagateConst<U>& pu) {
316 return pt.m_underlying >= pu.m_underlying;
317 }
318
319 template <class T, class U>
320 constexpr bool operator==(const PropagateConst<T>& pt, const U& u) {
321 return pt.m_underlying == u;
322 }
323
324 template <class T, class U>
325 constexpr bool operator!=(const PropagateConst<T>& pt, const U& u) {
326 return pt.m_underlying != u;
327 }
328
329 template <class T, class U>
330 constexpr bool operator==(const T& t, const PropagateConst<U>& pu) {
331 return t == pu.m_underlying;
332 }
333
334 template <class T, class U>
335 constexpr bool operator!=(const T& t, const PropagateConst<U>& pu) {
336 return t != pu.m_underlying;
337 }
338
339 template <class T, class U>
340 constexpr bool operator<(const PropagateConst<T>& pt, const U& u) {
341 return pt.m_underlying < u;
342 }
343
344 template <class T, class U>
345 constexpr bool operator>(const PropagateConst<T>& pt, const U& u) {
346 return pt.m_underlying > u;
347 }
348
349 template <class T, class U>
350 constexpr bool operator<=(const PropagateConst<T>& pt, const U& u) {
351 return pt.m_underlying <= u;
352 }
353
354 template <class T, class U>
355 constexpr bool operator>=(const PropagateConst<T>& pt, const U& u) {
356 return pt.m_underlying >= u;
357 }
358
359 template <class T, class U>
360 constexpr bool operator<(const T& t, const PropagateConst<U>& pu) {
361 return t < pu.m_underlying;
362 }
363
364 template <class T, class U>
365 constexpr bool operator>(const T& t, const PropagateConst<U>& pu) {
366 return t > pu.m_underlying;
367 }
368
369 template <class T, class U>
370 constexpr bool operator<=(const T& t, const PropagateConst<U>& pu) {
371 return t <= pu.m_underlying;
372 }
373
374 template <class T, class U>
375 constexpr bool operator>=(const T& t, const PropagateConst<U>& pu) {
376 return t >= pu.m_underlying;
377 }
378
379} // namespace marvin::library
380#endif
A compiler-support agnostic implementation of std::propagate_const
Definition marvin_PropagateConst.h:28
constexpr PropagateConst(PropagateConst< U > &&pu)
Definition marvin_PropagateConst.h:56
constexpr const element_type * operator->() const
Definition marvin_PropagateConst.h:192
constexpr element_type & operator*()
Definition marvin_PropagateConst.h:168
friend constexpr bool operator==(std::nullptr_t, const PropagateConst< U > &)
friend constexpr bool operator!=(std::nullptr_t, const PropagateConst< U > &)
constexpr const element_type * get() const
Definition marvin_PropagateConst.h:146
constexpr PropagateConst(U &&u)
Definition marvin_PropagateConst.h:74
constexpr PropagateConst(U &&u)
Definition marvin_PropagateConst.h:83
friend constexpr bool operator>=(const PropagateConst< T > &, const PropagateConst< U > &)
Definition marvin_PropagateConst.h:315
constexpr PropagateConst & operator=(PropagateConst &&)=default
friend constexpr bool operator<=(const PropagateConst< T > &, const PropagateConst< U > &)
Definition marvin_PropagateConst.h:310
constexpr PropagateConst & operator=(PropagateConst< U > &&pu)
Definition marvin_PropagateConst.h:99
constexpr element_type * operator->()
Definition marvin_PropagateConst.h:184
constexpr const element_type & operator*() const
Definition marvin_PropagateConst.h:176
friend constexpr bool operator>(const PropagateConst< T > &, const PropagateConst< U > &)
Definition marvin_PropagateConst.h:305
constexpr element_type * get()
Definition marvin_PropagateConst.h:133
friend constexpr bool operator!=(const PropagateConst< U > &, std::nullptr_t)
friend constexpr bool operator<(const PropagateConst< T > &, const PropagateConst< U > &)
Definition marvin_PropagateConst.h:300
PropagateConst & operator=(const PropagateConst &other)=delete
constexpr PropagateConst(PropagateConst< U > &&pu)
Definition marvin_PropagateConst.h:65
constexpr PropagateConst()=default
constexpr void swap(PropagateConst &pt) noexcept
Definition marvin_PropagateConst.h:125
constexpr PropagateConst(PropagateConst &&p)=default
friend constexpr bool operator==(const PropagateConst< U > &, std::nullptr_t)
Constrains T to a class that implements get(), reset() operator*() and operator->().
Definition marvin_Concepts.h:78
Standard library-esque utilities.
Definition marvin_PropagateConst.h:19
constexpr bool operator>(const PropagateConst< T > &pt, const PropagateConst< U > &pu)
Definition marvin_PropagateConst.h:305
constexpr bool operator!=(const PropagateConst< T > &pt, std::nullptr_t)
Definition marvin_PropagateConst.h:280
constexpr bool operator>=(const PropagateConst< T > &pt, const PropagateConst< U > &pu)
Definition marvin_PropagateConst.h:315
constexpr bool operator<(const PropagateConst< T > &pt, const PropagateConst< U > &pu)
Definition marvin_PropagateConst.h:300
constexpr bool operator==(const PropagateConst< T > &pt, std::nullptr_t)
Definition marvin_PropagateConst.h:271
constexpr bool operator<=(const PropagateConst< T > &pt, const PropagateConst< U > &pu)
Definition marvin_PropagateConst.h:310