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);
|
enum type type(const string_view &, std::nothrow_t);
|
||||||
string_view reflect(const enum type &);
|
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.
|
/// Higher order type beyond a string to cleanly delimit multiple keys.
|
||||||
using path = std::initializer_list<string_view>;
|
using path = std::initializer_list<string_view>;
|
||||||
std::ostream &operator<<(std::ostream &, const path &);
|
std::ostream &operator<<(std::ostream &, const path &);
|
||||||
|
@ -78,6 +83,7 @@ namespace ircd::json
|
||||||
|
|
||||||
namespace ircd
|
namespace ircd
|
||||||
{
|
{
|
||||||
|
using json::operator ""_;
|
||||||
using json::operator<<;
|
using json::operator<<;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,3 +194,21 @@ ircd::json::operator<<(std::ostream &s, const path &p)
|
||||||
|
|
||||||
return s;
|
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
|
namespace ircd::json
|
||||||
{
|
{
|
||||||
struct object;
|
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.
|
/// Lightweight interface to a JSON object string.
|
||||||
|
@ -81,6 +84,7 @@ struct ircd::json::object
|
||||||
const_iterator end() const;
|
const_iterator end() const;
|
||||||
const_iterator begin() const;
|
const_iterator begin() const;
|
||||||
const_iterator find(const string_view &key) const;
|
const_iterator find(const string_view &key) const;
|
||||||
|
const_iterator find(const name_hash_t &key) const;
|
||||||
|
|
||||||
// util
|
// util
|
||||||
size_t count() const;
|
size_t count() const;
|
||||||
|
@ -214,6 +218,25 @@ catch(const bad_lex_cast &e)
|
||||||
typeid(T).name());
|
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>
|
template<class T>
|
||||||
T
|
T
|
||||||
ircd::json::object::at(const string_view &key)
|
ircd::json::object::at(const string_view &key)
|
||||||
|
@ -273,6 +296,25 @@ catch(const bad_lex_cast &e)
|
||||||
return def;
|
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>
|
template<class T>
|
||||||
T
|
T
|
||||||
ircd::json::object::get(const string_view &key,
|
ircd::json::object::get(const string_view &key,
|
||||||
|
@ -329,6 +371,17 @@ const
|
||||||
return find(key) != end();
|
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
|
inline ircd::json::object::const_iterator
|
||||||
ircd::json::object::find(const string_view &key)
|
ircd::json::object::find(const string_view &key)
|
||||||
const
|
const
|
||||||
|
|
|
@ -22,19 +22,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define HAVE_IRCD_JSON_TUPLE_H
|
#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 ircd {
|
||||||
namespace json {
|
namespace json {
|
||||||
|
|
||||||
|
@ -169,7 +156,7 @@ template<class tuple,
|
||||||
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
||||||
indexof()
|
indexof()
|
||||||
{
|
{
|
||||||
const auto equal
|
constexpr auto equal
|
||||||
{
|
{
|
||||||
ircd::hash(key<tuple, i>()) == hash
|
ircd::hash(key<tuple, i>()) == hash
|
||||||
};
|
};
|
||||||
|
@ -190,7 +177,7 @@ template<class tuple,
|
||||||
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
||||||
indexof(const char *const &name)
|
indexof(const char *const &name)
|
||||||
{
|
{
|
||||||
const auto equal
|
constexpr auto equal
|
||||||
{
|
{
|
||||||
_constexpr_equal(key<tuple, i>(), name)
|
_constexpr_equal(key<tuple, i>(), name)
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue