From a49e175727928b8b45c0c2ccdb01f143ea6d18c2 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Wed, 15 Mar 2017 17:42:02 +0000 Subject: [PATCH] Migrate to a more value based meta programming model Introduce Meta::Type to store a type as value, and pass it around, migrate enum_desc and option_type_name to this. --- src/buffer.hh | 4 ++-- src/client.hh | 2 +- src/commands.cc | 14 ++++++------- src/enum.hh | 19 +++++++++--------- src/input_handler.hh | 2 +- src/insert_completer.hh | 12 +++++------ src/meta.hh | 14 +++++++++++++ src/option_manager.hh | 4 ++-- src/option_types.hh | 44 +++++++++++++++++++---------------------- 9 files changed, 62 insertions(+), 53 deletions(-) create mode 100644 src/meta.hh 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, 2> enum_desc(EolFormat) +constexpr Array, 2> enum_desc(Meta::Type) { return { { { EolFormat::Lf, "lf" }, @@ -35,7 +35,7 @@ enum class ByteOrderMark Utf8 }; -constexpr Array, 2> enum_desc(ByteOrderMark) +constexpr Array, 2> enum_desc(Meta::Type) { 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, 5> enum_desc(Autoreload) +constexpr Array, 5> enum_desc(Meta::Type) { 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> +StringView option_type_name(Meta::Type>) { - static StringView name() { return "line-flags"; } -}; + return "line-flags"; +} -template<> -struct option_type_name> +StringView option_type_name(Meta::Type>) { - 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 struct EnumDesc { T value; StringView name; }; -template +template{}))> EnableIfWithBitOps option_to_string(Flags flags) { - constexpr auto desc = enum_desc(Flags{}); + constexpr auto desc = enum_desc(Meta::Type{}); String res; for (int i = 0; i < desc.size(); ++i) { @@ -38,10 +39,10 @@ EnableIfWithBitOps option_to_string(Flags flags) return res; } -template +template{}))> EnableIfWithoutBitOps option_to_string(Enum e) { - constexpr auto desc = enum_desc(Enum{}); + constexpr auto desc = enum_desc(Meta::Type{}); auto it = find_if(desc, [e](const EnumDesc& d) { return d.value == e; }); if (it != desc.end()) return it->name.str(); @@ -49,10 +50,10 @@ EnableIfWithoutBitOps option_to_string(Enum e) return {}; } -template +template{}))> EnableIfWithBitOps option_from_string(StringView str, Flags& flags) { - constexpr auto desc = enum_desc(Flags{}); + constexpr auto desc = enum_desc(Meta::Type{}); flags = Flags{}; for (auto s : str | split('|')) { @@ -63,17 +64,17 @@ EnableIfWithBitOps option_from_string(StringView str, Flags& flags) } } -template +template{}))> EnableIfWithoutBitOps option_from_string(StringView str, Enum& e) { - constexpr auto desc = enum_desc(Enum{}); + constexpr auto desc = enum_desc(Meta::Type{}); auto it = find_if(desc, [str](const EnumDesc& d) { return d.name == str; }); if (it == desc.end()) throw runtime_error(format("invalid enum value '{}'", str)); e = it->value; } -template +template{}))> EnableIfWithBitOps 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 : std::true_type {}; -constexpr Array, 3> enum_desc(AutoInfo) +constexpr Array, 3> enum_desc(Meta::Type) { 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 struct option_type_name +inline StringView option_type_name(Meta::Type) { - static constexpr StringView name() { return "completer"; } -}; + return "completer"; +} using CompletionCandidate = std::tuple; using CompletionList = PrefixedList; -template<> struct option_type_name +inline StringView option_type_name(Meta::Type) { - 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 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::name()) - : format("[{}] - {}", option_type_name::name(), docstring); + String doc = docstring.empty() ? format("[{}]", option_type_name(Meta::Type{})) + : format("[{}] - {}", option_type_name(Meta::Type{}), docstring); m_descs.emplace_back(new OptionDesc{name.str(), std::move(doc), flags}); opts.emplace_back(new TypedCheckedOption{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 struct option_type_name; -template using void_t = void; +template using valid = std::true_type; template -struct option_type_name> +constexpr decltype(T::option_type_name) option_type_name(Meta::Type) { - static decltype(T::option_type_name) name() { return T::option_type_name; } -}; + return T::option_type_name; +} template -struct option_type_name::value>::type> +typename std::enable_if::value, String>::type +option_type_name(Meta::Type) { - static String name() - { - constexpr StringView type = WithBitOps::value ? "flags" : "enum"; - auto name = enum_desc(Enum{}); - return type + "(" + join(name | transform(std::mem_fn(&EnumDesc::name)), '|') + ")"; - } -}; + constexpr StringView type = WithBitOps::value ? "flags" : "enum"; + auto name = enum_desc(Meta::Type{}); + return type + "(" + join(name | transform(std::mem_fn(&EnumDesc::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 { static StringView name() { return "int"; } }; +inline StringView option_type_name(Meta::Type) { 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 { static StringView name() { return "bool"; } }; +inline StringView option_type_name(Meta::Type) { return "bool"; } constexpr char list_separator = ':'; @@ -101,10 +98,10 @@ bool option_add(Vector& opt, StringView str) } template -struct option_type_name> +String option_type_name(Meta::Type>) { - static String name() { return option_type_name::name() + StringView{"-list"}; } -}; + return option_type_name(Meta::Type{}) + StringView{"-list"}; +} template String option_to_string(const HashMap& opt) @@ -139,12 +136,11 @@ void option_from_string(StringView str, HashMap& opt) } template -struct option_type_name> +String option_type_name(Meta::Type>) { - static String name() { return format("{}-to-{}-map", - option_type_name::name(), - option_type_name::name()); } -}; + return format("{}-to-{}-map", option_type_name(Meta::Type{}), + option_type_name(Meta::Type{})); +} constexpr char tuple_separator = '|'; @@ -251,7 +247,7 @@ enum class DebugFlags template<> struct WithBitOps : std::true_type {}; -constexpr Array, 4> enum_desc(DebugFlags) +constexpr Array, 4> enum_desc(Meta::Type) { return { { { DebugFlags::Hooks, "hooks" },