From 537bdc5e1975e045100ed8bef367cec1fe720013 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 19 Mar 2020 15:13:02 -0700 Subject: [PATCH] ircd::json: Add tuple get()/at() non-constexpr accessor suite. --- include/ircd/json/tuple/at.h | 58 +++++++++++++++++++++++++++++++++ include/ircd/json/tuple/get.h | 22 +++++++++++++ include/ircd/json/tuple/tuple.h | 38 +++++++++++++++++++-- 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/include/ircd/json/tuple/at.h b/include/ircd/json/tuple/at.h index ce0c9a5a1..7a77eb2a7 100644 --- a/include/ircd/json/tuple/at.h +++ b/include/ircd/json/tuple/at.h @@ -126,5 +126,63 @@ at(const tuple &t, at(t, name, std::forward(f)); } +template +enable_if_tuple +at(const tuple &t, + const string_view &name) +{ + const R *ret; + const auto closure + { + [&name, &ret](const auto &key, const auto &val) + { + if(key == name) + { + ret = std::addressof(val); + return false; + } + else return true; + } + }; + + if(unlikely(until(t, closure))) + throw not_found + { + "%s", name + }; + + return *ret; +} + +template +enable_if_tuple +at(tuple &t, + const string_view &name) +{ + R *ret; + const auto closure + { + [&name, &ret](const auto &key, auto &val) + { + if(key == name) + { + ret = std::addressof(val); + return false; + } + else return true; + } + }; + + if(unlikely(until(t, closure))) + throw not_found + { + "%s", name + }; + + return *ret; +} + } // namespace json } // namespace ircd diff --git a/include/ircd/json/tuple/get.h b/include/ircd/json/tuple/get.h index a92b9b3cf..56cb2d171 100644 --- a/include/ircd/json/tuple/get.h +++ b/include/ircd/json/tuple/get.h @@ -125,5 +125,27 @@ noexcept return get(t, def); } +template +enable_if_tuple +get(const tuple &t, + const string_view &name, + R ret) +noexcept +{ + until(t, [&name, &ret] + (const auto &key, auto&& val) + { + if(key == name) + { + ret = val; + return false; + } + else return true; + }); + + return ret; +} + } // namespace json } // namespace ircd diff --git a/include/ircd/json/tuple/tuple.h b/include/ircd/json/tuple/tuple.h index 994183012..1ae2711c6 100644 --- a/include/ircd/json/tuple/tuple.h +++ b/include/ircd/json/tuple/tuple.h @@ -67,6 +67,10 @@ struct tuple template constexpr decltype(auto) at(name&&) const; template constexpr decltype(auto) at(name&&); + template R get(name&&, R def = {}) const noexcept; + template const R &at(name&&) const; + template R &at(name&&); + template explicit tuple(const tuple &); template explicit tuple(const json::object &, const json::keys &); template explicit tuple(const tuple &, const json::keys &); @@ -166,10 +170,10 @@ key_exists(const string_view &key) } // namespace json } // namespace ircd -#include "get.h" -#include "at.h" #include "for_each.h" #include "until.h" +#include "get.h" +#include "at.h" #include "set.h" namespace ircd { @@ -297,6 +301,36 @@ const noexcept return json::get(*this); } +template +template +R +tuple::get(name&& n, + R ret) +const noexcept +{ + return json::get(*this, n, ret); +} + +template +template +const R & +tuple::at(name&& n) +const +{ + return json::at(*this, n); +} + +template +template +R & +tuple::at(name&& n) +{ + return json::at(*this, n); +} + template constexpr size_t tuple::size()