From 6d31cccc5b006119bf37d6ab93dfbfe2861d685e Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 1 Sep 2019 14:45:56 +0900 Subject: [PATCH] feat: throw if multiple keys match to the key --- toml/find.hpp | 93 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/toml/find.hpp b/toml/find.hpp index 169323f..c1a84e6 100644 --- a/toml/find.hpp +++ b/toml/find.hpp @@ -422,6 +422,39 @@ struct levenstein_matcher // --------------------------------------------------------------------------- // toml::find_fuzzy(v, "tablename", FuzzyMatcher); +namespace detail +{ +template class M, template class V, + typename FuzzyMatcher> +Iterator find_unique( + Iterator iter, const Iterator end, const basic_value& v, + const toml::key& k, const FuzzyMatcher& match) +{ + Iterator found = end; + for(; iter != end; ++iter) + { + if(match(iter->first, k)) + { + if(found != end) + { + throw std::out_of_range(detail::format_underline( + concat_to_string("[error] key \"", k, "\" not found."), + { + {std::addressof(detail::get_region(v)),"in this table"}, + {std::addressof(detail::get_region(found->second)), + "did you mean this here?"}, + {std::addressof(detail::get_region(iter->second)), + "or this?"} + })); + } + found = iter; + } + } + return found; +} +} // detail + template class M, template class V, typename FuzzyMatcher = levenstein_matcher> @@ -435,13 +468,11 @@ auto find_fuzzy(const basic_value& v, const key& ky, } catch(const std::out_of_range& oor) { - const auto& tab = v.as_table(); - for(const auto& kv : tab) + const auto& t = v.as_table(); + const auto found = detail::find_unique(t.begin(), t.end(), v, ky, match); + if(found != t.end()) { - if(match(kv.first, ky)) - { - return get(kv.second); - } + return get(found->second); } throw; } @@ -459,13 +490,11 @@ auto find_fuzzy(basic_value& v, const key& ky, } catch(const std::out_of_range& oor) { - auto& tab = v.as_table(); - for(auto& kv : tab) + auto& t = v.as_table(); + const auto found = detail::find_unique(t.begin(), t.end(), v, ky, match); + if(found != t.end()) { - if(match(kv.first, ky)) - { - return get(kv.second); - } + return get(found->second); } throw; } @@ -484,13 +513,11 @@ auto find_fuzzy(basic_value&& v_, const key& ky, } catch(const std::out_of_range& oor) { - auto& tab = v.as_table(); // because v is used here - for(auto& kv : tab) + auto& t = v.as_table(); // because v is used here + const auto found = detail::find_unique(t.begin(), t.end(), v, ky, match); + if(found != t.end()) { - if(match(kv.first, ky)) - { - return get(std::move(kv.second)); - } + return get(std::move(found->second)); } throw; } @@ -513,13 +540,11 @@ find_fuzzy(const basic_value& v, const key& ky, } catch(const std::out_of_range& oor) { - const auto& tab = v.as_table(); - for(const auto& kv : tab) + const auto& t = v.as_table(); + const auto found = detail::find_unique(t.begin(), t.end(), v, ky, match); + if(found != t.end()) { - if(match(kv.first, ky)) - { - return kv.second; - } + return found->second; } throw; } @@ -537,13 +562,11 @@ find_fuzzy(basic_value& v, const key& ky, } catch(const std::out_of_range& oor) { - auto& tab = v.as_table(); - for(auto& kv : tab) + auto& t = v.as_table(); + const auto found = detail::find_unique(t.begin(), t.end(), v, ky, match); + if(found != t.end()) { - if(match(kv.first, ky)) - { - return kv.second; - } + return found->second; } throw; } @@ -562,13 +585,11 @@ find_fuzzy(basic_value&& v_, const key& ky, } catch(const std::out_of_range& oor) { - auto& tab = v.as_table(); - for(auto& kv : tab) + auto& t = v.as_table(); + const auto found = detail::find_unique(t.begin(), t.end(), v, ky, match); + if(found != t.end()) { - if(match(kv.first, ky)) - { - return std::move(kv.second); - } + return std::move(found->second); } throw; }