C++ Essence Library 0.1.0
A Utility Library for Modern C++ Programming
Loading...
Searching...
No Matches
literal_string.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 "../zstring_view.hpp"
26
27#include <algorithm>
28#include <array>
29#include <compare>
30#include <concepts>
31#include <cstddef>
32#include <span>
33#include <string_view>
34
35namespace essence::meta {
40 template <std::size_t N>
42 std::array<char, N + 1> elements;
43
44 consteval literal_string() noexcept : elements{} {}
45
46 consteval literal_string(const char (&data)[N + 1]) noexcept // NOLINT(*-explicit-constructor)
47 : elements{std::to_array(data)} {} // NOLINT(*-explicit-constructor)
48
49 template <std::size_t... Ns>
50 consteval literal_string(std::span<const char, Ns>... data) noexcept // NOLINT(*-explicit-constructor)
51 : elements{} { // NOLINT(*-explicit-constructor)
52 auto iter = elements.begin();
53
54 ((iter = std::ranges::copy(data, iter).out), ..., static_cast<void>(iter));
55 }
56
57 template <std::size_t... Ns>
58 consteval literal_string(const literal_string<Ns>&... data) noexcept // NOLINT(*-explicit-constructor)
59 : elements{} { // NOLINT(*-explicit-constructor)
60 auto iter = elements.begin();
61
62 ((iter = std::ranges::copy(data, iter).out), ..., static_cast<void>(iter));
63 }
64
65 template <std::same_as<char>... Ts>
66 requires(sizeof...(Ts) == N)
67 consteval literal_string(Ts... chars) noexcept : elements{chars...} {} // NOLINT(*-explicit-constructor)
68
69 constexpr char& operator[](std::size_t index) noexcept {
70 return elements[index];
71 }
72
73 constexpr const char& operator[](std::size_t index) const noexcept {
74 return elements[index];
75 }
76
77 constexpr operator std::string_view() const noexcept { // NOLINT(*-explicit-constructor)
78 return std::string_view{elements.data(), size()};
79 }
80
81 constexpr operator zstring_view() const noexcept { // NOLINT(*-explicit-constructor)
82 return zstring_view{elements.data(), size()};
83 }
84
85 [[nodiscard]] static constexpr bool empty() noexcept {
86 return size() == 0;
87 }
88
89 [[nodiscard]] static constexpr std::size_t size() noexcept {
90 return N;
91 }
92
93 [[nodiscard]] constexpr char& front() noexcept {
94 return elements.front();
95 }
96
97 [[nodiscard]] constexpr const char& front() const noexcept {
98 return elements.front();
99 }
100
101 [[nodiscard]] constexpr char& back() noexcept {
102 return elements[size() - 1];
103 }
104
105 [[nodiscard]] constexpr const char& back() const noexcept {
106 return elements[size() - 1];
107 }
108
109 [[nodiscard]] constexpr auto begin() noexcept {
110 return elements.begin();
111 }
112
113 [[nodiscard]] constexpr auto begin() const noexcept {
114 return elements.begin();
115 }
116
117 [[nodiscard]] constexpr auto end() noexcept {
118 return elements.begin() + size();
119 }
120
121 [[nodiscard]] constexpr auto end() const noexcept {
122 return elements.begin() + size();
123 }
124
125 [[nodiscard]] constexpr char* data() noexcept {
126 return elements.data();
127 }
128
129 [[nodiscard]] constexpr const char* data() const noexcept {
130 return elements.data();
131 }
132
133 [[nodiscard]] constexpr const char* c_str() const noexcept {
134 return elements.data();
135 }
136
137 [[nodiscard]] constexpr bool contains(char c) const noexcept {
138 return std::find(begin(), end(), c) != end();
139 }
140
141 [[nodiscard]] constexpr bool contains(std::string_view str) const noexcept {
142 return str.size() <= size() ? std::search(begin(), end(), str.begin(), str.end()) != end() : false;
143 }
144
145 [[nodiscard]] constexpr auto to_span() const noexcept {
146 return std::span<const char, N>{data(), size()};
147 }
148 };
149
150 template <std::size_t N>
151 literal_string(const char (&)[N]) -> literal_string<N - 1>;
152
153 template <std::size_t... Ns>
154 literal_string(std::span<const char, Ns>...) -> literal_string<(Ns + ...)>;
155
156 template <std::size_t... Ns>
157 literal_string(const literal_string<Ns>&...) -> literal_string<(Ns + ...)>;
158
159 template <std::same_as<char>... Ts>
160 literal_string(Ts...) -> literal_string<sizeof...(Ts)>;
161
162 template <std::size_t M, std::size_t N>
163 constexpr auto operator<=>(const literal_string<M>& left, const literal_string<N>& right) noexcept {
164 return static_cast<std::string_view>(left).compare(static_cast<std::string_view>(right)) <=> 0;
165 }
166
167 template <std::size_t M, std::size_t N>
168 constexpr bool operator==(const literal_string<M>& left, const literal_string<N>& right) noexcept {
169 return static_cast<std::string_view>(left) == static_cast<std::string_view>(right);
170 }
171
172 template <std::size_t M, std::size_t N>
173 consteval auto operator+(const literal_string<M>& left, const literal_string<N>& right) noexcept {
174 return literal_string{left, right};
175 }
176} // namespace essence::meta
Definition zstring_view.hpp:34
A literal type of collection of chars.
Definition literal_string.hpp:41