Rune Caster 1.0.0
Modern C++ Text Processing Framework
Loading...
Searching...
No Matches
rune_sequence.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <string>
5#include <string_view>
6#include <iterator>
7#include <ranges>
8#include <span>
9
10#include "rune.hpp"
11#include "language.hpp"
12
13namespace rune_caster {
14
27public:
28 // === STL-compatible typedefs ===
30 using size_type = std::size_t;
31 using difference_type = std::ptrdiff_t;
32 using reference = Rune&;
33 using const_reference = const Rune&;
34 using pointer = Rune*;
35 using const_pointer = const Rune*;
36 using iterator = std::vector<Rune>::iterator;
37 using const_iterator = std::vector<Rune>::const_iterator;
38 using reverse_iterator = std::vector<Rune>::reverse_iterator;
39 using const_reverse_iterator = std::vector<Rune>::const_reverse_iterator;
40
41 // === Special constants ===
42 static constexpr size_type npos = std::string::npos;
43
44private:
45 std::vector<Rune> runes_;
46 language::Code primary_language_;
47
48public:
49 // === Constructors (API Design Document enhanced) ===
50
54 RuneString() noexcept = default;
55
60 explicit RuneString(language::Code primary_lang) noexcept;
61
66 explicit RuneString(std::string_view utf8);
67
72 explicit RuneString(std::u16string_view utf16);
73
78 explicit RuneString(std::u32string_view utf32);
79
84 RuneString(std::initializer_list<Rune> runes);
85
92 template<std::input_iterator It>
93 requires std::convertible_to<std::iter_value_t<It>, Rune>
94 RuneString(It first, It last);
95
101 template<std::ranges::input_range R>
102 requires std::convertible_to<std::ranges::range_value_t<R>, Rune>
103 explicit RuneString(R&& range);
104
105 // === Copy/Move semantics ===
106 RuneString(const RuneString&) = default;
107 RuneString(RuneString&&) noexcept = default;
108 RuneString& operator=(const RuneString&) = default;
109 RuneString& operator=(RuneString&&) noexcept = default;
110 ~RuneString() = default;
111
112 // === Iterator access ===
113
114 iterator begin() noexcept { return runes_.begin(); }
115 const_iterator begin() const noexcept { return runes_.begin(); }
116 const_iterator cbegin() const noexcept { return runes_.cbegin(); }
117
118 iterator end() noexcept { return runes_.end(); }
119 const_iterator end() const noexcept { return runes_.end(); }
120 const_iterator cend() const noexcept { return runes_.cend(); }
121
122 reverse_iterator rbegin() noexcept { return runes_.rbegin(); }
123 const_reverse_iterator rbegin() const noexcept { return runes_.rbegin(); }
124 const_reverse_iterator crbegin() const noexcept { return runes_.crbegin(); }
125
126 reverse_iterator rend() noexcept { return runes_.rend(); }
127 const_reverse_iterator rend() const noexcept { return runes_.rend(); }
128 const_reverse_iterator crend() const noexcept { return runes_.crend(); }
129
130 // === Capacity ===
131
132 [[nodiscard]] bool empty() const noexcept { return runes_.empty(); }
133 [[nodiscard]] size_type size() const noexcept { return runes_.size(); }
134 [[nodiscard]] size_type length() const noexcept { return size(); }
135 [[nodiscard]] size_type max_size() const noexcept { return runes_.max_size(); }
136
137 void reserve(size_type new_cap) { runes_.reserve(new_cap); }
138 [[nodiscard]] size_type capacity() const noexcept { return runes_.capacity(); }
139 void shrink_to_fit() { runes_.shrink_to_fit(); }
140
141 // === Element access ===
142
143 [[nodiscard]] reference at(size_type pos) { return runes_.at(pos); }
144 [[nodiscard]] const_reference at(size_type pos) const { return runes_.at(pos); }
145
146 [[nodiscard]] reference operator[](size_type pos) noexcept { return runes_[pos]; }
147 [[nodiscard]] const_reference operator[](size_type pos) const noexcept { return runes_[pos]; }
148
149 [[nodiscard]] reference front() { return runes_.front(); }
150 [[nodiscard]] const_reference front() const { return runes_.front(); }
151
152 [[nodiscard]] reference back() { return runes_.back(); }
153 [[nodiscard]] const_reference back() const { return runes_.back(); }
154
155 [[nodiscard]] pointer data() noexcept { return runes_.data(); }
156 [[nodiscard]] const_pointer data() const noexcept { return runes_.data(); }
157
158 // === Views ===
159
163 [[nodiscard]] std::span<Rune> span() noexcept { return std::span<Rune>(runes_.data(), runes_.size()); }
164
168 [[nodiscard]] std::span<const Rune> span() const noexcept { return std::span<const Rune>(runes_.data(), runes_.size()); }
169
175 [[nodiscard]] std::span<const Rune> slice_view(size_type start, size_type length = npos) const noexcept {
176 if (start >= size()) return {};
177 size_type actual = (length == npos || start + length > size()) ? size() - start : length;
178 return std::span<const Rune>(data() + start, actual);
179 }
180
181 [[nodiscard]] std::span<Rune> slice_view(size_type start, size_type length = npos) noexcept {
182 if (start >= size()) return {};
183 size_type actual = (length == npos || start + length > size()) ? size() - start : length;
184 return std::span<Rune>(data() + start, actual);
185 }
186
187 // === Implicit conversion to span ===
188 operator std::span<Rune>() noexcept { return span(); }
189 operator std::span<const Rune>() const noexcept { return span(); }
190
191 // === Modifiers ===
192
193 void clear() noexcept { runes_.clear(); }
194
195 iterator insert(const_iterator pos, const Rune& rune) {
196 return runes_.insert(pos, rune);
197 }
198
200 return runes_.insert(pos, std::move(rune));
201 }
202
203 template<class... Args>
204 iterator emplace(const_iterator pos, Args&&... args) {
205 return runes_.emplace(pos, std::forward<Args>(args)...);
206 }
207
209 return runes_.erase(pos);
210 }
211
213 return runes_.erase(first, last);
214 }
215
216 void push_back(const Rune& rune) {
217 runes_.push_back(rune);
218 }
219
220 void push_back(Rune&& rune) {
221 runes_.push_back(std::move(rune));
222 }
223
224 template<class... Args>
225 reference emplace_back(Args&&... args) {
226 return runes_.emplace_back(std::forward<Args>(args)...);
227 }
228
229 void pop_back() {
230 runes_.pop_back();
231 }
232
233 void resize(size_type count) {
234 runes_.resize(count);
235 }
236
237 void resize(size_type count, const Rune& value) {
238 runes_.resize(count, value);
239 }
240
241 void swap(RuneString& other) noexcept {
242 runes_.swap(other.runes_);
243 std::swap(primary_language_, other.primary_language_);
244 }
245
246 // === String operations (API Design Document requirement) ===
247
252 [[nodiscard]] language::Code primary_language() const noexcept {
253 return primary_language_;
254 }
255
261 primary_language_ = lang;
262 }
263
268 [[nodiscard]] std::string to_utf8() const;
269
274 [[nodiscard]] std::u16string to_utf16() const;
275
280 [[nodiscard]] std::u32string to_utf32() const;
281
286 RuneString& append(const RuneString& other);
287
292 RuneString& append(const Rune& rune);
293
298 RuneString& append(std::string_view utf8);
299
306 [[nodiscard]] RuneString substr(size_type start, size_type length = npos) const;
307
308 // === Search operations (API Design Document requirement) ===
309
316 [[nodiscard]] size_type find(const Rune& rune, size_type pos = 0) const noexcept;
317
324 [[nodiscard]] size_type find(const RuneString& str, size_type pos = 0) const noexcept;
325
331 [[nodiscard]] bool contains(const Rune& rune) const noexcept;
332
338 [[nodiscard]] bool contains(const RuneString& str) const noexcept;
339
340 // === Factory methods (API Design Document requirement) ===
341
347 static RuneString from_utf8(std::string_view utf8_text);
348
355 static RuneString from_utf8(std::string_view utf8_text, language::Code lang);
356
362 static RuneString from_utf16(std::u16string_view utf16_text);
363
369 static RuneString from_utf32(std::u32string_view utf32_text);
370
371 // === Comparison operators (C++20 three-way comparison) ===
372
373 [[nodiscard]] auto operator<=>(const RuneString& other) const noexcept = default;
374 [[nodiscard]] bool operator==(const RuneString& other) const noexcept = default;
375
376 // === String concatenation operators ===
377
378 RuneString& operator+=(const RuneString& other) { return append(other); }
379 RuneString& operator+=(const Rune& rune) { return append(rune); }
380 RuneString& operator+=(std::string_view utf8) { return append(utf8); }
381
382 [[nodiscard]] friend RuneString operator+(const RuneString& lhs, const RuneString& rhs) {
383 RuneString result = lhs;
384 result += rhs;
385 return result;
386 }
387
388 [[nodiscard]] friend RuneString operator+(const RuneString& lhs, const Rune& rhs) {
389 RuneString result = lhs;
390 result += rhs;
391 return result;
392 }
393
394 [[nodiscard]] friend RuneString operator+(const Rune& lhs, const RuneString& rhs) {
395 RuneString result;
396 result.reserve(1 + rhs.size());
397 result += lhs;
398 result += rhs;
399 return result;
400 }
401};
402
403// === Template implementations ===
404
405template<std::input_iterator It>
406requires std::convertible_to<std::iter_value_t<It>, Rune>
407RuneString::RuneString(It first, It last)
408 : runes_(first, last)
409 , primary_language_(language::Code::Unknown)
410{
411}
412
413template<std::ranges::input_range R>
414requires std::convertible_to<std::ranges::range_value_t<R>, Rune>
416 : runes_(std::ranges::begin(range), std::ranges::end(range))
417 , primary_language_(language::Code::Unknown)
418{
419}
420
421// === Backward compatibility alias ===
422
430
431// === Free functions ===
432
438inline void swap(RuneString& lhs, RuneString& rhs) noexcept {
439 lhs.swap(rhs);
440}
441
442} // namespace rune_caster
443
444// === STL interoperability helpers ===
445#include <functional>
446#include <ranges>
447
448namespace std::ranges {
449 template<>
451}
452
453namespace std {
454 template<>
455 struct hash<rune_caster::RuneString> {
456 size_t operator()(const rune_caster::RuneString& rs) const noexcept {
457 return std::hash<std::string>{}(rs.to_utf8());
458 }
459 };
460}
A sequence container for Rune objects (API Design Document: RuneString)
reference emplace_back(Args &&... args)
reference operator[](size_type pos) noexcept
std::vector< Rune >::iterator iterator
bool contains(const Rune &rune) const noexcept
Check if the string contains a Rune.
bool empty() const noexcept
reverse_iterator rbegin() noexcept
void swap(RuneString &other) noexcept
std::span< const Rune > span() const noexcept
Get a read-only span view of the underlying runes.
static RuneString from_utf16(std::u16string_view utf16_text)
Create a RuneString from UTF-16 text.
friend RuneString operator+(const RuneString &lhs, const Rune &rhs)
std::vector< Rune >::const_iterator const_iterator
iterator emplace(const_iterator pos, Args &&... args)
const_iterator begin() const noexcept
std::ptrdiff_t difference_type
void push_back(Rune &&rune)
friend RuneString operator+(const RuneString &lhs, const RuneString &rhs)
const_reverse_iterator rend() const noexcept
language::Code primary_language() const noexcept
Get the primary language of the sequence.
const_iterator cbegin() const noexcept
iterator erase(const_iterator first, const_iterator last)
RuneString() noexcept=default
Default constructor.
RuneString & operator+=(std::string_view utf8)
const_reference back() const
const_reverse_iterator rbegin() const noexcept
static RuneString from_utf8(std::string_view utf8_text)
Create a RuneString from UTF-8 text.
std::span< Rune > span() noexcept
Get a mutable span view of the underlying runes.
const_iterator cend() const noexcept
const_reverse_iterator crbegin() const noexcept
std::vector< Rune >::reverse_iterator reverse_iterator
void reserve(size_type new_cap)
iterator insert(const_iterator pos, const Rune &rune)
static constexpr size_type npos
std::span< const Rune > slice_view(size_type start, size_type length=npos) const noexcept
Get a sub-view (lazy slice) without copying.
iterator insert(const_iterator pos, Rune &&rune)
iterator erase(const_iterator pos)
const_reference operator[](size_type pos) const noexcept
void push_back(const Rune &rune)
void set_primary_language(language::Code lang) noexcept
Set the primary language of the sequence.
reverse_iterator rend() noexcept
size_type find(const Rune &rune, size_type pos=0) const noexcept
Find first occurrence of a Rune.
static RuneString from_utf32(std::u32string_view utf32_text)
Create a RuneString from UTF-32 text.
reference at(size_type pos)
friend RuneString operator+(const Rune &lhs, const RuneString &rhs)
RuneString & operator+=(const Rune &rune)
const_reverse_iterator crend() const noexcept
std::vector< Rune >::const_reverse_iterator const_reverse_iterator
std::u16string to_utf16() const
Convert the sequence to UTF-16 string.
size_type size() const noexcept
const_pointer data() const noexcept
RuneString & append(const RuneString &other)
Append another RuneString.
void resize(size_type count, const Rune &value)
size_type max_size() const noexcept
const_reference at(size_type pos) const
std::u32string to_utf32() const
Convert the sequence to UTF-32 string.
const_reference front() const
std::span< Rune > slice_view(size_type start, size_type length=npos) noexcept
const_iterator end() const noexcept
RuneString substr(size_type start, size_type length=npos) const
Create a substring.
std::string to_utf8() const
Convert the sequence to UTF-8 string.
iterator end() noexcept
size_type capacity() const noexcept
size_type length() const noexcept
pointer data() noexcept
iterator begin() noexcept
void resize(size_type count)
Represents a single textual unit with Unicode and linguistic properties.
Definition rune.hpp:23
Language identification and localization support.
Language detection and identification functionality.
Definition concepts.hpp:15
Code
Enumeration of supported language codes.
Definition language.hpp:43
RuneString RuneSequence
Backward compatibility alias for RuneString.
void swap(RuneString &lhs, RuneString &rhs) noexcept
Swap two RuneString objects.
constexpr bool enable_borrowed_range< rune_caster::RuneString >
size_t operator()(const rune_caster::RuneString &rs) const noexcept