From b5693c6253bd99af5d27488562f9598c1c45c85d Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sun, 27 May 2018 13:00:04 +1000 Subject: [PATCH] Refactor option_from_string to return directly the option value --- src/color.cc | 4 +- src/color.hh | 3 +- src/highlighters.cc | 4 +- src/highlighters.hh | 2 +- src/insert_completer.cc | 26 ++------ src/insert_completer.hh | 2 +- src/option_manager.hh | 4 +- src/option_types.cc | 3 +- src/option_types.hh | 131 +++++++++++++++++----------------------- src/regex.cc | 4 +- src/regex.hh | 2 +- src/string_utils.hh | 2 +- 12 files changed, 73 insertions(+), 114 deletions(-) diff --git a/src/color.cc b/src/color.cc index a8d04ee6..4373684d 100644 --- a/src/color.cc +++ b/src/color.cc @@ -81,9 +81,9 @@ String option_to_string(Color color) return to_string(color); } -void option_from_string(StringView str, Color& color) +Color option_from_string(Meta::Type, StringView str) { - color = str_to_color(str); + return str_to_color(str); } } diff --git a/src/color.hh b/src/color.hh index ae8046ab..d42b112b 100644 --- a/src/color.hh +++ b/src/color.hh @@ -2,6 +2,7 @@ #define color_hh_INCLUDED #include "hash.hh" +#include "meta.hh" namespace Kakoune { @@ -59,7 +60,7 @@ Color str_to_color(StringView color); String to_string(Color color); String option_to_string(Color color); -void option_from_string(StringView str, Color& color); +Color option_from_string(Meta::Type, StringView str); bool is_color_name(StringView color); diff --git a/src/highlighters.cc b/src/highlighters.cc index 181b8fd5..71cfcbae 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -1379,7 +1379,7 @@ String option_to_string(InclusiveBufferRange range) range.last.line+1, range.last.column+1); } -void option_from_string(StringView str, InclusiveBufferRange& opt) +InclusiveBufferRange option_from_string(Meta::Type, StringView str) { auto sep = find_if(str, [](char c){ return c == ',' or c == '+'; }); auto dot_beg = find(StringView{str.begin(), sep}, '.'); @@ -1400,7 +1400,7 @@ void option_from_string(StringView str, InclusiveBufferRange& opt) if (first.line < 0 or first.column < 0 or last.line < 0 or last.column < 0) throw runtime_error("coordinates elements should be >= 1"); - opt = { std::min(first, last), std::max(first, last) }; + return { std::min(first, last), std::max(first, last) }; } BufferCoord& get_first(RangeAndString& r) { return std::get<0>(r).first; } diff --git a/src/highlighters.hh b/src/highlighters.hh index 69979e32..c635b8df 100644 --- a/src/highlighters.hh +++ b/src/highlighters.hh @@ -17,7 +17,7 @@ inline bool operator==(const InclusiveBufferRange& lhs, const InclusiveBufferRan return lhs.first == rhs.first and lhs.last == rhs.last; } String option_to_string(InclusiveBufferRange range); -void option_from_string(StringView str, InclusiveBufferRange& opt); +InclusiveBufferRange option_from_string(Meta::Type, StringView str); using LineAndSpec = std::tuple; using LineAndSpecList = TimestampedList; diff --git a/src/insert_completer.cc b/src/insert_completer.cc index 86b02e64..5d067ba0 100644 --- a/src/insert_completer.cc +++ b/src/insert_completer.cc @@ -40,39 +40,23 @@ String option_to_string(const InsertCompleterDesc& opt) return ""; } -void option_from_string(StringView str, InsertCompleterDesc& opt) +InsertCompleterDesc option_from_string(Meta::Type, StringView str) { if (str.substr(0_byte, 7_byte) == "option=") - { - opt.mode = InsertCompleterDesc::Option; - opt.param = str.substr(7_byte).str(); - return; - } + return {InsertCompleterDesc::Option, str.substr(7_byte).str()}; else if (str.substr(0_byte, 5_byte) == "word=") { auto param = str.substr(5_byte); if (param == "all" or param == "buffer") - { - opt.mode = InsertCompleterDesc::Word; - opt.param = param.str(); - return; - } + return {InsertCompleterDesc::Word, param.str()}; } else if (str == "filename") - { - opt.mode = InsertCompleterDesc::Filename; - opt.param = Optional{}; - return; - } + return {InsertCompleterDesc::Filename, {}}; else if (str.substr(0_byte, 5_byte) == "line=") { auto param = str.substr(5_byte); if (param == "all" or param == "buffer") - { - opt.mode = InsertCompleterDesc::Line; - opt.param = param.str(); - return; - } + return {InsertCompleterDesc::Line, param.str()}; } throw runtime_error(format("invalid completer description: '{}'", str)); } diff --git a/src/insert_completer.hh b/src/insert_completer.hh index 7e79bd09..0f16e8aa 100644 --- a/src/insert_completer.hh +++ b/src/insert_completer.hh @@ -38,7 +38,7 @@ struct InsertCompleterDesc using InsertCompleterDescList = Vector; String option_to_string(const InsertCompleterDesc& opt); -void option_from_string(StringView str, InsertCompleterDesc& opt); +InsertCompleterDesc option_from_string(Meta::Type, StringView str); inline StringView option_type_name(Meta::Type) { diff --git a/src/option_manager.hh b/src/option_manager.hh index f5d36ac0..b1ecf4ef 100644 --- a/src/option_manager.hh +++ b/src/option_manager.hh @@ -147,9 +147,7 @@ public: } void set_from_string(StringView str) override { - T val; - option_from_string(str, val); - set(std::move(val)); + set(option_from_string(Meta::Type{}, str)); } void add_from_string(StringView str) override { diff --git a/src/option_types.cc b/src/option_types.cc index bd30d4f8..f32e361f 100644 --- a/src/option_types.cc +++ b/src/option_types.cc @@ -9,8 +9,7 @@ UnitTest test_option_parsing{[]{ { auto repr = option_to_string(value); kak_assert(repr == str); - std::decay_t parsed; - option_from_string(str, parsed); + auto parsed = option_from_string(Meta::Type>{}, str); kak_assert(parsed == value); }; diff --git a/src/option_types.hh b/src/option_types.hh index 0617a183..c7b5d5f8 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -34,7 +34,7 @@ option_type_name(Meta::Type) } 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); } +inline int option_from_string(Meta::Type, StringView str) { return str_to_int(str); } inline bool option_add(int& opt, StringView str) { auto val = str_to_int(str); @@ -44,26 +44,26 @@ inline bool option_add(int& opt, StringView str) constexpr 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); } +inline size_t option_from_string(Meta::Type, StringView str) { return str_to_int(str); } inline String option_to_string(bool opt) { return opt ? "true" : "false"; } -inline void option_from_string(StringView str, bool& opt) +inline bool option_from_string(Meta::Type, StringView str) { if (str == "true" or str == "yes") - opt = true; + return true; else if (str == "false" or str == "no") - opt = false; + return false; else throw runtime_error("boolean values are either true, yes, false or no"); } constexpr StringView option_type_name(Meta::Type) { return "bool"; } inline String option_to_string(Codepoint opt) { return to_string(opt); } -inline void option_from_string(StringView str, Codepoint& opt) +inline Codepoint option_from_string(Meta::Type, StringView str) { if (str.char_length() != 1) throw runtime_error{format("'{}' is not a single codepoint", str)}; - opt = str[0_char]; + return str[0_char]; } constexpr StringView option_type_name(Meta::Type) { return "codepoint"; } @@ -81,24 +81,20 @@ void option_list_postprocess(Vector& opt) {} template -void option_from_string(StringView str, Vector& opt) +Vector option_from_string(Meta::Type>, StringView str) { - opt.clear(); - for (auto&& elem : str | split(list_separator, '\\') - | transform(unescape)) - { - T opt_elem; - option_from_string(elem, opt_elem); - opt.push_back(opt_elem); - } - option_list_postprocess(opt); + auto res = str | split(list_separator, '\\') + | transform(unescape) + | transform([](auto&& s) { return option_from_string(Meta::Type{}, s); }) + | gather>(); + option_list_postprocess(res); + return res; } template bool option_add(Vector& opt, StringView str) { - Vector vec; - option_from_string(str, vec); + auto vec = option_from_string(Meta::Type>{}, str); opt.insert(opt.end(), std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end())); @@ -139,20 +135,18 @@ bool option_add(HashMap& opt, StringView str) | transform(unescape<'=', '\\'>) | static_gather(); - HashItem item; - option_from_string(key_value[0], item.key); - option_from_string(key_value[1], item.value); - opt[std::move(item.key)] = std::move(item.value); + opt[option_from_string(Meta::Type{}, key_value[0])] = option_from_string(Meta::Type{}, key_value[1]); changed = true; } return changed; } template -void option_from_string(StringView str, HashMap& opt) +HashMap option_from_string(Meta::Type>, StringView str) { - opt.clear(); - option_add(opt, str); + HashMap res; + option_add(res, str); + return res; } template @@ -164,44 +158,21 @@ String option_type_name(Meta::Type>) constexpr char tuple_separator = '|'; -template -struct TupleOptionDetail +template +String option_to_string_impl(const std::tuple& opt, std::index_sequence) { - static String to_string(const std::tuple& opt) - { - return TupleOptionDetail::to_string(opt) + - tuple_separator + escape(option_to_string(std::get(opt)), tuple_separator, '\\'); - } - - static void from_string(ConstArrayView elems, std::tuple& opt) - { - option_from_string(elems[I], std::get(opt)); - TupleOptionDetail::from_string(elems, opt); - } -}; - -template -struct TupleOptionDetail<0, Types...> -{ - static String to_string(const std::tuple& opt) - { - return option_to_string(std::get<0>(opt)); - } - - static void from_string(ConstArrayView elems, std::tuple& opt) - { - option_from_string(elems[0], std::get<0>(opt)); - } -}; + return join(make_array({option_to_string(std::get(opt))...}), tuple_separator); +} template String option_to_string(const std::tuple& opt) { - return TupleOptionDetail::to_string(opt); + return option_to_string_impl(opt, std::make_index_sequence()); } -template -void option_from_string(StringView str, std::tuple& opt) +template +std::tuple option_from_string_impl(Meta::Type>, StringView str, + std::index_sequence) { struct error : runtime_error { @@ -212,8 +183,14 @@ void option_from_string(StringView str, std::tuple& opt) auto elems = str | split(tuple_separator, '\\') | transform(unescape) | static_gather(); + return {option_from_string(Meta::Type{}, elems[I])...}; +} - TupleOptionDetail::from_string(elems, opt); +template +std::tuple option_from_string(Meta::Type>, StringView str) +{ + return option_from_string_impl(Meta::Type>{}, str, + std::make_index_sequence()); } template @@ -222,15 +199,15 @@ inline String option_to_string(const StronglyTypedNumber& o return to_string(opt); } -template -inline void option_from_string(StringView str, StronglyTypedNumber& opt) +template +std::enable_if_t, Number>::value, Number> +option_from_string(Meta::Type, StringView str) { - opt = StronglyTypedNumber{str_to_int(str)}; + return Number{str_to_int(str)}; } template -inline bool option_add(StronglyTypedNumber& opt, - StringView str) +inline bool option_add(StronglyTypedNumber& opt, StringView str) { int val = str_to_int(str); opt += val; @@ -251,14 +228,14 @@ inline void option_update(WorstMatch, const Context&) throw runtime_error("no update operation supported for this option type"); } -template -inline void option_from_string(StringView str, LineAndColumn& opt) +template +std::enable_if_t, Coord>::value, Coord> +option_from_string(Meta::Type, StringView str) { struct error : runtime_error { error(size_t) : runtime_error{"expected ,"} {} }; auto vals = str | split(',') | static_gather(); - opt.line = str_to_int(vals[0]); - opt.column = str_to_int(vals[1]); + return {str_to_int(vals[0]), str_to_int(vals[1])}; } template @@ -295,10 +272,10 @@ EnableIfWithoutBitOps option_to_string(Enum e) } template{}))> -EnableIfWithBitOps option_from_string(StringView str, Flags& flags) +EnableIfWithBitOps option_from_string(Meta::Type, StringView str) { constexpr auto desc = enum_desc(Meta::Type{}); - flags = Flags{}; + Flags flags{}; for (auto s : str | split('|')) { auto it = find_if(desc, [s](const EnumDesc& d) { return d.name == s; }); @@ -306,23 +283,23 @@ EnableIfWithBitOps option_from_string(StringView str, Flags& flags) throw runtime_error(format("invalid flag value '{}'", s)); flags |= it->value; } + return flags; } template{}))> -EnableIfWithoutBitOps option_from_string(StringView str, Enum& e) +EnableIfWithoutBitOps option_from_string(Meta::Type, StringView str) { 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; + return it->value; } template{}))> EnableIfWithBitOps option_add(Flags& opt, StringView str) { - Flags res = Flags{}; - option_from_string(str, res); + const Flags res = option_from_string(Meta::Type{}, str); opt |= res; return res != (Flags)0; } @@ -338,12 +315,12 @@ inline String option_to_string(const PrefixedList& opt) } template -inline void option_from_string(StringView str, PrefixedList& opt) +inline PrefixedList option_from_string(Meta::Type>, StringView str) { + using VecType = Vector; auto it = find(str, list_separator); - option_from_string(StringView{str.begin(), it}, opt.prefix); - if (it != str.end()) - option_from_string({it+1, str.end()}, opt.list); + return {option_from_string(Meta::Type

