0
0
Fork 0
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:
Jason Volk 2017-10-11 18:13:30 -07:00
parent 0ae0172a25
commit bc5be1c6be
3 changed files with 79 additions and 15 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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)
}; };