22template<
typename FirstSpell,
typename SecondSpell>
29 FirstSpell first_spell_;
30 SecondSpell second_spell_;
31 std::string description_;
43 : first_spell_(
std::move(first))
44 , second_spell_(
std::move(second))
47 static_assert(std::same_as<typename FirstSpell::output_type, typename SecondSpell::input_type>,
48 "Output type of first spell must match input type of second spell");
57 auto intermediate = first_spell_(input);
58 return second_spell_(intermediate);
65 std::string
name()
const override {
66 return first_spell_.name() +
"→" + second_spell_.name();
72 const FirstSpell&
first_spell() const noexcept {
return first_spell_; }
77 const SecondSpell&
second_spell() const noexcept {
return second_spell_; }
93template<
typename FirstSpell,
typename SecondSpell>
94auto compose(FirstSpell&& first, SecondSpell&& second) {
100 std::forward<FirstSpell>(first),
101 std::forward<SecondSpell>(second)
116template<
typename Spell>
133template<
typename Spell>
136 static_assert(std::same_as<typename Spell::output_type, RuneSequence>,
137 "Spell must output RuneSequence for string conversion");
140 auto result =
spell(sequence);
141 return result.to_utf8();
147using composition::SpellComposition;
static RuneString from_utf8(std::string_view utf8_text)
Create a RuneString from UTF-8 text.
Unified spell object for text transformation.
Composition of two spells into a single spell pipeline.
std::string description() const override
Get the spell's description.
const SecondSpell & second_spell() const noexcept
Get the second spell in the composition.
std::string name() const override
Get the spell's name.
typename SecondSpell::output_type output_type
constexpr SpellComposition(FirstSpell first, SecondSpell second)
Construct a spell composition.
output_type operator()(const input_type &input) const override
Apply the composed spells.
const FirstSpell & first_spell() const noexcept
Get the first spell in the composition.
typename FirstSpell::input_type input_type
Concept for spells that can be chained together.
Concept defining what makes a valid spell.
Concept for spells that work with specific input types.
RuneSequence cast_spell(const RuneSequence &input, const Spell &spell)
Helper function for casting spells on RuneSequence.
auto compose(FirstSpell &&first, SecondSpell &&second)
Compose two spells into a single spell pipeline.
RuneString RuneSequence
Backward compatibility alias for RuneString.
spell_base< RuneSequence > sequence_spell
Most common spell type: RuneSequence -> RuneSequence.