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