Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <string>
7 : #include <vector>
8 :
9 : #include "ControlSystem/Metafunctions.hpp"
10 : #include "Utilities/Algorithm.hpp"
11 : #include "Utilities/TMPL.hpp"
12 : #include "Utilities/TypeTraits/IsA.hpp"
13 :
14 : namespace control_system {
15 : /*!
16 : * \brief Given a `tmpl::list` of control systems, returns a string which is a
17 : * sorted concatenation of all the control systems' names.
18 : *
19 : * \details As an example, if `ListOfControlSystems` is `tmpl::list<Rotation,
20 : * Expansion, Translation>`, this function would return
21 : * `ExpansionRotationTranslation`. Sorting is done using `std::sort`.
22 : *
23 : * \tparam ListOfControlSystems `tmpl::list` of control systems
24 : */
25 : template <typename ListOfControlSystems>
26 1 : const std::string& combined_name() {
27 : static const std::string combined_name = []() {
28 : std::vector<std::string> control_system_names{};
29 : control_system_names.reserve(tmpl::size<ListOfControlSystems>::value);
30 : std::string local_combined_name{};
31 :
32 : tmpl::for_each<ListOfControlSystems>(
33 : [&control_system_names](auto control_system_v) {
34 : using control_system = tmpl::type_from<decltype(control_system_v)>;
35 : control_system_names.emplace_back(control_system::name());
36 : });
37 :
38 : alg::sort(control_system_names);
39 :
40 : for (const std::string& name : control_system_names) {
41 : local_combined_name += name;
42 : }
43 :
44 : return local_combined_name;
45 : }();
46 : return combined_name;
47 : }
48 :
49 : /*!
50 : * \brief Given a `tmpl::list` of control systems, this returns a map between
51 : * the name of each control system, and the `control_system::combined_name` of
52 : * all control systems with the same measurement.
53 : *
54 : * \details All control systems have a type alias `measurement` corresponding to
55 : * a `control_system::protocols::Measurement`. Some control systems can have the
56 : * same measurement, while some have different ones. This function splits the
57 : * template list of control systems into a `tmpl::list` of `tmpl::list`s where
58 : * each inner list holds control systems with the same measurement. Each of
59 : * these inner lists is used in `control_system::combined_name` to get the
60 : * concatenated name for those control systems. This combined name is then used
61 : * as the value in the resulting map for they key of each control system in the
62 : * inner list.
63 : *
64 : * \tparam ControlSystems `tmpl::list` of control systems
65 : */
66 : template <typename ControlSystems>
67 1 : std::unordered_map<std::string, std::string> system_to_combined_names() {
68 : using measurements = metafunctions::measurements_t<ControlSystems>;
69 : using control_systems_with_measurements =
70 : tmpl::transform<measurements,
71 : metafunctions::control_systems_with_measurement<
72 : tmpl::pin<ControlSystems>, tmpl::_1>>;
73 :
74 : std::unordered_map<std::string, std::string> map_of_names{};
75 :
76 : tmpl::for_each<control_systems_with_measurements>([&map_of_names](
77 : auto list_v) {
78 : using control_systems_with_measurement = tmpl::type_from<decltype(list_v)>;
79 :
80 : const std::string& combined_name =
81 : control_system::combined_name<control_systems_with_measurement>();
82 :
83 : tmpl::for_each<control_systems_with_measurement>(
84 : [&map_of_names, &combined_name](auto control_system_v) {
85 : using control_system = tmpl::type_from<decltype(control_system_v)>;
86 : map_of_names[control_system::name()] = combined_name;
87 : });
88 : });
89 :
90 : return map_of_names;
91 : }
92 : } // namespace control_system
|