From 4c12dad51fb1a99b25be111dd5b156c56ae1c7cc Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 3 Oct 2019 15:27:25 +0900 Subject: [PATCH] feat: add find(value, idx) for arrays (#79) --- toml/get.hpp | 136 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 118 insertions(+), 18 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 16516c1..4cdbe81 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -465,6 +465,52 @@ basic_value find(basic_value&& v, const key& ky) return basic_value(std::move(tab.at(ky))); } +// ---------------------------------------------------------------------------- +// find(value, idx) +template class M, template class V> +basic_value const& +find(const basic_value& v, const std::size_t idx) +{ + const auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] index ", idx, " is out of range"), { + {std::addressof(detail::get_region(v)), "in this array"} + })); + } + return ary.at(idx); +} +template class M, template class V> +basic_value& find(basic_value& v, const std::size_t idx) +{ + auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] index ", idx, " is out of range"), { + {std::addressof(detail::get_region(v)), "in this array"} + })); + } + return ary.at(idx); +} +template class M, template class V> +basic_value find(basic_value&& v, const std::size_t idx) +{ + typename basic_value::array_type ary = std::move(v).as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] index ", idx, " is out of range"), { + {std::addressof(detail::get_region(v)), "in this array"} + })); + } + return basic_value(std::move(ary.at(idx))); +} + // ---------------------------------------------------------------------------- // find(value, key); @@ -516,57 +562,111 @@ find(basic_value&& v, const key& ky) return ::toml::get(std::move(tab.at(ky))); } +// ---------------------------------------------------------------------------- +// find(value, idx) +template class M, template class V> +decltype(::toml::get(std::declval const&>())) +find(const basic_value& v, const std::size_t idx) +{ + const auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] index ", idx, " is out of range"), { + {std::addressof(detail::get_region(v)), "in this array"} + })); + } + return ::toml::get(ary.at(idx)); +} +template class M, template class V> +decltype(::toml::get(std::declval&>())) +find(basic_value& v, const std::size_t idx) +{ + auto& ary = v.as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] index ", idx, " is out of range"), { + {std::addressof(detail::get_region(v)), "in this array"} + })); + } + return ::toml::get(ary.at(idx)); +} +template class M, template class V> +decltype(::toml::get(std::declval&&>())) +find(basic_value&& v, const std::size_t idx) +{ + typename basic_value::array_type ary = std::move(v).as_array(); + if(ary.size() <= idx) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] index ", idx, " is out of range"), { + {std::addressof(detail::get_region(v)), "in this array"} + })); + } + return ::toml::get(std::move(ary.at(idx))); +} + // -------------------------------------------------------------------------- // toml::find(toml::value, toml::key, Ts&& ... keys) template class M, template class V, - typename ... Ts> + typename Key1, typename Key2, typename ... Keys> const basic_value& -find(const basic_value& v, const ::toml::key& ky, Ts&& ... keys) +find(const basic_value& v, Key1&& k1, Key2&& k2, Keys&& ... keys) { - return ::toml::find(::toml::find(v, ky), std::forward(keys)...); + return ::toml::find(::toml::find(v, std::forward(k1)), + std::forward(k2), std::forward(keys)...); } template class M, template class V, - typename ... Ts> + typename Key1, typename Key2, typename ... Keys> basic_value& -find(basic_value& v, const ::toml::key& ky, Ts&& ... keys) +find(basic_value& v, Key1&& k1, Key2&& k2, Keys&& ... keys) { - return ::toml::find(::toml::find(v, ky), std::forward(keys)...); + return ::toml::find(::toml::find(v, std::forward(k1)), + std::forward(k2), std::forward(keys)...); } template class M, template class V, - typename ... Ts> + typename Key1, typename Key2, typename ... Keys> basic_value -find(basic_value&& v, const ::toml::key& ky, Ts&& ... keys) +find(basic_value&& v, Key1&& k1, Key2&& k2, Keys&& ... keys) { - return ::toml::find(::toml::find(std::move(v), ky), std::forward(keys)...); + return ::toml::find(::toml::find(std::move(v), std::forward(k1)), + std::forward(k2), std::forward(keys)...); } template class M, template class V, - typename ... Ts> + typename Key1, typename Key2, typename ... Keys> decltype(::toml::get(std::declval&>())) -find(const basic_value& v, const ::toml::key& ky, Ts&& ... keys) +find(const basic_value& v, Key1&& k1, Key2&& k2, Keys&& ... keys) { - return ::toml::find(::toml::find(v, ky), std::forward(keys)...); + return ::toml::find(::toml::find(v, std::forward(k1)), + std::forward(k2), std::forward(keys)...); } template class M, template class V, - typename ... Ts> + typename Key1, typename Key2, typename ... Keys> decltype(::toml::get(std::declval&>())) -find(basic_value& v, const ::toml::key& ky, Ts&& ... keys) +find(basic_value& v, Key1&& k1, Key2&& k2, Keys&& ... keys) { - return ::toml::find(::toml::find(v, ky), std::forward(keys)...); + return ::toml::find(::toml::find(v, std::forward(k1)), + std::forward(k2), std::forward(keys)...); } template class M, template class V, - typename ... Ts> + typename Key1, typename Key2, typename ... Keys> decltype(::toml::get(std::declval&&>())) -find(basic_value&& v, const ::toml::key& ky, Ts&& ... keys) +find(basic_value&& v, Key1&& k1, Key2&& k2, Keys&& ... keys) { - return ::toml::find(::toml::find(std::move(v), ky), std::forward(keys)...); + return ::toml::find(::toml::find(std::move(v), std::forward(k1)), + std::forward(k2), std::forward(keys)...); } // ============================================================================