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
|
enum type
|
||||||
{
|
{
|
||||||
OBJECT = 0,
|
STRING = 0,
|
||||||
STRING = 1,
|
OBJECT = 1,
|
||||||
NUMBER = 2,
|
ARRAY = 2,
|
||||||
LITERAL = 3,
|
NUMBER = 3,
|
||||||
ARRAY = 4,
|
LITERAL = 4,
|
||||||
};
|
};
|
||||||
|
enum type type(const string_view &);
|
||||||
type type(const string_view &);
|
enum type type(const string_view &, std::nothrow_t);
|
||||||
|
|
||||||
} // namespace json
|
} // namespace json
|
||||||
} // namespace ircd
|
} // namespace ircd
|
||||||
|
|
|
@ -42,11 +42,14 @@ struct arr
|
||||||
const_iterator end() const;
|
const_iterator end() const;
|
||||||
const_iterator begin() const;
|
const_iterator begin() const;
|
||||||
|
|
||||||
|
const_iterator find(size_t i) const;
|
||||||
size_t count() const;
|
size_t count() const;
|
||||||
|
|
||||||
const_iterator find(size_t i) const;
|
template<class T> T at(const size_t &i) const;
|
||||||
string_view at(size_t i) const;
|
string_view at(const size_t &i) const;
|
||||||
string_view operator[](size_t i) const;
|
string_view operator[](const size_t &i) const;
|
||||||
|
|
||||||
|
explicit operator std::string() const;
|
||||||
|
|
||||||
using string_view::string_view;
|
using string_view::string_view;
|
||||||
|
|
||||||
|
@ -81,50 +84,14 @@ struct arr::const_iterator
|
||||||
|
|
||||||
const_iterator &operator++();
|
const_iterator &operator++();
|
||||||
|
|
||||||
friend bool operator==(const arr::const_iterator &, const arr::const_iterator &);
|
friend bool operator==(const const_iterator &, const 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 arr::const_iterator &, const arr::const_iterator &);
|
friend bool operator<=(const const_iterator &, const 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 arr::const_iterator &, const arr::const_iterator &);
|
friend bool operator<(const const_iterator &, const const_iterator &);
|
||||||
friend bool operator>(const arr::const_iterator &, const arr::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 json
|
||||||
} // namespace ircd
|
} // namespace ircd
|
||||||
|
|
||||||
|
@ -137,19 +104,31 @@ const
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ircd::string_view
|
inline ircd::string_view
|
||||||
ircd::json::arr::operator[](size_t i)
|
ircd::json::arr::operator[](const size_t &i)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
const auto it(find(i));
|
const auto it(find(i));
|
||||||
return it != end()? *it : string_view{};
|
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
|
inline ircd::string_view
|
||||||
ircd::json::arr::at(size_t i)
|
ircd::json::arr::at(const size_t &i)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
const auto it(find(i));
|
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
|
inline ircd::json::arr::const_iterator
|
||||||
|
@ -167,3 +146,39 @@ const
|
||||||
{
|
{
|
||||||
return std::distance(begin(), end());
|
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 end() const;
|
||||||
const_iterator begin() 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;
|
size_t count() const;
|
||||||
|
|
||||||
string_view at(const char *const &name) const;
|
string_view at(const string_view &name) const;
|
||||||
string_view operator[](const char *const &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;
|
using string_view::string_view;
|
||||||
|
|
||||||
|
@ -66,11 +69,13 @@ struct doc::member
|
||||||
:std::pair<string_view, string_view>{first, second}
|
:std::pair<string_view, string_view>{first, second}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
friend bool operator==(const doc::member &, const doc::member &);
|
friend bool operator==(const member &, const member &);
|
||||||
friend bool operator<=(const doc::member &, const doc::member &);
|
friend bool operator!=(const member &, const member &);
|
||||||
friend bool operator>=(const doc::member &, const doc::member &);
|
friend bool operator<=(const member &, const member &);
|
||||||
friend bool operator<(const doc::member &, const doc::member &);
|
friend bool operator>=(const member &, const 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 std::ostream &operator<<(std::ostream &, const doc::member &);
|
friend std::ostream &operator<<(std::ostream &, const doc::member &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +92,7 @@ struct doc::const_iterator
|
||||||
|
|
||||||
const char *start;
|
const char *start;
|
||||||
const char *stop;
|
const char *stop;
|
||||||
mutable member state;
|
member state;
|
||||||
|
|
||||||
const_iterator(const char *const &start, const char *const &stop)
|
const_iterator(const char *const &start, const char *const &stop)
|
||||||
:start{start}
|
:start{start}
|
||||||
|
@ -100,112 +105,67 @@ struct doc::const_iterator
|
||||||
|
|
||||||
const_iterator &operator++();
|
const_iterator &operator++();
|
||||||
|
|
||||||
friend bool operator==(const doc::const_iterator &, const doc::const_iterator &);
|
friend bool operator==(const const_iterator &, const 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 doc::const_iterator &, const doc::const_iterator &);
|
friend bool operator<=(const const_iterator &, const 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 doc::const_iterator &, const doc::const_iterator &);
|
friend bool operator<(const const_iterator &, const const_iterator &);
|
||||||
friend bool operator>(const doc::const_iterator &, const doc::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 json
|
||||||
} // namespace ircd
|
} // namespace ircd
|
||||||
|
|
||||||
inline bool
|
inline ircd::string_view
|
||||||
ircd::json::doc::contains(const string_view &s)
|
ircd::json::doc::operator[](const string_view &name)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
return s.begin() >= this->string_view::begin() &&
|
const auto p(split(name, '.'));
|
||||||
s.end() <= this->string_view::end();
|
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
|
inline ircd::string_view
|
||||||
ircd::json::doc::operator[](const char *const &name)
|
ircd::json::doc::at(const string_view &name)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
const auto it(find(name));
|
const auto p(split(name, '.'));
|
||||||
return it != end()? it->second : string_view{};
|
const auto it(find(p.first));
|
||||||
}
|
|
||||||
|
|
||||||
inline ircd::string_view
|
|
||||||
ircd::json::doc::at(const char *const &name)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
const auto it(find(name));
|
|
||||||
if(unlikely(it == end()))
|
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;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ircd::json::doc::const_iterator
|
inline ircd::json::doc::const_iterator
|
||||||
ircd::json::doc::find(const char *const &name)
|
ircd::json::doc::find(const string_view &name)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
return std::find_if(begin(), end(), [&name]
|
return std::find_if(begin(), end(), [&name]
|
||||||
|
@ -221,3 +181,83 @@ const
|
||||||
{
|
{
|
||||||
return std::distance(begin(), end());
|
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 count() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
explicit operator std::string() const;
|
|
||||||
|
|
||||||
const_iterator find(const string_view &name) const;
|
const_iterator find(const string_view &name) const;
|
||||||
bool has(const string_view &name) const;
|
bool has(const string_view &name) const;
|
||||||
|
|
||||||
|
@ -61,8 +59,10 @@ struct obj
|
||||||
void erase(const const_iterator &s);
|
void erase(const const_iterator &s);
|
||||||
bool erase(const string_view &name);
|
bool erase(const string_view &name);
|
||||||
|
|
||||||
|
explicit operator std::string() const;
|
||||||
|
|
||||||
obj(std::initializer_list<member>);
|
obj(std::initializer_list<member>);
|
||||||
obj(const doc &d);
|
obj(const doc &d, const bool &recurse = false);
|
||||||
obj() = default;
|
obj() = default;
|
||||||
obj(obj &&) = default;
|
obj(obj &&) = default;
|
||||||
obj(const obj &) = delete;
|
obj(const obj &) = delete;
|
||||||
|
@ -75,33 +75,21 @@ struct obj
|
||||||
struct obj::member
|
struct obj::member
|
||||||
:std::pair<val, val>
|
:std::pair<val, val>
|
||||||
{
|
{
|
||||||
member(const string_view &k, const string_view &v)
|
template<class K> member(const K &k, std::initializer_list<member> v);
|
||||||
:std::pair<val, val>{k, 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(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}
|
|
||||||
{}
|
|
||||||
|
|
||||||
member() = default;
|
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 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
|
struct obj::const_iterator
|
||||||
|
@ -124,13 +112,14 @@ struct obj::const_iterator
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public:
|
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->(); }
|
||||||
value_type &operator*() const { return it.operator*(); }
|
value_type &operator*() const { return it.operator*(); }
|
||||||
|
|
||||||
const_iterator &operator++() { ++it; return *this; }
|
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
|
} // namespace json
|
||||||
|
@ -143,17 +132,6 @@ const
|
||||||
return at(name);
|
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
|
inline bool
|
||||||
ircd::json::obj::has(const string_view &name)
|
ircd::json::obj::has(const string_view &name)
|
||||||
const
|
const
|
||||||
|
@ -208,6 +186,53 @@ const
|
||||||
return { std::end(idx) };
|
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
|
inline bool
|
||||||
ircd::json::operator==(const obj::member &a, const obj::member &b)
|
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
|
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
|
inline bool
|
||||||
|
@ -227,7 +258,19 @@ ircd::json::operator==(const obj::member &a, const string_view &b)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
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
|
union // xxx std::variant
|
||||||
{
|
{
|
||||||
uint64_t integer;
|
int64_t integer;
|
||||||
|
double floating;
|
||||||
const char *string;
|
const char *string;
|
||||||
const struct obj *object;
|
const struct obj *object;
|
||||||
const struct array *array;
|
const struct array *array;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t len : 59;
|
uint64_t len : 58;
|
||||||
enum type type : 3;
|
enum type type : 3;
|
||||||
uint64_t serial : 1;
|
uint64_t serial : 1;
|
||||||
uint64_t alloc : 1;
|
uint64_t alloc : 1;
|
||||||
|
uint64_t floats : 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
operator string_view() const;
|
operator string_view() const;
|
||||||
explicit operator std::string() const;
|
explicit operator std::string() const;
|
||||||
|
|
||||||
val(const uint64_t &integer);
|
template<class T> explicit val(const T &specialized);
|
||||||
|
template<size_t N> val(const char (&)[N]);
|
||||||
val(const struct obj &object,
|
val(const string_view &sv, const enum type &);
|
||||||
const bool &alloc = false);
|
val(const string_view &sv);
|
||||||
|
val(const char *const &s);
|
||||||
val(const string_view &sv,
|
val(const struct obj *const &); // alloc = false
|
||||||
const enum type &type = STRING,
|
val(std::unique_ptr<obj>); // alloc = true
|
||||||
const bool &serial = true);
|
|
||||||
|
|
||||||
val() = default;
|
val() = default;
|
||||||
val(val &&) noexcept;
|
val(val &&) noexcept;
|
||||||
val(const val &) = delete;
|
val(const val &) = delete;
|
||||||
|
@ -62,46 +61,93 @@ struct val
|
||||||
val &operator=(const val &) = delete;
|
val &operator=(const val &) = delete;
|
||||||
~val() noexcept;
|
~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 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 &);
|
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 json
|
||||||
} // namespace ircd
|
} // 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
|
inline
|
||||||
ircd::json::val::val(const string_view &sv,
|
ircd::json::val::val(const string_view &sv,
|
||||||
const enum type &type,
|
const enum type &type)
|
||||||
const bool &serial)
|
|
||||||
:string{sv.data()}
|
:string{sv.data()}
|
||||||
,len{sv.size()}
|
,len{sv.size()}
|
||||||
,type{type}
|
,type{type}
|
||||||
,serial{serial}
|
,serial{true}
|
||||||
,alloc{false}
|
,alloc{false}
|
||||||
{
|
,floats{false}
|
||||||
}
|
{}
|
||||||
|
|
||||||
inline
|
template<> inline
|
||||||
ircd::json::val::val(const uint64_t &integer)
|
ircd::json::val::val(const int64_t &integer)
|
||||||
:integer{integer}
|
:integer{integer}
|
||||||
,len{0}
|
,len{0}
|
||||||
,type{NUMBER}
|
,type{NUMBER}
|
||||||
,serial{false}
|
,serial{false}
|
||||||
,alloc{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
|
inline
|
||||||
ircd::json::val::val(const struct obj &object,
|
ircd::json::val::val(const struct obj *const &object)
|
||||||
const bool &alloc)
|
:object{object}
|
||||||
:object{&object}
|
|
||||||
,len{0}
|
,len{0}
|
||||||
,type{OBJECT}
|
,type{OBJECT}
|
||||||
,serial{false}
|
,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
|
inline
|
||||||
|
@ -112,12 +158,12 @@ noexcept
|
||||||
,type{other.type}
|
,type{other.type}
|
||||||
,serial{other.serial}
|
,serial{other.serial}
|
||||||
,alloc{other.alloc}
|
,alloc{other.alloc}
|
||||||
|
,floats{other.floats}
|
||||||
{
|
{
|
||||||
other.alloc = false;
|
other.alloc = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline ircd::json::val &
|
||||||
ircd::json::val &
|
|
||||||
ircd::json::val::operator=(val &&other)
|
ircd::json::val::operator=(val &&other)
|
||||||
noexcept
|
noexcept
|
||||||
{
|
{
|
||||||
|
@ -128,23 +174,12 @@ noexcept
|
||||||
serial = other.serial;
|
serial = other.serial;
|
||||||
alloc = other.alloc;
|
alloc = other.alloc;
|
||||||
other.alloc = false;
|
other.alloc = false;
|
||||||
|
floats = other.floats;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline enum ircd::json::type
|
||||||
ircd::json::operator<(const val &a, const val &b)
|
ircd::json::type(const val &a)
|
||||||
{
|
{
|
||||||
if(unlikely(a.type != STRING || b.type != STRING))
|
return a.type;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue