Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
TemplateUtilities.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include <mutex>
5
7
8 /*
9 ********************************************************************************
10 ****************************** Common::Immortalize *****************************
11 ********************************************************************************
12 */
13 template <typename T, typename... ARGS>
14 inline T& Immortalize (ARGS... args)
15 {
16 struct StorageImpl_ {
17 union {
18 T _Storage;
19 };
20 constexpr StorageImpl_ () noexcept
21 : _Storage{}
22 {
23 }
24 StorageImpl_ (const StorageImpl_&) = delete;
25 StorageImpl_& operator= (const StorageImpl_&) = delete;
26#if __has_cpp_attribute(msvc::noop_dtor)
27 [[msvc::noop_dtor]]
28#endif
29 ~StorageImpl_ ()
30 {
31 }
32 };
33 static once_flag sFlag_{};
34 static StorageImpl_ sStorage_{};
35 call_once (sFlag_, [&] () { ::new (&sStorage_) T{args...}; });
36 return reinterpret_cast<T&> (sStorage_);
37 }
38
39 namespace Private_ {
40 template <typename VariantType, typename T, std::size_t index = 0>
41 constexpr std::size_t variant_index ()
42 {
43 // From https://stackoverflow.com/questions/52303316/get-index-by-type-in-stdvariant/66386518#66386518
44 static_assert (std::variant_size_v<VariantType> > index, "Type not found in variant");
45 if constexpr (index == std::variant_size_v<VariantType>) {
46 return index;
47 }
48 else if constexpr (std::same_as<std::variant_alternative_t<index, VariantType>, T>) {
49 return index;
50 }
51 else {
52 return variant_index<VariantType, T, index + 1> ();
53 }
54 }
55 }
56 template <typename VARIANT_VALUE, typename T>
57 constexpr size_t VariantIndex = Private_::variant_index<VARIANT_VALUE, T> ();
58
59}