6#ifndef _CPG_STD_EXTENSIONS_HPP
7#define _CPG_STD_EXTENSIONS_HPP
19 using cgt::common_type_exists_c;
21 #if defined(CPG_INCLUDE_SYCL)
23 template<
typename CharType, auto dims>
24 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
25 sycl::id<dims>
const& ids)
27 if constexpr(dims == 1)
33 else if constexpr (dims == 2)
41 else if constexpr (dims == 3)
52 static_assert(dims <= 3);
57 template<
typename CharType, auto dims>
58 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
59 sycl::range<dims>
const&
range)
61 if constexpr(dims == 1)
67 else if constexpr (dims == 2)
75 else if constexpr (dims == 3)
86 static_assert(dims <= 3);
95 template<
template<
typename,
typename,
typename...>
class ContainerType,
96 typename EleType,
typename Type,
typename ...Types, std::common_with<EleType> S>
97 ContainerType<EleType, Type, Types...>&
98 operator << (ContainerType<EleType, Type, Types...>& container, S&& s)
99 requires requires { container.emplace_back(EleType{}); } ||
100 requires { container.emplace(container.end(), EleType{}); } ||
101 requires { container.emplace(EleType{}); }
105 if constexpr(
requires { container.emplace_back(EleType{}); } )
107 container.emplace_back(cgt::smart_forward<EleType, S>(s));
109 else if constexpr(
requires { container.emplace(container.end(), EleType{}); } )
111 container.emplace(container.end(), cgt::smart_forward<EleType, S>(s));
113 else if constexpr(
requires { container.emplace(EleType{}); } )
115 container.emplace(cgt::smart_forward<EleType, S>(s));
122 template<
template<
typename,
typename,
typename...>
class ContainerType,
123 typename EleType,
typename Type,
typename ...Types, std::common_with<EleType> S>
124 ContainerType<EleType, Type, Types...>&
125 operator >> (ContainerType<EleType, Type, Types...>& container, S&& s)
requires
126 requires { container.emplace_front(EleType{}); } ||
127 requires { container.emplace(container.begin(), EleType{}); } ||
128 requires { container.emplace(EleType{}); }
132 if constexpr(
requires { container.emplace_front(EleType{}); } )
134 container.emplace_front(cgt::smart_forward<EleType, S>(s));
136 else if constexpr(
requires { container.emplace(container.begin(), EleType{}); } )
138 container.emplace(container.begin(), cgt::smart_forward<EleType, S>(s));
140 else if constexpr(
requires { container.emplace(EleType{}); } )
142 container.emplace(cgt::smart_forward<EleType, S>(s));
148 template<
typename Target,
typename Source>
151 { tgt << src } -> std::same_as<Target&>;
154 template<
typename Target,
typename Source>
157 { tgt >> src } -> std::same_as<Target&>;
161 template<
template<
typename,
typename,
typename...>
class ContainerType,
162 typename EleType,
typename Type,
typename ...Types,
163 cgt::view_flat_c ViewType>
164 ContainerType<EleType, Type, Types...>&
165 operator << (ContainerType<EleType, Type, Types...>& container, ViewType&& view)
requires
166 requires { container.emplace_back(EleType{}); } ||
167 requires { container.insert(container.end(), EleType{}); } ||
168 requires { container.emplace(EleType{}); }
170 if constexpr(
requires{ view.empty(); } )
172 if(view.empty())
return container;
175 if constexpr(
requires { container.reserve(std::size_t{1}); view.size(); } )
177 container.reserve(container.size() + view.size());
182 using S =
decltype(s);
186 if constexpr(
requires { container.emplace_back(EleType{}); } )
188 container.emplace_back(cgt::smart_forward<EleType, S>(s));
190 else if constexpr(
requires { container.insert(container.end(), EleType{}); } )
192 container.insert(container.end(), cgt::smart_forward<EleType, S>(s));
194 else if constexpr(
requires { container.emplace(EleType{}); } )
196 container.emplace(cgt::smart_forward<EleType, S>(s));
204 template<
template<
typename,
typename,
typename...>
class ContainerType,
205 typename EleType,
typename Type,
typename ...Types, cgt::view_flat_c ViewType>
206 ContainerType<EleType,
Type, Types...>&
207 operator >> (ContainerType<EleType, Type, Types...>& container, ViewType&& view)
requires
208 requires { container.emplace_front(EleType{}); } ||
209 requires { container.insert(container.begin(), EleType{}); } ||
210 requires { container.emplace(EleType{}); }
212 if constexpr(
requires{ view.empty(); })
214 if(view.empty())
return container;
217 if constexpr(
requires { container.reserve(std::size_t{1}); view.size(); })
219 container.reserve(container.size() + view.size());
224 using S =
decltype(s);
228 if constexpr(
requires { container.emplace_front(EleType{}); } )
230 container.emplace_front(cgt::smart_forward<EleType, S>(s));
232 else if constexpr(
requires { container.insert(container.begin(), EleType{}); } )
234 container.insert(container.begin(), cgt::smart_forward<EleType, S>(s));
236 else if constexpr(
requires { container.emplace(EleType{}); } )
238 container.emplace(cgt::smart_forward<EleType, S>(s));
245 template<
typename CharType> std::basic_ostream<CharType>&
251 template<
typename CharType> std::basic_ostream<CharType>&
257 template<
typename CharType> std::basic_ostream<CharType>&
263 template<
typename CharType> std::basic_ostringstream<CharType>&
266 if constexpr (std::same_as<CharType, char>)
275 os.clear();
return os;
279 template<
typename CharType> std::basic_ostringstream<CharType>&
282 if constexpr(std::same_as<CharType, char>)
296 os.clear();
return os;
299 template<
typename CharType> std::basic_ostringstream<CharType>&
302 if constexpr(std::same_as<CharType, char>)
316 os.clear();
return os;
319 template<
typename CharType> std::basic_ostringstream<CharType>&
322 if constexpr(std::same_as<CharType, char>)
336 os.clear();
return os;
339 template<
typename =
void>
340 std::ostream&
operator<<(std::ostream& os,
const wchar_t* str)
347 template<
typename =
void>
348 std::ostream&
operator<<(std::ostream& os, std::wstring
const& str)
355 template<
typename =
void>
356 std::ostream&
operator<<(std::ostream& os,
const char8_t* str)
363 template<
typename =
void>
364 std::ostream&
operator<<(std::ostream& os, std::u8string
const& str)
371 template<
typename =
void>
372 std::wostream&
operator<<(std::wostream& os,
const char* str)
379 template<
typename =
void>
380 std::wostream&
operator<<(std::wostream& os,
const char8_t* str)
387 template<
typename =
void>
388 std::wostream&
operator<<(std::wostream& os, std::u8string
const& str)
395 template<
typename CharType> std::basic_ostream<CharType>&
397 std::basic_stringstream<CharType>
const&
stream)
404 template<
typename... Ts,
typename... Ss>
407 return std::tuple<Ts..., Ss...>{};
410 template<
typename T,
typename... Ss>
413 return std::tuple< std::tuple<T, Ss>... >{};
416 template<
typename... Ts,
typename... Ss>
419 return std::tuple< std::tuple<Ts..., Ss>... >{};
422 template<
typename... TT,
typename T,
typename... Ts,
typename... Ss>
425 if constexpr(
sizeof...(Ts) != 0)
433 template<cgt::tuple_flat_c T, cgt::tuple_flat_c S, cgt::tuple_flat_c ... Tails>
436 if constexpr(
sizeof...(tails) > 0)
448 template<
typename TupleA,
typename... TupleTypes>
453 template<
typename TupleA,
typename... TupleTypes>
455 std::remove_cvref_t<TupleTypes>...>;
457 template<
typename TupleA,
typename... TupleTypes>
462 template<
typename L,
typename R>
468 template<
typename... Ls,
typename... Rs>
475 std::tuple_element_t<i, std::tuple<Rs...>>{})... };
479 template<
typename TupleA,
typename TupleB>
482 template<
typename L,
typename R>
488 template<
typename... Ls,
typename... Rs>
495 std::tuple_element_t<i, std::tuple<Rs...>>{})... };
499 template<cgt::tuple_flat_c TupleA, cgt::tuple_flat_c TupleB>
502 template<cgt::tuple_flat_c TupleType>
508 template<cgt::tuple_flat_c TupleA, cgt::tuple_flat_c TupleB, cgt::tuple_flat_c... TupleTypes>
511 if constexpr(
sizeof...(Tuples) == 0)
517 template<cgt::tuple_flat_c TupleType>
523 template<cgt::tuple_flat_c TupleA, cgt::tuple_flat_c TupleB, cgt::tuple_flat_c... TupleTypes>
526 if constexpr(
sizeof...(Tuples) == 0)
533 template<cgt::tuple_flat_c TupleType, cgt::tuple_flat_c... TupleTypes>
537 template<cgt::tuple_flat_c TupleType, cgt::tuple_flat_c... TupleTypes>
543 template<cgt::tuple_flat_c TupleType, cgt::tuple_flat_c... TupleTypes>
546 std::remove_cvref_t<TupleTypes>...>;
549 template<cgt::tuple_flat_c TupleType, cgt::tuple_flat_c... TupleTypes>
552 template<
typename CharType,
typename Type>
553 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
554 const std::optional<Type>& opt);
556 template<
typename CharType,
typename FirstType,
typename SecondType>
557 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
558 const std::pair<FirstType, SecondType>& pr)
565 template<
typename CharType,
typename... Types>
566 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
567 const std::tuple<Types...>& container);
569 template<
typename CharType,
typename Type,
typename... Types>
570 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
571 const std::variant<Type, Types...>& v);
573 template<
typename CharType,
typename ContainerType>
574 requires (cgt::std_array_flat_c< ContainerType >
575 || cgt::span_flat_c< ContainerType >
576 || ( cgt::c_array_flat_c<ContainerType> && cgt::non_chars_c<ContainerType> ) )
577 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
578 ContainerType&& container);
580 template <
class F,
typename T, std::
size_t N>
581 constexpr decltype(
auto)
apply(F&& f, T(&&c_array)[N]);
583 template <
class F,
typename T, std::
size_t N>
584 constexpr decltype(
auto)
apply(F&& f, T(&c_array)[N]);
586 template< std::
size_t I,
class T, std::
size_t N >
587 constexpr decltype(
auto)
get( T(&c_array)[N])
noexcept;
589 template< std::
size_t I,
class T, std::
size_t N >
590 constexpr decltype(
auto)
get( T(&&c_array)[N])
noexcept;
592 template<
typename CharType,
typename T, T... Indices> std::basic_ostream<CharType>&
594 std::integer_sequence<T, Indices...>
const& seq)
noexcept;
596 template<
typename CharType,
typename T> std::basic_ostream<CharType>&
597 operator >> (std::basic_ostream<CharType>& os, T
const& t);
599 template<
typename CharType,
typename... Types> std::basic_ostream<CharType>&
600 operator >> (std::basic_ostream<CharType>& os, std::tuple<Types...>
const& t);
604 template<
typename... Ls,
typename... Rs>
608 [&]<
typename... seqs>( std::tuple<seqs...>)
615 if constexpr(cgt::all_the_same_flat_c<
decltype(append(seqs{}))...>)
616 return std::array{ append(seqs{})... };
618 return std::tuple{ append(seqs{})... };
622 template<
typename... Ls,
typename R, std::size_t N2>
626 [&]<
typename... seqs>( std::tuple<seqs...>)
633 if constexpr(cgt::all_the_same_flat_c<
decltype(append(seqs{}))... >)
634 return std::array{ append(seqs{})... };
636 return std::tuple{ append(seqs{})... };
640 template<
typename L, std::size_t N1,
typename... Rs>
644 [&]<
typename... seqs>( std::tuple<seqs...>)
651 if constexpr(cgt::all_the_same_flat_c<
decltype(append(seqs{}))... >)
652 return std::array{ append(seqs{})... };
654 return std::tuple{ append(seqs{})... };
658 template<
typename L, std::
size_t N1,
typename R, std::
size_t N2>
661 return cgt::for_stallion_tuple<N1, N2>(
662 [&]<
typename... seqs>( std::tuple<seqs...>)
669 if constexpr(cgt::all_the_same_flat_c<
decltype(append(seqs{}))... >)
670 return std::array{ append(seqs{})... };
672 return std::tuple{ append(seqs{})... };
678 template<cgt::either_array_or_tuple_flat_c T, cgt::either_array_or_tuple_flat_c S,
679 cgt::either_array_or_tuple_flat_c... Tails>
682 if constexpr(
sizeof...(Tails) > 0 )
692 template<
typename CharType,
typename T> std::basic_ostream<CharType>&
695 using flat_t = std::remove_cvref_t<T>;
699 if constexpr(std::same_as<CharType, char>)
707 template<
typename CharType,
typename... Types> std::basic_ostream<CharType>&
708 operator >> (std::basic_ostream<CharType>& os, std::tuple<Types...>
const& t)
710 if constexpr(
sizeof...(Types) != 0)
714 cgt::for_workhorse<decltype(t)>([&os](
auto i)
717 std::tuple_element_t<(std::size_t)i.value, std::tuple<Types...>>;
734 template<std::
size_t SIZE,
typename CharType>
743 template<
typename CharType,
typename T, T... Indices> std::basic_ostream<CharType>&
745 std::integer_sequence<T, Indices...>
const& seq)
noexcept
747 if constexpr(
sizeof...(Indices) < 1 )
753 if constexpr(std::same_as<CharType, char>)
764 constexpr auto SIZE =
sizeof...(Indices);
765 std::size_t
count = 0;
771 if constexpr(std::same_as<CharType, char>)
778 ( hidden::print_sequence<SIZE>(os, Indices, ++
count) , ... );
797 template< std::
size_t I,
class T, std::
size_t N >
798 constexpr decltype(
auto)
get( T(&c_array)[N])
noexcept
803 template< std::
size_t I,
class T, std::
size_t N >
804 constexpr decltype(
auto)
get( T(&&c_array)[N])
noexcept
806 return std::move(c_array[I]);
826 template <
class F,
typename T, std::
size_t N>
827 constexpr decltype(
auto)
apply(F&& f, std::span<T, N>& sp)
831 return std::apply( std::forward<F>(f), std::forward_as_tuple(sp[i]...));
835 template <
class F,
typename T, std::
size_t N>
836 constexpr decltype(
auto)
apply(F&& f,
const std::span<T, N>& sp)
840 return std::apply( std::forward<F>(f), std::forward_as_tuple(sp[i]...));
844 template <
class F,
typename T, std::
size_t N>
845 constexpr decltype(
auto)
apply(F&& f, std::span<T, N>&& sp)
849 return std::apply( std::forward<F>(f), std::forward_as_tuple(sp[i]...));
859 template<
typename CharType,
typename Type>
860 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
861 const std::optional<Type>& opt)
871 template<
typename CharType, cgt::stream_undefined_container_flat_c ContainerType>
872 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
873 ContainerType&& container)
875 if(container.empty())
881 auto begin = container.begin();
882 auto last = container.end();
884 std::advance(last, -1);
888 for(
auto itr = begin; itr != last; ++itr)
898 template<
typename CharType, cgt::view_flat_c ViewType> std::basic_ostream<CharType>&
899 operator<<(std::basic_ostream<CharType>& os, ViewType&& view)
901 if constexpr(
requires{ view.empty(); } )
923 template<
typename CharType, cgt::map_c ContainerType>
924 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
925 const ContainerType& container)
927 if(container.empty())
933 if constexpr(cgt::std_map_c<ContainerType>)
935 auto begin = container.begin();
936 auto last = container.end();
938 std::advance(last, -1);
942 for(
auto itr = begin; itr != last; ++itr)
949 else if constexpr(cgt::tbb_map_c<ContainerType>)
951 auto begin = container.begin();
952 auto last = container.end();
954 std::advance(last, -1);
958 for(
auto itr = begin; itr != last; ++itr)
974 template<
typename CharType,
typename ContainerType>
975 requires (cgt::std_array_flat_c< ContainerType >
976 || cgt::span_flat_c< ContainerType >
977 || ( cgt::c_array_flat_c<ContainerType> && cgt::non_chars_c<ContainerType> ) )
978 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
979 ContainerType&& container)
981 auto begin = std::ranges::begin(container);
982 auto last = std::ranges::end(container);
994 for(
auto itr = begin; itr != last; ++itr)
1005 template<
size_t Index,
typename CharType,
typename... Types>
1007 const std::tuple<Types...>& container)
1009 constexpr size_t Size =
sizeof...(Types);
1011 if constexpr ( Index < Size-1 )
1013 os << std::get<Index>(container) <<
Cpg_CharStr(
", ");
1014 print_tuple< Index + 1>(os, container);
1016 else if constexpr(Index == Size - 1)
1018 os << std::get<Index>(container);
1023 template<
typename CharType,
typename... Types>
1024 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
1025 const std::tuple<Types...>& container)
1027 if constexpr(
sizeof...(Types) == 0)
1034 hidden::print_tuple<0>(os, container);
1041 template<
typename CharType,
typename Type,
typename... Types>
1042 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& os,
1043 const std::variant<Type, Types...>& v)
1045 auto visit_target = [&os]<
typename T>(T&& value) -> std::basic_ostream<CharType>&
1047 if constexpr( cgt::ostream_operator_available_c< std::remove_cvref_t<T>, CharType>)
1051 if constexpr(std::same_as<CharType, char>)
1054 <<
" does not support ostream operator<<()" <<
std::endl;
1060 << L
" does not support ostream operator<<()" <<
std::endl;
1070 #ifdef _TPF_TYPES_HPP
1072 template<
typename CharType, std::
size_t N,
typename T,
typename deleter>
1073 std::basic_ostream<CharType>&
operator << (std::basic_ostream<CharType>& os,
1076 os << upw.
ref();
return os;
#define Cpg_CharStr(asciistr)
#define Cpg_GetTypeCategory(instance_arg,...)
#define Tpf_TestTrunction(TargetType, SourceValue)
#define Cpg_GetTypeName(type_arg,...)
String conversions are implemented.
std::string utf16_to_windows_codepage(const std::wstring &utf16_string)
Converts UTF16 std::wstring to Windows codepage std::string.
std::wstring utf8_to_utf16(const std::string &utf8str)
Converts UTF8 std::string to UTF16 std::wstring.
std::wstring windows_codepage_to_utf16(const std::string &codepage_string)
Converts Windows codepage std::string to utf16 std::wstring.
std::string utf8_to_windows_codepage(const std::string &utf8_string)
Converts UTF8 std::string to Windows codepage string.
constexpr decltype(auto) for_stallion_tuple(WorkType &&work, std::tuple< Indices... > indices, ArgTypes &&... args)
constexpr auto tuple_append(std::tuple< Ls... > const &A, sequence< Li... >, std::tuple< Rs... > const &B, sequence< Ri... >) noexcept
constexpr decltype(auto) for_stallion(WorkType &&work, std::integer_sequence< T, Indices... >, ArgTypes &&... args)
std::wstring ascii_conversion(std::string const &str)
make_signed_t< std::common_type_t< std::remove_cvref_t< Types >... > > common_signed_t
make_unsigned_t< std::common_type_t< std::remove_cvref_t< Types >... > > common_unsigned_t
std::integer_sequence< std::common_type_t< std::remove_cvref_t< decltype(Indices)>... >, Indices... > sequence
constexpr auto tuple_connect_tail(std::tuple< Ts... >, std::tuple< Ss... >)
decltype(hidden::fn_common_unsigned_tuples(TupleType{}, TupleTypes{}...)) common_unsigned_tuple_t
decltype(fn_common_unsigned_tuple(TupleA{}, TupleB{})) common_unsigned_tuple_pair
constexpr auto tuple_pairs(std::tuple< Ts... >, std::tuple< Ss... >)
constexpr auto fn_common_unsigned_tuples(TupleA A, TupleB B, TupleTypes... Tuples)
constexpr auto fn_common_signed_tuple(std::tuple< Ls... > L, std::tuple< Rs... > R)
decltype(fn_common_signed_tuple(TupleA{}, TupleB{})) common_signed_tuple_pair
decltype((TupleA{} > > ... > > TupleTypes{})) tuple_cross_product_t
void print_tuple(std::basic_ostream< CharType > &os, const std::tuple< Types... > &container)
void print_sequence(std::basic_ostream< CharType > &os, auto Index, auto count)
decltype(hidden::fn_common_signed_tuples(TupleType{}, TupleTypes{}...)) common_signed_tuple_t
constexpr auto fn_common_unsigned_tuple(std::tuple< Ls... > L, std::tuple< Rs... > R)
constexpr auto fn_common_signed_tuples(TupleA A, TupleB B, TupleTypes... Tuples)
constexpr auto fn_tuple_cross_product(std::tuple< TT... > tt, std::tuple< T, Ts... > t, std::tuple< Ss... > s)
std::basic_ostream< CharType > & operator>>(std::basic_ostream< CharType > &os, std::tuple< Types... > const &t)
hidden::common_unsigned_tuple_t< TupleType, TupleTypes... > common_unsigned_tuple_t
hidden::common_signed_tuple_t< std::remove_cvref_t< TupleType >, std::remove_cvref_t< TupleTypes >... > common_signed_tuple_t
constexpr decltype(auto) tuple_cartesian_product(T &&A, S &&B, Tails &&... tails)
constexpr decltype(auto) get(T(&&c_array)[N]) noexcept
tuple_cross_product_t< TupleA, TupleTypes... > tuple_cartesian_product_t
constexpr decltype(auto) apply(F &&f, std::span< T, N > &&sp)
hidden::tuple_cross_product_t< std::remove_cvref_t< TupleA >, std::remove_cvref_t< TupleTypes >... > tuple_cross_product_t
constexpr auto tuple_cartesian_product_type(T A, S B, Tails... tails)
std::basic_ostream< CharType > & operator<<(std::basic_ostream< CharType > &os, const ContainerType &container)
enable_if_variant_t< VariantType > visit(VisitorType &&visitor, VariantType &&vt)