Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Stroika::Foundation::Execution::LazyInitialized< T > Class Template Reference

value-object, where the value construction is delayed until first needed (can be handy to avoid c++ include/initializer deadly embrace) More...

#include <LazyInitialized.h>

Public Member Functions

 LazyInitialized ()=delete
 
nonvirtual constexpr operator const T () const
 
nonvirtual const T operator() () const
 
nonvirtual T * operator-> ()
 

Detailed Description

template<typename T>
class Stroika::Foundation::Execution::LazyInitialized< T >

value-object, where the value construction is delayed until first needed (can be handy to avoid c++ include/initializer deadly embrace)

Also can be used to 'lazy initialize' facilities that might be costly to setup, but might never be used.

Can be used to initialize a static constant object - declared at file scope - dependent on another file-scope data object, without incurring the pain of static initialization problems (before main). Often this is not needed, if you just make the dependent objects constexpr. But sometimes you cannot do that.

LazyInitialized<T> acts mostly like a T (as much as I could figure out how to).

This object (at least the magic init part) - is fully internally synchronized (though other operations of T itself are in general not).

This object CAN be constructed before main, and accessed before main (after constructed) - but its up to caller to assure the 'oneTimeGetter' is safe to call when called.

Aliases
for ConstantProperty, 'virtual constant', VirtualConstant
Note
If you have an object 'obj' which MAYBE a T, or LazyInitialized<T>, you can convert it to type T with static_cast<T> (obj).
Example Usage
// say not legal to call EVP_md5 til you've initialized openssl, and maybe you never will - but still want to declare but
// not use these constants - or at least declare the constants in a file/module (file scope so constructed before main) and
// initialize openssl from after main starts?
const LazyInitialized<DigestAlgorithm> DigestAlgorithms::kMD5{[] () { return ::EVP_md5 (); }};
value-object, where the value construction is delayed until first needed (can be handy to avoid c++ i...
Example Usage
if (const char* env_p = std::getenv ("PATH")) {
return pathVar.Tokenize ({':'}).Map<Sequence<filesystem::path>> ([] (auto i) { return i.template As<filesystem::path> (); });
}
return {};
}};
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
static String FromNarrowSDKString(const char *from)
Definition String.inl:470
nonvirtual Containers::Sequence< String > Tokenize() const
Definition String.cpp:1234
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Definition Sequence.h:187
const LazyInitialized< Containers::Sequence< filesystem::path > > kPath
Definition Module.cpp:144
Example ALTERNATIVE (use lambda as with LazyInitialize but directly invoke) - but this invoked before main()
if (const char* env_p = std::getenv ("PATH")) {
return pathVar.Tokenize ({':'}).Map<Sequence<filesystem::path>> ([] (auto i) { return i.template As<filesystem::path> (); });
}
return {};
} ()};
Example Usage
inline String kXGetter_ () { return "X"; }
const LazyInitialized<String> kX {kXGetter_};
...
const String a = kX;
Note
it would be HIGHLY DESIRABLE if C++ allowed operator'.' overloading, as accessing one of these values without assigning to a temporary first - means that you cannot directly call its methods. That's a bit awkward.

So if you have a type T, with method m(), and variable of type T t. Your starter code might be: T t; t.m (); When you replace 'T t' with ConstantProperty<T> t; you must call t().m(); OR you must call t->m();

Note
C++ also only allows one level of automatic operator conversions, so things like comparing optional<T> {} == LazyInitialized<T,...> {} won't work. To workaround, simply apply () after the LazyInitialized<> instance.

Definition at line 99 of file LazyInitialized.h.

Constructor & Destructor Documentation

◆ LazyInitialized()

template<typename T >
Stroika::Foundation::Execution::LazyInitialized< T >::LazyInitialized ( )
delete

oneTimeGetter is a function (can be a lambda()) which computes the given value. It is called just once, and LAZILY, the first time the given VirtualConstant value is required.

LazyInitialized (ONE TIME GETTER) - is the normal way to use LazyInitialized
LazyInitialized (T) - somewhat pointless, but you can do it....
copy-constructible

Member Function Documentation

◆ operator const T()

template<typename T >
constexpr Stroika::Foundation::Execution::LazyInitialized< T >::operator const T ( ) const
constexpr

A LazyInitialized can be automatically assigned to its underlying base type. Due to how conversion operators work, this won't always be helpful (like with overloading or multiple levels of conversions). But when it works (80% of the time) - its helpful.

Definition at line 57 of file LazyInitialized.inl.

◆ operator()()

template<typename T >
const T Stroika::Foundation::Execution::LazyInitialized< T >::operator() ( ) const

Just use the function syntax, and you get back the initialized value.

Example Usage
namespace PredefinedInternetMediaType { const inline Execution::LazyInitialized<InternetMediaType> kPNG...
bool checkIsImage1 = PredefinedInternetMediaType::kPNG().IsA (InternetMediaTypes::Wildcards::kImage);

Definition at line 62 of file LazyInitialized.inl.

◆ operator->()

template<typename T >
T * Stroika::Foundation::Execution::LazyInitialized< T >::operator-> ( )

Just use the operator-> syntax, and you get back the wrapper objects value (initializing if needed).

Example Usage
namespace PredefinedInternetMediaType { const inline Execution::LazyInitialized<InternetMediaType> kPNG = ...
bool checkIsImage2 = PredefinedInternetMediaType::kPNG->IsA (InternetMediaTypes::Wildcards::kImage);

Definition at line 67 of file LazyInitialized.inl.


The documentation for this class was generated from the following files: