1//! @file register_data_structure.cpp
2//! @author ryftchen
3//! @brief The definitions (register_data_structure) in the application module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2026 ryftchen. All rights reserved.
6
7#include "register_data_structure.hpp"
8#include "apply_data_structure.hpp"
9
10namespace application::reg_ds
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 data structure choice applier.
23//! @return reference of the ApplyDataStructure object
24ApplyDataStructure& choiceApplier()
25{
26 static utility::common::NoDestructor<ApplyDataStructure> applier{};
27 return *applier.get();
28}
29
30//! @brief Check whether any data structure choices exist.
31//! @return any data structure choices exist or not
32bool present()
33{
34 bool isExist = false;
35 TypeInfo<ApplyDataStructure>::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 data structure choices.
40void clear()
41{
42 TypeInfo<ApplyDataStructure>::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 cache
57{
58//! @brief Register version number.
59//! @return version number (major.minor.patch)
60const char* version() noexcept
61{
62 return app_ds::cache::version;
63}
64} // namespace cache
65//! @brief Set cache-related choice.
66//! @param choice - target choice
67template <>
68void setChoice<CacheInstance>(const std::string& choice)
69{
70 constexpr auto category = Category::cache;
71 auto& spec = categoryOpts<category>();
72
73 switch (utility::common::bkdrHash(str: choice.c_str()))
74 {
75 case abbrLitHash(instance: CacheInstance::firstInFirstOut):
76 spec.set(position: mappedPos<CacheInstance>(MACRO_STRINGIFY(firstInFirstOut)));
77 break;
78 case abbrLitHash(instance: CacheInstance::leastFrequentlyUsed):
79 spec.set(position: mappedPos<CacheInstance>(MACRO_STRINGIFY(leastFrequentlyUsed)));
80 break;
81 case abbrLitHash(instance: CacheInstance::leastRecentlyUsed):
82 spec.set(position: mappedPos<CacheInstance>(MACRO_STRINGIFY(leastRecentlyUsed)));
83 break;
84 default:
85 spec.reset();
86 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
87 }
88}
89//! @brief Run cache-related candidates.
90//! @param candidates - container for the candidate target choices
91template <>
92void runCandidates<CacheInstance>(const std::vector<std::string>& candidates)
93{
94 app_ds::applyingCache(candidates);
95}
96
97namespace filter
98{
99//! @brief Register version number.
100//! @return version number (major.minor.patch)
101const char* version() noexcept
102{
103 return app_ds::filter::version;
104}
105} // namespace filter
106//! @brief Set filter-related choice.
107//! @param choice - target choice
108template <>
109void setChoice<FilterInstance>(const std::string& choice)
110{
111 constexpr auto category = Category::filter;
112 auto& spec = categoryOpts<category>();
113
114 switch (utility::common::bkdrHash(str: choice.c_str()))
115 {
116 case abbrLitHash(instance: FilterInstance::bloom):
117 spec.set(position: mappedPos<FilterInstance>(MACRO_STRINGIFY(bloom)));
118 break;
119 case abbrLitHash(instance: FilterInstance::quotient):
120 spec.set(position: mappedPos<FilterInstance>(MACRO_STRINGIFY(quotient)));
121 break;
122 default:
123 spec.reset();
124 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
125 }
126}
127//! @brief Run filter-related candidates.
128//! @param candidates - container for the candidate target choices
129template <>
130void runCandidates<FilterInstance>(const std::vector<std::string>& candidates)
131{
132 app_ds::applyingFilter(candidates);
133}
134
135namespace graph
136{
137//! @brief Register version number.
138//! @return version number (major.minor.patch)
139const char* version() noexcept
140{
141 return app_ds::graph::version;
142}
143} // namespace graph
144//! @brief Set graph-related choice.
145//! @param choice - target choice
146template <>
147void setChoice<GraphInstance>(const std::string& choice)
148{
149 constexpr auto category = Category::graph;
150 auto& spec = categoryOpts<category>();
151
152 switch (utility::common::bkdrHash(str: choice.c_str()))
153 {
154 case abbrLitHash(instance: GraphInstance::undirected):
155 spec.set(position: mappedPos<GraphInstance>(MACRO_STRINGIFY(undirected)));
156 break;
157 case abbrLitHash(instance: GraphInstance::directed):
158 spec.set(position: mappedPos<GraphInstance>(MACRO_STRINGIFY(directed)));
159 break;
160 default:
161 spec.reset();
162 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
163 }
164}
165//! @brief Run graph-related candidates.
166//! @param candidates - container for the candidate target choices
167template <>
168void runCandidates<GraphInstance>(const std::vector<std::string>& candidates)
169{
170 app_ds::applyingGraph(candidates);
171}
172
173namespace heap
174{
175//! @brief Register version number.
176//! @return version number (major.minor.patch)
177const char* version() noexcept
178{
179 return app_ds::heap::version;
180}
181} // namespace heap
182//! @brief Set heap-related choice.
183//! @param choice - target choice
184template <>
185void setChoice<HeapInstance>(const std::string& choice)
186{
187 constexpr auto category = Category::heap;
188 auto& spec = categoryOpts<category>();
189
190 switch (utility::common::bkdrHash(str: choice.c_str()))
191 {
192 case abbrLitHash(instance: HeapInstance::binary):
193 spec.set(position: mappedPos<HeapInstance>(MACRO_STRINGIFY(binary)));
194 break;
195 case abbrLitHash(instance: HeapInstance::leftist):
196 spec.set(position: mappedPos<HeapInstance>(MACRO_STRINGIFY(leftist)));
197 break;
198 case abbrLitHash(instance: HeapInstance::skew):
199 spec.set(position: mappedPos<HeapInstance>(MACRO_STRINGIFY(skew)));
200 break;
201 default:
202 spec.reset();
203 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
204 }
205}
206//! @brief Run heap-related candidates.
207//! @param candidates - container for the candidate target choices
208template <>
209void runCandidates<HeapInstance>(const std::vector<std::string>& candidates)
210{
211 app_ds::applyingHeap(candidates);
212}
213
214namespace linear
215{
216//! @brief Register version number.
217//! @return version number (major.minor.patch)
218const char* version() noexcept
219{
220 return app_ds::linear::version;
221}
222} // namespace linear
223//! @brief Set linear-related choice.
224//! @param choice - target choice
225template <>
226void setChoice<LinearInstance>(const std::string& choice)
227{
228 constexpr auto category = Category::linear;
229 auto& spec = categoryOpts<category>();
230
231 switch (utility::common::bkdrHash(str: choice.c_str()))
232 {
233 case abbrLitHash(instance: LinearInstance::doublyLinkedList):
234 spec.set(position: mappedPos<LinearInstance>(MACRO_STRINGIFY(doublyLinkedList)));
235 break;
236 case abbrLitHash(instance: LinearInstance::stack):
237 spec.set(position: mappedPos<LinearInstance>(MACRO_STRINGIFY(stack)));
238 break;
239 case abbrLitHash(instance: LinearInstance::queue):
240 spec.set(position: mappedPos<LinearInstance>(MACRO_STRINGIFY(queue)));
241 break;
242 default:
243 spec.reset();
244 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
245 }
246}
247//! @brief Run linear-related candidates.
248//! @param candidates - container for the candidate target choices
249template <>
250void runCandidates<LinearInstance>(const std::vector<std::string>& candidates)
251{
252 app_ds::applyingLinear(candidates);
253}
254
255namespace tree
256{
257//! @brief Register version number.
258//! @return version number (major.minor.patch)
259const char* version() noexcept
260{
261 return app_ds::tree::version;
262}
263} // namespace tree
264//! @brief Set tree-related choice.
265//! @param choice - target choice
266template <>
267void setChoice<TreeInstance>(const std::string& choice)
268{
269 constexpr auto category = Category::tree;
270 auto& spec = categoryOpts<category>();
271
272 switch (utility::common::bkdrHash(str: choice.c_str()))
273 {
274 case abbrLitHash(instance: TreeInstance::binarySearch):
275 spec.set(position: mappedPos<TreeInstance>(MACRO_STRINGIFY(binarySearch)));
276 break;
277 case abbrLitHash(instance: TreeInstance::adelsonVelskyLandis):
278 spec.set(position: mappedPos<TreeInstance>(MACRO_STRINGIFY(adelsonVelskyLandis)));
279 break;
280 case abbrLitHash(instance: TreeInstance::splay):
281 spec.set(position: mappedPos<TreeInstance>(MACRO_STRINGIFY(splay)));
282 break;
283 default:
284 spec.reset();
285 throw std::runtime_error{"Unexpected " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
286 }
287}
288//! @brief Run tree-related candidates.
289//! @param candidates - container for the candidate target choices
290template <>
291void runCandidates<TreeInstance>(const std::vector<std::string>& candidates)
292{
293 app_ds::applyingTree(candidates);
294}
295} // namespace application::reg_ds
296