24inline constexpr bool wchar_is_u16 =
sizeof(wchar_t) == 2;
26using wchar_type = std::conditional<wchar_is_u16, char16_t, char32_t>::type;
28inline wchar_type* to_w(
wchar_t* p) {
29 return (
reinterpret_cast<wchar_type*
>(p));
32inline const wchar_type* to_w(
const wchar_t* p) {
33 return (
reinterpret_cast<const wchar_type*
>(p));
36inline wchar_t* from_w(wchar_type* p) {
37 return (
reinterpret_cast<wchar_t*
>(p));
40inline const wchar_t* from_w(
const wchar_type* p) {
41 return (
reinterpret_cast<const wchar_t*
>(p));
49using uu8s = std::make_unsigned<u8s>::type;
52inline constexpr bool is_one_of_char_v = std::is_same_v<K, u8s> || std::is_same_v<K, wchar_t> || std::is_same_v<K, u16s> || std::is_same_v<K, u32s>;
55inline constexpr bool is_one_of_std_char_v = std::is_same_v<K, u8s> || std::is_same_v<K, wchar_t> || std::is_same_v<K, wchar_type>;
57template<
typename From>
58requires (is_one_of_std_char_v<From>)
59auto to_one_of_std_char(From* from) {
60 if constexpr (std::is_same_v<From, u8s> || std::is_same_v<From, wchar_t>) {
66template<
typename From>
67requires (is_one_of_std_char_v<From>)
68auto to_one_of_std_char(
const From* from) {
69 if constexpr (std::is_same_v<From, u8s> || std::is_same_v<From, wchar_t>) {
122template<
typename T>
struct const_lit;
125template<
typename T,
size_t N>
126 requires(is_one_of_char_v<T>)
127struct const_lit<
const T(&)[N]> {
129 constexpr static size_t Count = N;
134template<
typename K,
typename T>
struct const_lit_for;
136template<
typename K,
size_t N>
137 requires(is_one_of_char_v<K>)
138struct const_lit_for<K,
const K(&)[N]> {
139 constexpr static size_t Count = N;
142template<
typename K,
size_t N>
143class const_lit_to_array {
146 size_t find(K s)
const {
147 if constexpr (Idx < N) {
148 return s == symbols_[Idx] ? Idx : find<Idx + 1>(s);
154 bool exist(K s)
const {
155 if constexpr (Idx < N) {
156 return s == symbols_[Idx] || exist<Idx + 1>(s);
161 const K (&symbols_)[N + 1];
163 template<typename T, size_t M = const_lit_for<K, T>::Count>
requires (M == N + 1)
164 constexpr const_lit_to_array(T&& s)
167 constexpr bool contain(K s)
const {
170 constexpr size_t index_of(K s)
const {
196template<
typename A,
typename K>
198 { a.is_empty() } -> std::same_as<bool>;
199 { a.length() } -> std::convertible_to<size_t>;
200 { a.symbols() } -> std::same_as<const K*>;
201} && std::is_same_v<typename std::remove_cvref_t<A>::symb_type, K>;
322 typename A::symb_type;
323 { a.length() } -> std::convertible_to<size_t>;
324 { a.place(std::declval<typename A::symb_type*>()) } -> std::same_as<typename A::symb_type*>;
338template<
typename A,
typename K>
372template<StrExpr A, StrExprForType<
typename A::symb_type> B>
374 using symb_type =
typename A::symb_type;
377 constexpr strexprjoin(
const A& a_,
const B& b_) : a(a_), b(b_){}
378 constexpr size_t length()
const noexcept {
379 return a.length() + b.length();
381 constexpr symb_type* place(symb_type* p)
const noexcept {
382 return b.place(a.place(p));
384 constexpr symb_type* len_and_place(symb_type* p)
const noexcept {
414template<StrExpr A, StrExprForType<
typename A::symb_type> B>
439template<StrExpr A, StrExprForType<
typename A::symb_type> B,
bool last = true>
440struct strexprjoin_c {
441 using symb_type =
typename A::symb_type;
444 template<
typename... Args>
445 constexpr strexprjoin_c(
const A& a_, Args&&... args_) : a(a_), b(std::forward<Args>(args_)...) {}
446 constexpr size_t length()
const noexcept {
447 return a.length() + b.length();
449 constexpr symb_type* place(symb_type* p)
const noexcept {
450 if constexpr (last) {
451 return b.place(a.place(p));
453 return a.place(b.place(p));
456 constexpr symb_type* len_and_place(symb_type* p)
const noexcept {
463template<
typename T,
typename K = void,
typename... Types>
464struct is_one_of_type {
465 static constexpr bool value = std::is_same_v<T, K> || is_one_of_type<T, Types...>::value;
468struct is_one_of_type<T, void> : std::false_type {};
509 constexpr size_t length()
const noexcept {
512 constexpr symb_type* place(symb_type* p)
const noexcept {
546 expr_char(K v) : value(v){}
547 constexpr size_t length() const noexcept {
550 constexpr symb_type* place(symb_type* p)
const noexcept {
568template<
typename K, StrExprForType<K> A>
585 return expr_char<K>{s};
588template<
typename K,
size_t N>
591 const K (&str)[N + 1];
592 constexpr size_t length() const noexcept {
595 constexpr symb_type* place(symb_type* p)
const noexcept {
596 if constexpr (N != 0)
597 std::char_traits<K>::copy(p, str, N);
654template<typename T, size_t N = const_lit<T>::Count>
655constexpr inline auto e_t(T&& s) {
656 return expr_literal<typename const_lit<T>::symb_type,
static_cast<size_t>(N - 1)>{s};
659template<
bool first,
typename K,
size_t N,
typename A>
660struct expr_literal_join {
662 const K (&str)[N + 1];
664 constexpr size_t length() const noexcept {
665 return N + a.length();
667 constexpr symb_type* place(symb_type* p)
const noexcept {
668 if constexpr (N != 0) {
669 if constexpr (first) {
670 std::char_traits<K>::copy(p, str, N);
671 return a.place(p + N);
674 std::char_traits<K>::copy(p, str, N);
681 constexpr symb_type* len_and_place(symb_type* p)
const noexcept {
694template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
696 return expr_literal_join<
false, K, (N - 1), A>{s, a};
706template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
708 return expr_literal_join<
true, K, (N - 1), A>{s, a};
724template<
typename K,
size_t N,
size_t S = ' '>
727 constexpr size_t length()
const noexcept {
730 constexpr symb_type* place(symb_type* p)
const noexcept {
731 if constexpr (N != 0)
732 std::char_traits<K>::assign(p, N,
static_cast<K
>(S));
789 constexpr size_t length()
const noexcept {
792 constexpr symb_type* place(symb_type* p)
const noexcept {
794 std::char_traits<K>::assign(p, len, s);
813constexpr inline auto e_c(
size_t l, K s) {
830template<StrExpr A, StrExprForType<
typename A::symb_type> B>
832 using symb_type =
typename A::symb_type;
838 constexpr size_t length()
const noexcept {
839 return choice ? a.length() : b.length();
841 constexpr symb_type* place(symb_type* ptr)
const noexcept {
842 return choice ? a.place(ptr) : b.place(ptr);
859 using symb_type =
typename A::symb_type;
864 constexpr size_t length()
const noexcept {
865 return choice ? a.length() : 0;
867 constexpr symb_type* place(symb_type* ptr)
const noexcept {
868 return choice ? a.place(ptr) : ptr;
918template<StrExpr A,
size_t N,
bool Compare>
920 using symb_type =
typename A::symb_type;
921 const symb_type (&str)[N + 1];
925 constexpr size_t length()
const noexcept {
926 return choice == Compare ? a.length() : N;
928 constexpr symb_type* place(symb_type* ptr)
const noexcept {
929 if (choice == Compare) {
932 if constexpr (N != 0) {
933 std::char_traits<symb_type>::copy(ptr, str, N);
983template<
typename K,
size_t N,
size_t M>
986 const symb_type (&str_a)[N + 1];
987 const symb_type (&str_b)[M + 1];
990 constexpr size_t length()
const noexcept {
991 return choice ? N : M;
993 constexpr symb_type* place(symb_type* ptr)
const noexcept {
995 if constexpr (N != 0) {
996 std::char_traits<symb_type>::copy(ptr, str_a, N);
1000 if constexpr (M != 0) {
1001 std::char_traits<symb_type>::copy(ptr, str_b, M);
1036template<StrExpr A, StrExprForType<
typename A::symb_type> B>
1037inline constexpr auto e_choice(
bool c,
const A& a,
const B& b) {
1046template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
1047inline constexpr auto e_choice(
bool c,
const A& a, T&& str) {
1056template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
1057inline constexpr auto e_choice(
bool c, T&& str,
const A& a) {
1065template<typename T, typename L, size_t N = const_lit<T>::Count,
size_t M = const_lit_for<typename const_lit<T>::symb_type, L>::Count>
1066inline constexpr auto e_choice(
bool c, T&& str_a, L&& str_b) {
1113inline constexpr auto e_if(
bool c,
const A& a) {
1121template<typename T, size_t N = const_lit<T>::Count>
1122inline constexpr auto e_if(
bool c, T&& str) {
1123 const typename const_lit<T>::symb_type empty[1] = {0};
1136template<
typename K,
typename T>
1138 using symb_type = K;
1141 expr_stdstr(
const T& t) : t_(t){}
1143 constexpr size_t length()
const noexcept {
1146 constexpr symb_type* place(symb_type* p)
const noexcept {
1147 size_t s = t_.size();
1148 std::char_traits<K>::copy(p, (
const K*)t_.data(), s);
1158template<StrExprForType<u8s> A>
1168template<StrExprForType<u8s> A>
1178template<StrExprForType<u8s> A>
1188template<StrExprForType<u8s> A>
1198template<StrExprForType<uws> A>
1208template<StrExprForType<uws> A>
1218template<StrExprForType<uws> A>
1228template<StrExprForType<uws> A>
1240template<StrExprForType<
wchar_type> A>
1241auto operator+(
const A& a,
const std::wstring& s) {
1242 return strexprjoin_c<A, expr_stdstr<wchar_type, std::wstring>,
true>{a, s};
1252template<StrExprForType<
wchar_type> A>
1253auto operator+(
const std::wstring& s,
const A& a) {
1264template<StrExprForType<
wchar_type> A>
1265auto operator+(
const A& a,
const std::wstring_view& s) {
1276template<StrExprForType<
wchar_type> A>
1277auto operator+(
const std::wstring_view& s,
const A& a) {
The concept of a string expression of a given character type.
Definition strexpr.h:339
Concept of "String Expressions".
Definition strexpr.h:321
Base concept of string object.
Definition strexpr.h:197
constexpr auto e_spca()
Generates a string of N char spaces.
Definition strexpr.h:751
constexpr auto e_char(K s)
Generates a string of 1 given character.
Definition strexpr.h:584
constexpr empty_expr< uws > eew
Empty string expression of type wchar_t.
Definition strexpr.h:528
constexpr auto e_c(size_t l, K s)
Generates a string of l characters s of type K.
Definition strexpr.h:813
constexpr empty_expr< u32s > eeuu
Empty string expression of type char32_t.
Definition strexpr.h:540
constexpr auto e_t(T &&s)
Converts a string literal to a string expression.
Definition strexpr.h:655
constexpr auto e_choice(bool c, const A &a, const B &b)
Create a conditional string expression expr_choice.
Definition strexpr.h:1037
constexpr auto e_if(bool c, const A &a)
Creating a conditional string expression expr_if.
Definition strexpr.h:1113
constexpr empty_expr< u8s > eea
Empty string expression of type char.
Definition strexpr.h:522
constexpr empty_expr< u16s > eeu
Empty string expression of type char16_t.
Definition strexpr.h:534
constexpr auto operator+(const A &a, T s)
Concatenation operator for string expression and integer.
Definition sstring.h:5660
constexpr auto e_spcw()
Generates a string of N wchar_t spaces.
Definition strexpr.h:769
Library namespace.
Definition sstring.cpp:10
An "empty" string expression.
Definition strexpr.h:507
Conditional selection string expression.
Definition strexpr.h:919
Conditional selection string expression.
Definition strexpr.h:984
Conditional selection string expression.
Definition strexpr.h:831
Conditional selection string expression.
Definition strexpr.h:858
A type of string expression that returns N specified characters.
Definition strexpr.h:785
A type of string expression that returns N specified characters.
Definition strexpr.h:725
Concatenation of a reference to a string expression and the value of the string expression.
Definition strexpr.h:440
Template class for concatenating two string expressions into one using operator +
Definition strexpr.h:373