100struct non_null_lateinit {
102 static_assert(!std::is_reference_v<T>,
"====================> aui::non_null: reference type is not allowed");
103 void checkForNull()
const {
AUI_ASSERTX(value !=
nullptr,
"this value couldn't be nullptr"); }
107 non_null_lateinit() {}
109 template <convertible_to<T> F>
110 non_null_lateinit(F&& value) : value(std::forward<F>(value)) {
112 !std::is_same_v<std::decay_t<F>, std::nullptr_t>,
"====================> aui::non_null: this value couldn't be nullptr");
116 operator const T&()
const noexcept {
121 operator T&()
noexcept {
126 auto operator->()
const {
178 !std::is_reference<T>::value,
179 "====================> AUI: attempt to use aui::no_escape with reference type. Please use undecorated type "
180 "(without reference)");
182 !std::is_pointer_v<T>,
183 "====================> AUI: attempt to use aui::no_escape with pointer type. Please use undecorated type "
184 "(without pointer)");
190 no_escape(T& value) : value(&value) {
AUI_ASSERTX(no_escape::value !=
nullptr,
"the argument could not be null"); }
193 no_escape(T&& value) : value(&value) {
AUI_ASSERTX(no_escape::value !=
nullptr,
"the argument could not be null"); }
194 no_escape(T* value) : value(value) {
AUI_ASSERTX(no_escape::value !=
nullptr,
"the argument could not be null"); }
196 no_escape(
const _<T>& value) : value(&*value) {
197 AUI_ASSERTX(no_escape::value !=
nullptr,
"the argument could not be null");
199 no_escape(
const _unique<T>& value) : value(&*value) {
200 AUI_ASSERTX(no_escape::value !=
nullptr,
"the argument could not be null");
204 typename DerivedFromT,
205 std::enable_if_t<std::is_base_of_v<T, DerivedFromT> && !std::is_same_v<DerivedFromT, T>,
bool> =
true>
207 AUI_ASSERTX(no_escape::value !=
nullptr,
"the argument could not be null");
211 typename DerivedFromT,
212 std::enable_if_t<std::is_base_of_v<T, DerivedFromT> && !std::is_same_v<DerivedFromT, T>,
bool> =
true>
213 no_escape(
const _unique<DerivedFromT>& value) : value(&*value) {
214 AUI_ASSERTX(no_escape::value !=
nullptr,
"the argument could not be null");
218 T* ptr()
const noexcept {
222 T* operator->()
const noexcept {
return value; }
224 T& operator*()
const noexcept {
return *value; }
234 struct EvaluationLoopTrap {};
235 mutable std::variant<std::nullopt_t, T, EvaluationLoopTrap> value = std::nullopt;
236 std::function<T()> initializer;
239 template <
typename Factory, std::enable_if_t<std::is_invocable_r_v<T, Factory>,
bool> = true>
240 lazy(
Factory&& initializer) noexcept : initializer(std::forward<Factory>(initializer)) {}
242 lazy(
const lazy<T>& other) noexcept : value(other.value), initializer(other.initializer) {}
243 lazy(lazy<T>&& other) noexcept : value(std::move(other.value)), initializer(std::move(other.initializer)) {}
246 if (std::holds_alternative<T>(value)) {
247 return std::get<T>(value);
249 if (std::holds_alternative<std::nullopt_t>(value)) {
250 setEvaluationLoopTrap();
252 value = initializer();
254 value = std::nullopt;
257 return std::get<T>(value);
259 detail::evaluationLoop();
263 void setEvaluationLoopTrap() { value = EvaluationLoopTrap {}; }
265 const T& get()
const {
return const_cast<lazy<T>*
>(
this)->get(); }
267 operator T&() {
return get(); }
268 operator const T&()
const {
return get(); }
270 T& operator*() {
return get(); }
271 const T& operator*()
const {
return get(); }
273 T* operator->() {
return &get(); }
274 T
const* operator->()
const {
return &get(); }
276 lazy<T>& operator=(T&& t) {
277 value = std::move(t);
280 lazy<T>& operator=(
const T& t) {
285 void reset() { value = std::nullopt; }
287 explicit operator bool()
const noexcept
294 bool hasValue()
const noexcept {
295 return std::holds_alternative<T>(value);
306 mutable bool value =
false;
307 std::function<void()> initializer;
310 template <
typename Factory, std::enable_if_t<std::is_invocable_r_v<
void, Factory>,
bool> = true>
311 lazy(
Factory&& initializer) noexcept : initializer(std::forward<Factory>(initializer)) {}
313 lazy(
const lazy<void>& other) noexcept : value(other.value), initializer(other.initializer) {}
314 lazy(lazy<void>&& other) noexcept : value(other.value), initializer(std::move(other.initializer)) {}
322 void get()
const {
return const_cast<lazy<void>*
>(
this)->get(); }
324 void operator*() {
return get(); }
325 const void operator*()
const {
return get(); }
327 void reset() { value =
false; }
330 bool hasValue()
const noexcept {
345 std::function<T()> initializer;
348 template <
typename Factory, std::enable_if_t<std::is_invocable_r_v<T, Factory>,
bool> = true>
349 atomic_lazy(
Factory&& initializer) : initializer(std::forward<Factory>(initializer)) {}
351 atomic_lazy(
const atomic_lazy<T>& other) {
352 std::unique_lock lock(other.sync);
354 initializer = other.initializer;
356 atomic_lazy(atomic_lazy<T>&& other)
noexcept {
357 std::unique_lock lock(other.sync);
358 value = std::move(other.value);
359 initializer = std::move(other.initializer);
364 std::unique_lock lock(sync);
366 value = initializer();
371 const T& get()
const {
return const_cast<atomic_lazy<T>*
>(
this)->get(); }
373 operator T&() {
return get(); }
374 operator const T&()
const {
return get(); }
376 T& operator*() {
return get(); }
377 const T& operator*()
const {
return get(); }
379 T* operator->() {
return &get(); }
380 T
const* operator->()
const {
return &get(); }
382 atomic_lazy<T>& operator=(T&& t) {
383 std::unique_lock lock(sync);
384 value = std::move(t);
388 atomic_lazy<T>& operator=(
const T& t) {
389 std::unique_lock lock(sync);
395 std::unique_lock lock(sync);
400 bool hasValue()
const noexcept {
401 std::unique_lock lock(sync);
402 return value.hasValue();
#define AUI_ASSERTX(condition, what)
Asserts that the passed condition evaluates to true. Adds extra message string.
Definition Assert.h:74