{}, StringView{str.begin(), it}), + it != str.end() ? option_from_string(Meta::Type{}, {it+1, str.end()}) : VecType{}}; } template diff --git a/src/regex.cc b/src/regex.cc index 3967cebc..970721c7 100644 --- a/src/regex.cc +++ b/src/regex.cc @@ -13,9 +13,9 @@ String option_to_string(const Regex& re) return re.str(); } -void option_from_string(StringView str, Regex& re) +Regex option_from_string(Meta::Type, StringView str) { - re = Regex{str}; + return Regex{str}; } } diff --git a/src/regex.hh b/src/regex.hh index 531c258b..aac66921 100644 --- a/src/regex.hh +++ b/src/regex.hh @@ -161,7 +161,7 @@ bool backward_regex_search(It begin, It end, It subject_begin, It subject_end, } String option_to_string(const Regex& re); -void option_from_string(StringView str, Regex& re); +Regex option_from_string(Meta::Type, StringView str); template struct RegexIterator diff --git a/src/string_utils.hh b/src/string_utils.hh index 6f0124a1..bd803536 100644 --- a/src/string_utils.hh +++ b/src/string_utils.hh @@ -66,7 +66,7 @@ int str_to_int(StringView str); // throws on error Optional str_to_int_ifp(StringView str); inline String option_to_string(StringView opt) { return opt.str(); } -inline void option_from_string(StringView str, String& opt) { opt = str.str(); } +inline String option_from_string(Meta::Type, StringView str) { return str.str(); } inline bool option_add(String& opt, StringView val) { opt += val; return not val.empty(); } template