20inline constexpr bool wchar_is_u16 =
sizeof(wchar_t) == 2;
22using wchar_type = std::conditional<wchar_is_u16, char16_t, char32_t>::type;
24inline wchar_type* to_w(
wchar_t* p) {
25 return (
reinterpret_cast<wchar_type*
>(p));
28inline const wchar_type* to_w(
const wchar_t* p) {
29 return (
reinterpret_cast<const wchar_type*
>(p));
32inline wchar_t* from_w(wchar_type* p) {
33 return (
reinterpret_cast<wchar_t*
>(p));
36inline const wchar_t* from_w(
const wchar_type* p) {
37 return (
reinterpret_cast<const wchar_t*
>(p));
45using uu8s = std::make_unsigned<u8s>::type;
48inline 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>;
51inline 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>;
53template<
typename From>
54requires (is_one_of_std_char_v<From>)
55auto to_one_of_std_char(From* from) {
56 if constexpr (std::is_same_v<From, u8s> || std::is_same_v<From, wchar_t>) {
62template<
typename From>
63requires (is_one_of_std_char_v<From>)
64auto to_one_of_std_char(
const From* from) {
65 if constexpr (std::is_same_v<From, u8s> || std::is_same_v<From, wchar_t>) {
96template<
typename T>
struct const_lit;
98template<
typename T,
size_t N>
99 requires(is_one_of_char_v<T>)
100struct const_lit<
const T(&)[N]> {
102 constexpr static size_t Count = N;
106template<
typename K,
typename T>
struct const_lit_for;
108template<
typename K,
size_t N>
109 requires(is_one_of_char_v<K>)
110struct const_lit_for<K,
const K(&)[N]> {
111 constexpr static size_t Count = N;
114template<
typename K,
size_t N>
115class const_lit_to_array {
118 size_t find(K s)
const {
119 if constexpr (Idx < N) {
120 return s == symbols_[Idx] ? Idx : find<Idx + 1>(s);
126 bool exist(K s)
const {
127 if constexpr (Idx < N) {
128 return s == symbols_[Idx] || exist<Idx + 1>(s);
133 const K (&symbols_)[N + 1];
135 template<typename T, size_t M = const_lit_for<K, T>::Count>
requires (M == N + 1)
136 constexpr const_lit_to_array(T&& s)
139 constexpr bool contain(K s)
const {
142 constexpr size_t index_of(K s)
const {
158template<
typename A,
typename K>
160 { a.is_empty() } -> std::same_as<bool>;
161 { a.length() } -> std::convertible_to<size_t>;
162 { a.symbols() } -> std::same_as<const K*>;
163} && std::is_same_v<typename std::remove_cvref_t<A>::symb_type, K>;
229 typename A::symb_type;
230 { a.length() } -> std::convertible_to<size_t>;
231 { a.place(std::declval<typename A::symb_type*>()) } -> std::same_as<typename A::symb_type*>;
241template<
typename A,
typename K>
262template<StrExpr A, StrExprForType<
typename A::symb_type> B>
264 using symb_type =
typename A::symb_type;
267 constexpr strexprjoin(
const A& a_,
const B& b_) : a(a_), b(b_){}
268 constexpr size_t length()
const noexcept {
269 return a.length() + b.length();
271 constexpr symb_type* place(symb_type* p)
const noexcept {
272 return b.place(a.place(p));
274 constexpr symb_type* len_and_place(symb_type* p)
const noexcept {
294template<StrExpr A, StrExprForType<
typename A::symb_type> B>
310template<StrExpr A, StrExprForType<
typename A::symb_type> B,
bool last = true>
311struct strexprjoin_c {
312 using symb_type =
typename A::symb_type;
315 template<
typename... Args>
316 constexpr strexprjoin_c(
const A& a_, Args&&... args_) : a(a_), b(std::forward<Args>(args_)...) {}
317 constexpr size_t length()
const noexcept {
318 return a.length() + b.length();
320 constexpr symb_type* place(symb_type* p)
const noexcept {
321 if constexpr (last) {
322 return b.place(a.place(p));
324 return a.place(b.place(p));
327 constexpr symb_type* len_and_place(symb_type* p)
const noexcept {
334template<
typename T,
typename K = void,
typename... Types>
335struct is_one_of_type {
336 static constexpr bool value = std::is_same_v<T, K> || is_one_of_type<T, Types...>::value;
339struct is_one_of_type<T, void> : std::false_type {};
367 constexpr size_t length()
const noexcept {
370 constexpr symb_type* place(symb_type* p)
const noexcept {
400 expr_char(K v) : value(v){}
401 constexpr size_t length() const noexcept {
404 constexpr symb_type* place(symb_type* p)
const noexcept {
419template<
typename K, StrExprForType<K> A>
432 return expr_char<K>{s};
435template<
typename K,
size_t N>
438 const K (&str)[N + 1];
439 constexpr size_t length() const noexcept {
442 constexpr symb_type* place(symb_type* p)
const noexcept {
443 if constexpr (N != 0)
444 std::char_traits<K>::copy(p, str, N);
476template<typename T, size_t N = const_lit<T>::Count>
477constexpr inline auto e_t(T&& s) {
478 return expr_literal<typename const_lit<T>::symb_type,
static_cast<size_t>(N - 1)>{s};
481template<
bool first,
typename K,
size_t N,
typename A>
482struct expr_literal_join {
484 const K (&str)[N + 1];
486 constexpr size_t length() const noexcept {
487 return N + a.length();
489 constexpr symb_type* place(symb_type* p)
const noexcept {
490 if constexpr (N != 0) {
491 if constexpr (first) {
492 std::char_traits<K>::copy(p, str, N);
493 return a.place(p + N);
496 std::char_traits<K>::copy(p, str, N);
503 constexpr symb_type* len_and_place(symb_type* p)
const noexcept {
514template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
516 return expr_literal_join<
false, K, (N - 1), A>{s, a};
524template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
526 return expr_literal_join<
true, K, (N - 1), A>{s, a};
537template<
typename K,
size_t N,
size_t S = ' '>
540 constexpr size_t length()
const noexcept {
543 constexpr symb_type* place(symb_type* p)
const noexcept {
544 if constexpr (N != 0)
545 std::char_traits<K>::assign(p, N,
static_cast<K
>(S));
592 constexpr size_t length()
const noexcept {
595 constexpr symb_type* place(symb_type* p)
const noexcept {
597 std::char_traits<K>::assign(p, len, s);
611constexpr inline auto e_c(
size_t l, K s) {
623template<StrExpr A, StrExprForType<
typename A::symb_type> B>
625 using symb_type =
typename A::symb_type;
631 constexpr size_t length()
const noexcept {
632 return choice ? a.length() : b.length();
634 constexpr symb_type* place(symb_type* ptr)
const noexcept {
635 return choice ? a.place(ptr) : b.place(ptr);
648 using symb_type =
typename A::symb_type;
653 constexpr size_t length()
const noexcept {
654 return choice ? a.length() : 0;
656 constexpr symb_type* place(symb_type* ptr)
const noexcept {
657 return choice ? a.place(ptr) : ptr;
686template<StrExpr A,
size_t N,
bool Compare>
688 using symb_type =
typename A::symb_type;
689 const symb_type (&str)[N + 1];
693 constexpr size_t length()
const noexcept {
694 return choice == Compare ? a.length() : N;
696 constexpr symb_type* place(symb_type* ptr)
const noexcept {
697 if (choice == Compare) {
700 if constexpr (N != 0) {
701 std::char_traits<symb_type>::copy(ptr, str, N);
731template<
typename K,
size_t N,
size_t M>
734 const symb_type (&str_a)[N + 1];
735 const symb_type (&str_b)[M + 1];
738 constexpr size_t length()
const noexcept {
739 return choice ? N : M;
741 constexpr symb_type* place(symb_type* ptr)
const noexcept {
743 if constexpr (N != 0) {
744 std::char_traits<symb_type>::copy(ptr, str_a, N);
748 if constexpr (M != 0) {
749 std::char_traits<symb_type>::copy(ptr, str_b, M);
775template<StrExpr A, StrExprForType<
typename A::symb_type> B>
776inline constexpr auto e_choice(
bool c,
const A& a,
const B& b) {
784template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
785inline constexpr auto e_choice(
bool c,
const A& a, T&& str) {
793template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
794inline constexpr auto e_choice(
bool c, T&& str,
const A& a) {
801template<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>
802inline constexpr auto e_choice(
bool c, T&& str_a, L&& str_b) {
838inline constexpr auto e_if(
bool c,
const A& a) {
845template<typename T, size_t N = const_lit<T>::Count>
846inline constexpr auto e_if(
bool c, T&& str) {
847 const typename const_lit<T>::symb_type empty[1] = {0};
857template<
typename K,
typename T>
862 expr_stdstr(
const T& t) : t_(t){}
864 constexpr size_t length()
const noexcept {
867 constexpr symb_type* place(symb_type* p)
const noexcept {
868 size_t s = t_.size();
869 std::char_traits<K>::copy(p, (
const K*)t_.data(), s);
878template<StrExprForType<u8s> A>
887template<StrExprForType<u8s> A>
896template<StrExprForType<u8s> A>
905template<StrExprForType<u8s> A>
914template<StrExprForType<uws> A>
923template<StrExprForType<uws> A>
932template<StrExprForType<uws> A>
941template<StrExprForType<uws> A>
951template<StrExprForType<
wchar_type> A>
952auto operator+(
const A& a,
const std::wstring& s) {
953 return strexprjoin_c<A, expr_stdstr<wchar_type, std::wstring>,
true>{a, s};
961template<StrExprForType<
wchar_type> A>
962auto operator+(
const std::wstring& s,
const A& a) {
971template<StrExprForType<
wchar_type> A>
972auto operator+(
const A& a,
const std::wstring_view& s) {
981template<StrExprForType<
wchar_type> A>
982auto operator+(
const std::wstring_view& s,
const A& a) {
Концепт строкового выражения заданного типа символов
Определения strexpr.h:242
Концепт "Строковых выражений".
Определения strexpr.h:228
Базовая концепция строкового объекта.
Определения strexpr.h:159
constexpr auto e_spca()
Генерирует строку из N char пробелов
Определения strexpr.h:561
constexpr auto e_char(K s)
Генерирует строку из 1 заданного символа
Определения strexpr.h:431
constexpr empty_expr< uws > eew
Пустое строковое выражение типа wchar_t.
Определения strexpr.h:384
constexpr auto e_c(size_t l, K s)
Генерирует строку из l символов s типа K.
Определения strexpr.h:611
constexpr empty_expr< u32s > eeuu
Пустое строковое выражение типа char32_t.
Определения strexpr.h:394
constexpr auto e_t(T &&s)
Преобразует строковый литерал в строковое выражение.
Определения strexpr.h:477
constexpr auto e_choice(bool c, const A &a, const B &b)
Создание условного строкового выражения expr_choice.
Определения strexpr.h:776
constexpr auto e_if(bool c, const A &a)
Создание условного строкового выражения expr_if.
Определения strexpr.h:838
constexpr empty_expr< u8s > eea
Пустое строковое выражение типа char.
Определения strexpr.h:379
constexpr empty_expr< u16s > eeu
Пустое строковое выражение типа char16_t.
Определения strexpr.h:389
constexpr auto operator+(const A &a, T s)
Оператор конкатенации для строкового выражения и целого числа.
Определения sstring.h:4633
constexpr auto e_spcw()
Генерирует строку из N wchar_t пробелов
Определения strexpr.h:576
Пространство имён для объектов библиотеки
Определения sstring.cpp:10
"Пустое" строковое выражение
Определения strexpr.h:365
Строковое выражение условного выбора
Определения strexpr.h:687
Строковое выражение условного выбора
Определения strexpr.h:732
Строковое выражение условного выбора
Определения strexpr.h:624
Строковое выражение условного выбора
Определения strexpr.h:647
Тип строкового выражения, возвращающего N заданных символов.
Определения strexpr.h:588
Тип строкового выражения, возвращающего N заданных символов.
Определения strexpr.h:538
Конкатенация ссылки на строковое выражение и значения строкового выражения
Определения strexpr.h:311
Шаблонный класс для конкатенации двух строковых выражений в одно с помощью operator +
Определения strexpr.h:263