15#ifndef TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS
16#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1
19#ifndef TBB_SUPPRESS_DEPRECATED_MESSAGES
20 #define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
22 #undef TBB_SUPPRESS_DEPRECATED_MESSAGES
23 #define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
37#include <memory_resource>
39#include <unordered_set>
40#include <unordered_map>
56#if defined(CPG_INCLUDE_SYCL)
57 #include <cl/sycl.hpp>
60#if defined(__cpp_lib_source_location)
61#include <source_location>
66#if defined(_DEBUG) || defined(DEBUG) || defined(CPG_DEBUG) || !defined(CPG_SAFE_OPERATION)
67#define CPG_SAFE_OPERATION 2LL
70#if defined(CPG_SAFE_OPERATION) && ((CPG_SAFE_OPERATION<0) || (CPG_SAFE_OPERATION>2))
71#error Macro CPG_SAFE_OPERATION should be in the range [0, 2] inclusive
85#if defined(_DEBUG) || defined(DEBUG) || defined(CPG_DEBUG)
86 #define CpgSafe(arg) cpg::types::sbo<CPG_SAFE_OPERATION>(arg)
88 #define CpgSafe(arg) arg
105 template<
class T, std::
size_t N >
106 struct tuple_size< T[N] > :
107 std::integral_constant<std::size_t, N> { };
109 template<
class T, std::
size_t N >
110 struct tuple_size< const T[N] > :
111 std::integral_constant<std::size_t, N> { };
113 template<
class T, std::
size_t N >
114 struct tuple_size< T(&)[N] > :
115 std::integral_constant<std::size_t, N> { };
117 template<
class T, std::
size_t N >
118 struct tuple_size< const T(&)[N] > :
119 std::integral_constant<std::size_t, N> { };
121 template<
class T, std::
size_t N >
122 struct tuple_size< T(&&)[N] > :
123 std::integral_constant<std::size_t, N> { };
125 template<
class T, std::
size_t N >
126 struct tuple_size< const T(&&)[N] > :
127 std::integral_constant<std::size_t, N> { };
131 template<
class ...Ts>
132 struct tuple_size<
std::variant<Ts...>> :
133 std::integral_constant<std::size_t, sizeof...(Ts)> { };
135 template<
class ...Ts>
136 struct tuple_size<const
std::variant<Ts...>> :
137 std::integral_constant<std::size_t, sizeof...(Ts)> { };
139 template<
class ...Ts>
140 struct tuple_size<
std::variant<Ts...>&> :
141 std::integral_constant<std::size_t, sizeof...(Ts)> { };
143 template<
class ...Ts>
144 struct tuple_size<const
std::variant<Ts...>&> :
145 std::integral_constant<std::size_t, sizeof...(Ts)> { };
147 template<
class ...Ts>
148 struct tuple_size<
std::variant<Ts...>&&> :
149 std::integral_constant<std::size_t, sizeof...(Ts)> { };
151 template<
class ...Ts>
152 struct tuple_size<const
std::variant<Ts...>&&> :
153 std::integral_constant<std::size_t, sizeof...(Ts)> { };
159 inline constexpr std::size_t
operator""_size_t(
unsigned long long value)
161 return static_cast<std::size_t
>(value);
164 inline constexpr unsigned int operator""_unsigned(
unsigned long long value)
166 return static_cast<unsigned int>(value);
169 inline constexpr short operator""_short(
unsigned long long value)
171 return static_cast<short>(value);
174 inline constexpr unsigned short operator""_ushort(
unsigned long long value)
176 return static_cast<unsigned short>(value);
179 inline constexpr char operator""_char(
unsigned long long value)
181 return static_cast<char>(value);
184 inline constexpr char operator""_schar(
unsigned long long value)
186 return static_cast<signed char>(value);
189 inline constexpr unsigned char operator""_uchar(
unsigned long long value)
191 return static_cast<unsigned char>(value);
194 inline constexpr long double operator""_ldouble(
long double value)
216 template<
typename Type>
217 inline constexpr auto type_max_v = std::numeric_limits<Type>::max();
227 template<
typename Type>
230 if constexpr(std::is_same_v<Type, float>)
231 return std::nanf(
"not a number");
232 else if constexpr(std::is_same_v<Type, double>)
233 return std::nan(
"not a number");
234 else if constexpr(std::is_same_v<Type, long double>)
235 return std::nanl(
"not a number");
240 template<std::size_t KeyIndex,
typename Type,
auto Index,
auto... Indices>
241 constexpr auto get_nth_value(std::integer_sequence<Type, Index, Indices...>)
noexcept
243 if constexpr(KeyIndex == 0)
245 else if constexpr( KeyIndex != 0 &&
sizeof...(Indices) != 0)
247 return get_nth_value<KeyIndex-1>(std::integer_sequence<Type, Indices...>{});
261 template<
typename =
void>
264 auto count = str.size();
265 std::wstring rlt(
count, L
'\0');
267 for(
int i = 0; i <
count; ++i)
268 (
char&)rlt[i] = str[i];
273 template<
typename =
void>
276 auto count = str.size();
277 std::string rlt(
count,
'\0');
279 for(
int i = 0; i <
count; ++i)
280 rlt[i] = (
char)str[i];
287 template<
typename CharType> std::basic_ostream<CharType>&
290 if constexpr(std::same_as<CharType, char>)
298 template<
typename OperationType,
typename... DelimiterTypes>
class fold_visitor;
300 template<
typename OperationType,
typename DelimiterType>
315 m_arg_count{(long long)arg_count}, m_left_count{0}, m_right_count{(long long)arg_count},
316 m_operation{
std::move(opr) }, m_delimiter{
std::move(del) }{ }
320 this->m_left_count = 0;
321 this->m_right_count = this->m_arg_count;
326 this->m_operation(std::forward<
decltype(arg)>(arg));
328 ++this->m_left_count;
330 if(m_left_count < m_arg_count)
332 if constexpr(
requires { this->m_delimiter(std::forward<
decltype(arg)>(arg)); } )
334 this->m_delimiter(std::forward<
decltype(arg)>(arg));
336 else if constexpr(
requires { this->m_delimiter(); })
345 if(m_right_count != m_arg_count)
347 if constexpr(
requires { this->m_delimiter(std::forward<
decltype(arg)>(arg)); } )
349 this->m_delimiter(std::forward<
decltype(arg)>(arg));
351 else if constexpr(
requires { this->m_delimiter(); })
357 --this->m_right_count;
359 this->m_operation(arg);
364 fv.left_operation(std::forward<
decltype(arg)>(arg));
371 fv.right_operation(std::forward<
decltype(arg)>(arg));
377 template<
typename OperationType,
typename DelimiterOpen,
typename DelimiterType,
typename DelimiterClose>
378 class fold_visitor<OperationType, DelimiterOpen, DelimiterType, DelimiterClose>
394 DelimiterOpen d_open, DelimiterType del, DelimiterClose d_close):
395 m_arg_count{(long long)arg_count}, m_left_count{0}, m_right_count{(long long)arg_count},
396 m_operation{
std::move(opr) }, m_open_delimiter{
std::move(d_open) },
397 m_delimiter{
std::move(del) }, m_close_delimiter{
std::move(d_close) } { }
401 this->m_left_count = 0;
402 this->m_right_count = this->m_arg_count;
407 if(this->m_left_count == 0)
409 if constexpr(
requires { this->m_open_delimiter( std::forward<
decltype(arg)>(arg) ); })
411 this->m_open_delimiter(std::forward<
decltype(arg)>(arg));
413 else if constexpr(
requires { this->m_open_delimiter(); })
415 this->m_open_delimiter();
419 this->m_operation(std::forward<
decltype(arg)>(arg));
421 ++this->m_left_count;
423 if(m_left_count < m_arg_count)
425 if constexpr(
requires { this->m_delimiter(std::forward<
decltype(arg)>(arg)); } )
427 this->m_delimiter(std::forward<
decltype(arg)>(arg));
429 else if constexpr(
requires { this->m_delimiter(); })
434 else if(m_left_count == m_arg_count)
436 if constexpr(
requires { this->m_close_delimiter( std::forward<
decltype(arg)>(arg) ); })
438 this->m_close_delimiter(std::forward<
decltype(arg)>(arg));
440 else if constexpr(
requires { this->m_close_delimiter(); })
442 this->m_close_delimiter();
449 if(m_right_count == m_arg_count)
451 if constexpr(
requires { this->m_open_delimiter( std::forward<
decltype(arg)>(arg) ); })
453 this->m_open_delimiter(std::forward<
decltype(arg)>(arg));
455 else if constexpr(
requires { this->m_open_delimiter(); })
457 this->m_open_delimiter();
460 else if(m_right_count != m_arg_count)
462 if constexpr(
requires { this->m_delimiter(std::forward<
decltype(arg)>(arg)); } )
464 this->m_delimiter(std::forward<
decltype(arg)>(arg));
466 else if constexpr(
requires { this->m_delimiter(); })
472 --this->m_right_count;
474 this->m_operation(arg);
476 if(this->m_right_count == 0)
478 if constexpr(
requires { this->m_close_delimiter( std::forward<
decltype(arg)>(arg) ); })
480 this->m_close_delimiter(std::forward<
decltype(arg)>(arg));
482 else if constexpr(
requires { this->m_close_delimiter(); })
484 this->m_close_delimiter();
491 fv.left_operation(std::forward<
decltype(arg)>(arg));
498 fv.right_operation(std::forward<
decltype(arg)>(arg));
504 template<
typename OperationType>
507 OperationType m_operation;
517 this->m_operation(std::forward<
decltype(arg)>(arg));
522 fv.call_operation(std::forward<
decltype(arg)>(arg));
528 fv.call_operation(std::forward<
decltype(arg)>(arg));
533 template<
typename OperationType>
536 template<
typename OperationType,
typename DelimiterType>
537 fold_visitor(
auto, OperationType, DelimiterType)->fold_visitor<OperationType, DelimiterType>;
539 template<
typename OperationType,
typename DelimiterOpen,
typename DelimiterType,
typename DelimiterClose>
541 DelimiterOpen d_open, DelimiterType del, DelimiterClose d_close)
548 auto task = [&index](
auto&& arg)
559 (
visit << ... << args);
564 int index =
sizeof...(args) - 1;
566 auto task = [&index](
auto&& arg)
577 (
visit << ... << args);
582#define Cpg_CharStr(asciistr) cpg::types::cHarsTR{asciistr, L##asciistr}
589 std::string m_message;
591 std::string m_file_name;
592 std::string m_what_msg;
596 m_lineno(lineno), m_message(message), m_file_name(file_name)
598 std::ostringstream os;
600 os <<
"debug_exception - file [" << this->m_file_name <<
"]\n";
601 os <<
"thread id [" << std::this_thread::get_id() <<
"] - ";
602 os <<
"line [" << this->m_lineno<<
"]\n";
603 os <<
"message: " << this->m_message;
605 this->m_what_msg = os.str();
608 virtual const char*
what() const noexcept
override
610 return this->m_what_msg.c_str();
617 template<
typename Type>
622 std::string fname =
typeid(hidden::st_dummy_type_container<Type>).name();
624 const char* to_str =
"struct tpf::types::hidden::st_dummy_type_container<";
626 std::size_t len = strlen(to_str);
628 auto pos = fname.find(to_str);
630 if(pos != fname.npos)
631 fname = fname.substr(pos + len);
638 to_str =
" __ptr64"; len = strlen(to_str);
639 while( (pos = fname.find(to_str)) != fname.npos)
640 fname.erase(pos, len);
642 to_str =
" __ptr32"; len = strlen(to_str);
643 while( (pos = fname.find(to_str)) != fname.npos)
644 fname.erase(pos, len);
646 to_str =
"enum class"; len = strlen(to_str);
647 while( (pos = fname.find(to_str)) != fname.npos)
648 fname.erase(pos, len);
650 to_str =
"enum"; len = strlen(to_str);
651 while( (pos = fname.find(to_str)) != fname.npos)
652 fname.erase(pos, len);
654 to_str =
"class"; len = strlen(to_str);
655 while( (pos = fname.find(to_str)) != fname.npos)
656 fname.erase(pos, len);
658 to_str =
"struct"; len = strlen(to_str);
659 while( (pos = fname.find(to_str)) != fname.npos)
660 fname.erase(pos, len);
662 while(fname.back() ==
' ') fname.pop_back();
667 #elif defined(__FUNCSIG__)
668 std::string fname(__FUNCSIG__);
669 const char* to_str =
"tO_sTring<";
670 size_t len = strlen(to_str);
671 auto pos = fname.find(
"tO_sTring<");
672 fname = fname.substr(pos+len);
673 fname = fname.substr(0, fname.find_last_of(
'>'));
677 to_str =
" __ptr64"; len = strlen(to_str);
678 while( (pos = fname.find(to_str)) != fname.npos)
679 fname.erase(pos, len);
681 to_str =
" __ptr32"; len = strlen(to_str);
682 while( (pos = fname.find(to_str)) != fname.npos)
683 fname.erase(pos, len);
685 to_str =
"enum class"; len = strlen(to_str);
686 while( (pos = fname.find(to_str)) != fname.npos)
687 fname.erase(pos, len);
689 to_str =
"enum"; len = strlen(to_str);
690 while( (pos = fname.find(to_str)) != fname.npos)
691 fname.erase(pos, len);
693 to_str =
"class"; len = strlen(to_str);
694 while( (pos = fname.find(to_str)) != fname.npos)
695 fname.erase(pos, len);
697 to_str =
"struct"; len = strlen(to_str);
698 while( (pos = fname.find(to_str)) != fname.npos)
699 fname.erase(pos, len);
701 while(fname.back() ==
' ') fname.pop_back();
706 std::string fname(__PRETTY_FUNCTION__);
708 #ifdef __clang_major__
709 const char* ftext =
"[Type = ";
710 auto pos = fname.find(ftext) + strlen(ftext);
711 fname = fname.substr(pos);
716 const char* ftext =
"type_tO_sTring<";
717 auto pos = fname.find(ftext) + strlen(ftext);
718 fname = fname.substr(pos);
719 pos = fname.find_last_of(
'>');
720 return fname.substr(0, pos);
722 const char* ftext =
"[with Type = ";
723 auto pos = fname.find(ftext) + strlen(ftext);
724 fname = fname.substr(pos);
725 pos = fname.find_first_of(
';');
726 return fname.substr(0, pos);
740#define Cpg_GetTypeName(type_arg, ...) \
741 cpg::types::type_tO_sTring<type_arg, ##__VA_ARGS__>()
743#define Cpg_GetTypeCategory(instance_arg, ...) \
744 cpg::types::type_tO_sTring<decltype(instance_arg, ##__VA_ARGS__)>()
746#define Cpg_DebugException(debug_message) cpg::debug_exception{debug_message, __LINE__, __FILE__}
748#define Cpg_ThrowDebugException(debug_message) throw cpg::debug_exception{debug_message, __LINE__, __FILE__}
753#if defined(CPG_SAFE_OPERATION) && (CPG_SAFE_OPERATION > 0)
761 template<
auto... args>
766 template<
typename Type>
769 template<
auto... args>
773 template<
typename Type>
776 template<
typename CharType>
780 template<
typename CharType,
auto arg,
auto... args>
785 if constexpr(
sizeof...(args) != 0)
793 template<
typename CharType,
auto... args>
794 std::basic_ostream<CharType>&
operator <<
795 (std::basic_ostream<CharType>& os, nontype_container<args...> )
noexcept
805 template<
typename CharType,
auto... args>
806 std::basic_ostream<CharType>&
operator >>
812 template<std::size_t Index,
auto arg,
auto... args>
815 if constexpr( Index == 0)
817 else if constexpr( Index > 0 &&
sizeof...(args) != 0)
832 template<std::size_t N,
typename FuncType,
typename Type,
typename... Types>
835 if constexpr(
requires{ func( Type{}, Types{} ... ); } )
836 return func( Type{}, Types{} ... );
837 else if constexpr(
sizeof...(Types) + 1 < N )
843 template<std::size_t N,
typename FuncType,
typename Type,
typename... Types>
846 if constexpr(
requires{ func( Type{}, Types{} ... ); } )
847 return sizeof...(Types) + 1 ;
848 else if constexpr(
sizeof...(Types) + 1 < N )
857 template<
typename FuncType,
typename Type>
863 template<
typename FuncType,
typename Type>
866 template<
typename FuncType,
typename Type>
874 std::floating_point<std::remove_cvref_t<T>>;
879 template<
typename Type>
890 template<
typename CharType,
typename Type> std::basic_ostream<CharType>&
891 operator<<(std::basic_ostream<CharType>& os, range<Type>
const& r)
900 template<
typename Type>
903 template<
typename Type>
906 template<
auto Id,
auto... Ids>
907 using index_t = std::index_sequence<(std::size_t)Id, (std::size_t)Ids...>;
912 template<
typename ...Types>
913 using index_for = std::make_index_sequence<
sizeof...(Types)>;
915 template<
typename T, T Value>
920 static constexpr T
Size = Value;
927 concept pointer_c = std::is_pointer_v<std::remove_cvref_t<P>>;
929 template<
typename FuncType,
typename Po
interType>
931 requires (PointerType p, FuncType func) { func(p); };
933 template<po
inter_c Po
interType, po
inter_callable_c<Po
interType> FuncType>
936 auto deleter = [func](
auto ptr)
941 return std::unique_ptr< std::remove_pointer_t<PointerType>,
decltype(deleter)>
942 { object_ptr, deleter };
945 template<
typename CharType>
946 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
947 no_type
const& oh_no)
949 os <<
"no_type or void";
return os;
953 concept no_type_c = std::same_as<std::remove_cvref_t<T>, no_type>;
961 template<
typename ContainerType>
964 typename ContainerType::value_type;
966 container.push_back(
typename ContainerType::value_type{});
974 template<std::
integral T>
977 using type = std::make_signed_t<T>;
980 template<std::
floating_po
int T>
990 template<std::
integral T>
993 using type = std::make_unsigned_t<T>;
996 template<std::
floating_po
int T>
1004 template<
typename T>
1007 template<
typename T>
1010 template<
typename... Types>
1014 template<
typename... Types>
1020 using a_t =
decltype(a);
1021 using b_t =
decltype(b);
1023 if constexpr( std::is_floating_point_v<a_t> || std::is_floating_point_v<b_t> ||
1024 (std::is_unsigned_v<a_t> && std::is_unsigned_v<b_t>) )
1026 return a > b ? (a - b) : (b - a);
1033 return aa > bb ? (aa - bb) : (bb - aa);
1037 template<
typename... Types>
1043 typename std::common_type<Types...>::type;
1046 template<
typename P,
typename T>
1047 concept same_flat_c = std::same_as< std::remove_cvref_t<P>, std::remove_cvref_t<T> >;
1049 template<
typename P,
typename... Types>
1052 template<std::
floating_po
int T, std::
integral S>
1055 std::optional<T> result;
1057 if(std::numeric_limits<T>::min() <= s &&
1058 s <= std::numeric_limits<T>::max())
1060 #if defined(_DEBUG) || defined(DEBUG) || defined(CPG_DEBUG)
1061 if(
static_cast<T
>(s) == s)
1062 result =
static_cast<T
>(s);
1064 result =
static_cast<T
>(s);
1071 template<std::
integral T, std::
floating_po
int S>
1074 std::optional<T> result;
1076 if(std::numeric_limits<T>::min() <= s &&
1077 s <= std::numeric_limits<T>::max())
1079 #if defined(_DEBUG) || defined(DEBUG) || defined(CPG_DEBUG)
1080 if(
static_cast<T
>(s) == s)
1081 result =
static_cast<T
>(s);
1083 result =
static_cast<T
>(s);
1090 template<std::
signed_
integral T, std::
signed_
integral S>
1093 if(std::numeric_limits<T>::min() <= s &&
1094 s <= std::numeric_limits<T>::max())
1095 return std::optional<T>{
static_cast<T
>(s) };
1097 return std::optional<T>{ };
1100 template<std::
signed_
integral T, std::
unsigned_
integral U>
1103 if( u <= std::numeric_limits<T>::max())
1104 return std::optional<T>{
static_cast<T
>(u) };
1106 return std::optional<T>{ };
1109 template<std::
unsigned_
integral T, std::
signed_
integral S>
1112 if(s >= 0 && s <= std::numeric_limits<T>::max())
1113 return std::optional<T>{
static_cast<T
>(s) };
1115 return std::optional<T>{ };
1118 template<std::
unsigned_
integral T, std::
unsigned_
integral U>
1121 if(u <= std::numeric_limits<T>::max())
1122 return std::optional<T>{
static_cast<T
>(u) };
1124 return std::optional<T>{ };
1127 template<std::
floating_po
int T, numerical_c S>
1130 if(std::numeric_limits<T>::min() <= s &&
1131 s <= std::numeric_limits<T>::max())
1132 return std::optional<T>{
static_cast<T
>(s) };
1134 return std::optional<T>{ };
1137 #if defined(__cpp_lib_source_location)
1139 void log_location(
const std::string_view message,
1140 const std::source_location location =
1141 std::source_location::current())
1144 << location.file_name() <<
"("
1145 << location.line() <<
":"
1146 << location.column() <<
") \""
1147 << location.function_name() <<
"\": "
1151 template<
typename EleType,
typename S>
1153 const std::source_location location = std::source_location::current())
1155 if constexpr(numerical_c<EleType> && numerical_c<S>)
1157 auto result = numeric_cast<EleType>(s);
1161 std::ostringstream msg;
1162 msg <<
"truncated from " << s
1163 <<
" to " <<
static_cast<EleType
>(s) <<
std::endl;
1165 log_location(msg.str(), location);
1170 template<
typename EleType,
typename S>
1175 auto result = numeric_cast<EleType>(s);
1179 std::cout<<
"WARNING: truncated from " << s
1180 <<
" to " <<
static_cast<EleType
>(s) <<
std::endl;
1190#if defined(_DEBUG) || defined(DEBUG) || defined(CPG_DEBUG)
1191 #define Tpf_TestTrunction(TargetType, SourceValue) cpg::types::truncation_test<TargetType>(SourceValue)
1193 #define Tpf_TestTrunction(TargetType, SourceValue)
1200 template<numerical_c... ArgTypes>
1205 return std::tuple{ numeric_cast<c_t>(args)... };
1208 template<numerical_c... ArgTypes>
1213 return std::tuple{ numeric_cast<c_t>(args)...};
1216 template<
typename T>
1219 if constexpr(std::floating_point<std::remove_cvref_t<T>>)
1221 if(target != target)
1223 else if(target == target + 1)
1234 template <
class TargetType,
class _Ty>
1235 [[nodiscard]]
constexpr std::enable_if_t<std::is_same_v<std::remove_reference_t<TargetType>,
1236 std::remove_reference_t<_Ty>>, _Ty&&>
1240 return static_cast<_Ty&&
>(_Arg);
1243 template <
class TargetType,
class _Ty>
1244 [[nodiscard]]
constexpr std::enable_if_t< !std::is_same_v<std::remove_reference_t<TargetType>,
1245 std::remove_reference_t<_Ty>> && std::common_with<TargetType, _Ty>, TargetType>
1249 return static_cast<TargetType
>(_Arg);
1252 template <
class TargetType,
class _Ty>
1253 [[nodiscard]]
constexpr std::enable_if_t< std::is_same_v<std::remove_reference_t<TargetType>,
1254 std::remove_reference_t<_Ty>>, _Ty&&>
1258 static_assert(!std::is_lvalue_reference_v<_Ty>,
"bad forward call");
1259 return static_cast<_Ty&&
>(_Arg);
1262 template <
class TargetType,
class _Ty>
1263 [[nodiscard]]
constexpr std::enable_if_t< !std::is_same_v<std::remove_reference_t<TargetType>,
1264 std::remove_reference_t<_Ty>>&& std::common_with<TargetType, _Ty>, TargetType>
1268 return static_cast<TargetType
>(_Arg);
1271 template <
class TargetType,
class _Ty>
1272 [[nodiscard]]
constexpr std::enable_if_t< std::is_same_v<std::remove_reference_t<TargetType>,
1273 std::remove_reference_t<_Ty>>, std::remove_reference_t<_Ty>&&>
1277 return static_cast<std::remove_reference_t<_Ty>&&
>(_Arg);
1280 template <
class TargetType,
class _Ty>
1281 [[nodiscard]]
constexpr std::enable_if_t< !std::is_same_v<std::remove_reference_t<TargetType>,
1282 std::remove_reference_t<_Ty>>, TargetType>
1286 return static_cast<TargetType
>(_Arg);
1289 template<auto N,
typename T,
typename Deleter>
1290 inline auto&
cast_ref(std::unique_ptr<T[], Deleter>& uptr)
noexcept
1292 return reinterpret_cast<T(&)[N]
>(uptr[0]);
1295 template<auto N,
typename T,
typename Deleter>
1296 inline auto&
cast_ref(std::index_sequence<N>, std::unique_ptr<T[], Deleter>& uptr)
noexcept
1298 return reinterpret_cast<T(&)[N]
>(uptr[0]);
1301 template<auto N,
typename T,
typename Deleter>
1302 inline auto&
cast_ref(std::unique_ptr<T[], Deleter>
const& uptr)
noexcept
1304 return reinterpret_cast<const T(&)[N]
>(uptr[0]);
1307 template<auto N,
typename T,
typename Deleter>
1308 inline auto&
cast_ref(std::index_sequence<N>, std::unique_ptr<T[], Deleter>
const& uptr)
noexcept
1310 return reinterpret_cast<const T(&)[N]
>(uptr[0]);
1313 template<auto N1, auto N2,
typename T,
typename Deleter>
1314 inline auto&
cast_ref(std::unique_ptr<T[], Deleter>& uptr)
noexcept
1316 return reinterpret_cast<T(&)[N1][N2]
>(uptr[0]);
1319 template<auto N1, auto N2,
typename T,
typename Deleter>
1320 inline auto&
cast_ref(std::index_sequence<N1, N2>, std::unique_ptr<T[], Deleter>& uptr)
noexcept
1322 return reinterpret_cast<T(&)[N1][N2]
>(uptr[0]);
1325 template<auto N1, auto N2,
typename T,
typename Deleter>
1326 inline auto&
cast_ref(std::unique_ptr<T[], Deleter>
const& uptr)
noexcept
1328 return reinterpret_cast<const T(&)[N1][N2]
>(uptr[0]);
1331 template<auto N1, auto N2,
typename T,
typename Deleter>
1332 inline auto&
cast_ref(std::index_sequence<N1, N2>, std::unique_ptr<T[], Deleter>
const& uptr)
noexcept
1334 return reinterpret_cast<const T(&)[N1][N2]
>(uptr[0]);
1337 template<auto N1, auto N2, auto N3,
typename T,
typename Deleter>
1338 inline auto&
cast_ref(std::unique_ptr<T[], Deleter>& uptr)
noexcept
1340 return reinterpret_cast<T(&)[N1][N2][N3]
>(uptr[0]);
1343 template<auto N1, auto N2, auto N3,
typename T,
typename Deleter>
1344 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, std::unique_ptr<T[], Deleter>& uptr)
noexcept
1346 return reinterpret_cast<T(&)[N1][N2][N3]
>(uptr[0]);
1349 template<auto N1, auto N2, auto N3,
typename T,
typename Deleter>
1350 inline auto&
cast_ref(std::unique_ptr<T[], Deleter>
const& uptr)
noexcept
1352 return reinterpret_cast<const T(&)[N1][N2][N3]
>(uptr[0]);
1355 template<auto N1, auto N2, auto N3,
typename T,
typename Deleter>
1356 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, std::unique_ptr<T[], Deleter>
const& uptr)
noexcept
1358 return reinterpret_cast<const T(&)[N1][N2][N3]
>(uptr[0]);
1361 template<
auto N1,
auto N2,
typename T,
auto N,
1362 typename = std::enable_if_t<N1* N2 == N>>
1365 using array2_t = T[N1][N2];
1366 return reinterpret_cast<array2_t&
>(array[0]);
1369 template<
auto N1,
auto N2,
typename T,
auto N,
1370 typename = std::enable_if_t<N1* N2 == N>>
1371 inline auto&
cast_ref(std::index_sequence<N1, N2>, T(&array)[N])
noexcept
1373 using array2_t = T[N1][N2];
1374 return reinterpret_cast<array2_t&
>(array[0]);
1377 template<auto N1, auto N2,
typename T, auto N = N1 * N2>
1380 using array_t = T[N];
1381 return reinterpret_cast<array_t&
>(array[0][0]);
1384 template<auto N1, auto N2,
typename T, auto N = N1 * N2>
1385 inline auto&
cast_ref(std::index_sequence<N1, N2>, T(&array)[N1][N2])
noexcept
1387 using array_t = T[N];
1388 return reinterpret_cast<array_t&
>(array[0][0]);
1391 template<
auto N1,
auto N2,
auto N3,
typename T,
auto N,
1392 typename = std::enable_if_t<N1* N2* N3 == N>>
1395 using array3_t = T[N1][N2][N3];
1396 return reinterpret_cast<array3_t&
>(array[0]);
1399 template<
auto N1,
auto N2,
auto N3,
typename T,
auto N,
1400 typename = std::enable_if_t<N1* N2* N3 == N>>
1401 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, T(&array)[N])
noexcept
1403 using array3_t = T[N1][N2][N3];
1404 return reinterpret_cast<array3_t&
>(array[0]);
1407 template<auto N1, auto N2, auto N3,
typename T, auto N = N1 * N2* N3>
1410 using array_t = T[N];
1411 return reinterpret_cast<array_t&
>(array[0][0][0]);
1414 template<auto N1, auto N2, auto N3,
typename T, auto N = N1 * N2* N3>
1415 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, T(&array)[N1][N2][N3])
noexcept
1417 using array_t = T[N];
1418 return reinterpret_cast<array_t&
>(array[0][0][0]);
1421 template<
auto N,
typename T,
1422 typename = std::enable_if_t<std::is_pointer_v<T>>>
1425 using ele_t = std::remove_pointer_t<T>;
1427 using array_t = ele_t[N];
1428 return reinterpret_cast<array_t&
>(array[0]);
1431 template<
auto N1,
auto N2,
typename T,
1432 typename = std::enable_if_t<std::is_pointer_v<T>>>
1435 using ele_t = std::remove_pointer_t<T>;
1437 using array_t = ele_t[N1][N2];
1438 return reinterpret_cast<array_t&
>(array[0]);
1441 template<
auto N1,
auto N2,
auto N3,
typename T,
1442 typename = std::enable_if_t<std::is_pointer_v<T>>>
1445 using ele_t = std::remove_pointer_t<T>;
1447 using array_t = ele_t[N1][N2][N3];
1448 return reinterpret_cast<array_t&
>(array[0]);
1451 template<
auto N,
typename T,
1452 typename = std::enable_if_t<std::is_pointer_v<T>>>
1453 inline auto&
cast_ref(std::index_sequence<N>, T array)
noexcept
1455 using ele_t = std::remove_pointer_t<T>;
1456 using array_t = ele_t[N];
1457 return reinterpret_cast<array_t&
>(array[0]);
1460 template<
auto N1,
auto N2,
typename T,
1461 typename = std::enable_if_t<std::is_pointer_v<T>>>
1462 inline auto&
cast_ref(std::index_sequence<N1, N2>, T array)
noexcept
1464 using ele_t = std::remove_pointer_t<T>;
1465 using array_t = ele_t[N1][N2];
1466 return reinterpret_cast<array_t&
>(array[0]);
1469 template<
auto N1,
auto N2,
auto N3,
typename T,
1470 typename = std::enable_if_t<std::is_pointer_v<T>>>
1471 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, T array)
noexcept
1473 using ele_t = std::remove_pointer_t<T>;
1475 using array_t = ele_t[N1][N2][N3];
1476 return reinterpret_cast<array_t&
>(array[0]);
1479 template<std::size_t N1,
typename T, std::size_t N,
1480 typename = std::enable_if_t<N1 == N>>
1481 inline auto&
cast_ref(std::array<T, N>& array)
noexcept
1483 using c_array_t = T[N];
1484 return reinterpret_cast<c_array_t&
>(array[0]);
1487 template<std::size_t N1,
typename T, std::size_t N,
1488 typename = std::enable_if_t<N1 == N>>
1489 inline auto&
cast_ref(std::array<T, N>
const& array)
noexcept
1491 using c_array_t =
const T[N];
1492 return reinterpret_cast<c_array_t&
>(array[0]);
1495 template<std::size_t N1, std::size_t N2,
typename T, std::size_t N,
1496 typename = std::enable_if_t< N1 * N2 == N>>
1497 inline auto&
cast_ref(std::array<T, N>& array)
noexcept
1499 using c_array_t = T[N1][N2];
1500 return reinterpret_cast<c_array_t&
>(array[0]);
1503 template<std::size_t N1, std::size_t N2,
typename T, std::size_t N,
1504 typename = std::enable_if_t< N1 * N2 == N>>
1505 inline auto&
cast_ref(std::array<T, N>
const& array)
noexcept
1507 using c_array_t =
const T[N1][N2];
1508 return reinterpret_cast<c_array_t&
>(array[0]);
1511 template<std::size_t N1,
typename T, std::size_t N,
1512 typename = std::enable_if_t< N1 == N>>
1513 inline auto&
cast_ref(std::index_sequence<N1>, std::array<T, N>& array)
noexcept
1515 using c_array_t = T[N1];
1516 return reinterpret_cast<c_array_t&
>(array[0]);
1519 template<std::size_t N1,
typename T, std::size_t N,
1520 typename = std::enable_if_t< N1 == N>>
1521 inline auto&
cast_ref(std::index_sequence<N1>, std::array<T, N>
const& array)
noexcept
1523 using c_array_t =
const T[N1];
1524 return reinterpret_cast<c_array_t&
>(array[0]);
1527 template<std::size_t N1, std::size_t N2,
typename T, std::size_t N,
1528 typename = std::enable_if_t< N1 * N2 == N>>
1529 inline auto&
cast_ref(std::index_sequence<N1, N2>, std::array<T, N>& array)
noexcept
1531 using c_array_t = T[N1][N2];
1532 return reinterpret_cast<c_array_t&
>(array[0]);
1535 template<std::size_t N1, std::size_t N2,
typename T, std::size_t N,
1536 typename = std::enable_if_t< N1 * N2 == N>>
1537 inline auto&
cast_ref(std::index_sequence<N1, N2>, std::array<T, N>
const& array)
noexcept
1539 using c_array_t =
const T[N1][N2];
1540 return reinterpret_cast<c_array_t&
>(array[0]);
1543 template<std::size_t N1, std::size_t N2, std::size_t N3,
typename T, std::size_t N,
1544 typename = std::enable_if_t< N1 * N2 * N3 == N>>
1545 inline auto&
cast_ref(std::array<T, N>& array)
noexcept
1547 using c_array_t = T[N1][N2][N3];
1548 return reinterpret_cast<c_array_t&
>(array[0]);
1551 template<std::size_t N1, std::size_t N2, std::size_t N3,
typename T, std::size_t N,
1552 typename = std::enable_if_t< N1 * N2 * N3 == N>>
1553 inline auto&
cast_ref(std::array<T, N>
const& array)
noexcept
1555 using c_array_t =
const T[N1][N2][N3];
1556 return reinterpret_cast<c_array_t&
>(array[0]);
1559 template<std::size_t N1, std::size_t N2, std::size_t N3,
typename T, std::size_t N,
1560 typename = std::enable_if_t< N1 * N2 * N3 == N>>
1561 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, std::array<T, N>& array)
noexcept
1563 using c_array_t = T[N1][N2][N3];
1564 return reinterpret_cast<c_array_t&
>(array[0]);
1567 template<std::size_t N1, std::size_t N2, std::size_t N3,
typename T, std::size_t N,
1568 typename = std::enable_if_t< N1 * N2 * N3 == N>>
1569 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, std::array<T, N>
const& array)
noexcept
1571 using c_array_t =
const T[N1][N2][N3];
1572 return reinterpret_cast<c_array_t&
>(array[0]);
1575 template<std::
size_t N,
typename T>
1578 assert(N == vctr.size());
1580 using c_array_t = T[N];
1581 return reinterpret_cast<c_array_t&
>(vctr[0]);
1584 template<std::
size_t N,
typename T>
1585 inline auto&
cast_ref(std::vector<T>
const& vctr)
noexcept
1587 assert(N == vctr.size());
1589 using c_array_t =
const T[N];
1590 return reinterpret_cast<c_array_t&
>(vctr[0]);
1593 template<std::
size_t N,
typename T>
1594 inline auto&
cast_ref(std::index_sequence<N>, std::vector<T>& vctr)
noexcept
1596 assert(N == vctr.size());
1598 using c_array_t = T[N];
1599 return reinterpret_cast<c_array_t&
>(vctr[0]);
1602 template<std::
size_t N,
typename T>
1603 inline auto&
cast_ref(std::index_sequence<N>, std::vector<T>
const& vctr)
noexcept
1605 assert(N == vctr.size());
1607 using c_array_t =
const T[N];
1608 return reinterpret_cast<c_array_t&
>(vctr[0]);
1611 template<std::
size_t N1, std::
size_t N2,
typename T>
1614 assert(N1 * N2 == vctr.size());
1616 using c_array_t = T[N1][N2];
1617 return reinterpret_cast<c_array_t&
>(vctr[0]);
1620 template<std::
size_t N1, std::
size_t N2,
typename T>
1621 inline auto&
cast_ref(std::vector<T>
const& vctr)
noexcept
1623 assert(N1 * N2 == vctr.size());
1625 using c_array_t =
const T[N1][N2];
1626 return reinterpret_cast<c_array_t&
>(vctr[0]);
1629 template<std::
size_t N1, std::
size_t N2,
typename T>
1630 inline auto&
cast_ref(std::index_sequence<N1, N2>, std::vector<T>& vctr)
noexcept
1632 assert(N1 * N2 == vctr.size());
1634 using c_array_t = T[N1][N2];
1635 return reinterpret_cast<c_array_t&
>(vctr[0]);
1638 template<std::
size_t N1, std::
size_t N2,
typename T>
1639 inline auto&
cast_ref(std::index_sequence<N1, N2>, std::vector<T>
const& vctr)
noexcept
1641 assert(N1 * N2 == vctr.size());
1643 using c_array_t =
const T[N1][N2];
1644 return reinterpret_cast<c_array_t&
>(vctr[0]);
1647 template<std::
size_t N1, std::
size_t N2, std::
size_t N3,
typename T>
1650 assert(N1 * N2 * N3 == vctr.size());
1652 using c_array_t = T[N1][N2][N3];
1653 return reinterpret_cast<c_array_t&
>(vctr[0]);
1656 template<std::
size_t N1, std::
size_t N2, std::
size_t N3,
typename T>
1657 inline auto&
cast_ref(std::vector<T>
const& vctr)
noexcept
1659 assert(N1 * N2 * N3 == vctr.size());
1661 using c_array_t =
const T[N1][N2][N3];
1662 return reinterpret_cast<c_array_t&
>(vctr[0]);
1665 template<std::
size_t N1, std::
size_t N2, std::
size_t N3,
typename T>
1666 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, std::vector<T>& vctr)
noexcept
1668 assert(N1 * N2 * N3 == vctr.size());
1670 using c_array_t = T[N1][N2][N3];
1671 return reinterpret_cast<c_array_t&
>(vctr[0]);
1674 template<std::
size_t N1, std::
size_t N2, std::
size_t N3,
typename T>
1675 inline auto&
cast_ref(std::index_sequence<N1, N2, N3>, std::vector<T>
const& vctr)
noexcept
1677 assert(N1 * N2 * N3 == vctr.size());
1679 using c_array_t =
const T[N1][N2][N3];
1680 return reinterpret_cast<c_array_t&
>(vctr[0]);
1683 template<
size_t N1,
size_t N2,
typename T,
size_t N,
1684 typename = std::enable_if_t<N1* N2 == N>>
1687 using array_t = T[N1][N2];
1688 return *
reinterpret_cast<array_t*
>(array);
1691 template<
size_t N1,
size_t N2,
typename T,
size_t N = N1 * N2>
1694 using array_t = T[N];
1695 return *
reinterpret_cast<array_t*
>(array);
1698 template<
size_t N1,
size_t N2,
size_t N3,
typename T,
size_t N,
1699 typename = std::enable_if_t<N1* N2* N3 == N>>
1702 using array_t = T[N1][N2][N3];
1703 return *
reinterpret_cast<array_t*
>(array);
1706 template<
size_t N1,
size_t N2,
size_t N3,
typename T,
size_t N = N1 * N2* N3>
1709 using array_t = T[N];
1710 return *
reinterpret_cast<array_t*
>(array);
1713 template<
typename T,
size_t N>
1716 using c_array_t = T[N];
1717 return *
reinterpret_cast<c_array_t*
>(array.data());
1720 template<
typename T,
size_t N>
1723 using c_array_t =
const T[N];
1724 return *
reinterpret_cast<c_array_t*
>(array.data());
1727 template<
size_t N1,
size_t N2,
typename T,
size_t N,
1728 typename = std::enable_if_t< N1 * N2 == N>>
1731 using c_array_t = T[N1][N2];
1732 return *
reinterpret_cast<c_array_t*
>(array.data());
1735 template<
size_t N1,
size_t N2,
typename T,
size_t N,
1736 typename = std::enable_if_t< N1 * N2 == N>>
1739 using c_array_t =
const T[N1][N2];
1740 return *
reinterpret_cast<c_array_t*
>(array.data());
1743 template<
size_t N1,
size_t N2,
size_t N3,
typename T,
size_t N,
1744 typename = std::enable_if_t< N1 * N2 * N3 == N>>
1747 using c_array_t = T[N1][N2][N3];
1748 return *
reinterpret_cast<c_array_t*
>(array.data());
1751 template<
size_t N1,
size_t N2,
size_t N3,
typename T,
size_t N,
1752 typename = std::enable_if_t< N1 * N2 * N3 == N>>
1755 using c_array_t = T[N1][N2][N3];
1756 return *
reinterpret_cast<c_array_t*
>(array.data());
1763 template<
typename S,
typename T>
1769 template<
template<
typename,
typename...>
class ContainerTmpl,
1770 typename S,
typename... S_tail,
typename T,
typename... T_tail>
1776 using type = std::conditional_t< std::is_same_v<S, common_t>,
1777 ContainerTmpl<S, S_tail...>, ContainerTmpl<T, T_tail...>>;
1780 template<
template<
typename, std::
size_t>
class ContainerTmpl,
1781 typename S,
typename T, std::size_t M, std::size_t N>
1786 using type = ContainerTmpl<common_t, M + N>;
1789 template<
template<
typename, std::
size_t>
class ContainerTmpl,
1790 typename S,
typename T, std::size_t N>
1795 using type = ContainerTmpl<common_t, N>;
1798 template<
typename... Ss,
typename... Ts>
1802 using type = std::tuple< std::common_type_t<Ss, Ts>... >;
1807 template<
typename S,
typename T>
1813 template<
typename FuncType,
typename... ArgTypes>
1814 auto safe_apply(FuncType&& f, std::tuple<ArgTypes...>
const& args)
1815 ->
decltype( f( std::declval<ArgTypes>()...));
1817 template<
typename FuncType,
typename ArgType, std::size_t N, std::size_t... Ints>
1819 std::index_sequence<Ints...>)->
decltype( f( std::get<Ints>(args)... ));
1823 template<
typename FuncType,
typename ArgType, std::
size_t N>
1824 auto safe_apply(FuncType&& f, std::array<ArgType, N>
const& args)
1825 ->
decltype(
array_apply(f, args, std::make_index_sequence<N>{}) );
1829 template<
typename FuncType,
typename TupleType>
1834 template<
typename FuncType,
typename TupleType>
1837 template<
typename FuncType,
typename... TupleTypes>
1838 using common_apply_t = std::common_type_t< apply_return_t<FuncType, TupleTypes>... >;
1840 template<
typename FuncType,
typename TupleType>
1843 template<
typename FuncType,
typename... TupleTypes>
1844 constexpr bool all_apply_v = ( is_apply_v<FuncType, TupleTypes> && ... );
1846 template<
typename FuncType,
typename... TupleTypes>
1850 template<
typename ReturnType,
typename FuncType,
typename... TupleTypes>
1854 template<
typename FuncType,
typename... TupleTypes>
1857 template<
typename FuncType,
typename... TupleTypes>
1859 std::array<std::common_type_t<apply_return_t<FuncType, TupleTypes>...>,
sizeof...(TupleTypes)>;
1861 template<
typename FuncType,
typename... TupleTypes>
1863 std::vector<std::common_type_t<apply_return_t<FuncType, TupleTypes>...>>;
1865 template<
typename FuncType,
typename... TupleTypes>
1868 template<
typename FuncType,
typename... TupleTypes>
1872 template<
typename FuncType,
typename... TupleTypes>
1876 template<
typename FuncType,
typename... TupleTypes>
1880 template<
typename FuncType,
typename... TupleTypes>
1882 std::common_type_t<apply_return_t<FuncType, TupleTypes>...>>;
1884 template<
typename FuncType,
typename... ArgTypes>
1891 template<
typename FuncType,
typename... ArgTypes>
1899 template<
typename FuncType,
typename... ArgTypes>
1924 template<
typename T>
1927 template<
typename T>
1931 template<
typename T>
1932 concept safe_co_c = hidden::st_safe_cast_operation<std::remove_cvref_t<T>>::value;
1934 template<
typename T>
1937 template<
typename L,
typename R>
1945 auto aa = numeric_cast<r_t>(a.value);
1946 auto bb = numeric_cast<r_t>(b.value);
1948 if(aa.has_value() && bb.has_value())
1949 return aa.value() + bb.value();
1956 throw std::runtime_error(
"Integer Addition - Casting failed!");
1960 return a.value + b.value;
1963 template<
typename L,
typename R>
1971 auto aa = numeric_cast<r_t>(a.value);
1972 auto bb = numeric_cast<r_t>(b.value);
1974 if(aa.has_value() && bb.has_value())
1975 return aa.value() - bb.value();
1982 throw std::runtime_error(
"Integer Subtraction - Casting failed!");
1986 return a.value + b.value;
1989 template<
typename L,
typename R>
1997 auto aa = numeric_cast<r_t>(a.value);
1998 auto bb = numeric_cast<r_t>(b.value);
2000 if(aa.has_value() && bb.has_value())
2001 return aa.value() * bb.value();
2008 throw std::runtime_error(
"Integer Multiplication - Casting failed!");
2012 return a.value + b.value;
2015 template<
typename L,
typename R>
2023 auto aa = numeric_cast<r_t>(a.value);
2024 auto bb = numeric_cast<r_t>(b.value);
2026 if(aa.has_value() && bb.has_value())
2027 return aa.value() / bb.value();
2034 throw std::runtime_error(
"Integer Division - Casting failed!");
2038 return a.value + b.value;
2041 template<non_safe_co_c L,
typename R>
2047 template<
typename L, non_safe_co_c R>
2053 template<non_safe_co_c L,
typename R>
2059 template<
typename L, non_safe_co_c R>
2065 template<non_safe_co_c L,
typename R>
2071 template<
typename L, non_safe_co_c R>
2077 template<non_safe_co_c L,
typename R>
2083 template<
typename L, non_safe_co_c R>
2106 template<
typename T>
2109 template<
typename T>
2113 template<
typename T>
2114 concept safe_io_c = hidden::st_safe_integral_operation<std::remove_cvref_t<T>>::value;
2116 template<
typename T>
2119 template<
typename L,
typename R>
2123 if constexpr(std::integral<L> && std::integral<R>)
2132 if(!aa.has_value() || !bb.has_value())
2138 throw std::runtime_error(
"Integer Addition - Casting failed!");
2141 r_t result = aa.value() + bb.value();
2143 if( (a.
value > 0 && b.
value > 0 && result < 0)
2144 || (a.
value < 0 && b.
value < 0 && result > 0) )
2150 throw std::runtime_error(
"Integer Addition - Overflow!");
2159 template<
typename L,
typename R>
2163 if constexpr(std::integral<L> && std::integral<R>)
2167 auto aa = numeric_cast<r_t>(a.
value);
2168 auto bb = numeric_cast<r_t>(b.
value);
2170 if(!aa.has_value() || !bb.has_value())
2176 throw std::runtime_error(
"Integer Subtraction - Casting failed!");
2180 r_t result = aa.value() + bb.value();
2182 if( (aa.value() > 0 && bb.value() > 0 && result < 0) ||
2183 (aa.value() < 0 && bb.value() < 0 && result > 0) )
2189 throw std::runtime_error(
"Integer Subtraction - Overflow!");
2198 template<
typename L,
typename R>
2202 if constexpr(std::integral<L> && std::integral<R>)
2206 auto aa = numeric_cast<r_t>(a.
value);
2207 auto bb = numeric_cast<r_t>(b.
value);
2209 if(!aa.has_value() || !bb.has_value())
2215 throw std::runtime_error(
"Integer Multiplication - Casting failed!");
2218 r_t result = aa.value() * bb.value();
2222 else if(result / bb.value() == aa.value())
2230 throw std::runtime_error(
"Integer multiplication - Overflow!");
2237 template<
typename L,
typename R>
2241 if constexpr(std::integral<L> && std::integral<R>)
2247 auto aa = numeric_cast<r_t>(a.
value);
2248 auto bb = numeric_cast<r_t>(b.
value);
2250 if(aa.has_value() && bb.has_value())
2251 return aa.value() / bb.value();
2258 throw std::runtime_error(
"Integer Division - Casting failed!");
2267 throw std::runtime_error(
"Integer Division By Zero!");
2274 template<non_safe_io_c L,
typename R>
2280 template<
typename L, non_safe_io_c R>
2286 template<non_safe_io_c L,
typename R>
2292 template<
typename L, non_safe_io_c R>
2298 template<non_safe_io_c L,
typename R>
2304 template<
typename L, non_safe_io_c R>
2310 template<non_safe_io_c L,
typename R>
2316 template<
typename L, non_safe_io_c R>
2337 template<
typename T>
2340 template<
typename T>
2344 template<
typename T>
2345 concept safe_no_c = hidden::st_safe_numerical_operation<std::remove_cvref_t<T>>::value;
2347 template<
typename T>
2350 template<
typename L,
typename R>
2354 if constexpr(std::integral<L> && std::integral<R>)
2359 else if constexpr(std::floating_point<L> && std::floating_point<R>)
2363 R_t result =
static_cast<R_t
>(a.
value) +
static_cast<R_t
>(b.
value);
2377 throw std::runtime_error(
"binary addition failure");
2387 template<
typename L,
typename R>
2391 if constexpr(std::integral<L> && std::integral<R>)
2396 else if constexpr(std::floating_point<L> && std::floating_point<R>)
2400 R_t result =
static_cast<R_t
>(a.
value) -
static_cast<R_t
>(b.
value);
2413 throw std::runtime_error(
"binary subtraction failure");
2423 template<
typename L,
typename R>
2427 if constexpr(std::integral<L> && std::integral<R>)
2432 else if constexpr(std::floating_point<L> && std::floating_point<R>)
2436 R_t result =
static_cast<R_t
>(a.
value)
2437 *
static_cast<R_t
>(b.
value);
2451 throw std::runtime_error(
"binary multiplication failure");
2461 template<
typename L,
typename R>
2465 if constexpr(std::integral<L> && std::integral<R>)
2470 else if constexpr(std::floating_point<L> && std::floating_point<R>)
2476 R_t result =
static_cast<R_t
>(a.
value) /
static_cast<R_t
>(b.
value);
2488 throw std::runtime_error(
"Division by Zero");
2497 template<non_safe_no_c L,
typename R>
2503 template<
typename L, non_safe_no_c R>
2509 template<non_safe_no_c L,
typename R>
2515 template<
typename L, non_safe_no_c R>
2521 template<non_safe_no_c L,
typename R>
2527 template<
typename L, non_safe_no_c R>
2533 template<non_safe_no_c L,
typename R>
2539 template<
typename L, non_safe_no_c R>
2548 template<
long long DebugMode=2,
typename T=
int>
2551 if constexpr(DebugMode == 1)
2553 else if constexpr(DebugMode == 2)
2561 template<
typename... Types>
2567 template<
typename P,
typename... Types>
2568 struct st_all_same<P, Types...>: std::bool_constant<all_same_c<P, Types...>>{ };
2572 template<
typename... Types>
2575 template<
typename P,
typename... Types>
2578 template<
typename... Types>
2584 template<
typename P,
typename... Types>
2587 template<
typename P,
typename... Types>
2590 if constexpr(
sizeof...(Types) == 0)
2596 template<
typename T,
typename S>
2599 template<
template<
typename,
typename...>
class ContainerType,
2600 typename T1,
typename T2,
typename... Tails>
2602 < ContainerType<T1, Tails...>, ContainerType<T2, Tails...>> :
std::true_type { };
2604 template<
typename T>
2607 template<
typename T>
2610 template<
typename T>
2616 template<
template<
typename,
typename...>
class ContainerType,
2617 typename T,
typename... Types>
2623 template<
template<
typename,
auto...>
class ContainerType,
2624 typename T,
auto... Values>
2630 template<
template<
typename, std::
size_t>
class ContainerType,
2631 typename T, std::size_t N>
2639 template<
typename T>
2640 concept vector_c = hidden::st_is_vector<std::remove_cvref_t<T>>::value;
2642 template<
typename T>
2645 template<
typename T,
typename S>
2647 hidden::st_same_container<std::remove_cvref_t<T>, std::remove_cvref_t<S>>::value;
2649 template<
typename P,
typename... Types>
2652 template<
typename P,
typename... Types>
2655 template<
typename P,
typename Q,
typename... Types>
2658 template<
typename P,
typename Q,
typename... Types>
2660 std::remove_cvref_t<Q>, std::remove_cvref_t<Types>...>;
2662 template<
auto... Indices>
2667 template<
typename Type>
2670 template<
typename T>
2673 if constexpr( std::is_function_v<std::remove_reference_t<T>>
2674 || std::is_array_v<std::remove_reference_t<T>> )
2676 return static_cast<std::decay_t<std::remove_reference_t<T>
>>(value);
2680 return std::forward<T>(value);
2684 template<
template<
typename...>
class ContainerType,
typename... ArgTypes>
2687 return ContainerType{
decay_value(std::forward<ArgTypes>(args) )... };
2690 template<
template<
typename, auto>
class ContainerType,
2691 all_the_same_flat_c... ArgTypes>
2694 return ContainerType{
decay_value(std::forward<ArgTypes>(args) )... };
2697 template< all_the_same_flat_c... ArgTypes>
2700 return std::array{
decay_value(std::forward<ArgTypes>(args) )... };
2703 template<
typename... ArgTypes>
2713 template<
typename... Types>
2718 template<
typename T>
2721 template<
typename T>
2726 template<
typename A,
typename B>
2732 template<numerical_c A, numerical_c B>
2738 template<numerical_c A, numerical_c B>
2741 using type = std::vector< typename st_common_vector<A, B>::type >;
2744 template<vector_c A, vector_c B>
2747 using type = std::vector< typename st_common_vector<A, B>::type >;
2750 template<numerical_c A, numerical_c B>
2753 using type = std::vector< typename st_common_vector<A, B>::type >;
2756 template<numerical_c A, numerical_c B>
2759 using type = std::vector< typename st_common_vector<A, B>::type >;
2762 template<vector_c A, numerical_c B>
2765 using type = std::vector< typename st_common_vector<A, B>::type >;
2768 template<numerical_c A, vector_c B>
2771 using type = std::vector< typename st_common_vector<A, B>::type >;
2774 template<
typename A,
typename B, std::
size_t N>
2777 using type = std::vector< std::array<typename st_common_vector<A, B>::type, N> >;
2780 template<numerical_c A,
typename B, std::
size_t N>
2783 using type = std::vector< std::array<typename st_common_vector<A, B>::type, N> >;
2786 template<
typename A, numerical_c B, std::
size_t N>
2789 using type = std::vector< std::array<typename st_common_vector<A, B>::type, N> >;
2792 template<numerical_c A, numerical_c B, std::
size_t N>
2795 using type = std::vector< std::array<typename st_common_vector<A, B>::type, N> >;
2798 template<numerical_c A, numerical_c B, std::
size_t N>
2801 using type = std::vector< std::array<typename st_common_vector<A, B>::type, N> >;
2806 template<
typename A,
typename B>
2810 template<
typename A,
typename B>
2813 template<
typename A,
typename B>
2830 template<
typename CharType,
typename... Types>
2831 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
2832 const type_container<Types...>& tc);
2838 template<
typename CharType,
typename Type,
typename... Types>
2839 std::basic_ostream<CharType>&
2842 if constexpr(
sizeof...(Types) == 0)
2850 if constexpr(std::same_as<CharType, wchar_t>)
2866 if constexpr(std::same_as<CharType, wchar_t>)
2880 template<
typename CharType,
typename... Types> std::basic_ostream<CharType>&
2881 operator<<(std::basic_ostream<CharType>& os,
const type_container<Types...>& tc)
2883 if constexpr(
sizeof...(Types) == 0)
2906 template<
typename P>
2909 static constexpr bool value =
false;
2915 static constexpr bool value = std::same_as<P, Type> ||
2919 template<
typename P,
typename... Types,
typename... Tails>
2928 template<
typename P,
typename... Types>
2942 template<
typename Type,
typename... Types>
2948 template<
typename... Types>
2956 template<
typename... Types>
2961 template<
typename... LeftTypes>
2969 template<
typename... LeftTypes,
typename Head>
2978 template<
typename... LeftTypes,
typename First,
typename Second,
typename... Tails>
2999 template<
typename... Types>
3007 template<
typename... Types>
3010 template<
typename Type>
3013 template<
typename Type>
3028 template<
typename Type,
typename... Types,
3029 template<
typename,
typename...>
class ContainerTemplate >
3040 template<
typename KeyType,
typename ValueType,
typename... Types>
3046 template<
typename KeyType,
typename ValueType,
typename... Types>
3057 template<
typename KeyType,
typename ValueType,
typename... Types>
3063 template<
typename KeyType,
typename ValueType,
typename... Types>
3073 std::ranges::range<T> && std::movable<T> && std::ranges::enable_view<T>;
3078 template<
typename T>
3094 types::type_container<std::string, std::wstring, std::u8string, std::u16string, std::u32string,
3095 std::string_view, std::u8string_view, std::u16string_view, std::u32string_view, std::wstring_view>;
3102 template<
typename P>
3103 concept std_map_c = hidden::st_std_map_container<std::remove_cvref_t<P>>::value;
3105 template<
typename P>
3106 concept tbb_map_c = hidden::st_tbb_map_container<std::remove_cvref_t<P>>::value;
3108 template<
typename P>
3111 template<
typename P>
3115 template<
typename P>
3128 template<
typename Type,
typename... Types>
3136 template<
typename... Types>
3145 template<
typename... LeftTypes,
typename Head>
3152 template<
typename... LeftTypes,
typename First,
typename Second,
typename... Tails>
3165 template<
typename... Types>
3169 template<
typename P,
typename CharType>
3171 requires (P obj, std::basic_ostream<CharType>& os)
3178 template<
typename... Types>
3181 return std::variant<Types...>{};
3184 template<
typename... Types>
3203 template<
typename VariantType>
3206 template<
typename... Types>
3211 return std::vector<variant_t>{ args... };
3218 template<
typename T>
3221 template<
typename... Types>
3224 template<
typename T>
3227 template<
typename... Types>
3230 template<
typename T>
3233 template<
typename T, std::
size_t N>
3238 template<
typename T>
3241 template<
typename T, std::
size_t N>
3244 template<
typename T>
3247 template<
typename T, std::
size_t N>
3250 template<
typename T>
3253 template<
typename T,
typename S>
3257 template<
typename T, T START, T END, T STEP, T... Indices>
3260 if constexpr ( STEP > 0 && START < END )
3262 return fn_make_sequence<T, START + STEP, END, STEP>
3263 ( std::integer_sequence<T, Indices..., START>{ });
3265 else if constexpr( STEP < 0 && START > END )
3267 return fn_make_sequence<T, START + STEP, END, STEP>
3268 ( std::integer_sequence<T, Indices..., START>{ });
3274 template<
typename T>
3277 template<std::
size_t N>
3280 template<std::
size_t N>
3289 template<std::
size_t N>
3295 template<std::
size_t N>
3301 template<std::
size_t N>
3309 template<
typename T>
3312 template<std::
size_t N>
3315 template<std::
size_t N>
3324 template<std::
size_t N>
3330 template<std::
size_t N>
3336 template<std::
size_t N>
3345 template<
typename T>
3346 concept const_chars_c = hidden::st_const_chars< std::remove_reference_t<T> >::value;
3348 template<
typename T>
3351 template<
typename T>
3354 template<
typename T>
3357 template<
typename T, T START, T END, T STEP>
3359 hidden::fn_make_sequence<T, START, END, STEP>( std::integer_sequence<T>{} ) );
3362 template<
typename T>
3365 template<
typename T>
3368 template<
typename T>
3371 template<
typename T>
3374 template<
typename T>
3377 template<
typename T>
3380 template<
typename T>
3383 template<
typename T>
3386 template<
typename T>
3389 template<
typename T>
3392 template<
typename T>
3395 template<
typename T>
3398 template<
typename T>
3399 concept span_c = hidden::st_is_span<T>::value;
3401 template<
typename T>
3404 template<
typename T>
3407 template<
typename T>
3410 template<
typename T>
3413 template<
typename T>
3416 template<
typename T>
3419 template<
typename T>
3420 concept pair_c = hidden::st_is_pair<T>::value;
3422 template<
typename T>
3425 template<
vector_c... ContainerTypes,
auto N =
sizeof...(ContainerTypes)>
3429 auto Vs = std::forward_as_tuple(containers...);
3430 auto A_size = std::get<0>(Vs).size();
3435 return ( (A_size == std::get<k>(Vs).size()) && ... );
3439 template<std_array_flat_c... ContainerTypes,
3440 auto N =
sizeof...(ContainerTypes)>
requires (N > 0)
3443 auto Vs = std::tuple( containers... );
3445 using A_t = std::tuple_element_t<0,
decltype(Vs)>;
3446 auto A_size = std::tuple_size_v<A_t>;
3451 return ( ( A_size ==
3456 template<std::
size_t N, vector_c VectorType>
3460 return std::span<element_t, N>{v};
3463 template<std_array_flat_c ArrayType>
3466 return std::span{ array };
3469 template<
typename T, std::
size_t N>
3472 return std::span{ array };
3480 template<
typename A,
typename B>
3486 template<numerical_c A, numerical_c B>
3492 template<numerical_c A, numerical_c B, std::
size_t N>
3495 using type = std::array< typename st_std_common_array<A, B>::type, N>;
3498 template<std_array_c A, std_array_c B, std::
size_t N>
3501 using type = std::array< typename st_std_common_array<A, B>::type, N>;
3504 template<numerical_c A, numerical_c B, std::
size_t N>
3507 using type = std::array< typename st_std_common_array<A, B>::type, N>;
3510 template<numerical_c A, numerical_c B, std::
size_t N>
3513 using type = std::array< typename st_std_common_array<A, B>::type, N>;
3516 template<std_array_c A, numerical_c B, std::
size_t N>
3519 using type = std::array< typename st_std_common_array<A, B>::type, N>;
3522 template<numerical_c A, std_array_c B, std::
size_t N>
3525 using type = std::array< typename st_std_common_array<A, B>::type, N>;
3529 template<numerical_c A, std_array_c B, std::
size_t N>
3532 using type = std::array< typename st_std_common_array<A, B>::type, N>;
3535 template<std_array_c A, numerical_c B, std::
size_t N>
3538 using type = std::array< typename st_std_common_array<A, B>::type, N>;
3543 template<numerical_c A, std::
size_t M, std_array_c B, std::
size_t N>
3547 using type = std::array< std::array< ele_t, M>, N>;
3550 template<std_array_c A, std::
size_t M, numerical_c B, std::
size_t N>
3554 using type = std::array< std::array<ele_t, N>, M>;
3560 template<
typename A,
typename B>
3564 template<
typename A,
typename B>
3568 template<
typename... ArgTypes>
3572 std::tuple<ArgTypes...> m_tuple;
3577 std::runtime_error{
"From workhorse"},
3578 m_tuple{
std::move(args)...} { }
3587 return this->m_tuple;
3596 template<
typename T, T START, T END, T STEP>
3601 T r = (END - START) % STEP;
3602 T q = (END - START) / STEP;
3605 return START + (q - 1) * STEP;
3607 return START + q * STEP;
3616 template<
typename T, T START, T END, T STEP, T Index>
3623 hidden::compute_last_index<T, START, END, STEP>();
3625 constexpr static auto end = END;
3629 template<
typename T, T START, T END, T STEP, T Index>
3634 <<
" | start(index)=" << item.
start
3635 <<
" | value(cur. idx)=" << item.
value
3636 <<
" | last(max idx)=" << item.
last
3637 <<
" | end(count)=" << item.
end
3638 <<
" | step(incr'nt)=" << item.
step <<
" }";
return os;
3643 template<
auto... Args>
3649 using type = std::integer_sequence<long long>;
3659 template<auto START, auto END>
3666 template<auto START, auto END, auto STEP>
3675 template<
auto... Indices>
3676 requires (
sizeof...(Indices) < 4) ||
requires
3678 requires sizeof...(Indices) == 2;
3679 requires ( std::signed_integral<
decltype(Indices)> && ... );
3685 template<
typename T, T Row, T Column, T Index>
3691 constexpr static T
size = Row * Column;
3694 template<auto Row, auto Column, auto Index>
3697 template<
typename T, T Height, T Row, T Column, T Index>
3704 constexpr static T
size = Height * Row * Column;
3707 template<auto Height, auto Row, auto Column, auto Index>
3712 template<
typename T>
3715 template<
typename T, T Row, T Column, T Index>
3718 template<
typename T>
3721 template<
typename T, T Height, T Row, T Column, T Index>
3725 template<
typename T>
3728 template<
typename T>
3731 template<
typename CharType,
typename T, T Row, T Column, T Index>
3732 std::basic_ostream<CharType>&
3734 row_column_value<T, Row, Column, Index>
const& idx)
3743 template<
typename CharType,
typename T, T Height, T Row, T Column, T Index>
3744 std::basic_ostream<CharType>&
3756 template<std::size_t... Ints,
typename FuncType>
3762 template<std::size_t... Ints,
typename FuncType>
3768 template<std::
size_t N,
typename FuncType>
3771 return for_tuple(f, std::make_index_sequence<N>{});
3774 template<std::size_t... Ints,
typename FuncType>
3780 template<std::size_t... Ints,
typename FuncType>
3786 template<std::
size_t N,
typename FuncType>
3789 return for_array(f, std::make_index_sequence<N>{});
3792 template<std::size_t... Ints,
typename FuncType>
3798 template<std::size_t... Ints,
typename FuncType>
3804 template<std::
size_t N,
typename FuncType>
3807 return for_vector(f, std::make_index_sequence<N>{});
3812 template<
typename T, T START, T END, T STEP,
3813 typename WorkType, T... Indices,
typename... ArgTypes>
3814 void for_workhorse(WorkType&& work, std::integer_sequence<T, Indices...>, ArgTypes&&... args)
3821 std::forward<ArgTypes>(args)...) );
3824 template<
typename T, T START, T END, T STEP,
typename ContainerType,
3825 typename WorkType, T... Indices,
typename... ArgTypes>
3827 std::integer_sequence<T, Indices...>, ArgTypes&&... args)
3831 std::get<START>(std::forward<ContainerType>(container)),
3832 std::forward<ArgTypes>(args)...);
3836 std::get<Indices>(std::forward<ContainerType>(container)),
3837 std::forward<ArgTypes>(args)...) );
3840 template<
typename T, T START, T END, T STEP,
typename ContainerType,
3841 typename WorkType, T... Indices,
typename... ArgTypes>
3843 std::integer_sequence<T, Indices...>, ArgTypes&&... args)
3846 work( std::get<0>(std::forward<ContainerType>(container)),
3847 std::forward<ArgTypes>(args)...);
3850 ( ... , (void)work(std::get<Indices>(std::forward<ContainerType>(container)),
3851 std::forward<ArgTypes>(args)...) );
3856 template<
typename T, T START, T END, T STEP,
3857 typename WorkType, T... Indices,
typename... ArgTypes>
3859 std::integer_sequence<T, Indices...>, ArgTypes&&... args)
3863 sequence<Indices...>{}, std::forward<ArgTypes>(args)...);
3867 sequence<Indices...>{}, std::forward<ArgTypes>(args)...);
3870 template<
typename T, T START, T END, T STEP,
3871 typename WorkType, T... Indices,
typename... ArgTypes>
3873 std::integer_sequence<T, Indices...>, ArgTypes&&... args)
3881 item_index<T, START, END, STEP, START>{}, std::forward<ArgTypes>(args)...);
3884 template<
typename T, T START, T END, T STEP,
3885 typename WorkType, T... Indices,
typename... ArgTypes>
3887 std::integer_sequence<T, Indices...>, ArgTypes&&... args)
3896 template<
typename T, T Rows, T Columns>
3901 return std::tuple<
row_column_value<T, k / Columns, k % Columns, k> ... >{ };
3903 }, std::make_integer_sequence<T, Rows * Columns>{});
3906 template<
typename T, T Heights, T Rows, T Columns>
3912 k / (Rows * Columns), (k % (Rows * Columns))/Columns, (k % (Rows * Columns)) % Columns, k> ... >{ };
3914 }, std::make_integer_sequence<T, Heights * Rows * Columns>{});
3919 template<
typename T, T Rows, T Columns>
3922 template<auto Rows, auto Columns>
3924 decltype(hidden::generate_row_column_value<decltype(Rows), Rows, Columns>());
3926 template<
typename T, T Heights, T Rows, T Columns>
3928 decltype(hidden::generate_height_row_column_value<T, Heights, Rows, Columns>());
3930 template<auto Heights, auto Rows, auto Columns>
3936 template<
typename... Ls,
typename... Rs,
auto... Li,
auto... Ri>
3941 return std::array{ std::get<Li>(
A)..., std::get<Ri>(
B)... };
3943 return std::tuple{ std::get<Li>(
A)..., std::get<Ri>(
B)... };
3946 template<
typename... Ls,
typename R,
auto... Li, std::size_t N,
auto... Ri>
3951 return std::array{ std::get<Li>(
A)..., std::get<Ri>(
B)... };
3953 return std::tuple{ std::get<Li>(
A)..., std::get<Ri>(
B)... };
3956 template<
typename L, std::size_t N,
typename... Rs,
auto... Li,
auto... Ri>
3961 return std::array{ std::get<Li>(
A)..., std::get<Ri>(
B)... };
3963 return std::tuple{ std::get<Li>(
A)..., std::get<Ri>(
B)... };
3966 template<
typename L, std::size_t N1,
typename R, std::size_t N2,
auto... Li,
auto... Ri>
3971 return std::array{ std::get<Li>(
A)..., std::get<Ri>(
B)... };
3973 return std::tuple{ std::get<Li>(
A)..., std::get<Ri>(
B)... };
3978 template<
typename... Ls,
typename... Rs>
3979 constexpr auto tuple_append(std::tuple<Ls...>
const&
A, std::tuple<Rs...>
const&
B)
noexcept
3985 template<
typename... Ls,
typename R, std::size_t N2>
3986 constexpr auto tuple_append(std::tuple<Ls...>
const&
A, std::array<R, N2>
const&
B)
noexcept
3992 template<
typename L, std::size_t N1,
typename... Rs>
3993 constexpr auto tuple_append(std::array<L, N1>
const&
A, std::tuple<Rs...>
const&
B)
noexcept
3999 template<
typename L, std::
size_t N1,
typename R, std::
size_t N2>
4000 constexpr auto tuple_append(std::array<L, N1>
const&
A, std::array<R, N2>
const&
B)
noexcept
4005 template<
typename... Ls, neither_array_nor_tuple_c... ArgTypes>
4006 constexpr auto tuple_append(std::tuple<Ls...>
const&
A, ArgTypes&& ... args)
noexcept
4011 return std::array{ std::get<ii_>(
A)..., std::forward<ArgTypes>(args)... };
4013 return std::tuple{ std::get<ii_>(
A)..., std::forward<ArgTypes>(args)... };
4017 template<
typename L, std::size_t N, neither_array_nor_tuple_c... ArgTypes>
4018 constexpr auto tuple_append(std::array<L, N>
const&
A, ArgTypes&& ... args)
noexcept
4023 return std::array{ std::get<ii_>(
A)..., std::forward<ArgTypes>(args)... };
4025 return std::tuple{ std::get<ii_>(
A)..., std::forward<ArgTypes>(args)... };
4029 template<neither_array_nor_tuple_c... Types>
4033 return std::array{std::forward<Types>(args)...};
4035 return std::tuple{std::forward<Types>(args)...};
4041 template<
typename ContainerType = std::tuple<>,
4042 long long END = std::tuple_size_v<std::remove_cvref_t<ContainerType>>,
4043 typename WorkType = std::tuple<>,
typename... ArgTypes>
4044 requires (tuple_flat_c<ContainerType> || std_array_flat_c<ContainerType>)
4045 void for_workhorse(ContainerType&& container, WorkType&& work, ArgTypes&& ... args)
4048 hidden::for_workhorse<long long, 0ll, END, 1ll>(std::forward<ContainerType>(container),
4050 std::forward<ArgTypes>(args)... );
4053 hidden::for_workhorse<long long, 0ll, END, 1ll>(std::forward<ContainerType>(container),
4054 std::forward<WorkType>(work), make_sequence<long long, 0ll, END, 1ll>{},
4055 std::forward<ArgTypes>(args)... );
4061 template<
typename ContainerType = std::tuple<>,
typename WorkType= std::tuple<>,
4062 long long END = std::tuple_size_v<std::remove_cvref_t<ContainerType>>,
typename... ArgTypes>
4063 requires (variant_flat_c<ContainerType>||
4064 tuple_flat_c<ContainerType> ||
4065 std_array_flat_c<ContainerType>||
4066 c_array_flat_c<ContainerType>||
4067 pair_flat_c<ContainerType>)
4071 hidden::for_workhorse<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4073 std::forward<ArgTypes>(args)... );
4076 hidden::for_workhorse<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4077 make_sequence<long long, 0ll, END, 1ll>{},
4078 std::forward<ArgTypes>(args)... );
4084 template<
int END,
typename WorkType,
typename... ArgTypes>
4088 hidden::for_workhorse<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4090 std::forward<ArgTypes>(args)... );
4093 hidden::for_workhorse<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4094 make_sequence<long long, 0ll, END, 1ll>{},
4095 std::forward<ArgTypes>(args)... );
4101 template<
long long START,
long long END,
typename WorkType,
typename... ArgTypes>
4105 hidden::for_workhorse<
long long, START, END, START < END ? 1ll : -1ll>(std::forward<WorkType>(work),
4106 make_sequence<
long long, START, END, START < END ? 1ll : -1ll>{},
4107 std::forward<ArgTypes>(args)... );
4110 hidden::for_workhorse<
long long, START, END, START < END ? 1ll : -1ll>(std::forward<WorkType>(work),
4111 make_sequence<
long long, START, END, START < END ? 1ll : -1ll>{},
4112 std::forward<ArgTypes>(args)... );
4118 template<
long long START,
long long END,
long long STEP,
4119 typename WorkType,
typename... ArgTypes>
4123 hidden::for_workhorse<long long, START, END, STEP>(std::forward<WorkType>(work),
4125 std::forward<ArgTypes>(args)... );
4128 hidden::for_workhorse<long long, START, END, STEP>(std::forward<WorkType>(work),
4129 make_sequence<long long, START, END, STEP>{},
4130 std::forward<ArgTypes>(args)... );
4136 template<
typename ContainerType,
typename WorkType= std::tuple<>,
4137 long long END = std::tuple_size_v<std::remove_cvref_t<ContainerType>>,
typename... ArgTypes>
4138 requires (variant_flat_c<ContainerType>||
4139 tuple_flat_c<ContainerType> ||
4140 std_array_flat_c<ContainerType>||
4141 c_array_flat_c<ContainerType>||
4142 pair_flat_c<ContainerType>)
4143 constexpr decltype(
auto)
for_stallion(WorkType&& work, ArgTypes&& ... args)
4146 hidden::for_stallion<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4150 return hidden::for_stallion<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4151 make_sequence<long long, 0ll, END, 1ll>{}, std::forward<ArgTypes>(args)... );
4155 template<
typename ContainerType,
typename WorkType= std::tuple<>,
4156 long long END = std::tuple_size_v<std::remove_cvref_t<ContainerType>>,
typename... ArgTypes>
4157 requires (variant_flat_c<ContainerType>||
4158 tuple_flat_c<ContainerType> ||
4159 std_array_flat_c<ContainerType>||
4160 c_array_flat_c<ContainerType>||
4161 pair_flat_c<ContainerType>)
4163 WorkType&& work, ArgTypes&& ... args)
4166 hidden::for_stallion<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4170 return hidden::for_stallion<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4171 make_sequence<long long, 0ll, END, 1ll>{}, std::forward<ArgTypes>(args)... );
4174 template<
long long END,
typename WorkType,
typename... ArgTypes>
4175 constexpr decltype(
auto)
for_stallion(WorkType&& work, ArgTypes&& ... args)
4178 hidden::for_stallion<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4182 return hidden::for_stallion<long long, 0ll, END, 1ll>(std::forward<WorkType>(work),
4183 make_sequence<long long, 0ll, END, 1ll>{}, std::forward<ArgTypes>(args)... );
4186 template<
long long START,
long long END,
typename WorkType,
typename... ArgTypes>
4187 constexpr decltype(
auto)
for_stallion(WorkType&& work, ArgTypes&& ... args)
4190 hidden::for_stallion<
long long, START, END, START < END ? 1ll: -1ll>(std::forward<WorkType>(work),
4191 make_sequence<
long long, START, END, START < END ? 1ll: -1ll>{}, std::forward<ArgTypes>(args)... );
4194 return hidden::for_stallion<
long long, START, END, START < END ? 1ll: -1ll>(std::forward<WorkType>(work),
4195 make_sequence<
long long, START, END, START < END ? 1ll: -1ll>{}, std::forward<ArgTypes>(args)... );
4201 template<
long long START,
long long END,
long long STEP,
4202 typename WorkType,
typename... ArgTypes>
4203 constexpr decltype(
auto)
for_stallion(WorkType&& work, ArgTypes&& ... args)
4206 hidden::for_stallion<long long, START, END, STEP>(std::forward<WorkType>(work),
4210 return hidden::for_stallion<long long, START, END, STEP>(std::forward<WorkType>(work),
4211 make_sequence<long long, START, END, STEP>{}, std::forward<ArgTypes>(args)... );
4214 template<
auto head,
auto... tails>
4220 template<
auto left,
auto... lefts,
auto head,
auto... tails>
4223 if constexpr(
sizeof...(tails) == 0)
4229 template<
auto head,
auto... tails>
4232 if constexpr(
sizeof...(tails)==0)
4238 template<
auto ii,
auto head,
auto... tails>
4241 if constexpr(ii == 0)
4247 template<
auto... ms,
auto...rs>
4253 template<
auto kk,
auto ii = 0,
auto... ms,
auto head,
auto... indices>
4256 if constexpr(ii <
sizeof...(ms))
4265 template<
typename T, T... args>
4268 constexpr auto multipliers =
4271 constexpr auto total =
get_total(dimensions);
4275 return std::tuple{ get_index<ii>(
sequence<1LL>{}, multipliers) ... };
4281 template<
typename WorkType,
typename ... Indices,
typename... ArgTypes>
4283 std::tuple<Indices...> indices, ArgTypes&&... args)
4285 { work(indices, std::forward<ArgTypes>(args)...); }
4287 return work(indices, std::forward<ArgTypes>(args)...);
4292 template<
long long... Ns,
typename WorkType,
typename... ArgTypes>
4304 namespace array_tuple_hidden
4306 template<tuple_flat_c TupleType>
4309 return for_stallion<decltype(tuple)>([&tuple]<
auto...ii>(
sequence<ii...> )
4311 constexpr bool has_common_type =
4314 if constexpr(has_common_type)
4316 using common_t = std::common_type_t< decltype( std::get<ii>(tuple) )... >;
4322 auto to_array = []<
typename Type>(Type&& e)
4327 return std::forward<Type>(e);
4330 return std::array{
static_cast<c_t
>(to_array(std::get<ii>(tuple))) ... };
4334 auto to_array = []<
typename Type>(Type&& e)
4339 return std::forward<Type>(e);
4342 return std::array{ to_array(std::get<ii>(tuple)) ... };
4347 auto to_array = []<
typename Type>(Type&& e)
4352 return std::forward<Type>(e);
4355 return std::tuple{ to_array(std::get<ii>(tuple))... };
4361 template<tuple_flat_c TupleType>
4366 constexpr bool has_common_type =
4369 if constexpr(has_common_type)
4371 using common_t = std::common_type_t< decltype( std::get<ii_>(tuple) )... >;
4377 return std::array{
static_cast<c_t
>(std::get<ii_>(tuple)) ... };
4381 return std::array{ std::get<ii_>(tuple) ... };
4385 return std::forward<TupleType>(tuple);
4391 template<tuple_flat_c TupleType>
4397 template<tuple_flat_c TupleType>
4403 template<
typename... Types>
4406 constexpr long long N =
sizeof...(Types) - 1;
4410 return std::tuple{ std::get<i>(tuple) ... };
4416 template<
typename Type, std::
size_t N>
4419 std::array<Type, N> result = array;
integral_constant< bool, true > true_type
integral_constant< bool, false > false_type
typename enable_if< predicate, ReturnType >::type enable_if_t
debug_exception(std::string message, int lineno, std::string file_name)
virtual const char * what() const noexcept override
virtual ~exit_workhorse()
exit_workhorse(ArgTypes... args)
const auto & tuple() const noexcept
DelimiterType m_delimiter
DelimiterOpen m_open_delimiter
void right_operation(auto &&arg)
OperationType m_operation
fold_visitor(auto arg_count, OperationType opr, DelimiterOpen d_open, DelimiterType del, DelimiterClose d_close)
void left_operation(auto &&arg)
DelimiterClose m_close_delimiter
void right_operation(auto &&arg)
void left_operation(auto &&arg)
DelimiterType m_delimiter
fold_visitor(auto arg_count, OperationType opr, DelimiterType del)
OperationType m_operation
fold_visitor(OperationType opr)
void call_operation(auto &&arg)
#define Cpg_CharStr(asciistr)
#define Cpg_GetTypeName(type_arg,...)
std::common_type_t< S, T > common_t
std::make_signed_t< T > signed_t
constexpr decltype(auto) tuple_to_array_recursive(TupleType &&tuple)
constexpr decltype(auto) tuple_to_array(TupleType &&tuple)
constexpr auto fn_pop_back(type_container< LeftTypes... > left, type_container< > right)
constexpr auto generate_row_column_value()
constexpr auto fn_return_type(FuncType func, type_container< Type, Types... >)
constexpr decltype(auto) for_stallion_tuple(WorkType &&work, std::tuple< Indices... > indices, ArgTypes &&... args)
constexpr auto fn_make_sequence(std::integer_sequence< T, Indices... > seq)
constexpr auto tuple_append(std::tuple< Ls... > const &A, sequence< Li... >, std::tuple< Rs... > const &B, sequence< Ri... >) noexcept
constexpr auto argument_count(FuncType func, type_container< Type, Types... >)
consteval auto fn_make_unique_variant(std::variant< Types... >)
consteval bool fn_all_different()
constexpr decltype(auto) for_stallion(WorkType &&work, std::integer_sequence< T, Indices... >, ArgTypes &&... args)
constexpr auto generate_height_row_column_value()
std::wstring ascii_conversion(std::string const &str)
consteval T compute_last_index()
void for_workhorse(WorkType &&work, std::integer_sequence< T, Indices... >, ArgTypes &&... args)
std::basic_ostream< CharType > & print_type_container(std::basic_ostream< CharType > &os, const type_container< Type, Types... > &tc)
consteval auto fn_type_container_to_variant(types::type_container< Types... >)
types::array_if_all_apply_t< FuncType, ArgTypes... > apply_array(FuncType &&f, ArgTypes &&... args)
constexpr auto get(nontype_container< arg, args... >) noexcept
std::basic_ostream< CharType > & operator<<(std::basic_ostream< CharType > &os, cpg::types::cHarsTR const &charstr)
constexpr bool common_apply_v
void print_args_reverse(auto &&... args)
constexpr decltype(auto) signed_cast(ArgTypes... args)
auto raii_create_object(PointerType object_ptr, FuncType func)
typename hidden::st_pop_front_t< Types... >::type pop_front_t
std::vector< std::common_type_t< apply_return_t< FuncType, TupleTypes >... > > apply_return_vector_t
make_signed_t< std::common_type_t< std::remove_cvref_t< Types >... > > common_signed_t
auto for_vector(FuncType &&f, std::index_sequence< Ints... >)
constexpr decltype(auto) make_span(VectorType &&v)
types::vector_if_all_apply_t< FuncType, ArgTypes... > apply_vector(FuncType &&f, ArgTypes &&... args)
types::type_container< std::string, std::wstring, std::u8string, std::u16string, std::u32string, std::string_view, std::u8string_view, std::u16string_view, std::u32string_view, std::wstring_view > string_containers
constexpr auto operator/(safe_cast_operation< L > const &a, safe_cast_operation< R > const &b) noexcept
types::tuple_if_all_apply_t< FuncType, ArgTypes... > apply_tuple(FuncType &&f, ArgTypes &&... args)
fold_visitor(OperationType) -> fold_visitor< OperationType >
constexpr auto drop_head(sequence< head, tails... >)
std::common_type_t< apply_return_t< FuncType, TupleTypes >... > common_apply_t
std::index_sequence<(std::size_t) Id,(std::size_t) Ids... > index_t
typename hidden::st_pop_back_t< Types... >::type pop_back_t
std::string type_tO_sTring()
constexpr decltype(auto) decay_value(T &&value) noexcept
constexpr auto compute_multipliers(sequence< left, lefts... > result, sequence< head, tails... >)
auto & cast_ref(std::unique_ptr< T[], Deleter > &uptr) noexcept
constexpr auto tuple_append(std::tuple< Ls... > const &A, std::tuple< Rs... > const &B) noexcept
constexpr decltype(auto) for_stallion(WorkType &&work, ArgTypes &&... args)
decltype(generate_height_row_column_value< decltype(Heights), Heights, Rows, Columns >()) create_height_row_column_value_t
decltype(hidden::generate_row_column_value< decltype(Rows), Rows, Columns >()) create_row_column_value_t
constexpr decltype(auto) numeric_cast(S s)
decltype(hidden::fn_make_unique_variant(VariantType{})) make_unique_variant_t
typename hidden::st_make_unique_types< Types... >::type make_unique_types_t
auto for_tuple(FuncType &&f, std::index_sequence< Ints... >)
auto reverse_tuple(std::tuple< Types... > const &tuple)
std::enable_if_t< all_apply_v< FuncType, TupleTypes... >, ReturnType > enable_if_all_apply_t
make_unsigned_t< std::common_type_t< std::remove_cvref_t< Types >... > > common_unsigned_t
enable_if_all_apply_t< apply_return_tuple_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > tuple_if_all_apply_t
constexpr auto element_counts_are_the_same(ContainerTypes &&... containers)
std::basic_ostream< CharType > & operator>>(std::basic_ostream< CharType > &os, nontype_container< args... > nc) noexcept
typename hidden::st_create_sequence< Indices... >::type create_sequence
auto cast_array(T(&array)[N]) noexcept
constexpr bool is_apply_v
constexpr auto get_nth_value(std::integer_sequence< Type, Index, Indices... >) noexcept
constexpr decltype(auto) tuple_to_array(TupleType &&tuple)
typename hidden::st_common_container< S, T >::type common_container_t
constexpr auto create_container(ArgTypes &&... args) noexcept
std::add_pointer_t< std::add_const_t< Type > > const_ptr_t
typename hidden::st_first_element< std::remove_cvref_t< T > >::type first_type_t
decltype(return_type(std::declval< FuncType >(), Type{})) return_type_t
std::tuple< apply_return_t< FuncType, TupleTypes > ... > apply_return_tuple_t
void for_workhorse(ContainerType &&container, WorkType &&work, ArgTypes &&... args)
typename hidden::st_unsigned_type< std::remove_cvref_t< T > >::type make_unsigned_t
typename hidden::st_std_common_array< std::remove_cvref_t< A >, std::remove_cvref_t< B > >::type common_std_array_t
void print_args_inorder(auto &&... args)
range(Type) -> range< Type >
constexpr bool all_apply_v
constexpr auto check_operation_validity(T &&target)
typename hidden::st_common_vector< std::remove_cvref_t< A >, std::remove_cvref_t< B > >::type common_vector_t
constexpr auto argument_count(FuncType func, Type)
enable_if_all_apply_t< void, FuncType, TupleTypes... > void_if_all_apply_t
decltype(hidden::generate_row_column_value< T, Rows, Columns >()) generate_row_column_value
constexpr auto sbo(T &&value) noexcept(!cpg::bDetectOverFlow)
auto for_array(FuncType &&f, std::index_sequence< Ints... >)
constexpr auto operator-(safe_cast_operation< L > const &a, safe_cast_operation< R > const &b) noexcept
constexpr std::enable_if_t< std::is_same_v< std::remove_reference_t< TargetType >, std::remove_reference_t< _Ty > >, std::remove_reference_t< _Ty > && > smart_move(_Ty &&_Arg) noexcept
std::array< std::common_type_t< apply_return_t< FuncType, TupleTypes >... >, sizeof...(TupleTypes)> apply_return_array_t
constexpr auto reverse(sequence< ms... > mm, sequence< rs... >)
enable_if_all_apply_t< apply_return_array_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > array_if_all_apply_t
constexpr decltype(auto) unsigned_cast(ArgTypes... args)
constexpr decltype(auto) for_stallion_tuple(WorkType &&work, ArgTypes &&... args)
std::make_index_sequence<(std::size_t) N > make_index_t
constexpr auto not_a_number() noexcept
void truncation_test(S &&s)
constexpr auto get_total(sequence< head, tails... >)
constexpr auto make_tuple(ArgTypes &&... args) noexcept
std::enable_if_t< common_apply_v< FuncType, TupleTypes... >, std::common_type_t< apply_return_t< FuncType, TupleTypes >... > > common_type_if_all_apply_t
constexpr auto return_type(FuncType func, Type)
constexpr auto difference_absolute(arithmetic_c auto a, arithmetic_c auto b) noexcept
decltype(hidden::generate_height_row_column_value< T, Heights, Rows, Columns >()) generate_height_row_column_value
enable_if_all_apply_t< apply_return_vector_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > vector_if_all_apply_t
void display_nontypes(std::basic_ostream< CharType > &os, nontype_container<>) noexcept
constexpr auto operator+(safe_cast_operation< L > const &a, safe_cast_operation< R > const &b) noexcept
auto reverse_array(std::array< Type, N > const &array)
decltype(hidden::fn_make_sequence< T, START, END, STEP >(std::integer_sequence< T >{})) make_sequence
std::integer_sequence< std::common_type_t< std::remove_cvref_t< decltype(Indices)>... >, Indices... > sequence
constexpr decltype(auto) tuple_to_array_recursive(TupleType &&tuple)
auto make_vector_of_variants(Types... args)
constexpr auto get_index(sequence< head, indices... > index, sequence< ms... > mm)
constexpr std::enable_if_t< std::is_same_v< std::remove_reference_t< TargetType >, std::remove_reference_t< _Ty > >, _Ty && > smart_forward(std::remove_reference_t< _Ty > &_Arg) noexcept
std::make_index_sequence< sizeof...(Types)> index_for
constexpr auto operator*(safe_cast_operation< L > const &a, safe_cast_operation< R > const &b) noexcept
decltype(hidden::fn_apply(std::declval< FuncType >(), std::declval< TupleType >())) apply_return_t
constexpr auto create_tuple_sequence(std::integer_sequence< T, args... > dimensions)
constexpr auto make_array(ArgTypes &&... args) noexcept
typename hidden::st_signed_type< std::remove_cvref_t< T > >::type make_signed_t
Includes subnamespace conversion.
constexpr auto type_max_v
unsigned long long big_unsigned_t
constexpr size_t SelectAll
constexpr size_t InvalidIndex
constexpr const bool bDetectOverFlow
constexpr decltype(auto) apply(F &&f, T(&&c_array)[N])
typename st_common_type_solver< Types... >::type common_type_t
constexpr auto tuple_size_v
Type to string name conversions are defined.
enable_if_all_apply_t< apply_return_tuple_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > tuple_if_all_apply_t
std::common_type_t< apply_return_t< FuncType, TupleTypes >... > common_apply_t
enable_if_variant_t< VariantType > visit(VisitorType &&visitor, VariantType &&vt)
remove_cv_ref_t< Type > remove_cvref_t
enable_if_all_apply_t< apply_return_vector_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > vector_if_all_apply_t
enable_if_all_apply_t< apply_return_array_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > array_if_all_apply_t
static constexpr T column
static constexpr T height
std::common_type_t< S, T > common_t
ContainerTmpl< common_t, M+N > type
ContainerTmpl< common_t, N > type
std::common_type_t< S, T > common_t
std::common_type_t< S, T > common_t
std::conditional_t< std::is_same_v< S, common_t >, ContainerTmpl< S, S_tail... >, ContainerTmpl< T, T_tail... > > type
std::tuple< std::common_type_t< Ss, Ts >... > type
common_signed_t< A, B > type
std::vector< typename st_common_vector< A, B >::type > type
std::vector< std::array< typename st_common_vector< A, B >::type, N > > type
std::vector< std::array< typename st_common_vector< A, B >::type, N > > type
std::vector< typename st_common_vector< A, B >::type > type
std::vector< typename st_common_vector< A, B >::type > type
std::vector< std::array< typename st_common_vector< A, B >::type, N > > type
std::vector< std::array< typename st_common_vector< A, B >::type, N > > type
std::vector< std::array< typename st_common_vector< A, B >::type, N > > type
make_sequence< no_t,(no_t) 0, END, 1 > type
make_sequence< no_t, START,(no_t) END,(no_t) STEP > type
make_sequence< no_t, START,(no_t) END, START< END ?(no_t) 1 :(no_t) -1 > type
std::integer_sequence< long long > type
typename st_make_unique_types< type_container<>, type_container< Type, Types... > >::type type
typename st_make_unique_types< new_left_t, type_container< Second, Tails... > >::type type
typename st_make_unique_types< type_container< LeftTypes... >, type_container< First > >::type new_left_t
std::conditional_t< is_in_type_container_c< Head, type_container< LeftTypes... > >, type_container< LeftTypes... >, type_container< LeftTypes..., Head > > type
typename st_make_unique_types< type_container<>, type_container< Types... > >::type type
decltype(fn_pop_back(type_container<>{}, type_container< Type, Types... >{})) type
decltype(fn_pop_back(type_container<>{}, type_container< Types... >{})) type
typename st_pop_front_t< Types... >::type type
std::make_signed_t< T > type
common_signed_t< A, B > type
std::array< typename st_std_common_array< A, B >::type, N > type
common_signed_t< A, std::tuple_element_t< 0, B > > ele_t
std::array< std::array< ele_t, M >, N > type
std::array< typename st_std_common_array< A, B >::type, N > type
std::array< typename st_std_common_array< A, B >::type, N > type
static constexpr bool value
static constexpr bool value
static constexpr bool value
std::make_unsigned_t< T > type
static constexpr auto end
static constexpr auto step
static constexpr auto start
static constexpr auto last
static constexpr auto value
static constexpr T column
safe_cast_operation(const T &v)
safe_integral_operation(T v)
safe_integral_operation(const T &v)
safe_numerical_operation(T v)
safe_numerical_operation(const T &v)