1 #ifndef option_hh_INCLUDED
2 #define option_hh_INCLUDED
3
4 #include "enum.hh"
5 #include "meta.hh"
6 #include "vector.hh"
7 #include "constexpr_utils.hh"
8
9 namespace Kakoune
10 {
11
12 class String;
13 enum class Quoting;
14
15 // Forward declare functions that wont get found by ADL
16 inline String option_to_string(int opt);
17 inline String option_to_string(size_t opt);
18 inline String option_to_string(bool opt);
19
20 // Default fallback to single value functions
21 template<typename T>
option_from_string(Meta::Type<T>{},StringView{})22 decltype(option_from_string(Meta::Type<T>{}, StringView{}))
23 option_from_strings(Meta::Type<T>, ConstArrayView<String> strs)
24 {
25 if (strs.size() != 1)
26 throw runtime_error("expected a single value for option");
27 return option_from_string(Meta::Type<T>{}, strs[0]);
28 }
29
30 template<typename T>
31 Vector<decltype(option_to_string(std::declval<T>(), Quoting{}))>
option_to_strings(const T & opt)32 option_to_strings(const T& opt)
33 {
34 return Vector<String>{option_to_string(opt, Quoting{})};
35 }
36
37 template<typename T>
option_add(std::declval<T> (),std::declval<String> ())38 decltype(option_add(std::declval<T>(), std::declval<String>()))
39 option_add_from_strings(T& opt, ConstArrayView<String> strs)
40 {
41 if (strs.size() != 1)
42 throw runtime_error("expected a single value for option");
43 return option_add(opt, strs[0]);
44 }
45
46 template<typename T>
option_add(std::declval<T> (),std::declval<String> ())47 decltype(option_add(std::declval<T>(), std::declval<String>()))
48 option_remove_from_strings(T& opt, ConstArrayView<String> strs)
49 {
50 if (strs.size() != 1)
51 throw runtime_error("expected a single value for option");
52 return option_remove(opt, strs[0]);
53 }
54
55 template<typename P, typename T>
56 struct PrefixedList
57 {
58 P prefix;
59 Vector<T, MemoryDomain::Options> list;
60
operator ==(const PrefixedList & lhs,const PrefixedList & rhs)61 friend bool operator==(const PrefixedList& lhs, const PrefixedList& rhs)
62 {
63 return lhs.prefix == rhs.prefix and lhs.list == rhs.list;
64 }
65
operator !=(const PrefixedList & lhs,const PrefixedList & rhs)66 friend bool operator!=(const PrefixedList& lhs, const PrefixedList& rhs)
67 {
68 return not (lhs == rhs);
69 }
70 };
71
72 template<typename T>
73 using TimestampedList = PrefixedList<size_t, T>;
74
75 enum class DebugFlags
76 {
77 None = 0,
78 Hooks = 1 << 0,
79 Shell = 1 << 1,
80 Profile = 1 << 2,
81 Keys = 1 << 3,
82 Commands = 1 << 4,
83 };
84
with_bit_ops(Meta::Type<DebugFlags>)85 constexpr bool with_bit_ops(Meta::Type<DebugFlags>) { return true; }
86
enum_desc(Meta::Type<DebugFlags>)87 constexpr auto enum_desc(Meta::Type<DebugFlags>)
88 {
89 return make_array<EnumDesc<DebugFlags>>({
90 { DebugFlags::Hooks, "hooks" },
91 { DebugFlags::Shell, "shell" },
92 { DebugFlags::Profile, "profile" },
93 { DebugFlags::Keys, "keys" },
94 { DebugFlags::Commands, "commands" },
95 });
96 }
97
98 }
99
100 #endif // option_hh_INCLUDED
101