11#ifndef SLMADSP_PROPAGATECONST_H
12#define SLMADSP_PROPAGATECONST_H
29 using element_type =
typename std::pointer_traits<T>::element_type;
31 struct is_specialisation : std::false_type {};
35 static constexpr bool isConvertibleOrPointer =
requires(T a) {
36 std::is_pointer_v<T> || std::is_convertible_v<T, element_type*>;
55 requires std::is_constructible<T, U>::value && std::is_convertible<U, T>::value
64 requires std::is_constructible<T, U>::value && (!std::is_convertible<U, T>::value)
73 requires std::is_constructible<T, U>::value && (!is_specialisation<std::decay_t<U>>::value)
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)) {
98 requires std::is_convertible<U, T>::value
100 m_underlying = std::move(pu);
110 requires std::is_convertible<U, T>::value && (!is_specialisation<std::decay_t<U>>::value)
112 m_underlying = std::forward<U>(u);
126 std::swap(m_underlying, pt.m_underlying);
133 constexpr element_type*
get() {
134 if constexpr (isSmartPointer) {
135 return m_underlying.get();
146 constexpr const element_type*
get()
const {
147 if constexpr (isSmartPointer) {
148 return m_underlying.get();
159 constexpr explicit operator bool()
const {
160 return m_underlying !=
nullptr;
200 constexpr operator element_type*()
201 requires isConvertibleOrPointer
210 constexpr operator const element_type*()
211 requires isConvertibleOrPointer
218 static constexpr bool isSmartPointer =
requires(T a) {
272 return pt.m_underlying ==
nullptr;
277 return nullptr == pt.m_underlying;
281 return pt.m_underlying !=
nullptr;
286 return nullptr != pt.m_underlying;
289 template <
class T,
class U>
291 return pt.m_underlying == pu.m_underlying;
294 template <
class T,
class U>
296 return pt.m_underlying != pu.m_underlying;
299 template <
class T,
class U>
301 return pt.m_underlying < pu.m_underlying;
304 template <
class T,
class U>
306 return pt.m_underlying > pu.m_underlying;
309 template <
class T,
class U>
311 return pt.m_underlying <= pu.m_underlying;
314 template <
class T,
class U>
316 return pt.m_underlying >= pu.m_underlying;
319 template <
class T,
class U>
321 return pt.m_underlying == u;
324 template <
class T,
class U>
326 return pt.m_underlying != u;
329 template <
class T,
class U>
331 return t == pu.m_underlying;
334 template <
class T,
class U>
336 return t != pu.m_underlying;
339 template <
class T,
class U>
341 return pt.m_underlying < u;
344 template <
class T,
class U>
346 return pt.m_underlying > u;
349 template <
class T,
class U>
351 return pt.m_underlying <= u;
354 template <
class T,
class U>
356 return pt.m_underlying >= u;
359 template <
class T,
class U>
361 return t < pu.m_underlying;
364 template <
class T,
class U>
366 return t > pu.m_underlying;
369 template <
class T,
class U>
371 return t <= pu.m_underlying;
374 template <
class T,
class U>
376 return t >= pu.m_underlying;
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