1//! @file register_algorithm.cpp
2//! @author ryftchen
3//! @brief The definitions (register_algorithm) in the application module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2026 ryftchen. All rights reserved.
6
7#include "register_algorithm.hpp"
8#include "apply_algorithm.hpp"
9
10namespace application::reg_algo
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 algorithm choice applier.
23//! @return reference of the ApplyAlgorithm object
24ApplyAlgorithm& choiceApplier()
25{
26 static utility::common::NoDestructor<ApplyAlgorithm> applier{};
27 return *applier.get();
28}
29
30//! @brief Check whether any algorithm choices exist.
31//! @return any design pattern choices exist or not
32bool present()
33{
34 bool isExist = false;
35 TypeInfo<ApplyAlgorithm>::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 algorithm choices.
40void clear()
41{
42 TypeInfo<ApplyAlgorithm>::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 method.
47//! @tparam Meth - type of target method
48//! @param stringify - method name
49//! @return position of bit flags
50template <typename Meth>
51static consteval std::size_t mappedPos(const std::string_view stringify)
52{
53 return static_cast<std::underlying_type_t<Meth>>(TypeInfo<Meth>::fields.template valueOfName<Meth>(stringify));
54}
55
56namespace match
57{
58//! @brief Register version number.
59//! @return version number (major.minor.patch)
60const char* version() noexcept
61{
62 return app_algo::match::version;
63}
64} // namespace match
65//! @brief Set match-related choice.
66//! @param choice - target choice
67template <>
68void setChoice<MatchMethod>(const std::string& choice)
69{
70 constexpr auto category = Category::match;
71 auto& spec = categoryOpts<category>();
72
73 switch (utility::common::bkdrHash(str: choice.c_str()))
74 {
75 case abbrLitHash(method: MatchMethod::rabinKarp):
76 spec.set(position: mappedPos<MatchMethod>(MACRO_STRINGIFY(rabinKarp)));
77 break;
78 case abbrLitHash(method: MatchMethod::knuthMorrisPratt):
79 spec.set(position: mappedPos<MatchMethod>(MACRO_STRINGIFY(knuthMorrisPratt)));
80 break;
81 case abbrLitHash(method: MatchMethod::boyerMoore):
82 spec.set(position: mappedPos<MatchMethod>(MACRO_STRINGIFY(boyerMoore)));
83 break;
84 case abbrLitHash(method: MatchMethod::horspool):
85 spec.set(position: mappedPos<MatchMethod>(MACRO_STRINGIFY(horspool)));
86 break;
87 case abbrLitHash(method: MatchMethod::sunday):
88 spec.set(position: mappedPos<MatchMethod>(MACRO_STRINGIFY(sunday)));
89 break;
90 default:
91 spec.reset();
92 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
93 }
94}
95//! @brief Run match-related candidates.
96//! @param candidates - container for the candidate target choices
97template <>
98void runCandidates<MatchMethod>(const std::vector<std::string>& candidates)
99{
100 app_algo::applyingMatch(candidates);
101}
102
103namespace notation
104{
105//! @brief Register version number.
106//! @return version number (major.minor.patch)
107const char* version() noexcept
108{
109 return app_algo::notation::version;
110}
111} // namespace notation
112//! @brief Set notation-related choice.
113//! @param choice - target choice
114template <>
115void setChoice<NotationMethod>(const std::string& choice)
116{
117 constexpr auto category = Category::notation;
118 auto& spec = categoryOpts<category>();
119
120 switch (utility::common::bkdrHash(str: choice.c_str()))
121 {
122 case abbrLitHash(method: NotationMethod::prefix):
123 spec.set(position: mappedPos<NotationMethod>(MACRO_STRINGIFY(prefix)));
124 break;
125 case abbrLitHash(method: NotationMethod::postfix):
126 spec.set(position: mappedPos<NotationMethod>(MACRO_STRINGIFY(postfix)));
127 break;
128 default:
129 spec.reset();
130 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
131 }
132}
133//! @brief Run notation-related candidates.
134//! @param candidates - container for the candidate target choices
135template <>
136void runCandidates<NotationMethod>(const std::vector<std::string>& candidates)
137{
138 app_algo::applyingNotation(candidates);
139}
140
141namespace optimal
142{
143//! @brief Register version number.
144//! @return version number (major.minor.patch)
145const char* version() noexcept
146{
147 return app_algo::optimal::version;
148}
149} // namespace optimal
150//! @brief Set optimal-related choice.
151//! @param choice - target choice
152template <>
153void setChoice<OptimalMethod>(const std::string& choice)
154{
155 constexpr auto category = Category::optimal;
156 auto& spec = categoryOpts<category>();
157
158 switch (utility::common::bkdrHash(str: choice.c_str()))
159 {
160 case abbrLitHash(method: OptimalMethod::gradient):
161 spec.set(position: mappedPos<OptimalMethod>(MACRO_STRINGIFY(gradient)));
162 break;
163 case abbrLitHash(method: OptimalMethod::tabu):
164 spec.set(position: mappedPos<OptimalMethod>(MACRO_STRINGIFY(tabu)));
165 break;
166 case abbrLitHash(method: OptimalMethod::annealing):
167 spec.set(position: mappedPos<OptimalMethod>(MACRO_STRINGIFY(annealing)));
168 break;
169 case abbrLitHash(method: OptimalMethod::particle):
170 spec.set(position: mappedPos<OptimalMethod>(MACRO_STRINGIFY(particle)));
171 break;
172 case abbrLitHash(method: OptimalMethod::ant):
173 spec.set(position: mappedPos<OptimalMethod>(MACRO_STRINGIFY(ant)));
174 break;
175 case abbrLitHash(method: OptimalMethod::genetic):
176 spec.set(position: mappedPos<OptimalMethod>(MACRO_STRINGIFY(genetic)));
177 break;
178 default:
179 spec.reset();
180 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
181 }
182}
183//! @brief Run optimal-related candidates.
184//! @param candidates - container for the candidate target choices
185template <>
186void runCandidates<OptimalMethod>(const std::vector<std::string>& candidates)
187{
188 app_algo::applyingOptimal(candidates);
189}
190
191namespace search
192{
193//! @brief Register version number.
194//! @return version number (major.minor.patch)
195const char* version() noexcept
196{
197 return app_algo::search::version;
198}
199} // namespace search
200//! @brief Set search-related choice.
201//! @param choice - target choice
202template <>
203void setChoice<SearchMethod>(const std::string& choice)
204{
205 constexpr auto category = Category::search;
206 auto& spec = categoryOpts<category>();
207
208 switch (utility::common::bkdrHash(str: choice.c_str()))
209 {
210 case abbrLitHash(method: SearchMethod::binary):
211 spec.set(position: mappedPos<SearchMethod>(MACRO_STRINGIFY(binary)));
212 break;
213 case abbrLitHash(method: SearchMethod::interpolation):
214 spec.set(position: mappedPos<SearchMethod>(MACRO_STRINGIFY(interpolation)));
215 break;
216 case abbrLitHash(method: SearchMethod::fibonacci):
217 spec.set(position: mappedPos<SearchMethod>(MACRO_STRINGIFY(fibonacci)));
218 break;
219 default:
220 spec.reset();
221 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
222 }
223}
224//! @brief Run search-related candidates.
225//! @param candidates - container for the candidate target choices
226template <>
227void runCandidates<SearchMethod>(const std::vector<std::string>& candidates)
228{
229 app_algo::applyingSearch(candidates);
230}
231
232namespace sort
233{
234//! @brief Register version number.
235//! @return version number (major.minor.patch)
236const char* version() noexcept
237{
238 return app_algo::sort::version;
239}
240} // namespace sort
241//! @brief Set sort-related choice.
242//! @param choice - target choice
243template <>
244void setChoice<SortMethod>(const std::string& choice)
245{
246 constexpr auto category = Category::sort;
247 auto& spec = categoryOpts<category>();
248
249 switch (utility::common::bkdrHash(str: choice.c_str()))
250 {
251 case abbrLitHash(method: SortMethod::bubble):
252 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(bubble)));
253 break;
254 case abbrLitHash(method: SortMethod::selection):
255 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(selection)));
256 break;
257 case abbrLitHash(method: SortMethod::insertion):
258 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(insertion)));
259 break;
260 case abbrLitHash(method: SortMethod::shell):
261 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(shell)));
262 break;
263 case abbrLitHash(method: SortMethod::merge):
264 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(merge)));
265 break;
266 case abbrLitHash(method: SortMethod::quick):
267 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(quick)));
268 break;
269 case abbrLitHash(method: SortMethod::heap):
270 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(heap)));
271 break;
272 case abbrLitHash(method: SortMethod::counting):
273 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(counting)));
274 break;
275 case abbrLitHash(method: SortMethod::bucket):
276 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(bucket)));
277 break;
278 case abbrLitHash(method: SortMethod::radix):
279 spec.set(position: mappedPos<SortMethod>(MACRO_STRINGIFY(radix)));
280 break;
281 default:
282 spec.reset();
283 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
284 }
285}
286//! @brief Run sort-related candidates.
287//! @param candidates - container for the candidate target choices
288template <>
289void runCandidates<SortMethod>(const std::vector<std::string>& candidates)
290{
291 app_algo::applyingSort(candidates);
292}
293} // namespace application::reg_algo
294