xtd 0.2.0
basic_string_.hpp
Go to the documentation of this file.
1
4#pragma once
6#if !defined(__XTD_BASIC_STRING_INTERNAL__)
7#error "Do not include this file: Internal use only. Include <xtd/basic_string> or <xtd/basic_string.hpp> instead."
8#endif
9
10#include "array.hpp"
11//#include "formatter.hpp"
12
14template<class char_t, class traits_t, class allocator_t>
15inline xtd::basic_string<char_t, traits_t, allocator_t>::basic_string(const allocator_type& allocator) noexcept : chars_(allocator) {}
16
17template<class char_t, class traits_t, class allocator_t>
19 return index_of_any(values, 0, size());
20}
21
22template<class char_t, class traits_t, class allocator_t>
24 return index_of_any(values, start_index, size() - start_index);
25}
26
27template<class char_t, class traits_t, class allocator_t>
30 auto index = xtd::size {0};
31 for (const auto& item : *this) {
32 if (index++ < start_index) continue;
33 if (index - 1 > start_index + count) break;
34 if (std::find(values.begin(), values.end(), item) != values.end()) return index - 1;
35 }
36 return npos;
37}
38
39template<class char_t, class traits_t, class allocator_t>
40inline xtd::size xtd::basic_string<char_t, traits_t, allocator_t>::index_of_any(const std::initializer_list<value_type>& values) const noexcept {
41 return index_of_any(xtd::array<value_type>(values));
42}
43
44template<class char_t, class traits_t, class allocator_t>
45inline xtd::size xtd::basic_string<char_t, traits_t, allocator_t>::index_of_any(const std::initializer_list<value_type>& values, xtd::size start_index) const {
46 return index_of_any(xtd::array<value_type>(values), start_index);
47}
48
49template<class char_t, class traits_t, class allocator_t>
50inline xtd::size xtd::basic_string<char_t, traits_t, allocator_t>::index_of_any(const std::initializer_list<value_type>& values, xtd::size start_index, xtd::size count) const {
51 return index_of_any(xtd::array<value_type>(values), start_index, count);
52}
53
54template<class char_t, class traits_t, class allocator_t>
56 return last_index_of_any(values, 0, size());
57}
58
59template<class char_t, class traits_t, class allocator_t>
61 return last_index_of_any(values, start_index, size() - start_index);
62}
63
64template<class char_t, class traits_t, class allocator_t>
67 auto index = size() - 1;
68 for (auto iterator = crbegin(); iterator != crend(); ++iterator) {
69 if (index-- > start_index + count) continue;
70 if (index + 1 < start_index) break;
71 if (std::find(values.begin(), values.end(), *iterator) != values.end()) return index + 1;
72 }
73 return npos;
74}
75
76template<class char_t, class traits_t, class allocator_t>
77inline xtd::size xtd::basic_string<char_t, traits_t, allocator_t>::last_index_of_any(const std::initializer_list<value_type>& values) const noexcept {
78 return last_index_of_any(xtd::array<value_type>(values));
79}
80
81template<class char_t, class traits_t, class allocator_t>
82inline xtd::size xtd::basic_string<char_t, traits_t, allocator_t>::last_index_of_any(const std::initializer_list<value_type>& values, xtd::size start_index) const {
83 return last_index_of_any(xtd::array<value_type>(values), start_index);
84}
85
86template<class char_t, class traits_t, class allocator_t>
87inline xtd::size xtd::basic_string<char_t, traits_t, allocator_t>::last_index_of_any(const std::initializer_list<value_type>& values, xtd::size start_index, xtd::size count) const {
88 return last_index_of_any(xtd::array<value_type>(values), start_index, count);
89}
90
91template<class char_t, class traits_t, class allocator_t>
93 return split(default_split_separators, std::numeric_limits<xtd::size>::max(), xtd::string_split_options::none);
94}
95
96template<class char_t, class traits_t, class allocator_t>
98 return split(xtd::array<value_type> {separator}, std::numeric_limits<xtd::size>::max(), xtd::string_split_options::none);
99}
100
101template<class char_t, class traits_t, class allocator_t>
103 return split(xtd::array<value_type> {separator}, std::numeric_limits<xtd::size>::max(), options);
104}
105
106template<class char_t, class traits_t, class allocator_t>
109}
110
111template<class char_t, class traits_t, class allocator_t>
113 return split(xtd::array<value_type> {separator}, count, options);
114}
115
116template<class char_t, class traits_t, class allocator_t>
118 return split(separators, std::numeric_limits<xtd::size>::max(), xtd::string_split_options::none);
119}
120
121template<class char_t, class traits_t, class allocator_t>
123 return split(separators, std::numeric_limits<xtd::size>::max(), options);
124}
125
126template<class char_t, class traits_t, class allocator_t>
128 return split(separators, count, xtd::string_split_options::none);
129}
130
131template<class char_t, class traits_t, class allocator_t>
133 if (count == 0) return {};
134 if (count == 1) return {*this};
135
136 auto result = std::vector<basic_string> {};
137 auto sub_string = basic_string {};
138 auto split_char_separators = separators.size() == 0 ? default_split_separators : separators;
139 for (auto it = begin(); it != end(); ++it) {
140 auto is_separator = std::find(split_char_separators.begin(), split_char_separators.end(), *it) != split_char_separators.end();
141 if (!is_separator) sub_string.chars_.append(basic_string(1, *it));
142 auto is_last = (it + 1 == end());
143 auto should_add = is_last || is_separator;
144 auto keep_empty = sub_string.length() > 0 || (options != xtd::string_split_options::remove_empty_entries);
145
146 if (should_add && keep_empty) {
147 if (result.size() == count - 1) {
148 result.push_back(sub_string + basic_string(c_str(), it - begin() + (is_separator ? 0 : 1), length() - (it - begin()) + (is_separator ? 0 : 1)));
149 return result;
150 }
151 result.push_back(sub_string);
152 sub_string.chars_.clear();
153 }
154 }
155
156 if (size() > 0 && std::find(split_char_separators.begin(), split_char_separators.end(), at(size() - 1)) != split_char_separators.end() && options != xtd::string_split_options::remove_empty_entries) result.push_back(basic_string {});
157
158 return result;
159}
160
161template<class char_t, class traits_t, class allocator_t>
163 return to_array(0, size());
164}
165
166template<class char_t, class traits_t, class allocator_t>
168 return to_array(start_index, size() - start_index);
169}
170
171template<class char_t, class traits_t, class allocator_t>
173 if (start_index >= size()) return {};
174 if (start_index + length >= size()) return {begin() + start_index, end()};
175 return {begin() + start_index, begin() + start_index + length};
176}
177
178template<class char_t, class traits_t, class allocator_t>
180 return to_array(0, size());
181}
182
183template<class char_t, class traits_t, class allocator_t>
185 return to_array(start_index, length);
186}
187
188template<class char_t, class traits_t, class allocator_t>
190 auto words = split({' '});
191 for (auto& word : words)
192 if (word.size() && word != word.to_upper()) word = static_cast<value_type>(toupper(word[0])) + word.substring(1).to_lower();
193 return basic_string::join(" ", words);
194}
195
196template<class char_t, class traits_t, class allocator_t>
198 return trim(xtd::array<value_type> {trim_char});
199}
200
201template<class char_t, class traits_t, class allocator_t>
203 return trim_start(trim_chars).trim_end(trim_chars);
204}
205
206template<class char_t, class traits_t, class allocator_t>
208 return trim_end(xtd::array<value_type> {trim_char});
209}
210
211template<class char_t, class traits_t, class allocator_t>
213 if (!size()) return *this;
214 auto result = chars_;
215 while (std::find(trim_chars.begin(), trim_chars.end(), result[result.size() - 1]) != trim_chars.end())
216 result.erase(result.size() - 1, 1);
217 return result;
218}
219
220template<class char_t, class traits_t, class allocator_t>
222
223template<class char_t, class traits_t, class allocator_t>
225 if (!size()) return *this;
226 auto result = chars_;
227 while (std::find(trim_chars.begin(), trim_chars.end(), result[0]) != trim_chars.end())
228 result.erase(0, 1);
229 return result;
230}
231
232template<class char_t, class traits_t, class allocator_t>
234 auto result = basic_string::empty_string;
235 std::for_each(values.begin(), values.end(), [&](const auto & item) {result += item;});
236 return result;
237}
238
239template<class char_t, class traits_t, class allocator_t>
241 auto result = basic_string::empty_string;
242 std::for_each(values.begin(), values.end(), [&](const auto & item) {result += item;});
243 return result;
244}
245
246template<class char_t, class traits_t, class allocator_t>
247template<class other_char_t>
249 auto result = basic_string::empty_string;
250 std::for_each(values.begin(), values.end(), [&](const auto & item) {result += item;});
251 return result;
252}
253
254
255template<class char_t, class traits_t, class allocator_t>
256template<class object_t>
258 basic_string result;
259 for (const auto& arg : args)
260 result += format("{}", arg);
261 return result;
262}
263
264template<class char_t, class traits_t, class allocator_t>
265template<class ...args_t>
267 auto result = basic_string<char> {};
268 auto index = xtd::size {0};
269 auto formats = std::vector<__format_information<char>> {};
270 auto begin_format_iterator = fmt.end();
271 auto end_format_iterator = fmt.end();
272 for (auto iterator = fmt.begin(); iterator != fmt.end(); ++iterator) {
273 if (*iterator == '{') {
274 if (++iterator == fmt.end())
276 if (*iterator == '{')
277 result += *iterator;
278 else {
279 begin_format_iterator = iterator;
280 while (iterator != fmt.end() && *iterator != '}') ++iterator;
281 if (iterator == fmt.end())
283 end_format_iterator = iterator;
284 __format_information<char> fi;
285 fi.location = result.size();
286 auto format_str = std::basic_string<char> {begin_format_iterator, end_format_iterator};
287 if (format_str.size() == 0)
288 fi.index = index++;
289 else {
290 xtd::size index_alignment_separator = basic_string(format_str).index_of(',');
291 xtd::size index_format_separator = basic_string(format_str).index_of(u':');
292
293 if (index_alignment_separator != std::basic_string<char>::npos && index_format_separator != std::basic_string<char>::npos && index_alignment_separator > index_format_separator)
294 index_alignment_separator = std::basic_string<char>::npos;
295
296 if (index_alignment_separator != basic_string<char_t>::npos)
297 fi.alignment = format_str.substr(index_alignment_separator + 1, index_format_separator != std::basic_string<char>::npos ? index_format_separator - index_alignment_separator - 1 : std::basic_string<char>::npos);
298
299 if (index_format_separator != basic_string<char>::npos)
300 fi.format = format_str.substr(index_format_separator + 1);
301
302 if (index_alignment_separator == 0 || index_format_separator == 0)
303 fi.index = index++;
304 else {
305 auto index_str = std::basic_string<char> {};
306 if (index_alignment_separator != basic_string<char>::npos)
307 index_str = format_str.substr(0, index_alignment_separator);
308 else if (index_format_separator != basic_string<char>::npos)
309 index_str = format_str.substr(0, index_format_separator);
310 else
311 index_str = std::move(format_str);
312 try {
313 for (auto c : index_str)
315 fi.index = std::stoi(index_str);
316 } catch (...) {
318 }
319 }
320 }
321 formats.push_back(fi);
322 }
323 } else if (*iterator == '}') {
324 if (++iterator == fmt.end())
326 if (*iterator != '}')
328 result += *iterator;
329 } else
330 result += *iterator;
331 }
332
333 __basic_string_extract_format_arg(result, formats, std::forward<args_t>(args)...);
334 return result.c_str();
335}
336
337template<class char_t, class traits_t, class allocator_t>
338template<class value_t>
339inline xtd::basic_string<char_t, traits_t, allocator_t> xtd::basic_string<char_t, traits_t, allocator_t>::join(const basic_string& separator, const std::initializer_list<value_t>& values) noexcept {
340 return join(separator, xtd::array<value_t>(values));
341}
342
343template<class char_t, class traits_t, class allocator_t>
344template<class value_t>
345inline xtd::basic_string<char_t, traits_t, allocator_t> xtd::basic_string<char_t, traits_t, allocator_t>::join(const basic_string& separator, const std::initializer_list<value_t>& values, xtd::size index) {
346 return join(separator, xtd::array<value_t>(values), index);
347}
348
349template<class char_t, class traits_t, class allocator_t>
350template<class value_t>
351inline xtd::basic_string<char_t, traits_t, allocator_t> xtd::basic_string<char_t, traits_t, allocator_t>::join(const basic_string& separator, const std::initializer_list<value_t>& values, xtd::size index, xtd::size count) {
352 return join(separator, xtd::array<value_t>(values), index, count);
353}
354
355template<class char_t, class traits_t, class allocator_t>
357
358template<class char_t, class traits_t, class allocator_t>
359inline const xtd::array<typename xtd::basic_string<char_t, traits_t, allocator_t>::value_type> xtd::basic_string<char_t, traits_t, allocator_t>::default_split_separators = {9, 10, 11, 12, 13, 32};
360
361template<class char_t, class traits_t, class allocator_t>
362inline const xtd::array<typename xtd::basic_string<char_t, traits_t, allocator_t>::value_type> xtd::basic_string<char_t, traits_t, allocator_t>::default_trim_chars = {9, 10, 11, 12, 13, 32};
363
364template<class arg_t>
365void __basic_string_extract_format_arg(std::basic_string<char>& fmt, xtd::size& index, std::vector<__format_information<char >> & formats, arg_t&& arg) {
366 //void __basic_string_extract_format_arg(xtd::basic_string<char>& fmt, xtd::size& index, std::vector<__format_information<char>>& formats, arg_t&& arg) {
367 auto offset = xtd::size {0};
368 for (auto& format : formats) {
369 format.location += offset;
370 if (format.index == index) {
371 //xtd::basic_string<char> arg_str = xtd::formatter<arg_t> {}(arg, format.format, std::locale());
372 xtd::basic_string<char> arg_str = xtd::to_string(arg, format.format);
373
374 if (!format.alignment.empty()) {
375 xtd::int32 alignment = 0;
376 try {
377 alignment = std::stoi(format.alignment);
378 } catch (...) {
380 }
381 if (alignment > 0) arg_str = arg_str.pad_left(alignment);
382 else if (alignment < 0) arg_str = arg_str.pad_right(-alignment);
383 }
384 fmt.insert(format.location, arg_str);
385 offset += arg_str.size();
386 }
387 }
388 ++index;
389}
390
391template<class ...args_t>
392void __basic_string_extract_format_arg(xtd::basic_string<char>& fmt, std::vector<__format_information<char >> & formats, args_t&&... args) {
393 auto index = xtd::size {0};
394 (__basic_string_extract_format_arg(const_cast<std::basic_string<char>& > (fmt.chars()), index, formats, args), ...);
395 //(__basic_string_extract_format_arg(fmt, index, formats, args), ...);
396 unused_(index); // workaround to mute gcc warning: unused-but-set-variable
397}
398
399template<class target_t, class source_t>
400inline std::basic_string<target_t> __xtd_convert_to_string(std::basic_string<source_t>&& str) noexcept {
401 auto out = std::basic_string<target_t> {};
402 auto codepoint = 0u;
403 for (const auto& character : str) {
404 if (character >= 0xd800 && character <= 0xdbff)
405 codepoint = ((character - 0xd800) << 10) + 0x10000;
406 else {
407 if (character >= 0xdc00 && character <= 0xdfff) codepoint |= character - 0xdc00;
408 else codepoint = character;
409
410 if (codepoint <= 0x7f)
411 out.append(1, static_cast<target_t>(codepoint));
412 else if (codepoint <= 0x7ff) {
413 out.append(1, static_cast<target_t>(0xc0 | ((codepoint >> 6) & 0x1f)));
414 out.append(1, static_cast<target_t>(0x80 | (codepoint & 0x3f)));
415 } else if (codepoint <= 0xffff) {
416 out.append(1, static_cast<target_t>(0xe0 | ((codepoint >> 12) & 0x0f)));
417 out.append(1, static_cast<target_t>(0x80 | ((codepoint >> 6) & 0x3f)));
418 out.append(1, static_cast<target_t>(0x80 | (codepoint & 0x3f)));
419 } else {
420 out.append(1, static_cast<target_t>(0xf0 | ((codepoint >> 18) & 0x07)));
421 out.append(1, static_cast<target_t>(0x80 | ((codepoint >> 12) & 0x3f)));
422 out.append(1, static_cast<target_t>(0x80 | ((codepoint >> 6) & 0x3f)));
423 out.append(1, static_cast<target_t>(0x80 | (codepoint & 0x3f)));
424 }
425 codepoint = 0;
426 }
427 }
428 return out;
429}
430
431template<>
432inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, char>(std::basic_string<char>&& str) noexcept {
433 auto out = std::basic_string<xtd::char16> {};
434 auto codepoint = 0u;
435 auto str_ptr = str.data();
436 while (*str_ptr != 0) {
437 auto ch = static_cast<unsigned char>(*str_ptr);
438 if (ch <= 0x7f) codepoint = ch;
439 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
440 else if (ch <= 0xdf) codepoint = ch & 0x1f;
441 else if (ch <= 0xef) codepoint = ch & 0x0f;
442 else codepoint = ch & 0x07;
443 ++str_ptr;
444 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
445 if (codepoint > 0xffff) {
446 out.append(1, static_cast<xtd::char16>(0xd800 + (static_cast<xtd::char16>(codepoint) >> 10)));
447 out.append(1, static_cast<xtd::char16>(0xdc00 + (static_cast<xtd::char16>(codepoint) & 0x03ff)));
448 } else if (codepoint < 0xd800 || codepoint >= 0xe000)
449 out.append(1, static_cast<xtd::char16>(codepoint));
450 }
451 }
452 return out;
453}
454
455template<>
456inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, xtd::char8>(std::basic_string<xtd::char8>&& str) noexcept {
457 auto out = std::basic_string<xtd::char16> {};
458 auto codepoint = 0u;
459 auto str_ptr = str.data();
460 while (*str_ptr != 0) {
461 auto ch = static_cast<unsigned char>(*str_ptr);
462 if (ch <= 0x7f) codepoint = ch;
463 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
464 else if (ch <= 0xdf) codepoint = ch & 0x1f;
465 else if (ch <= 0xef) codepoint = ch & 0x0f;
466 else codepoint = ch & 0x07;
467 ++str_ptr;
468 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
469 if (codepoint > 0xffff) {
470 out.append(1, static_cast<xtd::char16>(0xd800 + (static_cast<xtd::char16>(codepoint) >> 10)));
471 out.append(1, static_cast<xtd::char16>(0xdc00 + (static_cast<xtd::char16>(codepoint) & 0x03ff)));
472 } else if (codepoint < 0xd800 || codepoint >= 0xe000)
473 out.append(1, static_cast<xtd::char16>(codepoint));
474 }
475 }
476 return out;
477}
478
479template<>
480inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, char>(std::basic_string<char>&& str) noexcept {
481 auto out = std::basic_string<xtd::wchar> {};
482 auto codepoint = 0u;
483 auto str_ptr = str.data();
484 while (*str_ptr != 0) {
485 auto ch = static_cast<unsigned char>(*str_ptr);
486 if (ch <= 0x7f) codepoint = ch;
487 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
488 else if (ch <= 0xdf) codepoint = ch & 0x1f;
489 else if (ch <= 0xef) codepoint = ch & 0x0f;
490 else codepoint = ch & 0x07;
491 ++str_ptr;
492 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
493 if (sizeof(xtd::wchar) > 2)
494 out.append(1, static_cast<xtd::wchar>(codepoint));
495 else if (codepoint > 0xffff) {
496 out.append(1, static_cast<xtd::wchar>(0xd800 + (static_cast<xtd::wchar>(codepoint) >> 10)));
497 out.append(1, static_cast<xtd::wchar>(0xdc00 + (static_cast<xtd::wchar>(codepoint) & 0x03ff)));
498 } else if (codepoint < 0xd800 || codepoint >= 0xe000)
499 out.append(1, static_cast<xtd::wchar>(codepoint));
500 }
501 }
502 return out;
503}
504
505template<>
506inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, xtd::char8>(std::basic_string<xtd::char8>&& str) noexcept {
507 auto out = std::basic_string<xtd::wchar> {};
508 auto codepoint = 0u;
509 auto str_ptr = str.data();
510 while (*str_ptr != 0) {
511 auto ch = static_cast<unsigned char>(*str_ptr);
512 if (ch <= 0x7f) codepoint = ch;
513 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
514 else if (ch <= 0xdf) codepoint = ch & 0x1f;
515 else if (ch <= 0xef) codepoint = ch & 0x0f;
516 else codepoint = ch & 0x07;
517 ++str_ptr;
518 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
519 if (sizeof(xtd::wchar) > 2)
520 out.append(1, static_cast<xtd::wchar>(codepoint));
521 else if (codepoint > 0xffff) {
522 out.append(1, static_cast<xtd::wchar>(0xd800 + (static_cast<xtd::wchar>(codepoint) >> 10)));
523 out.append(1, static_cast<xtd::wchar>(0xdc00 + (static_cast<xtd::wchar>(codepoint) & 0x03ff)));
524 } else if (codepoint < 0xd800 || codepoint >= 0xe000)
525 out.append(1, static_cast<xtd::wchar>(codepoint));
526 }
527 }
528 return out;
529}
530
531template<>
532inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, char>(std::basic_string<char>&& str) noexcept {
533 auto out = std::basic_string<xtd::char32> {};
534 auto codepoint = 0u;
535 auto str_ptr = str.data();
536 while (*str_ptr != 0) {
537 auto ch = static_cast<unsigned char>(*str_ptr);
538 if (ch <= 0x7f) codepoint = ch;
539 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
540 else if (ch <= 0xdf) codepoint = ch & 0x1f;
541 else if (ch <= 0xef) codepoint = ch & 0x0f;
542 else codepoint = ch & 0x07;
543 ++str_ptr;
544 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
545 out.append(1, static_cast<xtd::char32>(codepoint));
546 }
547 return out;
548}
549
550template<>
551inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, xtd::char8>(std::basic_string<xtd::char8>&& str) noexcept {
552 auto out = std::basic_string<xtd::char32> {};
553 auto codepoint = 0u;
554 auto str_ptr = str.data();
555 while (*str_ptr != 0) {
556 auto ch = static_cast<unsigned char>(*str_ptr);
557 if (ch <= 0x7f) codepoint = ch;
558 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
559 else if (ch <= 0xdf) codepoint = ch & 0x1f;
560 else if (ch <= 0xef) codepoint = ch & 0x0f;
561 else codepoint = ch & 0x07;
562 ++str_ptr;
563 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
564 out.append(1, static_cast<xtd::char32>(codepoint));
565 }
566 return out;
567}
568
569template<>
570inline std::basic_string<char> __xtd_convert_to_string<char, char>(std::basic_string<char>&& str) noexcept {
571 return std::move(str);
572}
573
574template<>
575inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, xtd::char16>(std::basic_string<xtd::char16>&& str) noexcept {
576 return std::move(str);
577}
578
579template<>
580inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, xtd::char32>(std::basic_string<xtd::char32>&& str) noexcept {
581 return std::move(str);
582}
583
584template<>
585inline std::basic_string<xtd::char8> __xtd_convert_to_string<xtd::char8, xtd::char8>(std::basic_string<xtd::char8>&& str) noexcept {
586 return std::move(str);
587}
588
589template<>
590inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, xtd::wchar>(std::basic_string<xtd::wchar>&& str) noexcept {
591 return std::move(str);
592}
593
594template<>
595inline std::basic_string<xtd::char8> __xtd_convert_to_string<xtd::char8, char>(std::basic_string<char>&& str) noexcept {
596 return std::basic_string<xtd::char8> {reinterpret_cast<const xtd::char8*>(str.c_str())};
597}
598
599template<>
600inline std::basic_string<char> __xtd_convert_to_string<char, xtd::char8>(std::basic_string<xtd::char8>&& str) noexcept {
601 return std::basic_string<char> {reinterpret_cast<const char*>(str.c_str())};
602}
603
604template<>
605inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, xtd::char32>(std::basic_string<xtd::char32>&& str) noexcept {
606 return __xtd_convert_to_string<xtd::char16>(__xtd_convert_to_string<char>(std::move(str)));
607}
608
609template<>
610inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, xtd::wchar>(std::basic_string<xtd::wchar>&& str) noexcept {
611 return __xtd_convert_to_string<xtd::char16>(__xtd_convert_to_string<char>(std::move(str)));
612}
613
614template<>
615inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, xtd::char16>(std::basic_string<xtd::char16>&& str) noexcept {
616 return __xtd_convert_to_string<xtd::char32>(__xtd_convert_to_string<char>(std::move(str)));
617}
618
619template<>
620inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, xtd::wchar>(std::basic_string<xtd::wchar>&& str) noexcept {
621 return __xtd_convert_to_string<xtd::char32>(__xtd_convert_to_string<char>(std::move(str)));
622}
623
624template<>
625inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, xtd::char16>(std::basic_string<xtd::char16>&& str) noexcept {
626 return __xtd_convert_to_string<xtd::wchar>(__xtd_convert_to_string<char>(std::move(str)));
627}
628
629template<>
630inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, xtd::char32>(std::basic_string<xtd::char32>&& str) noexcept {
631 return __xtd_convert_to_string<xtd::wchar>(__xtd_convert_to_string<char>(std::move(str)));
632}
633
634template<class target_t, class source_t>
635inline std::basic_string<target_t> __xtd_convert_to_string(const std::basic_string<source_t>& str) noexcept {
636 auto out = std::basic_string<target_t> {};
637 auto codepoint = 0u;
638 for (const auto& character : str) {
639 if (character >= 0xd800 && character <= 0xdbff)
640 codepoint = ((character - 0xd800) << 10) + 0x10000;
641 else {
642 if (character >= 0xdc00 && character <= 0xdfff) codepoint |= character - 0xdc00;
643 else codepoint = character;
644
645 if (codepoint <= 0x7f)
646 out.append(1, static_cast<target_t>(codepoint));
647 else if (codepoint <= 0x7ff) {
648 out.append(1, static_cast<target_t>(0xc0 | ((codepoint >> 6) & 0x1f)));
649 out.append(1, static_cast<target_t>(0x80 | (codepoint & 0x3f)));
650 } else if (codepoint <= 0xffff) {
651 out.append(1, static_cast<target_t>(0xe0 | ((codepoint >> 12) & 0x0f)));
652 out.append(1, static_cast<target_t>(0x80 | ((codepoint >> 6) & 0x3f)));
653 out.append(1, static_cast<target_t>(0x80 | (codepoint & 0x3f)));
654 } else {
655 out.append(1, static_cast<target_t>(0xf0 | ((codepoint >> 18) & 0x07)));
656 out.append(1, static_cast<target_t>(0x80 | ((codepoint >> 12) & 0x3f)));
657 out.append(1, static_cast<target_t>(0x80 | ((codepoint >> 6) & 0x3f)));
658 out.append(1, static_cast<target_t>(0x80 | (codepoint & 0x3f)));
659 }
660 codepoint = 0;
661 }
662 }
663 return out;
664}
665
666template<>
667inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, char>(const std::basic_string<char>& str) noexcept {
668 auto out = std::basic_string<xtd::char16> {};
669 auto codepoint = 0u;
670 auto str_ptr = str.data();
671 while (*str_ptr != 0) {
672 auto ch = static_cast<unsigned char>(*str_ptr);
673 if (ch <= 0x7f) codepoint = ch;
674 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
675 else if (ch <= 0xdf) codepoint = ch & 0x1f;
676 else if (ch <= 0xef) codepoint = ch & 0x0f;
677 else codepoint = ch & 0x07;
678 ++str_ptr;
679 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
680 if (codepoint > 0xffff) {
681 out.append(1, static_cast<xtd::char16>(0xd800 + (static_cast<xtd::char16>(codepoint) >> 10)));
682 out.append(1, static_cast<xtd::char16>(0xdc00 + (static_cast<xtd::char16>(codepoint) & 0x03ff)));
683 } else if (codepoint < 0xd800 || codepoint >= 0xe000)
684 out.append(1, static_cast<xtd::char16>(codepoint));
685 }
686 }
687 return out;
688}
689
690template<>
691inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, xtd::char8>(const std::basic_string<xtd::char8>& str) noexcept {
692 auto out = std::basic_string<xtd::char16> {};
693 auto codepoint = 0u;
694 auto str_ptr = str.data();
695 while (*str_ptr != 0) {
696 auto ch = static_cast<unsigned char>(*str_ptr);
697 if (ch <= 0x7f) codepoint = ch;
698 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
699 else if (ch <= 0xdf) codepoint = ch & 0x1f;
700 else if (ch <= 0xef) codepoint = ch & 0x0f;
701 else codepoint = ch & 0x07;
702 ++str_ptr;
703 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
704 if (codepoint > 0xffff) {
705 out.append(1, static_cast<xtd::char16>(0xd800 + (static_cast<xtd::char16>(codepoint) >> 10)));
706 out.append(1, static_cast<xtd::char16>(0xdc00 + (static_cast<xtd::char16>(codepoint) & 0x03ff)));
707 } else if (codepoint < 0xd800 || codepoint >= 0xe000)
708 out.append(1, static_cast<xtd::char16>(codepoint));
709 }
710 }
711 return out;
712}
713
714template<>
715inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, char>(const std::basic_string<char>& str) noexcept {
716 auto out = std::basic_string<xtd::wchar> {};
717 auto codepoint = 0u;
718 auto str_ptr = str.data();
719 while (*str_ptr != 0) {
720 auto ch = static_cast<unsigned char>(*str_ptr);
721 if (ch <= 0x7f) codepoint = ch;
722 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
723 else if (ch <= 0xdf) codepoint = ch & 0x1f;
724 else if (ch <= 0xef) codepoint = ch & 0x0f;
725 else codepoint = ch & 0x07;
726 ++str_ptr;
727 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
728 if (sizeof(xtd::wchar) > 2)
729 out.append(1, static_cast<xtd::wchar>(codepoint));
730 else if (codepoint > 0xffff) {
731 out.append(1, static_cast<xtd::wchar>(0xd800 + (static_cast<xtd::wchar>(codepoint) >> 10)));
732 out.append(1, static_cast<xtd::wchar>(0xdc00 + (static_cast<xtd::wchar>(codepoint) & 0x03ff)));
733 } else if (codepoint < 0xd800 || codepoint >= 0xe000)
734 out.append(1, static_cast<xtd::wchar>(codepoint));
735 }
736 }
737 return out;
738}
739
740template<>
741inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, xtd::char8>(const std::basic_string<xtd::char8>& str) noexcept {
742 auto out = std::basic_string<xtd::wchar> {};
743 auto codepoint = 0u;
744 auto str_ptr = str.data();
745 while (*str_ptr != 0) {
746 auto ch = static_cast<unsigned char>(*str_ptr);
747 if (ch <= 0x7f) codepoint = ch;
748 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
749 else if (ch <= 0xdf) codepoint = ch & 0x1f;
750 else if (ch <= 0xef) codepoint = ch & 0x0f;
751 else codepoint = ch & 0x07;
752 ++str_ptr;
753 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
754 if (sizeof(xtd::wchar) > 2)
755 out.append(1, static_cast<xtd::wchar>(codepoint));
756 else if (codepoint > 0xffff) {
757 out.append(1, static_cast<xtd::wchar>(0xd800 + (static_cast<xtd::wchar>(codepoint) >> 10)));
758 out.append(1, static_cast<xtd::wchar>(0xdc00 + (static_cast<xtd::wchar>(codepoint) & 0x03ff)));
759 } else if (codepoint < 0xd800 || codepoint >= 0xe000)
760 out.append(1, static_cast<xtd::wchar>(codepoint));
761 }
762 }
763 return out;
764}
765
766template<>
767inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, char>(const std::basic_string<char>& str) noexcept {
768 auto out = std::basic_string<xtd::char32> {};
769 auto codepoint = 0u;
770 auto str_ptr = str.data();
771 while (*str_ptr != 0) {
772 auto ch = static_cast<unsigned char>(*str_ptr);
773 if (ch <= 0x7f) codepoint = ch;
774 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
775 else if (ch <= 0xdf) codepoint = ch & 0x1f;
776 else if (ch <= 0xef) codepoint = ch & 0x0f;
777 else codepoint = ch & 0x07;
778 ++str_ptr;
779 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
780 out.append(1, static_cast<xtd::char32>(codepoint));
781 }
782 return out;
783}
784
785template<>
786inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, xtd::char8>(const std::basic_string<xtd::char8>& str) noexcept {
787 auto out = std::basic_string<xtd::char32> {};
788 auto codepoint = 0u;
789 auto str_ptr = str.data();
790 while (*str_ptr != 0) {
791 auto ch = static_cast<unsigned char>(*str_ptr);
792 if (ch <= 0x7f) codepoint = ch;
793 else if (ch <= 0xbf) codepoint = (codepoint << 6) | (ch & 0x3f);
794 else if (ch <= 0xdf) codepoint = ch & 0x1f;
795 else if (ch <= 0xef) codepoint = ch & 0x0f;
796 else codepoint = ch & 0x07;
797 ++str_ptr;
798 if (((*str_ptr & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
799 out.append(1, static_cast<xtd::char32>(codepoint));
800 }
801 return out;
802}
803
804template<>
805inline std::basic_string<char> __xtd_convert_to_string<char, char>(const std::basic_string<char>& str) noexcept {
806 return str;
807}
808
809template<>
810inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, xtd::char16>(const std::basic_string<xtd::char16>& str) noexcept {
811 return str;
812}
813
814template<>
815inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, xtd::char32>(const std::basic_string<xtd::char32>& str) noexcept {
816 return str;
817}
818
819template<>
820inline std::basic_string<xtd::char8> __xtd_convert_to_string<xtd::char8, xtd::char8>(const std::basic_string<xtd::char8>& str) noexcept {
821 return str;
822}
823
824template<>
825inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, xtd::wchar>(const std::basic_string<xtd::wchar>& str) noexcept {
826 return str;
827}
828
829template<>
830inline std::basic_string<xtd::char8> __xtd_convert_to_string<xtd::char8, char>(const std::basic_string<char>& str) noexcept {
831 return reinterpret_cast<const xtd::char8*>(str.c_str());
832}
833
834template<>
835inline std::basic_string<char> __xtd_convert_to_string<char, xtd::char8>(const std::basic_string<xtd::char8>& str) noexcept {
836 return reinterpret_cast<const char*>(str.c_str());
837}
838
839template<>
840inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, xtd::char32>(const std::basic_string<xtd::char32>& str) noexcept {
841 return __xtd_convert_to_string<xtd::char16>(__xtd_convert_to_string<char>(str));
842}
843
844template<>
845inline std::basic_string<xtd::char16> __xtd_convert_to_string<xtd::char16, xtd::wchar>(const std::basic_string<xtd::wchar>& str) noexcept {
846 return __xtd_convert_to_string<xtd::char16>(__xtd_convert_to_string<char>(str));
847}
848
849template<>
850inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, xtd::char16>(const std::basic_string<xtd::char16>& str) noexcept {
851 return __xtd_convert_to_string<xtd::char32>(__xtd_convert_to_string<char>(str));
852}
853
854template<>
855inline std::basic_string<xtd::char32> __xtd_convert_to_string<xtd::char32, xtd::wchar>(const std::basic_string<xtd::wchar>& str) noexcept {
856 return __xtd_convert_to_string<xtd::char32>(__xtd_convert_to_string<char>(str));
857}
858
859template<>
860inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, xtd::char16>(const std::basic_string<xtd::char16>& str) noexcept {
861 return __xtd_convert_to_string<xtd::wchar>(__xtd_convert_to_string<char>(str));
862}
863
864template<>
865inline std::basic_string<xtd::wchar> __xtd_convert_to_string<xtd::wchar, xtd::char32>(const std::basic_string<xtd::char32>& str) noexcept {
866 return __xtd_convert_to_string<xtd::wchar>(__xtd_convert_to_string<char>(str));
867}
Contains xtd::array class.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition array.hpp:61
const_iterator end() const noexcept override
Returns an iterator to the element following the last element of the enumerable.
Definition basic_array.hpp:178
const_iterator begin() const noexcept override
Returns an iterator to the first element of the enumerable.
Definition basic_array.hpp:134
Represents text as a sequence of character units.
Definition basic_string.hpp:71
basic_string pad_left(xtd::size total_width) const noexcept
Right-aligns the characters in this basic_string, padding with spaces on the left for a specified tot...
Definition basic_string.hpp:1543
xtd::size index_of_any(const xtd::array< value_type > &values) const noexcept
Reports the index of the first occurrence in this instance of any character in a specified array of c...
xtd::size last_index_of_any(const xtd::array< value_type > &values) const noexcept
Reports the index of the last occurrence in this instance of any character in a specified array of ch...
basic_string pad_right(xtd::size total_width) const noexcept
Left-aligns the characters in this basic_string, padding with spaces on the right for a specified tot...
Definition basic_string.hpp:1557
auto concat(const ienumerable< char_t > &second) const noexcept
Definition enumerable.hpp:185
static void throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current())
Throws an exption with specified exception case.
xtd::string format(const xtd::string &fmt, args_t &&... args)
Writes the text representation of the specified arguments list, to string using the specified format ...
Definition format.hpp:20
@ format
The format is not valid.
Definition exception_case.hpp:49
@ index_out_of_range
The index is out of range.
Definition exception_case.hpp:59
@ format_opened_bracket_without_end_bracket
The format contains open backet_without_end_bracket.
Definition exception_case.hpp:53
@ format_closing_bracket_without_open_bracket
The format contains close backet_without_open_bracket.
Definition exception_case.hpp:51
#define unused_
It may be used to suppress the "unused variable" or "unused local typedefs" compiler warnings when th...
Definition unused.hpp:30
@ character
Specifies that the text is trimmed to the nearest character.
Definition string_trimming.hpp:21
@ word
Specifies that text is trimmed to the nearest word.
Definition string_trimming.hpp:23
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
char8_t char8
Represents a 8-bit unicode character.
Definition char8.hpp:26
wchar_t wchar
Represents a wide character.
Definition wchar.hpp:24
int32_t int32
Represents a 32-bit signed integer.
Definition int32.hpp:23
char16_t char16
Represents a 16-bit unicode character.
Definition char16.hpp:26
char32_t char32
Represents a 32-bit unicode character.
Definition char32.hpp:23
string_split_options
Specifies whether applicable xtd::string::split method overloads include or omit empty substrings fro...
Definition string_split_options.hpp:14
@ none
The return value includes array elements that contain an empty string.
Definition string_split_options.hpp:16
@ remove_empty_entries
The return value does not include array elements that contain an empty string.
Definition string_split_options.hpp:18
@ u
The U key.
Definition console_key.hpp:128
@ separator
The Separator key.
Definition console_key.hpp:172
const_iterator begin() const
Returns an iterator to the beginning.
Definition read_only_span.hpp:183
string to_string() const noexcept override
Returns the string representation of this xtd::read_only_span <type_t> object.
Definition read_only_span.hpp:375
const_iterator end() const
Returns an iterator to the end.
Definition read_only_span.hpp:213
const_reverse_iterator crbegin() const
Returns a reverse iterator to the beginning.
Definition read_only_span.hpp:194
const_reference at(size_type pos) const
Gets the specified element with bounds checking.
Definition read_only_span.hpp:255
constexpr size_type length() const noexcept
Returns the length of the current read_only_span.
Definition read_only_span.hpp:229
const_reverse_iterator crend() const
Returns a reverse iterator to the end.
Definition read_only_span.hpp:197
xtd::array< std::remove_cv_t< type_t > > to_array() const noexcept
Copies the contents of this read_only_span into a new array.
Definition read_only_span.hpp:368