diff --git a/include/toml11/try_find.hpp b/include/toml11/try_find.hpp new file mode 100644 index 0000000..1f58c77 --- /dev/null +++ b/include/toml11/try_find.hpp @@ -0,0 +1,228 @@ +#ifndef TOML11_TRY_FIND_HPP +#define TOML11_TRY_FIND_HPP + +#include + +#include "try_get.hpp" +#include "utility.hpp" +#include "value.hpp" + +#if defined(TOML11_HAS_STRING_VIEW) +#include +#endif + +namespace toml +{ + +// ---------------------------------------------------------------------------- +// find(value, key); + +template +decltype(try_get(std::declval const&>())) +try_find(const basic_value& v, const typename basic_value::key_type& ky) noexcept +{ + const auto res = v.try_at(ky); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_get(res.as_ok()); +} + +template +decltype(try_get(std::declval&>())) +try_find(basic_value& v, const typename basic_value::key_type& ky) noexcept +{ + auto res = v.try_at(ky); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_get(res.as_ok()); +} + +template +decltype(try_get(std::declval&&>())) +try_find(basic_value&& v, const typename basic_value::key_type& ky) noexcept +{ + auto res = v.try_at(ky); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_get(std::move(res.as_ok())); +} + +// ---------------------------------------------------------------------------- +// find(value, idx) + +template +decltype(try_get(std::declval const&>())) +try_find(const basic_value& v, const std::size_t idx) noexcept +{ + const auto res = v.try_at(idx); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_get(res.as_ok()); +} +template +decltype(try_get(std::declval&>())) +try_find(basic_value& v, const std::size_t idx) noexcept +{ + auto res = v.try_at(idx); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_get(res.as_ok()); +} +template +decltype(try_get(std::declval&&>())) +try_find(basic_value&& v, const std::size_t idx) noexcept +{ + auto res = v.try_at(idx); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_get(std::move(res.as_ok())); +} + +// ---------------------------------------------------------------------------- +// find(value, key/idx), w/o conversion + +template +cxx::enable_if_t::value, + result>, error_info>> +try_find(basic_value& v, const typename basic_value::key_type& ky) noexcept +{ + return v.try_at(ky); +} +template +cxx::enable_if_t::value, + result>, error_info>> +try_find(basic_value const& v, const typename basic_value::key_type& ky) noexcept +{ + return v.try_at(ky); +} +template +cxx::enable_if_t::value, + result, error_info>> +try_find(basic_value&& v, const typename basic_value::key_type& ky) noexcept +{ + auto res = v.try_at(ky); + if(res.is_err()) + { + return err(res.as_err()); + } + return ok(basic_value(std::move(res.as_ok()))); +} + +template +cxx::enable_if_t::value, + result>, error_info>> +try_find(basic_value& v, const std::size_t idx) noexcept +{ + return v.try_at(idx); +} +template +cxx::enable_if_t::value, + result>, error_info>> +try_find(basic_value const& v, const std::size_t idx) noexcept +{ + return v.try_at(idx); +} +template +cxx::enable_if_t::value, + result, error_info>> +try_find(basic_value&& v, const std::size_t idx) noexcept +{ + auto res = v.try_at(idx); + if(res.is_err()) + { + return err(std::move(res.as_err())); + } + return ok(basic_value(std::move(res.as_ok()))); +} + +// -------------------------------------------------------------------------- +// toml::find(toml::value, toml::key, Ts&& ... keys) w/o conversion + +template +cxx::enable_if_t::value, + result>, error_info>> +try_find(const basic_value& v, const K1& k1, const K2& k2, const Ks& ... ks) noexcept +{ + auto res = v.try_at(detail::key_cast(k1)); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_find(res.as_ok(), detail::key_cast(k2), ks...); +} +template +cxx::enable_if_t::value, + result>, error_info>> +try_find(basic_value& v, const K1& k1, const K2& k2, const Ks& ... ks) noexcept +{ + auto res = v.try_at(detail::key_cast(k1)); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_find(res.as_ok(), detail::key_cast(k2), ks...); +} +template +cxx::enable_if_t::value, + result, error_info>> +try_find(basic_value&& v, const K1& k1, const K2& k2, const Ks& ... ks) noexcept +{ + auto res = v.try_at(detail::key_cast(k1)); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_find(std::move(res.as_ok()), detail::key_cast(k2), ks...); +} + +// ---------------------------------------------------------------------------- +// find(v, keys...) + +template +decltype(::toml::try_get(std::declval&>())) +try_find(const basic_value& v, const K1& k1, const K2& k2, const Ks& ... ks) noexcept +{ + auto res = v.try_at(detail::key_cast(k1)); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_find(res.as_ok(), detail::key_cast(k2), ks...); +} +template +decltype(::toml::try_get(std::declval&>())) +try_find(basic_value& v, const K1& k1, const K2& k2, const Ks& ... ks) noexcept +{ + auto res = v.try_at(detail::key_cast(k1)); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_find(res.as_ok(), detail::key_cast(k2), ks...); +} +template +decltype(::toml::try_get(std::declval&&>())) +try_find(basic_value&& v, const K1& k1, const K2& k2, const Ks& ... ks) noexcept +{ + auto res = v.try_at(detail::key_cast(k1)); + if(res.is_err()) + { + return err(res.as_err()); + } + return try_find(std::move(res.as_ok()), detail::key_cast(k2), ks...); +} + +} // toml +#endif // TOML11_FIND_HPP