Rune Caster 1.0.0
Modern C++ Text Processing Framework
Loading...
Searching...
No Matches
unified_spell.cpp
Go to the documentation of this file.
1#include "spell_unified.hpp"
2#include "rune_sequence.hpp"
3#include <atomic>
4#include <sstream>
5
6namespace rune_caster {
7
8// === Static ID generation ===
9
10uint64_t Spell::generate_id() {
11 static std::atomic<uint64_t> next_id{1};
12 return next_id.fetch_add(1);
13}
14
15// === Constructors ===
16
17Spell::Spell() noexcept
18 : transform_([](const RuneSequence& input) { return input; })
19 , name_("Identity")
20 , description_("Identity transformation (no change)")
21 , id_(generate_id())
22 , is_composition_(false)
23 , composition_depth_(1) {
24}
25
27 std::string name,
28 std::string description)
29 : transform_(std::move(transform))
30 , name_(std::move(name))
31 , description_(std::move(description))
32 , id_(generate_id())
33 , is_composition_(false)
34 , composition_depth_(1) {
35}
36
37// === Core transformation ===
38
40 return transform_(input);
41}
42
43std::string Spell::operator()(std::string_view utf8_input) const {
44 auto sequence = RuneSequence::from_utf8(utf8_input);
45 auto result = transform_(sequence);
46 return result.to_utf8();
47}
48
49// === Pipeline composition ===
50
51Spell Spell::operator|(const Spell& next) const {
52 auto composed_transform = [this_transform = transform_, next_transform = next.transform_]
53 (const RuneSequence& input) -> RuneSequence {
54 auto intermediate = this_transform(input);
55 return next_transform(intermediate);
56 };
57
58 std::string composed_name = name_ + "|" + next.name_;
59 std::string composed_description = description_ + " → " + next.description_;
60
61 Spell result(composed_transform, composed_name, composed_description);
62 result.is_composition_ = true;
63 result.composition_depth_ = composition_depth_ + next.composition_depth_;
64
65 return result;
66}
67
68// === Validation and properties ===
69
70bool Spell::is_identity() const noexcept {
71 return name_ == "Identity" && !is_composition_;
72}
73
74// === Debugging and introspection ===
75
76std::string Spell::to_string() const {
77 std::ostringstream oss;
78 oss << "Spell{";
79 oss << "id=" << id_;
80 oss << ", name=\"" << name_ << "\"";
81 oss << ", description=\"" << description_ << "\"";
82 oss << ", composition=" << (is_composition_ ? "true" : "false");
83 oss << ", depth=" << composition_depth_;
84 oss << "}";
85 return oss.str();
86}
87
88RuneSequence Spell::test(const RuneSequence& test_input) const {
89 return transform_(test_input);
90}
91
92// === Static factory methods ===
93
95 return Spell{}; // Default constructor creates identity
96}
97
99 auto transform = [result = std::move(constant_result)]
100 (const RuneSequence&) -> RuneSequence {
101 return result;
102 };
103
104 return Spell(transform, "Constant", "Always returns the same result");
105}
106
108 const Spell& if_true,
109 const Spell& if_false) {
110 auto transform = [condition, if_true, if_false]
111 (const RuneSequence& input) -> RuneSequence {
112 if (condition(input)) {
113 return if_true(input);
114 } else {
115 return if_false(input);
116 }
117 };
118
119 std::string name = "Conditional(" + if_true.name() + "/" + if_false.name() + ")";
120 std::string description = "Conditional: " + if_true.description() + " OR " + if_false.description();
121
122 return Spell(transform, name, description);
123}
124
125} // namespace rune_caster
126
127// === User-defined literals ===
128
129namespace rune_caster::literals {
130
131Spell operator""_spell(const char* replacement_rule, size_t len) {
132 std::string rule(replacement_rule, len);
133
134 // Simple parser for "old -> new" format
135 auto arrow_pos = rule.find(" -> ");
136 if (arrow_pos == std::string::npos) {
137 // Just return identity if format is wrong
138 return Spell::identity();
139 }
140
141 std::string old_text = rule.substr(0, arrow_pos);
142 std::string new_text = rule.substr(arrow_pos + 4);
143
144 auto transform = [old_text, new_text](const RuneSequence& input) -> RuneSequence {
145 auto utf8_input = input.to_utf8();
146
147 // Simple string replacement
148 std::string result = utf8_input;
149 size_t pos = 0;
150 while ((pos = result.find(old_text, pos)) != std::string::npos) {
151 result.replace(pos, old_text.length(), new_text);
152 pos += new_text.length();
153 }
154
155 return RuneSequence::from_utf8(result);
156 };
157
158 std::string name = "Replace(\"" + old_text + "\" -> \"" + new_text + "\")";
159 std::string description = "Replace \"" + old_text + "\" with \"" + new_text + "\"";
160
161 return Spell(transform, name, description);
162}
163
164} // namespace rune_caster::literals
static RuneString from_utf8(std::string_view utf8_text)
Create a RuneString from UTF-8 text.
Unified spell object for text transformation.
RuneSequence test(const RuneSequence &test_input) const
Test the spell with sample input.
Spell operator|(const Spell &next) const
Compose with another spell (pipeline operator)
std::function< RuneSequence(const RuneSequence &)> transform_function
bool is_identity() const noexcept
Check if this spell is the identity transformation.
std::string to_string() const
Get a detailed string representation.
static Spell constant(RuneSequence constant_result)
Create a spell that always returns the same result.
const std::string & description() const noexcept
Get the spell description.
std::function< bool(const RuneSequence &)> validation_function
RuneSequence operator()(const RuneSequence &input) const
Apply the spell transformation.
static Spell identity()
Create an identity spell (no transformation)
const std::string & name() const noexcept
Get the spell name.
Spell() noexcept
Default constructor (identity spell)
static Spell conditional(validation_function condition, const Spell &if_true, const Spell &if_false)
Create a conditional spell.
RuneString RuneSequence
Backward compatibility alias for RuneString.