1//! @file register_numeric.cpp
2//! @author ryftchen
3//! @brief The definitions (register_numeric) in the application module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2026 ryftchen. All rights reserved.
6
7#include "register_numeric.hpp"
8#include "apply_numeric.hpp"
9
10namespace application::reg_num
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 numeric choice applier.
23//! @return reference of the ApplyNumeric object
24ApplyNumeric& choiceApplier()
25{
26 static utility::common::NoDestructor<ApplyNumeric> applier{};
27 return *applier.get();
28}
29
30//! @brief Check whether any numeric choices exist.
31//! @return any numeric choices exist or not
32bool present()
33{
34 bool isExist = false;
35 TypeInfo<ApplyNumeric>::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 numeric choices.
40void clear()
41{
42 TypeInfo<ApplyNumeric>::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 arithmetic
57{
58//! @brief Register version number.
59//! @return version number (major.minor.patch)
60const char* version() noexcept
61{
62 return app_num::arithmetic::version;
63}
64} // namespace arithmetic
65//! @brief Set arithmetic-related choice.
66//! @param choice - target choice
67template <>
68void setChoice<ArithmeticMethod>(const std::string& choice)
69{
70 constexpr auto category = Category::arithmetic;
71 auto& spec = categoryOpts<category>();
72
73 switch (utility::common::bkdrHash(str: choice.c_str()))
74 {
75 case abbrLitHash(method: ArithmeticMethod::addition):
76 spec.set(position: mappedPos<ArithmeticMethod>(MACRO_STRINGIFY(addition)));
77 break;
78 case abbrLitHash(method: ArithmeticMethod::subtraction):
79 spec.set(position: mappedPos<ArithmeticMethod>(MACRO_STRINGIFY(subtraction)));
80 break;
81 case abbrLitHash(method: ArithmeticMethod::multiplication):
82 spec.set(position: mappedPos<ArithmeticMethod>(MACRO_STRINGIFY(multiplication)));
83 break;
84 case abbrLitHash(method: ArithmeticMethod::division):
85 spec.set(position: mappedPos<ArithmeticMethod>(MACRO_STRINGIFY(division)));
86 break;
87 default:
88 spec.reset();
89 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
90 }
91}
92//! @brief Run arithmetic-related candidates.
93//! @param candidates - container for the candidate target choices
94template <>
95void runCandidates<ArithmeticMethod>(const std::vector<std::string>& candidates)
96{
97 app_num::applyingArithmetic(candidates);
98}
99
100namespace divisor
101{
102//! @brief Register version number.
103//! @return version number (major.minor.patch)
104const char* version() noexcept
105{
106 return app_num::divisor::version;
107}
108} // namespace divisor
109//! @brief Set divisor-related choice.
110//! @param choice - target choice
111template <>
112void setChoice<DivisorMethod>(const std::string& choice)
113{
114 constexpr auto category = Category::divisor;
115 auto& spec = categoryOpts<category>();
116
117 switch (utility::common::bkdrHash(str: choice.c_str()))
118 {
119 case abbrLitHash(method: DivisorMethod::euclidean):
120 spec.set(position: mappedPos<DivisorMethod>(MACRO_STRINGIFY(euclidean)));
121 break;
122 case abbrLitHash(method: DivisorMethod::stein):
123 spec.set(position: mappedPos<DivisorMethod>(MACRO_STRINGIFY(stein)));
124 break;
125 default:
126 spec.reset();
127 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
128 }
129}
130//! @brief Run divisor-related candidates.
131//! @param candidates - container for the candidate target choices
132template <>
133void runCandidates<DivisorMethod>(const std::vector<std::string>& candidates)
134{
135 app_num::applyingDivisor(candidates);
136}
137
138namespace integral
139{
140//! @brief Register version number.
141//! @return version number (major.minor.patch)
142const char* version() noexcept
143{
144 return app_num::integral::version;
145}
146} // namespace integral
147//! @brief Set integral-related choice.
148//! @param choice - target choice
149template <>
150void setChoice<IntegralMethod>(const std::string& choice)
151{
152 constexpr auto category = Category::integral;
153 auto& spec = categoryOpts<category>();
154
155 switch (utility::common::bkdrHash(str: choice.c_str()))
156 {
157 case abbrLitHash(method: IntegralMethod::trapezoidal):
158 spec.set(position: mappedPos<IntegralMethod>(MACRO_STRINGIFY(trapezoidal)));
159 break;
160 case abbrLitHash(method: IntegralMethod::simpson):
161 spec.set(position: mappedPos<IntegralMethod>(MACRO_STRINGIFY(simpson)));
162 break;
163 case abbrLitHash(method: IntegralMethod::romberg):
164 spec.set(position: mappedPos<IntegralMethod>(MACRO_STRINGIFY(romberg)));
165 break;
166 case abbrLitHash(method: IntegralMethod::gauss):
167 spec.set(position: mappedPos<IntegralMethod>(MACRO_STRINGIFY(gauss)));
168 break;
169 case abbrLitHash(method: IntegralMethod::monteCarlo):
170 spec.set(position: mappedPos<IntegralMethod>(MACRO_STRINGIFY(monteCarlo)));
171 break;
172 default:
173 spec.reset();
174 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
175 }
176}
177//! @brief Run integral-related candidates.
178//! @param candidates - container for the candidate target choices
179template <>
180void runCandidates<IntegralMethod>(const std::vector<std::string>& candidates)
181{
182 app_num::applyingIntegral(candidates);
183}
184
185namespace prime
186{
187//! @brief Register version number.
188//! @return version number (major.minor.patch)
189const char* version() noexcept
190{
191 return app_num::prime::version;
192}
193} // namespace prime
194//! @brief Set prime-related choice.
195//! @param choice - target choice
196template <>
197void setChoice<PrimeMethod>(const std::string& choice)
198{
199 constexpr auto category = Category::prime;
200 auto& spec = categoryOpts<category>();
201
202 switch (utility::common::bkdrHash(str: choice.c_str()))
203 {
204 case abbrLitHash(method: PrimeMethod::eratosthenes):
205 spec.set(position: mappedPos<PrimeMethod>(MACRO_STRINGIFY(eratosthenes)));
206 break;
207 case abbrLitHash(method: PrimeMethod::euler):
208 spec.set(position: mappedPos<PrimeMethod>(MACRO_STRINGIFY(euler)));
209 break;
210 default:
211 spec.reset();
212 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
213 }
214}
215//! @brief Run prime-related candidates.
216//! @param candidates - container for the candidate target choices
217template <>
218void runCandidates<PrimeMethod>(const std::vector<std::string>& candidates)
219{
220 app_num::applyingPrime(candidates);
221}
222} // namespace application::reg_num
223