C++ Essence Library 0.1.0
A Utility Library for Modern C++ Programming
Loading...
Searching...
No Matches
literal_string_util.hpp
1/*
2 * Copyright (c) 2024 The RefValue Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include "literal_string.hpp"
26
27#include <algorithm>
28#include <array>
29#include <cstddef>
30#include <span>
31#include <string_view>
32#include <utility>
33
34namespace essence::meta {
40 template <literal_string S, literal_string Delimiter>
41 struct split_of {
42 static constexpr auto value = [] {
43 constexpr std::string_view view{S};
44 constexpr auto group_count =
45 std::count_if(S.begin(), S.end(), [](char c) { return Delimiter.contains(c); }) + 1;
46 std::array<std::string_view, group_count> result{};
47
48 auto iter = result.begin();
49
50 for (std::size_t start_index = 0, end_index = view.find_first_of(Delimiter);;
51 start_index = end_index + 1, end_index = view.find_first_of(Delimiter, start_index)) {
52 *(iter++) = view.substr(start_index, end_index - start_index);
53
54 if (end_index == std::string_view::npos) {
55 break;
56 }
57 }
58
59 return result;
60 }();
61 };
62
68 template <literal_string S, literal_string Delimiter>
69 inline constexpr auto&& split_of_v = split_of<S, Delimiter>::value;
70
76 template <literal_string S, literal_string Delimiter>
77 struct split {
78 static constexpr std::string_view view{S};
79 static constexpr auto value = [] {
80 constexpr auto group_count = [] {
81 std::size_t count{};
82 std::size_t index{};
83
84 while ((index = view.find(Delimiter, index)) != std::string_view::npos) {
85 count++;
86 index += Delimiter.size();
87 }
88
89 return count + 1;
90 }();
91 std::array<std::string_view, group_count> result{};
92
93 auto iter = result.begin();
94
95 for (std::size_t start_index = 0, end_index = view.find(Delimiter);;
96 start_index = end_index + Delimiter.size(), end_index = view.find(Delimiter, start_index)) {
97 *(iter++) = view.substr(start_index, end_index - start_index);
98
99 if (end_index == std::string_view::npos) {
100 break;
101 }
102 }
103
104 return result;
105 }();
106 };
107
113 template <literal_string S, literal_string Delimiter>
114 inline constexpr auto&& split_v = split<S, Delimiter>::value;
115
121 template <literal_string S, char C>
122 struct remove_char {
123 static constexpr auto value = [] {
124 struct removal_metadata {
125 decltype(S) result;
126 std::size_t actual_size;
127 };
128
129 constexpr auto metadata = [] {
130 auto result = S;
131 auto removal_end = std::remove(result.begin(), result.end(), C);
132
133 return removal_metadata{
134 .result = std::move(result),
135 .actual_size = static_cast<std::size_t>(removal_end - result.begin()),
136 };
137 }();
138
139 literal_string<metadata.actual_size> result;
140
141 std::copy(metadata.result.begin(), metadata.result.begin() + metadata.actual_size, result.begin());
142
143 return result;
144 }();
145 };
146
152 template <literal_string S, char C>
153 inline constexpr auto&& remove_char_v = remove_char<S, C>::value;
154
160 template <literal_string S, literal_string Removal>
161 struct remove {
162 static constexpr auto groups = split_v<S, Removal>;
163 static constexpr auto value = [] {
164 return []<std::size_t... Is>(std::index_sequence<Is...>) {
165 return literal_string{
166 std::span<const char, groups[Is].size()>{groups[Is].data(), groups[Is].size()}...};
167 }(std::make_index_sequence<groups.size()>{});
168 }();
169 };
170
176 template <literal_string S, literal_string Removal>
177 inline constexpr auto&& remove_v = remove<S, Removal>::value;
178} // namespace essence::meta
A literal type of collection of chars.
Definition literal_string.hpp:41
Removes a character from a literal string.
Definition literal_string_util.hpp:122
Removes a substring from a literal string.
Definition literal_string_util.hpp:161
Splits a literal string with a set of delimiters.
Definition literal_string_util.hpp:41
Splits a literal string with a delimiter.
Definition literal_string_util.hpp:77