openMSX
EnumSetting.hh
Go to the documentation of this file.
1#ifndef ENUMSETTING_HH
2#define ENUMSETTING_HH
3
4#include "Setting.hh"
5#include "view.hh"
6#include <concepts>
7#include <iterator>
8#include <utility>
9#include <vector>
10
11namespace openmsx {
12
13class TclObject;
14
15// non-templatized base class
17{
18public:
19 struct MapEntry {
20 template<typename Enum>
21 MapEntry(std::string_view name_, Enum value_)
22 : name(name_), value(static_cast<int>(value_)) {}
23
24 std::string name; // cannot be string_view because of the 'default_machine' setting
25 int value;
26 };
27 using Map = std::vector<MapEntry>;
28 [[nodiscard]] const auto& getMap() const { return baseMap; }
29
30 explicit EnumSettingBase(Map&& m);
31
32 [[nodiscard]] int fromStringBase(std::string_view str) const;
33 [[nodiscard]] std::string_view toStringBase(int value) const;
34
35 [[nodiscard]] auto getPossibleValues() const {
36 return view::transform(baseMap,
37 [](const auto& e) -> std::string_view { return e.name; });
38 }
39
40 void additionalInfoBase(TclObject& result) const;
41 void tabCompletionBase(std::vector<std::string>& tokens) const;
42
43private:
44 Map baseMap;
45};
46
47template<typename T>
48concept EnumSettingValue = requires(T t, int i) {
49 static_cast<T>(i);
50 static_cast<int>(t);
51};
52
53template<EnumSettingValue T> class EnumSetting final : public EnumSettingBase, public Setting
54{
55public:
57
58 EnumSetting(CommandController& commandController, std::string_view name,
59 static_string_view description, T initialValue,
60 Map&& map_, Save save = Save::YES);
61
62 [[nodiscard]] std::string_view getTypeString() const override;
63 void additionalInfo(TclObject& result) const override;
64 void tabCompletion(std::vector<std::string>& tokens) const override;
65
66 [[nodiscard]] T getEnum() const noexcept;
67 void setEnum(T e);
68 [[nodiscard]] std::string_view getString() const;
69
70private:
71 std::string_view toString(T e) const;
72};
73
74
75//-------------
76
77
78template<EnumSettingValue T>
80 CommandController& commandController_, std::string_view name,
81 static_string_view description_, T initialValue,
82 Map&& map, Save save_)
83 : EnumSettingBase(std::move(map))
84 , Setting(commandController_, name, description_,
85 TclObject(EnumSettingBase::toStringBase(static_cast<int>(initialValue))), save_)
86{
87 setChecker([this](const TclObject& newValue) {
88 (void)fromStringBase(newValue.getString()); // may throw
89 });
90 init();
91}
92
93template<EnumSettingValue T>
94std::string_view EnumSetting<T>::getTypeString() const
95{
96 return "enumeration";
97}
98
99template<EnumSettingValue T>
101{
102 additionalInfoBase(result);
103}
104
105template<EnumSettingValue T>
106void EnumSetting<T>::tabCompletion(std::vector<std::string>& tokens) const
107{
108 tabCompletionBase(tokens);
109}
110
111template<EnumSettingValue T>
112T EnumSetting<T>::getEnum() const noexcept
113{
114 return static_cast<T>(fromStringBase(getValue().getString()));
115}
116template<> inline bool EnumSetting<bool>::getEnum() const noexcept
117{
118 // _exactly_ the same functionality as above, but suppress VS warning
119 return fromStringBase(getValue().getString()) != 0;
120}
121
122template<EnumSettingValue T>
124{
125 setValue(TclObject(toString(e)));
126}
127
128template<EnumSettingValue T>
129std::string_view EnumSetting<T>::getString() const
130{
131 return getValue().getString();
132}
133
134template<EnumSettingValue T>
135std::string_view EnumSetting<T>::toString(T e) const
136{
137 return toStringBase(static_cast<int>(e));
138}
139
140} // namespace openmsx
141
142#endif
TclObject t
std::vector< MapEntry > Map
void tabCompletionBase(std::vector< std::string > &tokens) const
void additionalInfoBase(TclObject &result) const
std::string_view toStringBase(int value) const
int fromStringBase(std::string_view str) const
auto getPossibleValues() const
const auto & getMap() const
EnumSettingBase::Map Map
void additionalInfo(TclObject &result) const override
Helper method for info().
std::string_view getTypeString() const override
Returns a string describing the setting type (integer, string, ..) Could be used in a GUI to pick an ...
std::string_view getString() const
void tabCompletion(std::vector< std::string > &tokens) const override
Complete a partly typed value.
T getEnum() const noexcept
EnumSetting(CommandController &commandController, std::string_view name, static_string_view description, T initialValue, Map &&map_, Save save=Save::YES)
void setChecker(std::function< void(TclObject &)> checkFunc_)
Set value-check-callback.
Definition Setting.hh:146
const TclObject & getValue() const final
Gets the current value of this setting as a TclObject.
Definition Setting.hh:134
void setValue(const TclObject &newValue) final
Change the value of this setting to the given value.
Definition Setting.cc:81
zstring_view getString() const
Definition TclObject.cc:141
static_string_view
This file implemented 3 utility functions:
Definition Autofire.cc:11
STL namespace.
constexpr auto transform(Range &&range, UnaryOp op)
Definition view.hh:520
MapEntry(std::string_view name_, Enum value_)