mimic++ v4
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
336 {
338 requires std::regular<string_char_t<T>>;
339 requires std::ranges::contiguous_range<string_view_t<T>>;
340 requires std::ranges::sized_range<string_view_t<T>>;
341 requires std::ranges::borrowed_range<string_view_t<T>>;
342 requires std::same_as<
344 std::ranges::range_value_t<string_view_t<T>>>;
345 };
346
368 template <satisfies<is_character> Char>
370
376 template <typename String>
379 && requires(const string_case_fold_converter<string_char_t<String>> converter, string_view_t<String> view)
380 {
381 { std::invoke(converter, std::move(view)) } -> std::ranges::forward_range;
382 }
383 && requires(std::invoke_result_t<string_case_fold_converter<string_char_t<String>>, string_view_t<String>> normalized)
384 {
385 requires std::same_as<
387 std::ranges::range_value_t<decltype(normalized)>>;
388 };
389}
390
391namespace mimicpp::detail
392{
393 template <typename View, typename Char>
394 concept compatible_string_view_with = is_character_v<Char>
395 && std::ranges::borrowed_range<View>
396 && std::ranges::contiguous_range<View>
397 && std::ranges::sized_range<View>
398 && std::same_as<Char, std::ranges::range_value_t<View>>;
399}
400
401#ifndef MIMICPP_CONFIG_EXPERIMENTAL_UNICODE_STR_MATCHER
402
407template <>
409{
410 template <detail::compatible_string_view_with<char> String>
411 [[nodiscard]]
412 constexpr auto operator ()(String&& str) const
413 {
414 return std::views::all(std::forward<String>(str))
415 | std::views::transform(
416 [](const char c) noexcept
417 {
418 // see notes of https://en.cppreference.com/w/cpp/string/byte/toupper
419 // This approach will fail, if str actually contains an utf8-encoded string.
420 return static_cast<char>(
421 static_cast<unsigned char>(std::toupper(c)));
422 });
423 }
424};
425
426#else
427
428#if __has_include(<uni_algo/case.h>) \
429 && __has_include(<uni_algo/conv.h>)
430#include <uni_algo/case.h>
431#include <uni_algo/conv.h>
432#else
433 #error "Unable to find uni_algo includes."
434#endif
435
440template <>
442{
443 template <detail::compatible_string_view_with<char> String>
444 [[nodiscard]]
445 constexpr auto operator ()(String&& str) const
446 {
447 return una::cases::to_casefold_utf8(
448 std::string_view{
449 std::ranges::data(str),
450 std::ranges::size(str)
451 });
452 }
453};
454
459template <>
461{
462 template <detail::compatible_string_view_with<wchar_t> String>
463 [[nodiscard]]
464 constexpr auto operator ()(String&& str) const
465 {
466 return una::cases::to_casefold_utf16(
467 std::wstring_view{
468 std::ranges::data(str),
469 std::ranges::size(str)
470 });
471 }
472};
473
478template <>
480{
481 template <detail::compatible_string_view_with<char8_t> String>
482 [[nodiscard]]
483 constexpr auto operator ()(String&& str) const
484 {
485 return una::cases::to_casefold_utf8(
486 std::u8string_view{
487 std::ranges::data(str),
488 std::ranges::size(str)
489 });
490 }
491};
492
497template <>
499{
500 template <detail::compatible_string_view_with<char16_t> String>
501 [[nodiscard]]
502 constexpr auto operator ()(String&& str) const
503 {
504 return una::cases::to_casefold_utf16(
505 std::u16string_view{
506 std::ranges::data(str),
507 std::ranges::size(str)
508 });
509 }
510};
511
516template <>
518{
519 template <detail::compatible_string_view_with<char32_t> String>
520 [[nodiscard]]
521 constexpr auto operator ()(String&& str) const
522 {
523 return una::utf8to32<char8_t, char32_t>(
524 una::cases::to_casefold_utf8(
525 una::utf32to8u(
526 std::u32string_view{
527 std::ranges::data(str),
528 std::ranges::size(str)
529 })));
530 }
531};
532
533#endif
534
535#endif
Determines, whether the given type supports string normalization.
Definition String.hpp:377
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:208
Primary template, which always yields false.
Definition String.hpp:105
Primary template, purposely undefined.
Definition String.hpp:369
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:168