mirror of
https://github.com/matrix-construct/construct
synced 2024-12-15 18:03:43 +01:00
ircd::json: Improve constexpr-hashed-name related and uniform overloads for non-tuples.
This commit is contained in:
parent
0ae0172a25
commit
bc5be1c6be
3 changed files with 79 additions and 15 deletions
|
@ -50,6 +50,11 @@ namespace ircd::json
|
|||
enum type type(const string_view &, std::nothrow_t);
|
||||
string_view reflect(const enum type &);
|
||||
|
||||
using name_hash_t = size_t;
|
||||
constexpr name_hash_t name_hash(const char *const name, const size_t len = 0);
|
||||
constexpr name_hash_t name_hash(const string_view &name);
|
||||
constexpr name_hash_t operator ""_(const char *const name, const size_t len);
|
||||
|
||||
/// Higher order type beyond a string to cleanly delimit multiple keys.
|
||||
using path = std::initializer_list<string_view>;
|
||||
std::ostream &operator<<(std::ostream &, const path &);
|
||||
|
@ -78,6 +83,7 @@ namespace ircd::json
|
|||
|
||||
namespace ircd
|
||||
{
|
||||
using json::operator ""_;
|
||||
using json::operator<<;
|
||||
}
|
||||
|
||||
|
@ -188,3 +194,21 @@ ircd::json::operator<<(std::ostream &s, const path &p)
|
|||
|
||||
return s;
|
||||
}
|
||||
|
||||
constexpr ircd::json::name_hash_t
|
||||
ircd::json::operator ""_(const char *const text, const size_t len)
|
||||
{
|
||||
return name_hash(text, len);
|
||||
}
|
||||
|
||||
constexpr ircd::json::name_hash_t
|
||||
ircd::json::name_hash(const string_view &name)
|
||||
{
|
||||
return ircd::hash(name);
|
||||
}
|
||||
|
||||
constexpr ircd::json::name_hash_t
|
||||
ircd::json::name_hash(const char *const name, const size_t len)
|
||||
{
|
||||
return ircd::hash(name);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
namespace ircd::json
|
||||
{
|
||||
struct object;
|
||||
|
||||
template<name_hash_t key, class T = string_view> T at(const object &);
|
||||
template<name_hash_t key, class T = string_view> T get(const object &, const T &def = {});
|
||||
}
|
||||
|
||||
/// Lightweight interface to a JSON object string.
|
||||
|
@ -81,6 +84,7 @@ struct ircd::json::object
|
|||
const_iterator end() const;
|
||||
const_iterator begin() const;
|
||||
const_iterator find(const string_view &key) const;
|
||||
const_iterator find(const name_hash_t &key) const;
|
||||
|
||||
// util
|
||||
size_t count() const;
|
||||
|
@ -214,6 +218,25 @@ catch(const bad_lex_cast &e)
|
|||
typeid(T).name());
|
||||
}
|
||||
|
||||
template<ircd::json::name_hash_t key,
|
||||
class T>
|
||||
T
|
||||
ircd::json::at(const object &object)
|
||||
try
|
||||
{
|
||||
const auto it(object.find(key));
|
||||
if(it == end(object))
|
||||
throw not_found("[key hash] '%zu'", key);
|
||||
|
||||
return lex_cast<T>(it->second);
|
||||
}
|
||||
catch(const bad_lex_cast &e)
|
||||
{
|
||||
throw type_error("[key hash] '%zu' must cast to type %s",
|
||||
key,
|
||||
typeid(T).name());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T
|
||||
ircd::json::object::at(const string_view &key)
|
||||
|
@ -273,6 +296,25 @@ catch(const bad_lex_cast &e)
|
|||
return def;
|
||||
}
|
||||
|
||||
template<ircd::json::name_hash_t key,
|
||||
class T>
|
||||
ircd::string_view
|
||||
ircd::json::get(const object &object,
|
||||
const T &def)
|
||||
try
|
||||
{
|
||||
const auto it{object.find(key)};
|
||||
if(it == end(object))
|
||||
return def;
|
||||
|
||||
const string_view sv{it->second};
|
||||
return !sv.empty()? lex_cast<T>(sv) : def;
|
||||
}
|
||||
catch(const bad_lex_cast &e)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T
|
||||
ircd::json::object::get(const string_view &key,
|
||||
|
@ -329,6 +371,17 @@ const
|
|||
return find(key) != end();
|
||||
}
|
||||
|
||||
inline ircd::json::object::const_iterator
|
||||
ircd::json::object::find(const name_hash_t &key)
|
||||
const
|
||||
{
|
||||
return std::find_if(begin(), end(), [&key]
|
||||
(const auto &member)
|
||||
{
|
||||
return name_hash(member.first) == key;
|
||||
});
|
||||
}
|
||||
|
||||
inline ircd::json::object::const_iterator
|
||||
ircd::json::object::find(const string_view &key)
|
||||
const
|
||||
|
|
|
@ -22,19 +22,6 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_JSON_TUPLE_H
|
||||
|
||||
namespace ircd::json
|
||||
{
|
||||
constexpr size_t operator ""_(const char *const text, const size_t len)
|
||||
{
|
||||
return ircd::hash(text);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
using json::operator ""_;
|
||||
}
|
||||
|
||||
namespace ircd {
|
||||
namespace json {
|
||||
|
||||
|
@ -169,7 +156,7 @@ template<class tuple,
|
|||
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
||||
indexof()
|
||||
{
|
||||
const auto equal
|
||||
constexpr auto equal
|
||||
{
|
||||
ircd::hash(key<tuple, i>()) == hash
|
||||
};
|
||||
|
@ -190,7 +177,7 @@ template<class tuple,
|
|||
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
||||
indexof(const char *const &name)
|
||||
{
|
||||
const auto equal
|
||||
constexpr auto equal
|
||||
{
|
||||
_constexpr_equal(key<tuple, i>(), name)
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue