mirror of
https://github.com/matrix-construct/construct
synced 2024-10-01 21:28:53 +02:00
ircd: JSON subsystem related.
This commit is contained in:
parent
42ce334528
commit
3badb2ff90
5 changed files with 373 additions and 240 deletions
|
@ -39,14 +39,14 @@ struct obj;
|
|||
|
||||
enum type
|
||||
{
|
||||
OBJECT = 0,
|
||||
STRING = 1,
|
||||
NUMBER = 2,
|
||||
LITERAL = 3,
|
||||
ARRAY = 4,
|
||||
STRING = 0,
|
||||
OBJECT = 1,
|
||||
ARRAY = 2,
|
||||
NUMBER = 3,
|
||||
LITERAL = 4,
|
||||
};
|
||||
|
||||
type type(const string_view &);
|
||||
enum type type(const string_view &);
|
||||
enum type type(const string_view &, std::nothrow_t);
|
||||
|
||||
} // namespace json
|
||||
} // namespace ircd
|
||||
|
|
|
@ -42,11 +42,14 @@ struct arr
|
|||
const_iterator end() const;
|
||||
const_iterator begin() const;
|
||||
|
||||
const_iterator find(size_t i) const;
|
||||
size_t count() const;
|
||||
|
||||
const_iterator find(size_t i) const;
|
||||
string_view at(size_t i) const;
|
||||
string_view operator[](size_t i) const;
|
||||
template<class T> T at(const size_t &i) const;
|
||||
string_view at(const size_t &i) const;
|
||||
string_view operator[](const size_t &i) const;
|
||||
|
||||
explicit operator std::string() const;
|
||||
|
||||
using string_view::string_view;
|
||||
|
||||
|
@ -81,50 +84,14 @@ struct arr::const_iterator
|
|||
|
||||
const_iterator &operator++();
|
||||
|
||||
friend bool operator==(const arr::const_iterator &, const arr::const_iterator &);
|
||||
friend bool operator!=(const arr::const_iterator &, const arr::const_iterator &);
|
||||
friend bool operator<=(const arr::const_iterator &, const arr::const_iterator &);
|
||||
friend bool operator>=(const arr::const_iterator &, const arr::const_iterator &);
|
||||
friend bool operator<(const arr::const_iterator &, const arr::const_iterator &);
|
||||
friend bool operator>(const arr::const_iterator &, const arr::const_iterator &);
|
||||
friend bool operator==(const const_iterator &, const const_iterator &);
|
||||
friend bool operator!=(const const_iterator &, const const_iterator &);
|
||||
friend bool operator<=(const const_iterator &, const const_iterator &);
|
||||
friend bool operator>=(const const_iterator &, const const_iterator &);
|
||||
friend bool operator<(const const_iterator &, const const_iterator &);
|
||||
friend bool operator>(const const_iterator &, const const_iterator &);
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start == b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start != b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<=(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start <= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>=(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start >= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start < b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start > b.start;
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
} // namespace ircd
|
||||
|
||||
|
@ -137,19 +104,31 @@ const
|
|||
}
|
||||
|
||||
inline ircd::string_view
|
||||
ircd::json::arr::operator[](size_t i)
|
||||
ircd::json::arr::operator[](const size_t &i)
|
||||
const
|
||||
{
|
||||
const auto it(find(i));
|
||||
return it != end()? *it : string_view{};
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T
|
||||
ircd::json::arr::at(const size_t &i)
|
||||
const try
|
||||
{
|
||||
return lex_cast<T>(at(i));
|
||||
}
|
||||
catch(const bad_lex_cast &e)
|
||||
{
|
||||
throw type_error("indice %zu must cast to type %s", i, typeid(T).name());
|
||||
}
|
||||
|
||||
inline ircd::string_view
|
||||
ircd::json::arr::at(size_t i)
|
||||
ircd::json::arr::at(const size_t &i)
|
||||
const
|
||||
{
|
||||
const auto it(find(i));
|
||||
return likely(it != end())? *it : throw not_found("[%zu]", i);
|
||||
return likely(it != end())? *it : throw not_found("indice %zu", i);
|
||||
}
|
||||
|
||||
inline ircd::json::arr::const_iterator
|
||||
|
@ -167,3 +146,39 @@ const
|
|||
{
|
||||
return std::distance(begin(), end());
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator==(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start == b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!=(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start != b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<=(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start <= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator>=(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start >= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start < b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator>(const arr::const_iterator &a, const arr::const_iterator &b)
|
||||
{
|
||||
return a.start > b.start;
|
||||
}
|
||||
|
|
|
@ -46,11 +46,14 @@ struct doc
|
|||
const_iterator end() const;
|
||||
const_iterator begin() const;
|
||||
|
||||
const_iterator find(const char *const &name) const;
|
||||
const_iterator find(const string_view &name) const;
|
||||
size_t count() const;
|
||||
|
||||
string_view at(const char *const &name) const;
|
||||
string_view operator[](const char *const &name) const;
|
||||
string_view at(const string_view &name) const;
|
||||
template<class T> T at(const string_view &name) const;
|
||||
string_view operator[](const string_view &name) const;
|
||||
|
||||
explicit operator std::string() const;
|
||||
|
||||
using string_view::string_view;
|
||||
|
||||
|
@ -66,11 +69,13 @@ struct doc::member
|
|||
:std::pair<string_view, string_view>{first, second}
|
||||
{}
|
||||
|
||||
friend bool operator==(const doc::member &, const doc::member &);
|
||||
friend bool operator<=(const doc::member &, const doc::member &);
|
||||
friend bool operator>=(const doc::member &, const doc::member &);
|
||||
friend bool operator<(const doc::member &, const doc::member &);
|
||||
friend bool operator>(const doc::member &, const doc::member &);
|
||||
friend bool operator==(const member &, const member &);
|
||||
friend bool operator!=(const member &, const member &);
|
||||
friend bool operator<=(const member &, const member &);
|
||||
friend bool operator>=(const member &, const member &);
|
||||
friend bool operator<(const member &, const member &);
|
||||
friend bool operator>(const member &, const member &);
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, const doc::member &);
|
||||
};
|
||||
|
||||
|
@ -87,7 +92,7 @@ struct doc::const_iterator
|
|||
|
||||
const char *start;
|
||||
const char *stop;
|
||||
mutable member state;
|
||||
member state;
|
||||
|
||||
const_iterator(const char *const &start, const char *const &stop)
|
||||
:start{start}
|
||||
|
@ -100,112 +105,67 @@ struct doc::const_iterator
|
|||
|
||||
const_iterator &operator++();
|
||||
|
||||
friend bool operator==(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator!=(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator<=(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator>=(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator<(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator>(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator==(const const_iterator &, const const_iterator &);
|
||||
friend bool operator!=(const const_iterator &, const const_iterator &);
|
||||
friend bool operator<=(const const_iterator &, const const_iterator &);
|
||||
friend bool operator>=(const const_iterator &, const const_iterator &);
|
||||
friend bool operator<(const const_iterator &, const const_iterator &);
|
||||
friend bool operator>(const const_iterator &, const const_iterator &);
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start == b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start != b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start <= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start >= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start < b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start > b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first == b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<=(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first <= b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>=(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first >= b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first < b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first > b.first;
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
} // namespace ircd
|
||||
|
||||
inline bool
|
||||
ircd::json::doc::contains(const string_view &s)
|
||||
inline ircd::string_view
|
||||
ircd::json::doc::operator[](const string_view &name)
|
||||
const
|
||||
{
|
||||
return s.begin() >= this->string_view::begin() &&
|
||||
s.end() <= this->string_view::end();
|
||||
const auto p(split(name, '.'));
|
||||
const auto it(find(p.first));
|
||||
if(it == end())
|
||||
return {};
|
||||
|
||||
if(!p.second.empty())
|
||||
{
|
||||
const doc d(it->second);
|
||||
return d[p.second];
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T
|
||||
ircd::json::doc::at(const string_view &name)
|
||||
const try
|
||||
{
|
||||
return lex_cast<T>(at(name));
|
||||
}
|
||||
catch(const bad_lex_cast &e)
|
||||
{
|
||||
throw type_error("'%s' must cast to type %s", name, typeid(T).name());
|
||||
}
|
||||
|
||||
inline ircd::string_view
|
||||
ircd::json::doc::operator[](const char *const &name)
|
||||
ircd::json::doc::at(const string_view &name)
|
||||
const
|
||||
{
|
||||
const auto it(find(name));
|
||||
return it != end()? it->second : string_view{};
|
||||
}
|
||||
|
||||
inline ircd::string_view
|
||||
ircd::json::doc::at(const char *const &name)
|
||||
const
|
||||
{
|
||||
const auto it(find(name));
|
||||
const auto p(split(name, '.'));
|
||||
const auto it(find(p.first));
|
||||
if(unlikely(it == end()))
|
||||
throw not_found("name \"%s\"", name);
|
||||
throw not_found("'%s'", p.first);
|
||||
|
||||
if(!p.second.empty())
|
||||
{
|
||||
const doc d(it->second);
|
||||
return d.at(p.second);
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline ircd::json::doc::const_iterator
|
||||
ircd::json::doc::find(const char *const &name)
|
||||
ircd::json::doc::find(const string_view &name)
|
||||
const
|
||||
{
|
||||
return std::find_if(begin(), end(), [&name]
|
||||
|
@ -221,3 +181,83 @@ const
|
|||
{
|
||||
return std::distance(begin(), end());
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::doc::contains(const string_view &s)
|
||||
const
|
||||
{
|
||||
return s.begin() >= this->string_view::begin() &&
|
||||
s.end() <= this->string_view::end();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator==(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start == b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start != b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start <= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator>=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start >= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start < b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator>(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start > b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator==(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first == b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!=(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first != b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<=(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first <= b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator>=(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first >= b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first < b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator>(const doc::member &a, const doc::member &b)
|
||||
{
|
||||
return a.first > b.first;
|
||||
}
|
||||
|
|
|
@ -49,8 +49,6 @@ struct obj
|
|||
size_t count() const;
|
||||
size_t size() const;
|
||||
|
||||
explicit operator std::string() const;
|
||||
|
||||
const_iterator find(const string_view &name) const;
|
||||
bool has(const string_view &name) const;
|
||||
|
||||
|
@ -61,8 +59,10 @@ struct obj
|
|||
void erase(const const_iterator &s);
|
||||
bool erase(const string_view &name);
|
||||
|
||||
explicit operator std::string() const;
|
||||
|
||||
obj(std::initializer_list<member>);
|
||||
obj(const doc &d);
|
||||
obj(const doc &d, const bool &recurse = false);
|
||||
obj() = default;
|
||||
obj(obj &&) = default;
|
||||
obj(const obj &) = delete;
|
||||
|
@ -75,33 +75,21 @@ struct obj
|
|||
struct obj::member
|
||||
:std::pair<val, val>
|
||||
{
|
||||
member(const string_view &k, const string_view &v)
|
||||
:std::pair<val, val>{k, v}
|
||||
{}
|
||||
|
||||
member(const string_view &k, const obj *const &v)
|
||||
:std::pair<val, val>{k, *v}
|
||||
{}
|
||||
|
||||
member(const string_view &k, std::initializer_list<member> v)
|
||||
:std::pair<val, val>{k, val{*new obj(v), true}}
|
||||
{}
|
||||
|
||||
explicit member(const string_view &k)
|
||||
:std::pair<val, val>{k, string_view{}}
|
||||
{}
|
||||
|
||||
explicit member(const doc::member &dm)
|
||||
:member{dm.first, dm.second}
|
||||
{}
|
||||
|
||||
template<class K> member(const K &k, std::initializer_list<member> v);
|
||||
template<class K, class V> member(const K &k, V&& v);
|
||||
explicit member(const string_view &k);
|
||||
explicit member(const doc::member &m);
|
||||
member() = default;
|
||||
|
||||
friend bool operator<(const member &a, const string_view &b);
|
||||
friend bool operator==(const member &a, const string_view &b);
|
||||
|
||||
friend bool operator<(const member &a, const member &b);
|
||||
friend bool operator==(const member &a, const member &b);
|
||||
friend bool operator!=(const member &a, const member &b);
|
||||
friend bool operator<(const member &a, const member &b);
|
||||
|
||||
friend bool operator==(const member &a, const string_view &b);
|
||||
friend bool operator!=(const member &a, const string_view &b);
|
||||
friend bool operator<(const member &a, const string_view &b);
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, const member &);
|
||||
};
|
||||
|
||||
struct obj::const_iterator
|
||||
|
@ -124,13 +112,14 @@ struct obj::const_iterator
|
|||
{}
|
||||
|
||||
public:
|
||||
auto operator==(const const_iterator &o) const { return it == o.it; }
|
||||
auto operator!=(const const_iterator &o) const { return it != o.it; }
|
||||
|
||||
value_type *operator->() const { return it.operator->(); }
|
||||
value_type &operator*() const { return it.operator*(); }
|
||||
|
||||
const_iterator &operator++() { ++it; return *this; }
|
||||
|
||||
friend bool operator==(const const_iterator &a, const const_iterator &b);
|
||||
friend bool operator!=(const const_iterator &a, const const_iterator &b);
|
||||
friend bool operator<(const const_iterator &a, const const_iterator &b);
|
||||
};
|
||||
|
||||
} // namespace json
|
||||
|
@ -143,17 +132,6 @@ const
|
|||
return at(name);
|
||||
}
|
||||
|
||||
inline const ircd::json::val &
|
||||
ircd::json::obj::at(const string_view &name)
|
||||
const
|
||||
{
|
||||
const auto it(find(name));
|
||||
if(unlikely(it == end()))
|
||||
throw not_found("name \"%s\"", name.data());
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::obj::has(const string_view &name)
|
||||
const
|
||||
|
@ -208,6 +186,53 @@ const
|
|||
return { std::end(idx) };
|
||||
}
|
||||
|
||||
template<class K,
|
||||
class V>
|
||||
ircd::json::obj::member::member(const K &k,
|
||||
V&& v)
|
||||
:std::pair<val, val>
|
||||
{
|
||||
val { k }, val { std::forward<V>(v) }
|
||||
}
|
||||
{}
|
||||
|
||||
template<class K>
|
||||
ircd::json::obj::member::member(const K &k,
|
||||
std::initializer_list<member> v)
|
||||
:std::pair<val, val>
|
||||
{
|
||||
val { k }, val { std::make_unique<obj>(std::move(v)) }
|
||||
}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::json::obj::member::member(const doc::member &m)
|
||||
:std::pair<val, val>
|
||||
{
|
||||
m.first, val { m.second, type(m.second) }
|
||||
}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::json::obj::member::member(const string_view &k)
|
||||
:std::pair<val, val>
|
||||
{
|
||||
k, string_view{}
|
||||
}
|
||||
{}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const obj::member &a, const obj::member &b)
|
||||
{
|
||||
return a.first < b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!=(const obj::member &a, const obj::member &b)
|
||||
{
|
||||
return a.first != b.first;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator==(const obj::member &a, const obj::member &b)
|
||||
{
|
||||
|
@ -215,9 +240,15 @@ ircd::json::operator==(const obj::member &a, const obj::member &b)
|
|||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const obj::member &a, const obj::member &b)
|
||||
ircd::json::operator<(const obj::member &a, const string_view &b)
|
||||
{
|
||||
return a.first < b.first;
|
||||
return string_view(a.first.string, a.first.len) < b;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!=(const obj::member &a, const string_view &b)
|
||||
{
|
||||
return string_view(a.first.string, a.first.len) == b;
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
@ -227,7 +258,19 @@ ircd::json::operator==(const obj::member &a, const string_view &b)
|
|||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const obj::member &a, const string_view &b)
|
||||
ircd::json::operator<(const obj::const_iterator &a, const obj::const_iterator &b)
|
||||
{
|
||||
return string_view(a.first.string, a.first.len) < b;
|
||||
return a.it < b.it;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator!=(const obj::const_iterator &a, const obj::const_iterator &b)
|
||||
{
|
||||
return a.it != b.it;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator==(const obj::const_iterator &a, const obj::const_iterator &b)
|
||||
{
|
||||
return a.it == b.it;
|
||||
}
|
||||
|
|
|
@ -29,32 +29,31 @@ struct val
|
|||
{
|
||||
union // xxx std::variant
|
||||
{
|
||||
uint64_t integer;
|
||||
int64_t integer;
|
||||
double floating;
|
||||
const char *string;
|
||||
const struct obj *object;
|
||||
const struct array *array;
|
||||
};
|
||||
|
||||
uint64_t len : 59;
|
||||
uint64_t len : 58;
|
||||
enum type type : 3;
|
||||
uint64_t serial : 1;
|
||||
uint64_t alloc : 1;
|
||||
uint64_t floats : 1;
|
||||
|
||||
public:
|
||||
size_t size() const;
|
||||
|
||||
operator string_view() const;
|
||||
explicit operator std::string() const;
|
||||
|
||||
val(const uint64_t &integer);
|
||||
|
||||
val(const struct obj &object,
|
||||
const bool &alloc = false);
|
||||
|
||||
val(const string_view &sv,
|
||||
const enum type &type = STRING,
|
||||
const bool &serial = true);
|
||||
|
||||
template<class T> explicit val(const T &specialized);
|
||||
template<size_t N> val(const char (&)[N]);
|
||||
val(const string_view &sv, const enum type &);
|
||||
val(const string_view &sv);
|
||||
val(const char *const &s);
|
||||
val(const struct obj *const &); // alloc = false
|
||||
val(std::unique_ptr<obj>); // alloc = true
|
||||
val() = default;
|
||||
val(val &&) noexcept;
|
||||
val(const val &) = delete;
|
||||
|
@ -62,46 +61,93 @@ struct val
|
|||
val &operator=(const val &) = delete;
|
||||
~val() noexcept;
|
||||
|
||||
friend enum type type(const val &a);
|
||||
friend bool operator==(const val &a, const val &b);
|
||||
friend bool operator!=(const val &a, const val &b);
|
||||
friend bool operator<=(const val &a, const val &b);
|
||||
friend bool operator>=(const val &a, const val &b);
|
||||
friend bool operator<(const val &a, const val &b);
|
||||
|
||||
friend bool operator>(const val &a, const val &b);
|
||||
friend std::ostream &operator<<(std::ostream &, const val &);
|
||||
};
|
||||
template<> val::val(const double &floating);
|
||||
template<> val::val(const int64_t &integer);
|
||||
template<> inline val::val(const float &floating): val { double(floating) } {}
|
||||
template<> inline val::val(const int32_t &integer): val { int64_t(integer) } {}
|
||||
template<> inline val::val(const int16_t &integer): val { int64_t(integer) } {}
|
||||
template<> inline val::val(const std::string &str): val { string_view{str} } {}
|
||||
|
||||
static_assert(sizeof(val) == 16, "");
|
||||
|
||||
} // namespace json
|
||||
} // namespace ircd
|
||||
|
||||
template<size_t N>
|
||||
ircd::json::val::val(const char (&str)[N])
|
||||
:val{string_view{str}}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::json::val::val(const char *const &s)
|
||||
:val{string_view{s}}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::json::val::val(const string_view &sv)
|
||||
:val{sv, json::type(sv, std::nothrow)}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::json::val::val(const string_view &sv,
|
||||
const enum type &type,
|
||||
const bool &serial)
|
||||
const enum type &type)
|
||||
:string{sv.data()}
|
||||
,len{sv.size()}
|
||||
,type{type}
|
||||
,serial{serial}
|
||||
,serial{true}
|
||||
,alloc{false}
|
||||
{
|
||||
}
|
||||
,floats{false}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::json::val::val(const uint64_t &integer)
|
||||
template<> inline
|
||||
ircd::json::val::val(const int64_t &integer)
|
||||
:integer{integer}
|
||||
,len{0}
|
||||
,type{NUMBER}
|
||||
,serial{false}
|
||||
,alloc{false}
|
||||
{
|
||||
}
|
||||
,floats{false}
|
||||
{}
|
||||
|
||||
template<> inline
|
||||
ircd::json::val::val(const double &floating)
|
||||
:floating{floating}
|
||||
,len{0}
|
||||
,type{NUMBER}
|
||||
,serial{false}
|
||||
,alloc{false}
|
||||
,floats{true}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::json::val::val(const struct obj &object,
|
||||
const bool &alloc)
|
||||
:object{&object}
|
||||
ircd::json::val::val(const struct obj *const &object)
|
||||
:object{object}
|
||||
,len{0}
|
||||
,type{OBJECT}
|
||||
,serial{false}
|
||||
,alloc{alloc}
|
||||
,alloc{false}
|
||||
,floats{false}
|
||||
{}
|
||||
|
||||
inline
|
||||
ircd::json::val::val(std::unique_ptr<obj> object)
|
||||
:object{object.get()}
|
||||
,len{0}
|
||||
,type{OBJECT}
|
||||
,serial{false}
|
||||
,alloc{true}
|
||||
,floats{false}
|
||||
{
|
||||
object.release();
|
||||
}
|
||||
|
||||
inline
|
||||
|
@ -112,12 +158,12 @@ noexcept
|
|||
,type{other.type}
|
||||
,serial{other.serial}
|
||||
,alloc{other.alloc}
|
||||
,floats{other.floats}
|
||||
{
|
||||
other.alloc = false;
|
||||
}
|
||||
|
||||
inline
|
||||
ircd::json::val &
|
||||
inline ircd::json::val &
|
||||
ircd::json::val::operator=(val &&other)
|
||||
noexcept
|
||||
{
|
||||
|
@ -128,23 +174,12 @@ noexcept
|
|||
serial = other.serial;
|
||||
alloc = other.alloc;
|
||||
other.alloc = false;
|
||||
floats = other.floats;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator<(const val &a, const val &b)
|
||||
inline enum ircd::json::type
|
||||
ircd::json::type(const val &a)
|
||||
{
|
||||
if(unlikely(a.type != STRING || b.type != STRING))
|
||||
throw type_error("cannot compare values");
|
||||
|
||||
return static_cast<string_view>(a) < static_cast<string_view>(b);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::json::operator==(const val &a, const val &b)
|
||||
{
|
||||
if(unlikely(a.type != STRING || b.type != STRING))
|
||||
throw type_error("cannot compare values");
|
||||
|
||||
return static_cast<string_view>(a) == static_cast<string_view>(b);
|
||||
return a.type;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue