mimic++ v5
Loading...
Searching...
No Matches
String.hpp
Go to the documentation of this file.
1// // Copyright Dominic (DNKpp) Koepke 2024 - 2024.
2// // Distributed under the Boost Software License, Version 1.0.
3// // (See accompanying file LICENSE_1_0.txt or copy at
4// // https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_STRING_HPP
7#define MIMICPP_STRING_HPP
8
9#pragma once
10
11#include "mimic++/Fwd.hpp"
12#include "mimic++/Utility.hpp"
13
14#include <concepts>
15#include <functional>
16#include <ranges>
17#include <string>
18#include <string_view>
19#include <type_traits>
20
21namespace mimicpp
22{
102 template <typename T>
104 : public std::false_type
105 {
106 };
107
112 template <typename T>
114
118 template <>
119 struct is_character<char>
120 : public std::true_type
121 {
122 };
123
127 template <>
128 struct is_character<signed char>
129 : public std::true_type
130 {
131 };
132
136 template <>
137 struct is_character<unsigned char>
138 : public std::true_type
139 {
140 };
141
145 template <>
146 struct is_character<wchar_t>
147 : public std::true_type
148 {
149 };
150
154 template <>
155 struct is_character<char8_t>
156 : public std::true_type
157 {
158 };
159
163 template <>
164 struct is_character<char16_t>
165 : public std::true_type
166 {
167 };
168
172 template <>
173 struct is_character<char32_t>
174 : public std::true_type
175 {
176 };
177
196 template <satisfies<is_character> Char>
197 [[maybe_unused]]
199
203 template <>
204 [[maybe_unused]]
206
210 template <>
211 [[maybe_unused]]
213
217 template <>
218 [[maybe_unused]]
220
224 template <>
225 [[maybe_unused]]
227
231 template <>
232 [[maybe_unused]]
234
252 template <typename T>
253 using string_view_t = decltype(string_traits<std::remove_cvref_t<T>>::view(std::declval<T&>()));
254
259 template <typename T>
261
266 template <typename T>
267 requires std::is_pointer_v<T>
269 struct string_traits<T>
270 {
271 using char_t = std::remove_const_t<std::remove_pointer_t<T>>;
272 using view_t = std::basic_string_view<char_t>;
273
274 [[nodiscard]]
275 static constexpr view_t view(const std::remove_pointer_t<T>* str) noexcept
276 {
277 return view_t{str};
278 }
279 };
280
285 template <typename T>
286 requires std::is_array_v<T>
288 : public string_traits<std::remove_extent_t<T>*>
289 {
290 };
291
295 template <typename Char, typename Traits, typename Allocator>
296 struct string_traits<std::basic_string<Char, Traits, Allocator>>
297 {
298 using char_t = Char;
299 using string_t = std::basic_string<Char, Traits, Allocator>;
300 using view_t = std::basic_string_view<Char, Traits>;
301
302 [[nodiscard]]
303 static constexpr view_t view(const string_t& str) noexcept
304 {
305 return view_t{str};
306 }
307 };
308
312 template <typename Char, typename Traits>
313 struct string_traits<std::basic_string_view<Char, Traits>>
314 {
315 using char_t = Char;
316 using view_t = std::basic_string_view<Char, Traits>;
317
318 [[nodiscard]]
319 static constexpr view_t view(view_t str) noexcept
320 {
321 return str;
322 }
323 };
324
334 template <typename T>
335 concept string = requires {
337 requires std::regular<string_char_t<T>>;
338 requires std::ranges::contiguous_range<string_view_t<T>>;
339 requires std::ranges::sized_range<string_view_t<T>>;
340 requires std::ranges::borrowed_range<string_view_t<T>>;
341 requires std::same_as<
343 std::ranges::range_value_t<string_view_t<T>>>;
344 };
345
367 template <satisfies<is_character> Char>
369
375 template <typename String>
378 && requires(const string_case_fold_converter<string_char_t<String>> converter, string_view_t<String> view) {
379 { std::invoke(converter, std::move(view)) } -> std::ranges::forward_range;
380 } && requires(std::invoke_result_t<string_case_fold_converter<string_char_t<String>>, string_view_t<String>> normalized) {
381 requires std::same_as<
383 std::ranges::range_value_t<decltype(normalized)>>;
384 };
385}
386
387namespace mimicpp::detail
388{
389 template <typename View, typename Char>
390 concept compatible_string_view_with = is_character_v<Char>
391 && std::ranges::borrowed_range<View>
392 && std::ranges::contiguous_range<View>
393 && std::ranges::sized_range<View>
394 && std::same_as<Char, std::ranges::range_value_t<View>>;
395}
396
397#ifndef MIMICPP_CONFIG_EXPERIMENTAL_UNICODE_STR_MATCHER
398
403template <>
405{
406 template <detail::compatible_string_view_with<char> String>
407 [[nodiscard]]
408 constexpr auto operator()(String&& str) const
409 {
410 return std::views::all(std::forward<String>(str))
411 | std::views::transform(
412 [](const char c) noexcept {
413 // see notes of https://en.cppreference.com/w/cpp/string/byte/toupper
414 // This approach will fail, if str actually contains an utf8-encoded string.
415 return static_cast<char>(
416 static_cast<unsigned char>(std::toupper(c)));
417 });
418 }
419};
420
421#else
422
423 #if __has_include(<uni_algo/case.h>) \
424 && __has_include(<uni_algo/conv.h>)
425 #include <uni_algo/case.h>
426 #include <uni_algo/conv.h>
427 #else
428 #error "Unable to find uni_algo includes."
429 #endif
430
435template <>
437{
438 template <detail::compatible_string_view_with<char> String>
439 [[nodiscard]]
440 constexpr auto operator()(String&& str) const
441 {
442 return una::cases::to_casefold_utf8(
443 std::string_view{
444 std::ranges::data(str),
445 std::ranges::size(str)});
446 }
447};
448
453template <>
455{
456 template <detail::compatible_string_view_with<wchar_t> String>
457 [[nodiscard]]
458 constexpr auto operator()(String&& str) const
459 {
460 return una::cases::to_casefold_utf16(
461 std::wstring_view{
462 std::ranges::data(str),
463 std::ranges::size(str)});
464 }
465};
466
471template <>
473{
474 template <detail::compatible_string_view_with<char8_t> String>
475 [[nodiscard]]
476 constexpr auto operator()(String&& str) const
477 {
478 return una::cases::to_casefold_utf8(
479 std::u8string_view{
480 std::ranges::data(str),
481 std::ranges::size(str)});
482 }
483};
484
489template <>
491{
492 template <detail::compatible_string_view_with<char16_t> String>
493 [[nodiscard]]
494 constexpr auto operator()(String&& str) const
495 {
496 return una::cases::to_casefold_utf16(
497 std::u16string_view{
498 std::ranges::data(str),
499 std::ranges::size(str)});
500 }
501};
502
507template <>
509{
510 template <detail::compatible_string_view_with<char32_t> String>
511 [[nodiscard]]
512 constexpr auto operator()(String&& str) const
513 {
514 return una::utf8to32<char8_t, char32_t>(
515 una::cases::to_casefold_utf8(
516 una::utf32to8u(
517 std::u32string_view{
518 std::ranges::data(str),
519 std::ranges::size(str)})));
520 }
521};
522
523#endif
524
525#endif
Determines, whether the given type supports string normalization.
Definition String.hpp:376
Determines, whether the given type can be used as a string-type.
Definition String.hpp:335
constexpr bool is_character_v
Convenience boolean-constant to the result of is_character trait.
Definition String.hpp:113
constexpr StringViewT string_literal_prefix< char16_t >
char16_t specialization.
Definition String.hpp:226
constexpr StringViewT string_literal_prefix< wchar_t >
wchar_t specialization.
Definition String.hpp:212
constexpr StringViewT string_literal_prefix< char32_t >
char32_t specialization.
Definition String.hpp:233
constexpr StringViewT string_literal_prefix< char >
char specialization.
Definition String.hpp:205
constexpr StringViewT string_literal_prefix< char8_t >
char8_t specialization.
Definition String.hpp:219
constexpr StringViewT string_literal_prefix
Primary template, yielding an empty string.
Definition String.hpp:198
decltype(string_traits< std::remove_cvref_t< T > >::view(std::declval< T & >())) string_view_t
Computes the view type for the given string.
Definition String.hpp:253
typename string_traits< std::remove_cvref_t< T > >::char_t string_char_t
Computes the character type for the given string.
Definition String.hpp:260
Definition BoostTest.hpp:20
std::basic_string_view< CharT, CharTraitsT > StringViewT
Definition Fwd.hpp:343
Primary template, which always yields false.
Definition String.hpp:105
constexpr auto operator()(String &&str) const
Definition String.hpp:408
Primary template, purposely undefined.
Definition String.hpp:368
std::remove_const_t< std::remove_pointer_t< T > > char_t
Definition String.hpp:271
std::basic_string_view< char_t > view_t
Definition String.hpp:272
static constexpr view_t view(const std::remove_pointer_t< T > *str) noexcept
Definition String.hpp:275
std::basic_string_view< Char, Traits > view_t
Definition String.hpp:300
std::basic_string< Char, Traits, Allocator > string_t
Definition String.hpp:299
static constexpr view_t view(const string_t &str) noexcept
Definition String.hpp:303
static constexpr view_t view(view_t str) noexcept
Definition String.hpp:319
std::basic_string_view< Char, Traits > view_t
Definition String.hpp:316
Definition Fwd.hpp:317