4#ifndef _Stroika_Foundation_Common_StdCompat_h_
5#define _Stroika_Foundation_Common_StdCompat_h_ 1
7#include "Stroika/Foundation/StroikaPreComp.h"
26#if qStroika_HasComponent_fmtlib
27#include <fmt/chrono.h>
28#include <fmt/format.h>
30#elif __has_include(<format>)
48namespace Stroika::Foundation::Common::StdCompat {
55#if qStroika_HasComponent_fmtlib
56#define qStroika_Foundation_Characters_FMT_PREFIX_ fmt
57#elif __has_include(<format>)
58#define qStroika_Foundation_Characters_FMT_PREFIX_ std
60 static_assert (
false,
"Stroika v3 requires some std::format compatible library - if building with one lacking builtin std::format, "
61 "configure --fmtlib use");
68 using qStroika_Foundation_Characters_FMT_PREFIX_::basic_format_parse_context;
69 using qStroika_Foundation_Characters_FMT_PREFIX_::format;
70 using qStroika_Foundation_Characters_FMT_PREFIX_::format_args;
71 using qStroika_Foundation_Characters_FMT_PREFIX_::format_error;
72 using qStroika_Foundation_Characters_FMT_PREFIX_::format_string;
73 using qStroika_Foundation_Characters_FMT_PREFIX_::format_to;
74 using qStroika_Foundation_Characters_FMT_PREFIX_::make_format_args;
75 using qStroika_Foundation_Characters_FMT_PREFIX_::make_wformat_args;
76 using qStroika_Foundation_Characters_FMT_PREFIX_::vformat;
77 using qStroika_Foundation_Characters_FMT_PREFIX_::wformat_args;
78 using qStroika_Foundation_Characters_FMT_PREFIX_::wformat_string;
80#if __cplusplus >= kStrokia_Foundation_Common_cplusplus_23 || _HAS_CXX23
81 template <
class T,
class CharT>
82 concept formattable = std::formattable<T, CharT>;
85 template <
class _CharT>
86 struct _Phony_fmt_iter_for {
87 using difference_type = ptrdiff_t;
88 _CharT& operator* ()
const;
89 _Phony_fmt_iter_for& operator++ ();
90 _Phony_fmt_iter_for operator++ (
int);
93 template <
class _Ty,
class _Context,
class _Formatter =
typename _Context::
template formatter_type<remove_const_t<_Ty>>>
94 concept _Formattable_with = semiregular<_Formatter> &&
requires (_Formatter& __f,
const _Formatter& __cf, _Ty&& __t, _Context __fc,
95 basic_format_parse_context<typename _Context::char_type> __pc) {
96 { __f.parse (__pc) } -> same_as<
typename decltype (__pc)::iterator>;
97 { __cf.format (__t, __fc) } -> same_as<typename _Context::iterator>;
100 template <
class T,
class CharT>
101 concept formattable =
102 Private_::_Formattable_with<remove_reference_t<T>, qStroika_Foundation_Characters_FMT_PREFIX_::basic_format_context<Private_::_Phony_fmt_iter_for<CharT>, CharT>>;
108#if __cpp_lib_bit_cast >= 201806L
111 template <
class To,
class From>
113 requires (
sizeof (To) ==
sizeof (From) && std::is_trivially_copyable_v<From> && std::is_trivially_copyable_v<To>)
115 static_assert (std::is_trivially_constructible_v<To>,
"This implementation additionally requires "
116 "destination type to be trivially constructible");
118 std::memcpy (&dst, &src,
sizeof (To));
126#if __cpp_lib_byteswap >= 202110L
132 DISABLE_COMPILER_GCC_WARNING_START (
"GCC diagnostic ignored \"-Warray-bounds\"");
133 static_assert (std::has_unique_object_representations_v<T>,
"T may not have padding bits");
134 auto value_representation =
bit_cast<array<byte,
sizeof (T)>> (n);
135 for (
size_t i = 0; i < value_representation.size () / 2; ++i) {
136 swap (value_representation[i], value_representation[value_representation.size () - i]);
138 return bit_cast<T> (value_representation);
139 DISABLE_COMPILER_GCC_WARNING_END (
"GCC diagnostic ignored \"-Warray-bounds\"");
146 template <
typename T>
147#if __cplusplus >= kStrokia_Foundation_Common_cplusplus_23 || _MSVC_LANG >= kStrokia_Foundation_Common_cplusplus_23
155#if qCompilerAndStdLib_fpclasifyEtcOfInteger_Buggy
156 if constexpr (integral<T>) {
161 return std::isinf (v);
167 template <
typename T>
168#if __cplusplus >= kStrokia_Foundation_Common_cplusplus_23
176#if qCompilerAndStdLib_fpclasifyEtcOfInteger_Buggy
177 if constexpr (integral<T>) {
182 return std::isnan (v);
185#if qCompilerAndStdLib_stdlib_compare_three_way_present_but_Buggy
186 struct compare_three_way {
188 template <
typename LT,
typename RT>
189 constexpr auto operator() (LT&& lhs, RT&& rhs)
const
191 using CT = common_type_t<LT, RT>;
192 if (equal_to<CT>{}(forward<LT> (lhs), forward<RT> (rhs))) {
193 return strong_ordering::equal;
195 return less<CT>{}(forward<LT> (lhs), forward<RT> (rhs)) ? strong_ordering::less : strong_ordering::greater;
197 using is_transparent = void;
200 using compare_three_way = std::compare_three_way;
206#if __cpp_lib_expected
207 template <
typename T>
208 using unexpected = std::unexpected<T>;
209 template <
typename T,
typename E>
210 using expected = std::expected<T, E>;
212 template <
typename T>
215 template <
typename _UError = T>
216 requires (!is_same_v<remove_cvref_t<_UError>,
unexpected> && !is_same_v<remove_cvref_t<_UError>, in_place_t> && is_constructible_v<T, _UError>)
217 constexpr explicit unexpected (_UError&& _Unex)
218 : _Unexpected (forward<_UError> (_Unex))
221 template <
typename... _Args>
222 requires is_constructible_v<T, _Args...>
223 constexpr explicit unexpected (in_place_t, _Args&&... _Vals)
224 : _Unexpected (forward<_Args> (_Vals)...)
227 template <
typename _Uty,
typename... _Args>
228 requires is_constructible_v<T, initializer_list<_Uty>&, _Args...>
229 constexpr explicit unexpected (in_place_t, initializer_list<_Uty> _Ilist, _Args&&... _Vals)
230 : _Unexpected (_Ilist, forward<_Args> (_Vals)...)
234 constexpr const T& error ()
const&
noexcept
238 constexpr T& error () &
noexcept
242 constexpr const T&& error ()
const&&
noexcept
244 return std::move (_Unexpected);
246 constexpr T&& error () &&
noexcept
248 return std::move (_Unexpected);
254 swap (_Unexpected, _Other._Unexpected);
258 requires is_swappable<T>::value
263 template <
class _UErr>
266 return _Left._Unexpected == _Right.error ();
272 template <
typename T>
281 template <
typename T,
typename E>
283 template <
typename T,
typename E>
286 using value_type = T;
287 using error_type = E;
290 constexpr expected ()
noexcept =
default;
300 template <
typename T1,
typename E1>
310 explicit operator bool ()
const noexcept
312 return std::get_if<T> (&fData_) !=
nullptr;
320 return get<T> (fData_);
324 return get<E> (fData_);
328 variant<T, E> fData_;
339#include "StdCompat.inl"
constexpr bool isnan(T v) noexcept
To bit_cast(const From &src) noexcept
constexpr bool isinf(T v) noexcept