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