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