diff options
| author | Maxime Coste <mawww@kakoune.org> | 2017-03-15 17:42:02 +0000 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2017-03-15 17:42:02 +0000 |
| commit | a49e175727928b8b45c0c2ccdb01f143ea6d18c2 (patch) | |
| tree | 88c1c3909c2ab06394a63af5ebab8fdcd0a389f0 | |
| parent | a88e58763bd33e021511d2e821703f478afd85bf (diff) | |
Migrate to a more value based meta programming model
Introduce Meta::Type<T> to store a type as value, and pass it
around, migrate enum_desc and option_type_name to this.
| -rw-r--r-- | src/buffer.hh | 4 | ||||
| -rw-r--r-- | src/client.hh | 2 | ||||
| -rw-r--r-- | src/commands.cc | 14 | ||||
| -rw-r--r-- | src/enum.hh | 19 | ||||
| -rw-r--r-- | src/input_handler.hh | 2 | ||||
| -rw-r--r-- | src/insert_completer.hh | 12 | ||||
| -rw-r--r-- | src/meta.hh | 14 | ||||
| -rw-r--r-- | src/option_manager.hh | 4 | ||||
| -rw-r--r-- | src/option_types.hh | 44 |
9 files changed, 62 insertions, 53 deletions
diff --git a/src/buffer.hh b/src/buffer.hh index 81f68441..bc960b20 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -21,7 +21,7 @@ enum class EolFormat Crlf }; -constexpr Array<EnumDesc<EolFormat>, 2> enum_desc(EolFormat) +constexpr Array<EnumDesc<EolFormat>, 2> enum_desc(Meta::Type<EolFormat>) { return { { { EolFormat::Lf, "lf" }, @@ -35,7 +35,7 @@ enum class ByteOrderMark Utf8 }; -constexpr Array<EnumDesc<ByteOrderMark>, 2> enum_desc(ByteOrderMark) +constexpr Array<EnumDesc<ByteOrderMark>, 2> enum_desc(Meta::Type<ByteOrderMark>) { return { { { ByteOrderMark::None, "none" }, diff --git a/src/client.hh b/src/client.hh index 80a1ef08..d5abc929 100644 --- a/src/client.hh +++ b/src/client.hh @@ -131,7 +131,7 @@ enum class Autoreload Ask }; -constexpr Array<EnumDesc<Autoreload>, 5> enum_desc(Autoreload) +constexpr Array<EnumDesc<Autoreload>, 5> enum_desc(Meta::Type<Autoreload>) { return { { { Autoreload::Yes, "yes" }, diff --git a/src/commands.cc b/src/commands.cc index 7ffc0c0e..a57e8031 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -43,17 +43,15 @@ namespace Kakoune { -template<> -struct option_type_name<TimestampedList<LineAndFlag>> +StringView option_type_name(Meta::Type<TimestampedList<LineAndFlag>>) { - static StringView name() { return "line-flags"; } -}; + return "line-flags"; +} -template<> -struct option_type_name<TimestampedList<RangeAndFace>> +StringView option_type_name(Meta::Type<TimestampedList<RangeAndFace>>) { - static StringView name() { return "range-faces"; } -}; + return "range-faces"; +} namespace { diff --git a/src/enum.hh b/src/enum.hh index 01f89b32..56242508 100644 --- a/src/enum.hh +++ b/src/enum.hh @@ -5,6 +5,7 @@ #include "string.hh" #include "exception.hh" #include "containers.hh" +#include "meta.hh" namespace Kakoune { @@ -22,10 +23,10 @@ struct Array template<typename T> struct EnumDesc { T value; StringView name; }; -template<typename Flags, typename = decltype(enum_desc(Flags{}))> +template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))> EnableIfWithBitOps<Flags, String> option_to_string(Flags flags) { - constexpr auto desc = enum_desc(Flags{}); + constexpr auto desc = enum_desc(Meta::Type<Flags>{}); String res; for (int i = 0; i < desc.size(); ++i) { @@ -38,10 +39,10 @@ EnableIfWithBitOps<Flags, String> option_to_string(Flags flags) return res; } -template<typename Enum, typename = decltype(enum_desc(Enum{}))> +template<typename Enum, typename = decltype(enum_desc(Meta::Type<Enum>{}))> EnableIfWithoutBitOps<Enum, String> option_to_string(Enum e) { - constexpr auto desc = enum_desc(Enum{}); + constexpr auto desc = enum_desc(Meta::Type<Enum>{}); auto it = find_if(desc, [e](const EnumDesc<Enum>& d) { return d.value == e; }); if (it != desc.end()) return it->name.str(); @@ -49,10 +50,10 @@ EnableIfWithoutBitOps<Enum, String> option_to_string(Enum e) return {}; } -template<typename Flags, typename = decltype(enum_desc(Flags{}))> +template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))> EnableIfWithBitOps<Flags> option_from_string(StringView str, Flags& flags) { - constexpr auto desc = enum_desc(Flags{}); + constexpr auto desc = enum_desc(Meta::Type<Flags>{}); flags = Flags{}; for (auto s : str | split<StringView>('|')) { @@ -63,17 +64,17 @@ EnableIfWithBitOps<Flags> option_from_string(StringView str, Flags& flags) } } -template<typename Enum, typename = decltype(enum_desc(Enum{}))> +template<typename Enum, typename = decltype(enum_desc(Meta::Type<Enum>{}))> EnableIfWithoutBitOps<Enum> option_from_string(StringView str, Enum& e) { - constexpr auto desc = enum_desc(Enum{}); + constexpr auto desc = enum_desc(Meta::Type<Enum>{}); auto it = find_if(desc, [str](const EnumDesc<Enum>& d) { return d.name == str; }); if (it == desc.end()) throw runtime_error(format("invalid enum value '{}'", str)); e = it->value; } -template<typename Flags, typename = decltype(enum_desc(Flags{}))> +template<typename Flags, typename = decltype(enum_desc(Meta::Type<Flags>{}))> EnableIfWithBitOps<Flags, bool> option_add(Flags& opt, StringView str) { Flags res = Flags{}; diff --git a/src/input_handler.hh b/src/input_handler.hh index 43fd9ecb..fd13a5a0 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -134,7 +134,7 @@ enum class AutoInfo template<> struct WithBitOps<AutoInfo> : std::true_type {}; -constexpr Array<EnumDesc<AutoInfo>, 3> enum_desc(AutoInfo) +constexpr Array<EnumDesc<AutoInfo>, 3> enum_desc(Meta::Type<AutoInfo>) { return { { { AutoInfo::Command, "command"}, diff --git a/src/insert_completer.hh b/src/insert_completer.hh index dac3db27..d7061c37 100644 --- a/src/insert_completer.hh +++ b/src/insert_completer.hh @@ -37,18 +37,18 @@ using InsertCompleterDescList = Vector<InsertCompleterDesc, MemoryDomain::Option String option_to_string(const InsertCompleterDesc& opt); void option_from_string(StringView str, InsertCompleterDesc& opt); -template<> struct option_type_name<InsertCompleterDesc> +inline StringView option_type_name(Meta::Type<InsertCompleterDesc>) { - static constexpr StringView name() { return "completer"; } -}; + return "completer"; +} using CompletionCandidate = std::tuple<String, String, String>; using CompletionList = PrefixedList<String, CompletionCandidate>; -template<> struct option_type_name<CompletionList> +inline StringView option_type_name(Meta::Type<CompletionList>) { - static constexpr StringView name() { return "completions"; } -}; + return "completions"; +} struct InsertCompletion { diff --git a/src/meta.hh b/src/meta.hh new file mode 100644 index 00000000..32f28dbb --- /dev/null +++ b/src/meta.hh @@ -0,0 +1,14 @@ +#ifndef meta_hh_INCLUDED +#define meta_hh_INCLUDED + +namespace Kakoune +{ +namespace Meta +{ + +template<typename T> struct Type {}; + +} +} + +#endif // meta_hh_INCLUDED diff --git a/src/option_manager.hh b/src/option_manager.hh index 958a01f4..e794a3c9 100644 --- a/src/option_manager.hh +++ b/src/option_manager.hh @@ -221,8 +221,8 @@ public: return **it; throw runtime_error{format("option '{}' already declared with different type or flags", name)}; } - String doc = docstring.empty() ? format("[{}]", option_type_name<T>::name()) - : format("[{}] - {}", option_type_name<T>::name(), docstring); + String doc = docstring.empty() ? format("[{}]", option_type_name(Meta::Type<T>{})) + : format("[{}] - {}", option_type_name(Meta::Type<T>{}), docstring); m_descs.emplace_back(new OptionDesc{name.str(), std::move(doc), flags}); opts.emplace_back(new TypedCheckedOption<T, validator>{m_global_manager, *m_descs.back(), value}); return *opts.back(); diff --git a/src/option_types.hh b/src/option_types.hh index d9dc7db7..ab2c35fa 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -16,25 +16,22 @@ namespace Kakoune { -template<typename T, typename = void> struct option_type_name; -template<typename T> using void_t = void; +template<typename T> using valid = std::true_type; template<typename T> -struct option_type_name<T, void_t<decltype(T::option_type_name)>> +constexpr decltype(T::option_type_name) option_type_name(Meta::Type<T>) { - static decltype(T::option_type_name) name() { return T::option_type_name; } -}; + return T::option_type_name; +} template<typename Enum> -struct option_type_name<Enum, typename std::enable_if<std::is_enum<Enum>::value>::type> +typename std::enable_if<std::is_enum<Enum>::value, String>::type +option_type_name(Meta::Type<Enum>) { - static String name() - { - constexpr StringView type = WithBitOps<Enum>::value ? "flags" : "enum"; - auto name = enum_desc(Enum{}); - return type + "(" + join(name | transform(std::mem_fn(&EnumDesc<Enum>::name)), '|') + ")"; - } -}; + constexpr StringView type = WithBitOps<Enum>::value ? "flags" : "enum"; + auto name = enum_desc(Meta::Type<Enum>{}); + return type + "(" + join(name | transform(std::mem_fn(&EnumDesc<Enum>::name)), '|') + ")"; +} inline String option_to_string(int opt) { return to_string(opt); } inline void option_from_string(StringView str, int& opt) { opt = str_to_int(str); } @@ -44,7 +41,7 @@ inline bool option_add(int& opt, StringView str) opt += val; return val != 0; } -template<> struct option_type_name<int> { static StringView name() { return "int"; } }; +inline StringView option_type_name(Meta::Type<int>) { return "int"; } inline String option_to_string(size_t opt) { return to_string(opt); } inline void option_from_string(StringView str, size_t& opt) { opt = str_to_int(str); } @@ -59,7 +56,7 @@ inline void option_from_string(StringView str, bool& opt) else throw runtime_error("boolean values are either true, yes, false or no"); } -template<> struct option_type_name<bool> { static StringView name() { return "bool"; } }; +inline StringView option_type_name(Meta::Type<bool>) { return "bool"; } constexpr char list_separator = ':'; @@ -101,10 +98,10 @@ bool option_add(Vector<T, domain>& opt, StringView str) } template<typename T, MemoryDomain D> -struct option_type_name<Vector<T, D>> +String option_type_name(Meta::Type<Vector<T, D>>) { - static String name() { return option_type_name<T>::name() + StringView{"-list"}; } -}; + return option_type_name(Meta::Type<T>{}) + StringView{"-list"}; +} template<typename Key, typename Value, MemoryDomain domain> String option_to_string(const HashMap<Key, Value, domain>& opt) @@ -139,12 +136,11 @@ void option_from_string(StringView str, HashMap<Key, Value, domain>& opt) } template<typename K, typename V, MemoryDomain D> -struct option_type_name<HashMap<K, V, D>> +String option_type_name(Meta::Type<HashMap<K, V, D>>) { - static String name() { return format("{}-to-{}-map", - option_type_name<K>::name(), - option_type_name<V>::name()); } -}; + return format("{}-to-{}-map", option_type_name(Meta::Type<K>{}), + option_type_name(Meta::Type<V>{})); +} constexpr char tuple_separator = '|'; @@ -251,7 +247,7 @@ enum class DebugFlags template<> struct WithBitOps<DebugFlags> : std::true_type {}; -constexpr Array<EnumDesc<DebugFlags>, 4> enum_desc(DebugFlags) +constexpr Array<EnumDesc<DebugFlags>, 4> enum_desc(Meta::Type<DebugFlags>) { return { { { DebugFlags::Hooks, "hooks" }, |
