1//! @file register_design_pattern.cpp
2//! @author ryftchen
3//! @brief The definitions (register_design_pattern) in the application module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2026 ryftchen. All rights reserved.
6
7#include "register_design_pattern.hpp"
8#include "apply_design_pattern.hpp"
9
10namespace application::reg_dp
11{
12//! @brief Register version number.
13//! @return version number (major.minor.patch)
14const char* version() noexcept
15{
16 static const char* const ver = "0.1.0";
17 return ver;
18}
19
20namespace manage
21{
22//! @brief Get the design pattern choice applier.
23//! @return reference of the ApplyDesignPattern object
24ApplyDesignPattern& choiceApplier()
25{
26 static utility::common::NoDestructor<ApplyDesignPattern> applier{};
27 return *applier.get();
28}
29
30//! @brief Check whether any design pattern choices exist.
31//! @return any design pattern choices exist or not
32bool present()
33{
34 bool isExist = false;
35 TypeInfo<ApplyDesignPattern>::forEachVarOf(
36 obj&: choiceApplier(), func: [&isExist](const auto /*field*/, auto&& var) { isExist |= !var.none(); });
37 return isExist;
38}
39//! @brief Reset bit flags that manage design pattern choices.
40void clear()
41{
42 TypeInfo<ApplyDesignPattern>::forEachVarOf(obj&: choiceApplier(), func: [](const auto /*field*/, auto&& var) { var.reset(); });
43}
44} // namespace manage
45
46//! @brief Find the position of bit flags to set a particular instance.
47//! @tparam Inst - type of target instance
48//! @param stringify - instance name
49//! @return position of bit flags
50template <typename Inst>
51static consteval std::size_t mappedPos(const std::string_view stringify)
52{
53 return static_cast<std::underlying_type_t<Inst>>(TypeInfo<Inst>::fields.template valueOfName<Inst>(stringify));
54}
55
56namespace behavioral
57{
58//! @brief Register version number.
59//! @return version number (major.minor.patch)
60const char* version() noexcept
61{
62 return app_dp::behavioral::version;
63}
64} // namespace behavioral
65//! @brief Set behavioral-related choice.
66//! @param choice - target choice
67template <>
68void setChoice<BehavioralInstance>(const std::string& choice)
69{
70 constexpr auto category = Category::behavioral;
71 auto& spec = categoryOpts<category>();
72
73 switch (utility::common::bkdrHash(str: choice.c_str()))
74 {
75 case abbrLitHash(instance: BehavioralInstance::chainOfResponsibility):
76 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(chainOfResponsibility)));
77 break;
78 case abbrLitHash(instance: BehavioralInstance::command):
79 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(command)));
80 break;
81 case abbrLitHash(instance: BehavioralInstance::interpreter):
82 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(interpreter)));
83 break;
84 case abbrLitHash(instance: BehavioralInstance::iterator):
85 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(iterator)));
86 break;
87 case abbrLitHash(instance: BehavioralInstance::mediator):
88 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(mediator)));
89 break;
90 case abbrLitHash(instance: BehavioralInstance::memento):
91 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(memento)));
92 break;
93 case abbrLitHash(instance: BehavioralInstance::observer):
94 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(observer)));
95 break;
96 case abbrLitHash(instance: BehavioralInstance::state):
97 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(state)));
98 break;
99 case abbrLitHash(instance: BehavioralInstance::strategy):
100 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(strategy)));
101 break;
102 case abbrLitHash(instance: BehavioralInstance::templateMethod):
103 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(templateMethod)));
104 break;
105 case abbrLitHash(instance: BehavioralInstance::visitor):
106 spec.set(position: mappedPos<BehavioralInstance>(MACRO_STRINGIFY(visitor)));
107 break;
108 default:
109 spec.reset();
110 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
111 }
112}
113//! @brief Run behavioral-related candidates.
114//! @param candidates - container for the candidate target choices
115template <>
116void runCandidates<BehavioralInstance>(const std::vector<std::string>& candidates)
117{
118 app_dp::applyingBehavioral(candidates);
119}
120
121namespace creational
122{
123//! @brief Register version number.
124//! @return version number (major.minor.patch)
125const char* version() noexcept
126{
127 return app_dp::creational::version;
128}
129} // namespace creational
130//! @brief Set creational-related choice.
131//! @param choice - target choice
132template <>
133void setChoice<CreationalInstance>(const std::string& choice)
134{
135 constexpr auto category = Category::creational;
136 auto& spec = categoryOpts<category>();
137
138 switch (utility::common::bkdrHash(str: choice.c_str()))
139 {
140 case abbrLitHash(instance: CreationalInstance::abstractFactory):
141 spec.set(position: mappedPos<CreationalInstance>(MACRO_STRINGIFY(abstractFactory)));
142 break;
143 case abbrLitHash(instance: CreationalInstance::builder):
144 spec.set(position: mappedPos<CreationalInstance>(MACRO_STRINGIFY(builder)));
145 break;
146 case abbrLitHash(instance: CreationalInstance::factoryMethod):
147 spec.set(position: mappedPos<CreationalInstance>(MACRO_STRINGIFY(factoryMethod)));
148 break;
149 case abbrLitHash(instance: CreationalInstance::prototype):
150 spec.set(position: mappedPos<CreationalInstance>(MACRO_STRINGIFY(prototype)));
151 break;
152 case abbrLitHash(instance: CreationalInstance::singleton):
153 spec.set(position: mappedPos<CreationalInstance>(MACRO_STRINGIFY(singleton)));
154 break;
155 default:
156 spec.reset();
157 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
158 }
159}
160//! @brief Run creational-related candidates.
161//! @param candidates - container for the candidate target choices
162template <>
163void runCandidates<CreationalInstance>(const std::vector<std::string>& candidates)
164{
165 app_dp::applyingCreational(candidates);
166}
167
168namespace structural
169{
170//! @brief Register version number.
171//! @return version number (major.minor.patch)
172const char* version() noexcept
173{
174 return app_dp::structural::version;
175}
176} // namespace structural
177//! @brief Set structural-related choice.
178//! @param choice - target choice
179template <>
180void setChoice<StructuralInstance>(const std::string& choice)
181{
182 constexpr auto category = Category::structural;
183 auto& spec = categoryOpts<category>();
184
185 switch (utility::common::bkdrHash(str: choice.c_str()))
186 {
187 case abbrLitHash(instance: StructuralInstance::adapter):
188 spec.set(position: mappedPos<StructuralInstance>(MACRO_STRINGIFY(adapter)));
189 break;
190 case abbrLitHash(instance: StructuralInstance::bridge):
191 spec.set(position: mappedPos<StructuralInstance>(MACRO_STRINGIFY(bridge)));
192 break;
193 case abbrLitHash(instance: StructuralInstance::composite):
194 spec.set(position: mappedPos<StructuralInstance>(MACRO_STRINGIFY(composite)));
195 break;
196 case abbrLitHash(instance: StructuralInstance::decorator):
197 spec.set(position: mappedPos<StructuralInstance>(MACRO_STRINGIFY(decorator)));
198 break;
199 case abbrLitHash(instance: StructuralInstance::facade):
200 spec.set(position: mappedPos<StructuralInstance>(MACRO_STRINGIFY(facade)));
201 break;
202 case abbrLitHash(instance: StructuralInstance::flyweight):
203 spec.set(position: mappedPos<StructuralInstance>(MACRO_STRINGIFY(flyweight)));
204 break;
205 case abbrLitHash(instance: StructuralInstance::proxy):
206 spec.set(position: mappedPos<StructuralInstance>(MACRO_STRINGIFY(proxy)));
207 break;
208 default:
209 spec.reset();
210 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
211 }
212}
213//! @brief Run structural-related candidates.
214//! @param candidates - container for the candidate target choices
215template <>
216void runCandidates<StructuralInstance>(const std::vector<std::string>& candidates)
217{
218 app_dp::applyingStructural(candidates);
219}
220} // namespace application::reg_dp
221