1//! @file apply_algorithm.cpp
2//! @author ryftchen
3//! @brief The definitions (apply_algorithm) in the application module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2026 ryftchen. All rights reserved.
6
7#include "apply_algorithm.hpp"
8#include "register_algorithm.hpp"
9
10#ifndef _PRECOMPILED_HEADER
11#include <iomanip>
12#include <ranges>
13#else
14#include "application/pch/precompiled_header.hpp"
15#endif
16
17#include "application/core/include/log.hpp"
18#include "utility/include/currying.hpp"
19#include "utility/include/time.hpp"
20
21//! @brief Title of printing when algorithm tasks are beginning.
22#define APP_ALGO_PRINT_TASK_TITLE_SCOPE_BEGIN(title) \
23 std::osyncstream(std::cout) << "\nAPPLY ALGORITHM: " << std::setiosflags(std::ios_base::left) << std::setfill('.') \
24 << std::setw(50) << (title) << "BEGIN" << std::resetiosflags(std::ios_base::left) \
25 << std::setfill(' ') << std::endl; \
26 {
27//! @brief Title of printing when algorithm tasks are ending.
28#define APP_ALGO_PRINT_TASK_TITLE_SCOPE_END(title) \
29 } \
30 std::osyncstream(std::cout) << "\nAPPLY ALGORITHM: " << std::setiosflags(std::ios_base::left) << std::setfill('.') \
31 << std::setw(50) << (title) << "END" << std::resetiosflags(std::ios_base::left) \
32 << std::setfill(' ') << '\n' \
33 << std::endl;
34
35namespace application::app_algo
36{
37using namespace reg_algo; // NOLINT(google-build-using-namespace)
38
39//! @brief Make the title of a particular method in algorithm choices.
40//! @tparam Meth - type of target method
41//! @param method - target method
42//! @return initial capitalized title
43template <typename Meth>
44static std::string customTitle(const Meth method)
45{
46 std::string title(TypeInfo<Meth>::fields.nameOfValue(method));
47 title.at(n: 0) = static_cast<char>(std::toupper(c: title.at(n: 0)));
48 return title;
49}
50
51//! @brief Get the curried task name.
52//! @return curried task name
53static const auto& curriedTaskName()
54{
55 static const auto curried = utility::currying::curry(func: configure::task::presetName, args: TypeInfo<ApplyAlgorithm>::name);
56 return curried;
57}
58
59//! @brief Get the alias of the category in algorithm choices.
60//! @tparam Cat - target category
61//! @return alias of the category name
62template <Category Cat>
63static consteval std::string_view categoryAlias()
64{
65 constexpr auto attr =
66 TypeInfo<ApplyAlgorithm>::fields.find(REFLECTION_STR(toString(Cat))).attrs.find(REFLECTION_STR("alias"));
67 static_assert(attr.hasValue);
68 return attr.value;
69}
70
71namespace match
72{
73//! @brief Show the contents of the match result.
74//! @param method - used match method
75//! @param result - match result
76//! @param pattern - single pattern
77//! @param interval - time interval
78static void display(
79 const MatchMethod method, const std::int64_t result, const std::string& pattern, const double interval)
80{
81 if (result != -1)
82 {
83 std::printf(
84 format: "\n==> %-16s Method <==\npattern \"%s\" found starting (1st) at index %ld, run time: %8.5f ms\n",
85 customTitle(method).c_str(),
86 pattern.c_str(),
87 result,
88 interval);
89 }
90 else
91 {
92 std::printf(
93 format: "\n==> %-16s Method <==\npattern \"%s\" could not be found, run time: %8.5f ms\n",
94 customTitle(method).c_str(),
95 pattern.c_str(),
96 interval);
97 }
98}
99
100//! @brief Solution of match.
101//! @param method - used match method
102//! @param text - matching text
103//! @param pattern - single pattern
104//! @param textLen - length of matching text
105//! @param patternLen - length of single pattern
106static void solution(
107 const MatchMethod method,
108 const unsigned char* const text,
109 const unsigned char* const pattern,
110 const std::uint32_t textLen,
111 const std::uint32_t patternLen)
112try
113{
114 std::int64_t result = 0;
115 const utility::time::Stopwatch timing{};
116 switch (method)
117 {
118 using algorithm::match::Match;
119 case MatchMethod::rabinKarp:
120 result = Match::rk(text, pattern, textLen, patternLen);
121 break;
122 case MatchMethod::knuthMorrisPratt:
123 result = Match::kmp(text, pattern, textLen, patternLen);
124 break;
125 case MatchMethod::boyerMoore:
126 result = Match::bm(text, pattern, textLen, patternLen);
127 break;
128 case MatchMethod::horspool:
129 result = Match::horspool(text, pattern, textLen, patternLen);
130 break;
131 case MatchMethod::sunday:
132 result = Match::sunday(text, pattern, textLen, patternLen);
133 break;
134 default:
135 return;
136 }
137 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
138 display(method, result, pattern: std::string(reinterpret_cast<const char*>(pattern), patternLen), interval: timing.elapsedTime());
139}
140catch (const std::exception& err)
141{
142 LOG_WRN_P("Exception in %s (%s): %s", __func__, customTitle(method).c_str(), err.what());
143}
144} // namespace match
145//! @brief To apply match-related methods that are mapped to choices.
146//! @param candidates - container for the candidate target choices
147void applyingMatch(const std::vector<std::string>& candidates)
148{
149 constexpr auto category = Category::match;
150 const auto& spec = categoryOpts<category>();
151 if (MACRO_IMPLIES(spec.any(), spec.size() != candidates.size()))
152 {
153 return;
154 }
155
156 const std::string_view title = algorithm::match::description();
157 APP_ALGO_PRINT_TASK_TITLE_SCOPE_BEGIN(title);
158
159 auto& pooling = configure::task::resourcePool();
160 auto* const allocatedJob = pooling.newEntry(args: spec.count());
161 using match::InputBuilder, match::input::patternString;
162 static_assert(InputBuilder::maxDigit > patternString.length());
163 const auto inputData = std::make_shared<InputBuilder>(args: patternString);
164 const auto taskNamer = utility::currying::curry(curried: curriedTaskName(), args: categoryAlias<category>());
165 const auto addTask =
166 [allocatedJob, &inputData, &taskNamer](const std::string_view subtask, const MatchMethod method)
167 {
168 allocatedJob->enqueue(
169 name: taskNamer(subtask),
170 func&: match::solution,
171 args: method,
172 args: inputData->getMatchingText().get(),
173 args: inputData->getSinglePattern().get(),
174 args: inputData->getTextLength(),
175 args: inputData->getPatternLength());
176 };
177 MACRO_DEFER(utility::common::wrapClosure([&]() { pooling.deleteEntry(allocatedJob); }));
178
179 for (const auto index :
180 std::views::iota(0U, spec.size()) | std::views::filter([&spec](const auto i) { return spec.test(position: i); }))
181 {
182 const auto& choice = candidates.at(n: index);
183 switch (utility::common::bkdrHash(str: choice.c_str()))
184 {
185 case abbrLitHash(method: MatchMethod::rabinKarp):
186 addTask(choice, MatchMethod::rabinKarp);
187 break;
188 case abbrLitHash(method: MatchMethod::knuthMorrisPratt):
189 addTask(choice, MatchMethod::knuthMorrisPratt);
190 break;
191 case abbrLitHash(method: MatchMethod::boyerMoore):
192 addTask(choice, MatchMethod::boyerMoore);
193 break;
194 case abbrLitHash(method: MatchMethod::horspool):
195 addTask(choice, MatchMethod::horspool);
196 break;
197 case abbrLitHash(method: MatchMethod::sunday):
198 addTask(choice, MatchMethod::sunday);
199 break;
200 default:
201 throw std::runtime_error{"Unknown " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
202 }
203 }
204
205 APP_ALGO_PRINT_TASK_TITLE_SCOPE_END(title);
206}
207
208namespace notation
209{
210//! @brief Show the contents of the notation result.
211//! @param method - used notation method
212//! @param result - notation result
213//! @param descr - notation description
214static void display(const NotationMethod method, const std::string& result, const std::string& descr)
215{
216 std::printf(format: "\n==> %-7s Method <==\n%s: %s\n", customTitle(method).c_str(), descr.c_str(), result.c_str());
217}
218
219//! @brief Solution of notation.
220//! @param method - used notation method
221//! @param infix - infix notation
222static void solution(const NotationMethod method, const std::string_view infix)
223try
224{
225 std::string result{};
226 std::string descr{};
227 switch (method)
228 {
229 using algorithm::notation::Notation;
230 case NotationMethod::prefix:
231 result = Notation::prefix(infix);
232 descr = "polish notation";
233 break;
234 case NotationMethod::postfix:
235 result = Notation::postfix(infix);
236 descr = "reverse polish notation";
237 break;
238 default:
239 return;
240 }
241 display(method, result, descr);
242}
243catch (const std::exception& err)
244{
245 LOG_WRN_P("Exception in %s (%s): %s", __func__, customTitle(method).c_str(), err.what());
246}
247} // namespace notation
248//! @brief To apply notation-related methods that are mapped to choices.
249//! @param candidates - container for the candidate target choices
250void applyingNotation(const std::vector<std::string>& candidates)
251{
252 constexpr auto category = Category::notation;
253 const auto& spec = categoryOpts<category>();
254 if (MACRO_IMPLIES(spec.any(), spec.size() != candidates.size()))
255 {
256 return;
257 }
258
259 const std::string_view title = algorithm::notation::description();
260 APP_ALGO_PRINT_TASK_TITLE_SCOPE_BEGIN(title);
261
262 auto& pooling = configure::task::resourcePool();
263 auto* const allocatedJob = pooling.newEntry(args: spec.count());
264 using notation::InputBuilder, notation::input::infixString;
265 const auto inputData = std::make_shared<InputBuilder>(args: infixString);
266 const auto taskNamer = utility::currying::curry(curried: curriedTaskName(), args: categoryAlias<category>());
267 const auto addTask =
268 [allocatedJob, &inputData, &taskNamer](const std::string_view subtask, const NotationMethod method)
269 { allocatedJob->enqueue(name: taskNamer(subtask), func&: notation::solution, args: method, args: inputData->getInfixNotation()); };
270 MACRO_DEFER(utility::common::wrapClosure([&]() { pooling.deleteEntry(allocatedJob); }));
271
272 for (const auto index :
273 std::views::iota(0U, spec.size()) | std::views::filter([&spec](const auto i) { return spec.test(position: i); }))
274 {
275 const auto& choice = candidates.at(n: index);
276 switch (utility::common::bkdrHash(str: choice.c_str()))
277 {
278 case abbrLitHash(method: NotationMethod::prefix):
279 addTask(choice, NotationMethod::prefix);
280 break;
281 case abbrLitHash(method: NotationMethod::postfix):
282 addTask(choice, NotationMethod::postfix);
283 break;
284 default:
285 throw std::runtime_error{"Unknown " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
286 }
287 }
288
289 APP_ALGO_PRINT_TASK_TITLE_SCOPE_END(title);
290}
291
292namespace optimal
293{
294//! @brief Show the contents of the optimal result.
295//! @param method - used optimal method
296//! @param result - optimal result
297//! @param interval - time interval
298static void display(
299 const OptimalMethod method, const std::optional<std::tuple<double, double>>& result, const double interval)
300{
301 if (result.has_value())
302 {
303 std::printf(
304 format: "\n==> %-9s Method <==\nF(min)=%+.5f X=%+.5f, run time: %8.5f ms\n",
305 customTitle(method).c_str(),
306 std::get<0>(t: result.value()),
307 std::get<1>(t: result.value()),
308 interval);
309 }
310 else
311 {
312 std::printf(
313 format: "\n==> %-9s Method <==\nF(min) could not be found, run time: %8.5f ms\n",
314 customTitle(method).c_str(),
315 interval);
316 }
317}
318
319//! @brief Solution of optimal.
320//! @param method - used optimal method
321//! @param func - target function
322//! @param left - left endpoint
323//! @param right - right endpoint
324static void solution(const OptimalMethod method, const Function& func, const double left, const double right)
325try
326{
327 using namespace algorithm::optimal; // NOLINT(google-build-using-namespace)
328 Result result{};
329 const utility::time::Stopwatch timing{};
330 switch (method)
331 {
332 case OptimalMethod::gradient:
333 result = Gradient(func)(left, right, epsilon);
334 break;
335 case OptimalMethod::tabu:
336 result = Tabu(func)(left, right, epsilon);
337 break;
338 case OptimalMethod::annealing:
339 result = Annealing(func)(left, right, epsilon);
340 break;
341 case OptimalMethod::particle:
342 result = Particle(func)(left, right, epsilon);
343 break;
344 case OptimalMethod::ant:
345 result = Ant(func)(left, right, epsilon);
346 break;
347 case OptimalMethod::genetic:
348 result = Genetic(func)(left, right, epsilon);
349 break;
350 default:
351 return;
352 }
353 display(method, result, interval: timing.elapsedTime());
354}
355catch (const std::exception& err)
356{
357 LOG_WRN_P("Exception in %s (%s): %s", __func__, customTitle(method).c_str(), err.what());
358}
359} // namespace optimal
360//! @brief To apply optimal-related methods that are mapped to choices.
361//! @param candidates - container for the candidate target choices
362void applyingOptimal(const std::vector<std::string>& candidates)
363{
364 constexpr auto category = Category::optimal;
365 const auto& spec = categoryOpts<category>();
366 if (MACRO_IMPLIES(spec.any(), spec.size() != candidates.size()))
367 {
368 return;
369 }
370
371 const std::string_view title = algorithm::optimal::description();
372 APP_ALGO_PRINT_TASK_TITLE_SCOPE_BEGIN(title);
373
374 auto& pooling = configure::task::resourcePool();
375 auto* const allocatedJob = pooling.newEntry(args: spec.count());
376 using optimal::InputBuilder, optimal::input::SphericalBessel, optimal::Function;
377 static_assert(algorithm::optimal::epsilon >= std::numeric_limits<double>::epsilon());
378 const auto inputData = std::make_shared<InputBuilder>(
379 args: SphericalBessel{}, args: SphericalBessel::range1, args: SphericalBessel::range2, args: SphericalBessel::funcDescr);
380 const auto taskNamer = utility::currying::curry(curried: curriedTaskName(), args: categoryAlias<category>());
381 const auto addTask =
382 [allocatedJob, &inputData, &taskNamer](const std::string_view subtask, const OptimalMethod method)
383 {
384 allocatedJob->enqueue(
385 name: taskNamer(subtask),
386 func&: optimal::solution,
387 args: method,
388 args: inputData->getFunction(),
389 args: inputData->getRanges().first,
390 args: inputData->getRanges().second);
391 };
392 MACRO_DEFER(utility::common::wrapClosure([&]() { pooling.deleteEntry(allocatedJob); }));
393
394 for (const auto index :
395 std::views::iota(0U, spec.size()) | std::views::filter([&spec](const auto i) { return spec.test(position: i); }))
396 {
397 const auto& choice = candidates.at(n: index);
398 switch (utility::common::bkdrHash(str: choice.c_str()))
399 {
400 case abbrLitHash(method: OptimalMethod::gradient):
401 addTask(choice, OptimalMethod::gradient);
402 break;
403 case abbrLitHash(method: OptimalMethod::tabu):
404 addTask(choice, OptimalMethod::tabu);
405 break;
406 case abbrLitHash(method: OptimalMethod::annealing):
407 addTask(choice, OptimalMethod::annealing);
408 break;
409 case abbrLitHash(method: OptimalMethod::particle):
410 addTask(choice, OptimalMethod::particle);
411 break;
412 case abbrLitHash(method: OptimalMethod::ant):
413 addTask(choice, OptimalMethod::ant);
414 break;
415 case abbrLitHash(method: OptimalMethod::genetic):
416 addTask(choice, OptimalMethod::genetic);
417 break;
418 default:
419 throw std::runtime_error{"Unknown " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
420 }
421 }
422
423 APP_ALGO_PRINT_TASK_TITLE_SCOPE_END(title);
424}
425
426namespace search
427{
428//! @brief Show the contents of the search result.
429//! @param method - used search method
430//! @param result - search result
431//! @param key - search key
432//! @param interval - time interval
433static void display(const SearchMethod method, const std::int64_t result, const float key, const double interval)
434{
435 if (result != -1)
436 {
437 std::printf(
438 format: "\n==> %-13s Method <==\nfound the key \"%.5f\" that appears in the index %ld, run time: %8.5f ms\n",
439 customTitle(method).c_str(),
440 key,
441 result,
442 interval);
443 }
444 else
445 {
446 std::printf(
447 format: "\n==> %-13s Method <==\ncould not find the key \"%.5f\", run time: %8.5f ms\n",
448 customTitle(method).c_str(),
449 key,
450 interval);
451 }
452}
453
454//! @brief Solution of search.
455//! @param method - used search method
456//! @param array - ordered array to be searched
457//! @param length - length of array
458//! @param key - search key
459static void solution(const SearchMethod method, const float* const array, const std::uint32_t length, const float key)
460try
461{
462 std::int64_t result = 0;
463 const utility::time::Stopwatch timing{};
464 switch (method)
465 {
466 using algorithm::search::Search;
467 case SearchMethod::binary:
468 result = Search<float>::binary(array, length, key);
469 break;
470 case SearchMethod::interpolation:
471 result = Search<float>::interpolation(array, length, key);
472 break;
473 case SearchMethod::fibonacci:
474 result = Search<float>::fibonacci(array, length, key);
475 break;
476 default:
477 return;
478 }
479 display(method, result, key, interval: timing.elapsedTime());
480}
481catch (const std::exception& err)
482{
483 LOG_WRN_P("Exception in %s (%s): %s", __func__, customTitle(method).c_str(), err.what());
484}
485} // namespace search
486//! @brief To apply search-related methods that are mapped to choices.
487//! @param candidates - container for the candidate target choices
488void applyingSearch(const std::vector<std::string>& candidates)
489{
490 constexpr auto category = Category::search;
491 const auto& spec = categoryOpts<category>();
492 if (MACRO_IMPLIES(spec.any(), spec.size() != candidates.size()))
493 {
494 return;
495 }
496
497 const std::string_view title = algorithm::search::description();
498 APP_ALGO_PRINT_TASK_TITLE_SCOPE_BEGIN(title);
499
500 auto& pooling = configure::task::resourcePool();
501 auto* const allocatedJob = pooling.newEntry(args: spec.count());
502 using search::InputBuilder, search::input::arrayLength, search::input::arrayRangeMin, search::input::arrayRangeMax;
503 static_assert((arrayRangeMin < arrayRangeMax) && (arrayLength > 0));
504 const auto inputData = std::make_shared<InputBuilder<float>>(args: arrayLength, args: arrayRangeMin, args: arrayRangeMax);
505 const auto taskNamer = utility::currying::curry(curried: curriedTaskName(), args: categoryAlias<category>());
506 const auto addTask =
507 [allocatedJob, &inputData, &taskNamer](const std::string_view subtask, const SearchMethod method)
508 {
509 allocatedJob->enqueue(
510 name: taskNamer(subtask),
511 func&: search::solution,
512 args: method,
513 args: inputData->getOrderedArray().get(),
514 args: inputData->getLength(),
515 args: inputData->getSearchKey());
516 };
517 MACRO_DEFER(utility::common::wrapClosure([&]() { pooling.deleteEntry(allocatedJob); }));
518
519 for (const auto index :
520 std::views::iota(0U, spec.size()) | std::views::filter([&spec](const auto i) { return spec.test(position: i); }))
521 {
522 const auto& choice = candidates.at(n: index);
523 switch (utility::common::bkdrHash(str: choice.c_str()))
524 {
525 case abbrLitHash(method: SearchMethod::binary):
526 addTask(choice, SearchMethod::binary);
527 break;
528 case abbrLitHash(method: SearchMethod::interpolation):
529 addTask(choice, SearchMethod::interpolation);
530 break;
531 case abbrLitHash(method: SearchMethod::fibonacci):
532 addTask(choice, SearchMethod::fibonacci);
533 break;
534 default:
535 throw std::runtime_error{"Unknown " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
536 }
537 }
538
539 APP_ALGO_PRINT_TASK_TITLE_SCOPE_END(title);
540}
541
542namespace sort
543{
544//! @brief Show the contents of the sort result.
545//! @param method - used sort method
546//! @param result - sort result
547//! @param interval - time interval
548static void display(const SortMethod method, const std::vector<std::int32_t>& result, const double interval)
549{
550 const std::uint32_t bufferSize = result.size() * maxAlignOfPrint;
551 std::vector<char> fmtBuffer(bufferSize + 1);
552 std::printf(
553 format: "\n==> %-9s Method <==\n%s\n(asc) run time: %8.5f ms\n",
554 customTitle(method).c_str(),
555 InputBuilder<std::int32_t>::spliceAll(array: result.data(), length: result.size(), fmtBuffer: fmtBuffer.data(), bufferSize: bufferSize + 1),
556 interval);
557}
558
559//! @brief Solution of sort.
560//! @param method - used sort method
561//! @param array - array to be sorted
562//! @param length - length of array
563static void solution(const SortMethod method, const std::int32_t* const array, const std::uint32_t length)
564try
565{
566 std::vector<std::int32_t> result{};
567 const utility::time::Stopwatch timing{};
568 switch (method)
569 {
570 using algorithm::sort::Sort;
571 case SortMethod::bubble:
572 result = Sort<std::int32_t>::bubble(array, length);
573 break;
574 case SortMethod::selection:
575 result = Sort<std::int32_t>::selection(array, length);
576 break;
577 case SortMethod::insertion:
578 result = Sort<std::int32_t>::insertion(array, length);
579 break;
580 case SortMethod::shell:
581 result = Sort<std::int32_t>::shell(array, length);
582 break;
583 case SortMethod::merge:
584 result = Sort<std::int32_t>::merge(array, length);
585 break;
586 case SortMethod::quick:
587 result = Sort<std::int32_t>::quick(array, length);
588 break;
589 case SortMethod::heap:
590 result = Sort<std::int32_t>::heap(array, length);
591 break;
592 case SortMethod::counting:
593 result = Sort<std::int32_t>::counting(array, length);
594 break;
595 case SortMethod::bucket:
596 result = Sort<std::int32_t>::bucket(array, length);
597 break;
598 case SortMethod::radix:
599 result = Sort<std::int32_t>::radix(array, length);
600 break;
601 default:
602 return;
603 }
604 display(method, result, interval: timing.elapsedTime());
605}
606catch (const std::exception& err)
607{
608 LOG_WRN_P("Exception in %s (%s): %s", __func__, customTitle(method).c_str(), err.what());
609}
610} // namespace sort
611//! @brief To apply sort-related methods that are mapped to choices.
612//! @param candidates - container for the candidate target choices
613void applyingSort(const std::vector<std::string>& candidates)
614{
615 constexpr auto category = Category::sort;
616 const auto& spec = categoryOpts<category>();
617 if (MACRO_IMPLIES(spec.any(), spec.size() != candidates.size()))
618 {
619 return;
620 }
621
622 const std::string_view title = algorithm::sort::description();
623 APP_ALGO_PRINT_TASK_TITLE_SCOPE_BEGIN(title);
624
625 auto& pooling = configure::task::resourcePool();
626 auto* const allocatedJob = pooling.newEntry(args: spec.count());
627 using sort::InputBuilder, sort::input::arrayLength, sort::input::arrayRangeMin, sort::input::arrayRangeMax;
628 static_assert((arrayRangeMin < arrayRangeMax) && (arrayLength > 0));
629 const auto inputData = std::make_shared<InputBuilder<std::int32_t>>(args: arrayLength, args: arrayRangeMin, args: arrayRangeMax);
630 const auto taskNamer = utility::currying::curry(curried: curriedTaskName(), args: categoryAlias<category>());
631 const auto addTask = [allocatedJob, &inputData, &taskNamer](const std::string_view subtask, const SortMethod method)
632 {
633 allocatedJob->enqueue(
634 name: taskNamer(subtask), func&: sort::solution, args: method, args: inputData->getRandomArray().get(), args: inputData->getLength());
635 };
636 MACRO_DEFER(utility::common::wrapClosure([&]() { pooling.deleteEntry(allocatedJob); }));
637
638 for (const auto index :
639 std::views::iota(0U, spec.size()) | std::views::filter([&spec](const auto i) { return spec.test(position: i); }))
640 {
641 const auto& choice = candidates.at(n: index);
642 switch (utility::common::bkdrHash(str: choice.c_str()))
643 {
644 case abbrLitHash(method: SortMethod::bubble):
645 addTask(choice, SortMethod::bubble);
646 break;
647 case abbrLitHash(method: SortMethod::selection):
648 addTask(choice, SortMethod::selection);
649 break;
650 case abbrLitHash(method: SortMethod::insertion):
651 addTask(choice, SortMethod::insertion);
652 break;
653 case abbrLitHash(method: SortMethod::shell):
654 addTask(choice, SortMethod::shell);
655 break;
656 case abbrLitHash(method: SortMethod::merge):
657 addTask(choice, SortMethod::merge);
658 break;
659 case abbrLitHash(method: SortMethod::quick):
660 addTask(choice, SortMethod::quick);
661 break;
662 case abbrLitHash(method: SortMethod::heap):
663 addTask(choice, SortMethod::heap);
664 break;
665 case abbrLitHash(method: SortMethod::counting):
666 addTask(choice, SortMethod::counting);
667 break;
668 case abbrLitHash(method: SortMethod::bucket):
669 addTask(choice, SortMethod::bucket);
670 break;
671 case abbrLitHash(method: SortMethod::radix):
672 addTask(choice, SortMethod::radix);
673 break;
674 default:
675 throw std::runtime_error{"Unknown " + std::string{toString(cat: category)} + " choice: " + choice + '.'};
676 }
677 }
678
679 APP_ALGO_PRINT_TASK_TITLE_SCOPE_END(title);
680}
681} // namespace application::app_algo
682
683#undef APP_ALGO_PRINT_TASK_TITLE_SCOPE_BEGIN
684#undef APP_ALGO_PRINT_TASK_TITLE_SCOPE_END
685