0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2025-03-24 02:10:28 +01:00

ircd::json/modules: Rename various types.

This commit is contained in:
Jason Volk 2017-08-23 15:32:28 -06:00
parent 2a6527993b
commit 4fd787d9d5
18 changed files with 1030 additions and 1142 deletions

View file

@ -31,11 +31,10 @@ IRCD_EXCEPTION(error, print_error);
IRCD_EXCEPTION(error, type_error);
IRCD_EXCEPTION(error, not_found);
struct doc;
struct arr;
struct val;
struct obj;
struct array;
struct object;
struct value;
struct index;
enum type
{
@ -51,8 +50,8 @@ enum type type(const string_view &, std::nothrow_t);
} // namespace json
} // namespace ircd
#include "json/arr.h"
#include "json/doc.h"
#include "json/val.h"
#include "json/obj.h"
#include "json/map.h"
#include "json/array.h"
#include "json/object.h"
#include "json/value.h"
#include "json/index.h"
// #include "json/parse.h"

View file

@ -20,12 +20,12 @@
*/
#pragma once
#define HAVE_IRCD_JSON_ARR_H
#define HAVE_IRCD_JSON_ARRAY_H
namespace ircd {
namespace json {
struct arr
struct array
:string_view
{
struct const_iterator;
@ -51,12 +51,12 @@ struct arr
using string_view::string_view;
friend arr serialize(const arr &, char *&buf, char *const &stop);
friend size_t print(char *const &buf, const size_t &max, const arr &);
friend std::ostream &operator<<(std::ostream &, const arr &);
friend array serialize(const array &, char *&buf, char *const &stop);
friend size_t print(char *const &buf, const size_t &max, const array &);
friend std::ostream &operator<<(std::ostream &, const array &);
};
struct arr::const_iterator
struct array::const_iterator
{
using value_type = const string_view;
using pointer = value_type *;
@ -65,7 +65,7 @@ struct arr::const_iterator
using iterator_category = std::forward_iterator_tag;
protected:
friend class arr;
friend class array;
const char *start;
const char *stop;
@ -94,7 +94,7 @@ struct arr::const_iterator
} // namespace ircd
inline ircd::string_view
ircd::json::arr::operator[](const size_t &i)
ircd::json::array::operator[](const size_t &i)
const
{
const auto it(find(i));
@ -103,7 +103,7 @@ const
template<class T>
T
ircd::json::arr::at(const size_t &i)
ircd::json::array::at(const size_t &i)
const try
{
return lex_cast<T>(at(i));
@ -114,15 +114,15 @@ catch(const bad_lex_cast &e)
}
inline ircd::string_view
ircd::json::arr::at(const size_t &i)
ircd::json::array::at(const size_t &i)
const
{
const auto it(find(i));
return likely(it != end())? *it : throw not_found("indice %zu", i);
}
inline ircd::json::arr::const_iterator
ircd::json::arr::find(size_t i)
inline ircd::json::array::const_iterator
ircd::json::array::find(size_t i)
const
{
auto it(begin());
@ -131,44 +131,44 @@ const
}
inline size_t
ircd::json::arr::count()
ircd::json::array::count()
const
{
return std::distance(begin(), end());
}
inline bool
ircd::json::operator==(const arr::const_iterator &a, const arr::const_iterator &b)
ircd::json::operator==(const array::const_iterator &a, const array::const_iterator &b)
{
return a.start == b.start;
}
inline bool
ircd::json::operator!=(const arr::const_iterator &a, const arr::const_iterator &b)
ircd::json::operator!=(const array::const_iterator &a, const array::const_iterator &b)
{
return a.start != b.start;
}
inline bool
ircd::json::operator<=(const arr::const_iterator &a, const arr::const_iterator &b)
ircd::json::operator<=(const array::const_iterator &a, const array::const_iterator &b)
{
return a.start <= b.start;
}
inline bool
ircd::json::operator>=(const arr::const_iterator &a, const arr::const_iterator &b)
ircd::json::operator>=(const array::const_iterator &a, const array::const_iterator &b)
{
return a.start >= b.start;
}
inline bool
ircd::json::operator<(const arr::const_iterator &a, const arr::const_iterator &b)
ircd::json::operator<(const array::const_iterator &a, const array::const_iterator &b)
{
return a.start < b.start;
}
inline bool
ircd::json::operator>(const arr::const_iterator &a, const arr::const_iterator &b)
ircd::json::operator>(const array::const_iterator &a, const array::const_iterator &b)
{
return a.start > b.start;
}

View file

@ -1,295 +0,0 @@
/*
* Copyright (C) 2017 Charybdis Development Team
* Copyright (C) 2017 Jason Volk <jason@zemos.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#define HAVE_IRCD_JSON_DOC_H
namespace ircd {
namespace json {
struct doc
:string_view
{
struct member;
struct const_iterator;
using key_type = string_view;
using mapped_type = string_view;
using value_type = const member;
using pointer = value_type *;
using reference = value_type &;
using iterator = const_iterator;
using size_type = size_t;
using difference_type = ptrdiff_t;
using key_compare = std::less<member>;
const_iterator end() const;
const_iterator begin() const;
bool has(const string_view &name) const;
const_iterator find(const string_view &name) const;
size_t count() 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;
template<class T = string_view> T get(const string_view &name, const T &def = T()) const;
string_view get(const string_view &name, const string_view &def = {}) const;
explicit operator std::string() const;
using string_view::string_view;
friend doc serialize(const doc &, char *&buf, char *const &stop);
friend size_t print(char *const &buf, const size_t &max, const doc &);
friend std::ostream &operator<<(std::ostream &, const doc &);
};
struct doc::member
:std::pair<string_view, string_view>
{
member(const string_view &first = {}, const string_view &second = {})
:std::pair<string_view, string_view>{first, second}
{}
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 &);
};
struct doc::const_iterator
{
using value_type = const member;
using pointer = value_type *;
using reference = value_type &;
using difference_type = size_t;
using iterator_category = std::forward_iterator_tag;
protected:
friend class doc;
const char *start;
const char *stop;
member state;
const_iterator(const char *const &start, const char *const &stop)
:start{start}
,stop{stop}
{}
public:
value_type *operator->() const { return &state; }
value_type &operator*() const { return *operator->(); }
const_iterator &operator++();
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 &);
};
} // namespace json
} // namespace ircd
inline ircd::string_view
ircd::json::doc::get(const string_view &name,
const string_view &def)
const
{
const string_view sv(operator[](name));
return !sv.empty()? sv : def;
}
template<class T>
T
ircd::json::doc::get(const string_view &name,
const T &def)
const try
{
const string_view sv(operator[](name));
return !sv.empty()? lex_cast<T>(sv) : def;
}
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 string_view &name)
const
{
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::at(const string_view &name)
const
{
const auto p(split(name, '.'));
const auto it(find(p.first));
if(unlikely(it == end()))
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 string_view &name)
const
{
return std::find_if(begin(), end(), [&name]
(const auto &member)
{
return member.first == name;
});
}
inline size_t
ircd::json::doc::count()
const
{
return std::distance(begin(), end());
}
inline bool
ircd::json::doc::has(const string_view &name)
const
{
const auto p(split(name, '.'));
const auto it(find(p.first));
if(it == end())
return false;
if(p.second.empty())
return true;
const doc d(it->second);
return d.has(p.second);
}
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;
}

View file

@ -20,25 +20,25 @@
*/
#pragma once
#define HAVE_IRCD_JSON_OBJ_H
#define HAVE_IRCD_JSON_INDEX_H
namespace ircd {
namespace json {
struct obj
struct index
{
struct member;
struct const_iterator;
using key_type = val;
using mapped_type = val;
using key_type = value;
using mapped_type = value;
using value_type = const member;
using size_type = size_t;
using difference_type = size_t;
using key_compare = std::less<member>;
using index = std::vector<member>;
using index_type = std::vector<member>;
index idx;
index_type idx;
const_iterator begin() const;
const_iterator end() const;
@ -52,8 +52,8 @@ struct obj
const_iterator find(const string_view &name) const;
bool has(const string_view &name) const;
const val &operator[](const string_view &name) const;
const val &at(const string_view &name) const;
const value &operator[](const string_view &name) const;
const value &at(const string_view &name) const;
const_iterator erase(const const_iterator &s, const const_iterator &e);
void erase(const const_iterator &s);
@ -63,28 +63,28 @@ struct obj
IRCD_OVERLOAD(recursive)
obj(std::initializer_list<member>);
obj(const doc &d);
obj(recursive_t, const doc &d);
obj() = default;
obj(obj &&) = default;
obj(const obj &) = delete;
index(std::initializer_list<member>);
index(const object &d);
index(recursive_t, const object &d);
index() = default;
index(index &&) = default;
index(const index &) = delete;
friend obj &operator+=(obj &, const doc &); // integration
friend obj operator+(const doc &, const doc &); // integral
friend index &operator+=(index &, const object &); // integration
friend index operator+(const object &, const object &); // integral
friend doc serialize(const obj &, char *&start, char *const &stop);
friend size_t print(char *const &buf, const size_t &max, const obj &);
friend std::ostream &operator<<(std::ostream &, const obj &);
friend object serialize(const index &, char *&start, char *const &stop);
friend size_t print(char *const &buf, const size_t &max, const index &);
friend std::ostream &operator<<(std::ostream &, const index &);
};
struct obj::member
:std::pair<val, val>
struct index::member
:std::pair<value, value>
{
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);
explicit member(const object::member &m);
member() = default;
friend bool operator==(const member &a, const member &b);
@ -98,7 +98,7 @@ struct obj::member
friend std::ostream &operator<<(std::ostream &, const member &);
};
struct obj::const_iterator
struct index::const_iterator
{
using value_type = const member;
using pointer = value_type *;
@ -107,9 +107,9 @@ struct obj::const_iterator
using iterator_category = std::bidirectional_iterator_tag;
protected:
friend class obj;
friend class index;
obj::index::const_iterator it;
index::index_type::const_iterator it;
operator const auto &() const { return it; }
@ -132,62 +132,62 @@ struct obj::const_iterator
} // namespace json
} // namespace ircd
inline const ircd::json::val &
ircd::json::obj::operator[](const string_view &name)
inline const ircd::json::value &
ircd::json::index::operator[](const string_view &name)
const
{
return at(name);
}
inline bool
ircd::json::obj::has(const string_view &name)
ircd::json::index::has(const string_view &name)
const
{
return find(name) != end();
}
inline ircd::json::obj::const_iterator
ircd::json::obj::find(const string_view &name)
inline ircd::json::index::const_iterator
ircd::json::index::find(const string_view &name)
const
{
return std::find(std::begin(idx), std::end(idx), name);
}
inline size_t
ircd::json::obj::count()
ircd::json::index::count()
const
{
return idx.size();
}
inline bool
ircd::json::obj::empty()
ircd::json::index::empty()
const
{
return idx.empty();
}
inline ircd::json::obj::const_iterator
ircd::json::obj::cbegin()
inline ircd::json::index::const_iterator
ircd::json::index::cbegin()
{
return { std::begin(idx) };
}
inline ircd::json::obj::const_iterator
ircd::json::obj::cend()
inline ircd::json::index::const_iterator
ircd::json::index::cend()
{
return { std::end(idx) };
}
inline ircd::json::obj::const_iterator
ircd::json::obj::begin()
inline ircd::json::index::const_iterator
ircd::json::index::begin()
const
{
return { std::begin(idx) };
}
inline ircd::json::obj::const_iterator
ircd::json::obj::end()
inline ircd::json::index::const_iterator
ircd::json::index::end()
const
{
return { std::end(idx) };
@ -195,89 +195,89 @@ const
template<class K,
class V>
ircd::json::obj::member::member(const K &k,
V&& v)
:std::pair<val, val>
ircd::json::index::member::member(const K &k,
V&& v)
:std::pair<value, value>
{
val { k }, val { std::forward<V>(v) }
value { k }, value { std::forward<V>(v) }
}
{}
template<class K>
ircd::json::obj::member::member(const K &k,
std::initializer_list<member> v)
:std::pair<val, val>
ircd::json::index::member::member(const K &k,
std::initializer_list<member> v)
:std::pair<value, value>
{
val { k }, val { std::make_unique<obj>(std::move(v)) }
value { k }, value { std::make_unique<index>(std::move(v)) }
}
{}
inline
ircd::json::obj::member::member(const doc::member &m)
:std::pair<val, val>
ircd::json::index::member::member(const object::member &m)
:std::pair<value, value>
{
m.first, val { m.second, type(m.second) }
m.first, value { m.second, type(m.second) }
}
{}
inline
ircd::json::obj::member::member(const string_view &k)
:std::pair<val, val>
ircd::json::index::member::member(const string_view &k)
:std::pair<value, value>
{
k, string_view{}
}
{}
inline bool
ircd::json::operator<(const obj::member &a, const obj::member &b)
ircd::json::operator<(const index::member &a, const index::member &b)
{
return a.first < b.first;
}
inline bool
ircd::json::operator!=(const obj::member &a, const obj::member &b)
ircd::json::operator!=(const index::member &a, const index::member &b)
{
return a.first != b.first;
}
inline bool
ircd::json::operator==(const obj::member &a, const obj::member &b)
ircd::json::operator==(const index::member &a, const index::member &b)
{
return a.first == b.first;
}
inline bool
ircd::json::operator<(const obj::member &a, const string_view &b)
ircd::json::operator<(const index::member &a, const string_view &b)
{
return string_view(a.first.string, a.first.len) < b;
}
inline bool
ircd::json::operator!=(const obj::member &a, const string_view &b)
ircd::json::operator!=(const index::member &a, const string_view &b)
{
return string_view(a.first.string, a.first.len) != b;
}
inline bool
ircd::json::operator==(const obj::member &a, const string_view &b)
ircd::json::operator==(const index::member &a, const string_view &b)
{
return string_view(a.first.string, a.first.len) == b;
}
inline bool
ircd::json::operator<(const obj::const_iterator &a, const obj::const_iterator &b)
ircd::json::operator<(const index::const_iterator &a, const index::const_iterator &b)
{
return a.it < b.it;
}
inline bool
ircd::json::operator!=(const obj::const_iterator &a, const obj::const_iterator &b)
ircd::json::operator!=(const index::const_iterator &a, const index::const_iterator &b)
{
return a.it != b.it;
}
inline bool
ircd::json::operator==(const obj::const_iterator &a, const obj::const_iterator &b)
ircd::json::operator==(const index::const_iterator &a, const index::const_iterator &b)
{
return a.it == b.it;
}

View file

@ -1,170 +0,0 @@
/*
* Copyright (C) 2017 Charybdis Development Team
* Copyright (C) 2017 Jason Volk <jason@zemos.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#define HAVE_IRCD_JSON_MAP_H
namespace ircd {
namespace json {
struct map
{
struct const_iterator;
using key_type = string_view;
using mapped_type = std::string;
using value_type = std::pair<key_type, mapped_type>;
using pointer = value_type *;
using reference = value_type &;
using size_type = size_t;
using difference_type = size_t;
std::map<std::string, std::string, std::less<>> idx;
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin();
const_iterator cend();
bool empty() const;
size_t size() const;
const_iterator find(const string_view &name) const;
bool has(const string_view &name) const;
const val &operator[](const string_view &name) const;
const val &at(const string_view &name) const;
const_iterator erase(const const_iterator &s, const const_iterator &e);
void erase(const const_iterator &s);
bool erase(const string_view &name);
map(const doc &d);
map() = default;
friend doc serialize(const map &, char *&start, char *const &stop);
friend size_t print(char *const &buf, const size_t &max, const map &);
friend std::ostream &operator<<(std::ostream &, const map &);
};
struct map::const_iterator
{
using value_type = map::value_type;
using iterator_category = std::bidirectional_iterator_tag;
protected:
friend class map;
decltype(map::idx)::const_iterator it;
mutable value_type val;
operator const auto &() const { return it; }
const_iterator(const decltype(it) &it)
:it{it}
{}
public:
value_type *operator->() const { return &val; }
value_type &operator*() const { return val; }
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 ircd
inline const ircd::json::val &
ircd::json::map::operator[](const string_view &name)
const
{
return at(name);
}
inline bool
ircd::json::map::has(const string_view &name)
const
{
return find(name) != end();
}
inline ircd::json::map::const_iterator
ircd::json::map::find(const string_view &name)
const
{
return std::end(idx);
}
inline bool
ircd::json::map::empty()
const
{
return idx.empty();
}
inline ircd::json::map::const_iterator
ircd::json::map::cbegin()
{
return { std::begin(idx) };
}
inline ircd::json::map::const_iterator
ircd::json::map::cend()
{
return { std::end(idx) };
}
inline ircd::json::map::const_iterator
ircd::json::map::begin()
const
{
return { std::begin(idx) };
}
inline ircd::json::map::const_iterator
ircd::json::map::end()
const
{
return { std::end(idx) };
}
inline bool
ircd::json::operator<(const map::const_iterator &a, const map::const_iterator &b)
{
return a.it < b.it;
}
inline bool
ircd::json::operator!=(const map::const_iterator &a, const map::const_iterator &b)
{
return a.it != b.it;
}
inline bool
ircd::json::operator==(const map::const_iterator &a, const map::const_iterator &b)
{
return a.it == b.it;
}

View file

@ -20,357 +20,276 @@
*/
#pragma once
#define HAVE_IRCD_JSON_REFLECT_H
#define IRCD_MEMBERS(_name_, _vals_...) \
static constexpr const char *_member_(const size_t i) \
{ \
constexpr const char *const val[] \
{ \
_vals_ \
}; \
\
return val[i]; \
}
#define HAVE_IRCD_JSON_OBJECT_H
namespace ircd {
namespace json {
struct basic_object
{
};
template<class... T>
struct object
:basic_object
,std::tuple<T...>
:string_view
{
using tuple_type = std::tuple<T...>;
struct member;
struct const_iterator;
static constexpr size_t size()
{
return std::tuple_size<tuple_type>();
}
using key_type = string_view;
using mapped_type = string_view;
using value_type = const member;
using pointer = value_type *;
using reference = value_type &;
using iterator = const_iterator;
using size_type = size_t;
using difference_type = ptrdiff_t;
using key_compare = std::less<member>;
using std::tuple<T...>::tuple;
const_iterator end() const;
const_iterator begin() const;
bool has(const string_view &name) const;
const_iterator find(const string_view &name) const;
size_t count() 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;
template<class T = string_view> T get(const string_view &name, const T &def = T()) const;
string_view get(const string_view &name, const string_view &def = {}) const;
explicit operator std::string() const;
using string_view::string_view;
friend object serialize(const object &, char *&buf, char *const &stop);
friend size_t print(char *const &buf, const size_t &max, const object &);
friend std::ostream &operator<<(std::ostream &, const object &);
};
template<class object>
using tuple_type = typename object::tuple_type;
template<class object>
using tuple_size = std::tuple_size<tuple_type<object>>;
template<size_t i,
class object>
using tuple_element = typename std::tuple_element<i, tuple_type<object>>::type;
template<class object>
constexpr auto &
tuple(const object &o)
struct object::member
:std::pair<string_view, string_view>
{
return static_cast<const typename object::tuple_type &>(o);
}
member(const string_view &first = {}, const string_view &second = {})
:std::pair<string_view, string_view>{first, second}
{}
template<class object>
constexpr auto &
tuple(object &o)
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 object::member &);
};
struct object::const_iterator
{
return static_cast<typename object::tuple_type &>(o);
}
using value_type = const member;
using pointer = value_type *;
using reference = value_type &;
using difference_type = size_t;
using iterator_category = std::forward_iterator_tag;
template<class... T>
constexpr auto
size(const object<T...> &t)
{
return t.size();
}
protected:
friend class object;
template<size_t i,
class... T>
constexpr auto &
get(const object<T...> &t)
{
return std::get<i>(t);
}
const char *start;
const char *stop;
member state;
template<size_t i,
class... T>
constexpr auto &
get(object<T...> &t)
{
return std::get<i>(t);
}
const_iterator(const char *const &start, const char *const &stop)
:start{start}
,stop{stop}
{}
template<size_t i,
class object>
constexpr const char *
reflect(const object &t)
{
return t._member_(i);
}
public:
value_type *operator->() const { return &state; }
value_type &operator*() const { return *operator->(); }
template<size_t i,
class object,
class function>
constexpr
typename std::enable_if<i == tuple_size<object>::value, void>::type
for_each(const object &t,
function&& f)
{}
const_iterator &operator++();
template<size_t i,
class object,
class function>
constexpr
typename std::enable_if<i == tuple_size<object>::value, void>::type
for_each(object &t,
function&& f)
{}
template<size_t i = 0,
class object,
class function>
constexpr
typename std::enable_if<i < tuple_size<object>::value, void>::type
for_each(const object &t,
function&& f)
{
using type = tuple_element<i, object>;
f(reflect<i>(t), static_cast<const type &>(get<i>(t)));
for_each<i + 1>(t, std::forward<function>(f));
}
template<size_t i = 0,
class object,
class function>
constexpr
typename std::enable_if<i < tuple_size<object>::value, void>::type
for_each(object &t,
function&& f)
{
using type = tuple_element<i, object>;
f(reflect<i>(t), static_cast<type &>(get<i>(t)));
for_each<i + 1>(t, std::forward<function>(f));
}
template<class object,
class function,
ssize_t i>
constexpr
typename std::enable_if<(i < 0), void>::type
rfor_each(const object &t,
function&& f)
{}
template<class object,
class function,
ssize_t i>
constexpr
typename std::enable_if<(i < 0), void>::type
rfor_each(object &t,
function&& f)
{}
template<class object,
class function,
ssize_t i = tuple_size<object>() - 1>
constexpr
typename std::enable_if<i < tuple_size<object>(), void>::type
rfor_each(const object &t,
function&& f)
{
using type = tuple_element<i, object>;
f(reflect<i>(t), static_cast<const type &>(get<i>(t)));
rfor_each<object, function, i - 1>(t, std::forward<function>(f));
}
template<class object,
class function,
ssize_t i = tuple_size<object>() - 1>
constexpr
typename std::enable_if<i < tuple_size<object>(), void>::type
rfor_each(object &t,
function&& f)
{
using type = tuple_element<i, object>;
f(reflect<i>(t), static_cast<type &>(get<i>(t)));
rfor_each<object, function, i - 1>(t, std::forward<function>(f));
}
template<size_t i,
class object,
class function>
constexpr
typename std::enable_if<i == tuple_size<object>::value, bool>::type
until(const object &t,
function&& f)
{
return true;
}
template<size_t i,
class object,
class function>
constexpr
typename std::enable_if<i == tuple_size<object>::value, bool>::type
until(object &t,
function&& f)
{
return true;
}
template<size_t i = 0,
class object,
class function>
constexpr
typename std::enable_if<i < tuple_size<object>::value, bool>::type
until(const object &t,
function&& f)
{
using type = tuple_element<i, object>;
const auto &value(static_cast<const type &>(get<i>(t)));
return f(reflect<i>(t), value)?
until<i + 1>(t, std::forward<function>(f)):
false;
}
template<size_t i = 0,
class object,
class function>
constexpr
typename std::enable_if<i < tuple_size<object>::value, bool>::type
until(object &t,
function&& f)
{
using type = tuple_element<i, object>;
auto &value(static_cast<type &>(get<i>(t)));
return f(reflect<i>(t), value)?
until<i + 1>(t, std::forward<function>(f)):
false;
}
template<class object,
class function,
ssize_t i>
constexpr
typename std::enable_if<(i < 0), bool>::type
runtil(const object &t,
function&& f)
{
return true;
}
template<class object,
class function,
ssize_t i>
constexpr
typename std::enable_if<(i < 0), bool>::type
runtil(object &t,
function&& f)
{
return true;
}
template<class object,
class function,
ssize_t i = tuple_size<object>() - 1>
constexpr
typename std::enable_if<i < tuple_size<object>::value, bool>::type
runtil(const object &t,
function&& f)
{
using type = tuple_element<i, object>;
const auto &value(static_cast<const type &>(get<i>(t)));
return f(reflect<i>(t), value)?
runtil<object, function, i - 1>(t, std::forward<function>(f)):
false;
}
template<class object,
class function,
ssize_t i = tuple_size<object>() - 1>
constexpr
typename std::enable_if<i < tuple_size<object>::value, bool>::type
runtil(object &t,
function&& f)
{
using type = tuple_element<i, object>;
auto &value(static_cast<type &>(get<i>(t)));
return f(reflect<i>(t), value)?
runtil<object, function, i - 1>(t, std::forward<function>(f)):
false;
}
template<class object>
constexpr size_t
index(object&& t,
const string_view &name)
{
size_t ret(0);
const auto res(until(t, [&ret, &name]
(const string_view &key, auto&& member)
{
if(key == name)
return false;
++ret;
return true;
}));
return !res? ret : throw std::out_of_range("Object has no member with that name");
}
template<class object,
class function>
constexpr bool
at(object&& t,
const string_view &name,
function&& f)
{
return until(t, [&name, &f]
(const string_view &key, auto&& member)
{
if(key != name)
return true;
f(member);
return false;
});
}
template<class object>
constexpr void
keys(object&& t,
const std::function<void (string_view)> &f)
{
for_each(t, [&f]
(const char *const key, auto&& member)
{
f(key);
});
}
template<class object,
class function>
constexpr void
values(object&& t,
function&& f)
{
for_each(t, [&f]
(const char *const key, auto&& member)
{
f(member);
});
}
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 &);
};
} // namespace json
} // namespace ircd
inline ircd::string_view
ircd::json::object::get(const string_view &name,
const string_view &def)
const
{
const string_view sv(operator[](name));
return !sv.empty()? sv : def;
}
template<class T>
T
ircd::json::object::get(const string_view &name,
const T &def)
const try
{
const string_view sv(operator[](name));
return !sv.empty()? lex_cast<T>(sv) : def;
}
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::object::operator[](const string_view &name)
const
{
const auto p(split(name, '.'));
const auto it(find(p.first));
if(it == end())
return {};
if(!p.second.empty())
{
const object d(it->second);
return d[p.second];
}
return it->second;
}
template<class T>
T
ircd::json::object::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::object::at(const string_view &name)
const
{
const auto p(split(name, '.'));
const auto it(find(p.first));
if(unlikely(it == end()))
throw not_found("'%s'", p.first);
if(!p.second.empty())
{
const object d(it->second);
return d.at(p.second);
}
return it->second;
}
inline ircd::json::object::const_iterator
ircd::json::object::find(const string_view &name)
const
{
return std::find_if(begin(), end(), [&name]
(const auto &member)
{
return member.first == name;
});
}
inline size_t
ircd::json::object::count()
const
{
return std::distance(begin(), end());
}
inline bool
ircd::json::object::has(const string_view &name)
const
{
const auto p(split(name, '.'));
const auto it(find(p.first));
if(it == end())
return false;
if(p.second.empty())
return true;
const object d(it->second);
return d.has(p.second);
}
inline bool
ircd::json::operator==(const object::const_iterator &a, const object::const_iterator &b)
{
return a.start == b.start;
}
inline bool
ircd::json::operator!=(const object::const_iterator &a, const object::const_iterator &b)
{
return a.start != b.start;
}
inline bool
ircd::json::operator<=(const object::const_iterator &a, const object::const_iterator &b)
{
return a.start <= b.start;
}
inline bool
ircd::json::operator>=(const object::const_iterator &a, const object::const_iterator &b)
{
return a.start >= b.start;
}
inline bool
ircd::json::operator<(const object::const_iterator &a, const object::const_iterator &b)
{
return a.start < b.start;
}
inline bool
ircd::json::operator>(const object::const_iterator &a, const object::const_iterator &b)
{
return a.start > b.start;
}
inline bool
ircd::json::operator==(const object::member &a, const object::member &b)
{
return a.first == b.first;
}
inline bool
ircd::json::operator!=(const object::member &a, const object::member &b)
{
return a.first != b.first;
}
inline bool
ircd::json::operator<=(const object::member &a, const object::member &b)
{
return a.first <= b.first;
}
inline bool
ircd::json::operator>=(const object::member &a, const object::member &b)
{
return a.first >= b.first;
}
inline bool
ircd::json::operator<(const object::member &a, const object::member &b)
{
return a.first < b.first;
}
inline bool
ircd::json::operator>(const object::member &a, const object::member &b)
{
return a.first > b.first;
}

402
include/ircd/json/parse.h Normal file
View file

@ -0,0 +1,402 @@
/*
* Copyright (C) 2017 Charybdis Development Team
* Copyright (C) 2017 Jason Volk <jason@zemos.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#define HAVE_IRCD_JSON_PARSE_H
#define IRCD_MEMBERS(_vals_...) \
static constexpr const char *_member_(const size_t i) \
{ \
constexpr const char *const val[] \
{ \
_vals_ \
}; \
\
return val[i]; \
}
namespace ircd {
namespace json {
struct basic_parse
{
};
template<class... T>
struct parse
:basic_parse
,std::tuple<T...>
{
using tuple_type = std::tuple<T...>;
static constexpr size_t size()
{
return std::tuple_size<tuple_type>();
}
template<class R> parse(R &r, const json::object &obj);
};
template<class... T>
template<class R>
parse<T...>::parse(R &r,
const json::object &object)
{
std::for_each(std::begin(object), std::end(object), [this, &r]
(auto &&member)
{
at(r, member.first, [&member]
(auto&& target)
{
using target_type = decltype(target);
using cast_type = typename std::remove_reference<target_type>::type; try
{
target = lex_cast<cast_type>(member.second);
}
catch(const bad_lex_cast &e)
{
throw parse_error("member \"%s\" must convert to '%s'",
member.first,
typeid(target_type).name());
}
});
});
}
template<class parse>
using tuple_type = typename parse::tuple_type;
template<class parse>
using tuple_size = std::tuple_size<tuple_type<parse>>;
template<size_t i,
class parse>
using tuple_element = typename std::tuple_element<i, tuple_type<parse>>::type;
template<class parse>
constexpr auto &
tuple(const parse &o)
{
return static_cast<const typename parse::tuple_type &>(o);
}
template<class parse>
constexpr auto &
tuple(parse &o)
{
return static_cast<typename parse::tuple_type &>(o);
}
template<class... T>
constexpr auto
size(const parse<T...> &t)
{
return t.size();
}
template<size_t i,
class... T>
constexpr auto &
get(const parse<T...> &t)
{
return std::get<i>(t);
}
template<size_t i,
class... T>
constexpr auto &
get(parse<T...> &t)
{
return std::get<i>(t);
}
template<size_t i,
class parse>
constexpr const char *
reflect(const parse &t)
{
return t._member_(i);
}
template<size_t i,
class parse,
class function>
constexpr
typename std::enable_if<i == tuple_size<parse>::value, void>::type
for_each(const parse &t,
function&& f)
{}
template<size_t i,
class parse,
class function>
constexpr
typename std::enable_if<i == tuple_size<parse>::value, void>::type
for_each(parse &t,
function&& f)
{}
template<size_t i = 0,
class parse,
class function>
constexpr
typename std::enable_if<i < tuple_size<parse>::value, void>::type
for_each(const parse &t,
function&& f)
{
using type = tuple_element<i, parse>;
f(reflect<i>(t), static_cast<const type &>(get<i>(t)));
for_each<i + 1>(t, std::forward<function>(f));
}
template<size_t i = 0,
class parse,
class function>
constexpr
typename std::enable_if<i < tuple_size<parse>::value, void>::type
for_each(parse &t,
function&& f)
{
using type = tuple_element<i, parse>;
f(reflect<i>(t), static_cast<type &>(get<i>(t)));
for_each<i + 1>(t, std::forward<function>(f));
}
template<class parse,
class function,
ssize_t i>
constexpr
typename std::enable_if<(i < 0), void>::type
rfor_each(const parse &t,
function&& f)
{}
template<class parse,
class function,
ssize_t i>
constexpr
typename std::enable_if<(i < 0), void>::type
rfor_each(parse &t,
function&& f)
{}
template<class parse,
class function,
ssize_t i = tuple_size<parse>() - 1>
constexpr
typename std::enable_if<i < tuple_size<parse>(), void>::type
rfor_each(const parse &t,
function&& f)
{
using type = tuple_element<i, parse>;
f(reflect<i>(t), static_cast<const type &>(get<i>(t)));
rfor_each<parse, function, i - 1>(t, std::forward<function>(f));
}
template<class parse,
class function,
ssize_t i = tuple_size<parse>() - 1>
constexpr
typename std::enable_if<i < tuple_size<parse>(), void>::type
rfor_each(parse &t,
function&& f)
{
using type = tuple_element<i, parse>;
f(reflect<i>(t), static_cast<type &>(get<i>(t)));
rfor_each<parse, function, i - 1>(t, std::forward<function>(f));
}
template<size_t i,
class parse,
class function>
constexpr
typename std::enable_if<i == tuple_size<parse>::value, bool>::type
until(const parse &t,
function&& f)
{
return true;
}
template<size_t i,
class parse,
class function>
constexpr
typename std::enable_if<i == tuple_size<parse>::value, bool>::type
until(parse &t,
function&& f)
{
return true;
}
template<size_t i = 0,
class parse,
class function>
constexpr
typename std::enable_if<i < tuple_size<parse>::value, bool>::type
until(const parse &t,
function&& f)
{
using type = tuple_element<i, parse>;
const auto &value(static_cast<const type &>(get<i>(t)));
return f(reflect<i>(t), value)?
until<i + 1>(t, std::forward<function>(f)):
false;
}
template<size_t i = 0,
class parse,
class function>
constexpr
typename std::enable_if<i < tuple_size<parse>::value, bool>::type
until(parse &t,
function&& f)
{
using type = tuple_element<i, parse>;
auto &value(static_cast<type &>(get<i>(t)));
return f(reflect<i>(t), value)?
until<i + 1>(t, std::forward<function>(f)):
false;
}
template<class parse,
class function,
ssize_t i>
constexpr
typename std::enable_if<(i < 0), bool>::type
runtil(const parse &t,
function&& f)
{
return true;
}
template<class parse,
class function,
ssize_t i>
constexpr
typename std::enable_if<(i < 0), bool>::type
runtil(parse &t,
function&& f)
{
return true;
}
template<class parse,
class function,
ssize_t i = tuple_size<parse>() - 1>
constexpr
typename std::enable_if<i < tuple_size<parse>::value, bool>::type
runtil(const parse &t,
function&& f)
{
using type = tuple_element<i, parse>;
const auto &value(static_cast<const type &>(get<i>(t)));
return f(reflect<i>(t), value)?
runtil<parse, function, i - 1>(t, std::forward<function>(f)):
false;
}
template<class parse,
class function,
ssize_t i = tuple_size<parse>() - 1>
constexpr
typename std::enable_if<i < tuple_size<parse>::value, bool>::type
runtil(parse &t,
function&& f)
{
using type = tuple_element<i, parse>;
auto &value(static_cast<type &>(get<i>(t)));
return f(reflect<i>(t), value)?
runtil<parse, function, i - 1>(t, std::forward<function>(f)):
false;
}
template<class parse>
constexpr size_t
indexof(parse&& t,
const string_view &name)
{
size_t ret(0);
const auto res(until(t, [&ret, &name]
(const string_view &key, auto&& member)
{
if(key == name)
return false;
++ret;
return true;
}));
return !res? ret : throw std::out_of_range("parse has no member with that name");
}
template<class parse,
class function>
constexpr bool
at(parse&& t,
const string_view &name,
function&& f)
{
return until(t, [&name, &f]
(const string_view &key, auto&& member)
{
if(key != name)
return true;
f(member);
return false;
});
}
template<class parse>
constexpr void
keys(parse&& t,
const std::function<void (string_view)> &f)
{
for_each(t, [&f]
(const char *const key, auto&& member)
{
f(key);
});
}
template<class parse,
class function>
constexpr void
values(parse&& t,
function&& f)
{
for_each(t, [&f]
(const char *const key, auto&& member)
{
f(member);
});
}
} // namespace json
} // namespace ircd

View file

@ -20,19 +20,19 @@
*/
#pragma once
#define HAVE_IRCD_JSON_VAL_H
#define HAVE_IRCD_JSON_VALUE_H
namespace ircd {
namespace json {
struct val
struct value
{
union // xxx std::variant
{
int64_t integer;
double floating;
const char *string;
const struct obj *object;
const struct index *object;
const struct array *array;
};
@ -48,43 +48,43 @@ struct val
operator string_view() const;
explicit operator std::string() const;
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();
val(val &&) noexcept;
val(const val &) = delete;
val &operator=(val &&) noexcept;
val &operator=(const val &) = delete;
~val() noexcept;
template<class T> explicit value(const T &specialized);
template<size_t N> value(const char (&)[N]);
value(const string_view &sv, const enum type &);
value(const string_view &sv);
value(const char *const &s);
value(const struct index *const &); // alloc = false
value(std::unique_ptr<struct index>); // alloc = true
value();
value(value &&) noexcept;
value(const value &) = delete;
value &operator=(value &&) noexcept;
value &operator=(const value &) = delete;
~value() 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 &);
friend enum type type(const value &a);
friend bool operator==(const value &a, const value &b);
friend bool operator!=(const value &a, const value &b);
friend bool operator<=(const value &a, const value &b);
friend bool operator>=(const value &a, const value &b);
friend bool operator<(const value &a, const value &b);
friend bool operator>(const value &a, const value &b);
friend std::ostream &operator<<(std::ostream &, const value &);
};
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} } {}
template<> value::value(const double &floating);
template<> value::value(const int64_t &integer);
template<> value::value(const float &floating);
template<> value::value(const int32_t &integer);
template<> value::value(const int16_t &integer);
template<> value::value(const std::string &str);
static_assert(sizeof(val) == 16, "");
static_assert(sizeof(value) == 16, "");
} // namespace json
} // namespace ircd
inline
ircd::json::val::val()
ircd::json::value::value()
:string{""}
,len{0}
,type{STRING}
@ -93,24 +93,9 @@ ircd::json::val::val()
,floats{false}
{}
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)
ircd::json::value::value(const string_view &sv,
const enum type &type)
:string{sv.data()}
,len{sv.size()}
,type{type}
@ -119,28 +104,8 @@ ircd::json::val::val(const string_view &sv,
,floats{false}
{}
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 *const &object)
ircd::json::value::value(const struct index *const &object)
:object{object}
,len{0}
,type{OBJECT}
@ -150,7 +115,7 @@ ircd::json::val::val(const struct obj *const &object)
{}
inline
ircd::json::val::val(std::unique_ptr<obj> object)
ircd::json::value::value(std::unique_ptr<struct index> object)
:object{object.get()}
,len{0}
,type{OBJECT}
@ -161,8 +126,63 @@ ircd::json::val::val(std::unique_ptr<obj> object)
object.release();
}
template<> inline
ircd::json::value::value(const int64_t &integer)
:integer{integer}
,len{0}
,type{NUMBER}
,serial{false}
,alloc{false}
,floats{false}
{}
template<> inline
ircd::json::value::value(const double &floating)
:floating{floating}
,len{0}
,type{NUMBER}
,serial{false}
,alloc{false}
,floats{true}
{}
template<> inline
ircd::json::value::value(const float &floating)
:value{double(floating)}
{}
template<> inline
ircd::json::value::value(const int32_t &integer)
:value{int64_t(integer)}
{}
template<> inline
ircd::json::value::value(const int16_t &integer)
:value{int64_t(integer)}
{}
template<> inline
ircd::json::value::value(const std::string &str)
:value{string_view{str}}
{}
template<size_t N>
ircd::json::value::value(const char (&str)[N])
:value{string_view{str}}
{}
inline
ircd::json::val::val(val &&other)
ircd::json::value::value(const char *const &s)
:value{string_view{s}}
{}
inline
ircd::json::value::value(const string_view &sv)
:value{sv, json::type(sv, std::nothrow)}
{}
inline
ircd::json::value::value(value &&other)
noexcept
:integer{other.integer}
,len{other.len}
@ -174,11 +194,11 @@ noexcept
other.alloc = false;
}
inline ircd::json::val &
ircd::json::val::operator=(val &&other)
inline ircd::json::value &
ircd::json::value::operator=(value &&other)
noexcept
{
this->~val();
this->~value();
integer = other.integer;
len = other.len;
type = other.type;
@ -190,7 +210,7 @@ noexcept
}
inline enum ircd::json::type
ircd::json::type(const val &a)
ircd::json::type(const value &a)
{
return a.type;
}

View file

@ -25,9 +25,9 @@
BOOST_FUSION_ADAPT_STRUCT
(
ircd::json::doc::member,
( decltype(ircd::json::doc::member::first), first )
( decltype(ircd::json::doc::member::second), second )
ircd::json::object::member,
( decltype(ircd::json::object::member::first), first )
( decltype(ircd::json::object::member::second), second )
)
namespace ircd {
@ -81,7 +81,7 @@ struct input
rule<> ws { *(WS) ,"whitespace monoid" };
rule<> wsp { +(WS) ,"whitespace semigroup" };
// structural
// structural
rule<> object_begin { lit('{') ,"object begin" };
rule<> object_end { lit('}') ,"object end" };
rule<> array_begin { lit('[') ,"array begin" };
@ -121,7 +121,7 @@ struct input
,"value"
};
rule<doc::member> member
rule<object::member> member
{
name >> ws >> name_sep >> ws >> value
,"member"
@ -164,7 +164,7 @@ struct output
rule<> ws { *(WS) ,"whitespace monoid" };
rule<> wsp { +(WS) ,"whitespace semigroup" };
// structural
// structural
rule<> object_begin { lit('{') ,"object begin" };
rule<> object_end { lit('}') ,"object end" };
rule<> array_begin { lit('[') ,"array begin" };
@ -176,25 +176,38 @@ struct output
rule<string_view> lit_true { karma::string("true") ,"literal true" };
rule<string_view> lit_false { karma::string("false") ,"literal false" };
rule<string_view> lit_null { karma::string("null") ,"literal null" };
rule<string_view> boolean { lit_true | lit_false ,"boolean" };
rule<string_view> literal { lit_true | lit_false | lit_null ,"literal" };
rule<string_view> chars { *(~char_('"')) ,"characters" };
rule<string_view> string { quote << chars << quote ,"string" };
rule<string_view> number { double_ ,"number" };
rule<string_view> name { quote << +(~char_('"')) << quote ,"name" };
rule<string_view> value { rule<string_view>{} /* subclass implemented */ ,"value" };
rule<const doc::member &> member { name << name_sep << value ,"member" };
rule<const string_view &> elem { value ,"element" };
rule<const json::arr &> elems { -(value % value_sep) ,"elements" };
rule<const json::arr &> array { array_begin << elems << array_end ,"array" };
rule<const json::array &> elems { -(value % value_sep) ,"elements" };
rule<const json::array &> array
{
array_begin << elems << array_end
,"array"
};
rule<const json::doc &> members { -(member % value_sep) ,"members" };
rule<const json::doc &> document { object_begin << members << object_end ,"document" };
rule<const json::object::member &> member
{
name << name_sep << value
,"member"
};
rule<const json::object &> members
{
-(member % value_sep)
,"members"
};
rule<const json::object &> object
{
object_begin << members << object_end
,"object"
};
output()
:output::base_type{rule<>{}}
@ -235,17 +248,17 @@ struct ostreamer
}
const ostreamer;
size_t print(char *const &buf, const size_t &max, const arr &);
size_t print(char *const &buf, const size_t &max, const doc &);
size_t print(char *const &buf, const size_t &max, const obj &);
arr serialize(const arr &, char *&start, char *const &stop);
doc serialize(const doc &, char *&start, char *const &stop);
doc serialize(const obj &, char *&start, char *const &stop);
size_t print(char *const &buf, const size_t &max, const array &);
size_t print(char *const &buf, const size_t &max, const object &);
size_t print(char *const &buf, const size_t &max, const index &);
array serialize(const array &, char *&start, char *const &stop);
object serialize(const object &, char *&start, char *const &stop);
object serialize(const index &, char *&start, char *const &stop);
std::ostream &operator<<(std::ostream &, const arr &);
std::ostream &operator<<(std::ostream &, const doc::member &);
std::ostream &operator<<(std::ostream &, const doc &);
std::ostream &operator<<(std::ostream &, const obj &);
std::ostream &operator<<(std::ostream &, const array &);
std::ostream &operator<<(std::ostream &, const object::member &);
std::ostream &operator<<(std::ostream &, const object &);
std::ostream &operator<<(std::ostream &, const index &);
} // namespace json
} // namespace ircd
@ -266,7 +279,7 @@ failed_to_stream_object()
throw print_error("The JSON generator failed to stream object");
}
}
} // namespace <anonymous>
} // namespace json
} // namespace ircd
@ -277,9 +290,9 @@ std::string
merge_operator(const string_view &key,
const std::pair<string_view, string_view> &delta)
{
ircd::json::obj obj{delta.first};
obj += delta.second;
return obj;
ircd::json::index index{delta.first};
index += delta.second;
return index;
}
} // namespace db
@ -292,14 +305,14 @@ ircd::json::printer::printer()
const auto recurse_array([&]
{
char *out(const_cast<char *>(a.data()));
const arr r(serialize(json::arr(a), out, out + a.size()));
const auto r(serialize(json::array(a), out, out + a.size()));
a.resize(size_t(out - r.data()));
});
const auto recurse_document([&]
const auto recurse_object([&]
{
char *out(const_cast<char *>(a.data()));
const doc d(serialize(json::doc(a), out, out + a.size()));
const auto d(serialize(json::object(a), out, out + a.size()));
a.resize(size_t(out - d.data()));
});
@ -311,7 +324,7 @@ ircd::json::printer::printer()
if(likely(!a.empty())) switch(a.front())
{
case '{': recurse_document(); break;
case '{': recurse_object(); break;
case '[': recurse_array(); break;
case '"': break;
case '0': break;
@ -374,7 +387,7 @@ const
size_t
ircd::json::print(char *const &buf,
const size_t &max,
const obj &obj)
const index &obj)
{
if(unlikely(!max))
return 0;
@ -385,65 +398,65 @@ ircd::json::print(char *const &buf,
return out - buf;
}
ircd::json::doc
ircd::json::serialize(const obj &obj,
ircd::json::object
ircd::json::serialize(const index &obj,
char *&out,
char *const &stop)
{
const auto print_string([&stop, &out](const val &val)
const auto print_string([&stop, &out](const value &value)
{
printer(out, stop, printer.string, string_view{val});
printer(out, stop, printer.string, string_view{value});
});
const auto print_literal([&stop, &out](const val &val)
const auto print_literal([&stop, &out](const value &value)
{
printer(out, stop, karma::string, string_view{val});
printer(out, stop, karma::string, string_view{value});
});
const auto print_object([&stop, &out](const val &val)
const auto print_object([&stop, &out](const value &value)
{
if(val.serial)
if(value.serial)
{
printer(out, stop, printer.document, string_view{val});
printer(out, stop, printer.object, string_view{value});
return;
}
assert(val.object);
serialize(*val.object, out, stop);
assert(value.object);
serialize(*value.object, out, stop);
});
const auto print_array([&stop, &out](const val &val)
const auto print_array([&stop, &out](const value &value)
{
if(val.serial)
if(value.serial)
{
printer(out, stop, printer.array, string_view{val});
printer(out, stop, printer.array, string_view{value});
return;
}
assert(0);
//assert(val.object);
//serialize(*val.object, out, stop);
//assert(value.object);
//serialize(*value.object, out, stop);
});
const auto print_number([&stop, &out](const val &val)
const auto print_number([&stop, &out](const value &value)
{
if(val.serial)
if(value.serial)
{
if(val.floats)
printer(out, stop, double_, string_view{val});
if(value.floats)
printer(out, stop, double_, string_view{value});
else
printer(out, stop, long_, string_view{val});
printer(out, stop, long_, string_view{value});
return;
}
if(val.floats)
printer(out, stop, double_, val.floating);
if(value.floats)
printer(out, stop, double_, value.floating);
else
printer(out, stop, long_, val.integer);
printer(out, stop, long_, value.integer);
});
const auto print_member([&](const obj::member &member)
const auto print_member([&](const index::member &member)
{
printer(out, stop, printer.name << printer.name_sep, member.first);
@ -482,14 +495,14 @@ ircd::json::ostreamer::ostreamer()
const auto recurse_array([&]
{
char *out(const_cast<char *>(a.data()));
const arr r(serialize(json::arr(a), out, out + a.size()));
const auto r(serialize(json::array(a), out, out + a.size()));
a.resize(size_t(out - r.data()));
});
const auto recurse_document([&]
const auto recurse_object([&]
{
char *out(const_cast<char *>(a.data()));
const doc d(serialize(json::doc(a), out, out + a.size()));
const auto d(serialize(json::object(a), out, out + a.size()));
a.resize(size_t(out - d.data()));
});
@ -501,7 +514,7 @@ ircd::json::ostreamer::ostreamer()
if(likely(!a.empty())) switch(a.front())
{
case '{': recurse_document(); break;
case '{': recurse_object(); break;
case '[': recurse_array(); break;
case '"': break;
case '0': break;
@ -530,64 +543,64 @@ ircd::json::ostreamer::ostreamer()
}
std::ostream &
ircd::json::operator<<(std::ostream &s, const obj &obj)
ircd::json::operator<<(std::ostream &s, const index &obj)
{
karma::ostream_iterator<char> osi(s);
const auto stream_string([&osi](const val &val)
const auto stream_string([&osi](const value &value)
{
karma::generate(osi, ostreamer.string, string_view{val});
karma::generate(osi, ostreamer.string, string_view{value});
});
const auto stream_literal([&osi](const val &val)
const auto stream_literal([&osi](const value &value)
{
karma::generate(osi, karma::string, string_view{val});
karma::generate(osi, karma::string, string_view{value});
});
const auto stream_object([&osi, &s](const val &val)
const auto stream_object([&osi, &s](const value &value)
{
if(val.serial)
if(value.serial)
{
karma::generate(osi, ostreamer.document, string_view{val});
karma::generate(osi, ostreamer.object, string_view{value});
return;
}
assert(val.object);
s << *val.object;
assert(value.object);
s << *value.object;
});
const auto stream_array([&osi](const val &val)
const auto stream_array([&osi](const value &value)
{
if(val.serial)
if(value.serial)
{
karma::generate(osi, ostreamer.array, string_view{val});
karma::generate(osi, ostreamer.array, string_view{value});
return;
}
assert(0);
//assert(val.object);
//s << *val.object;
//assert(value.object);
//s << *value.object;
});
const auto stream_number([&osi](const val &val)
const auto stream_number([&osi](const value &value)
{
if(val.serial)
if(value.serial)
{
if(val.floats)
karma::generate(osi, double_, string_view{val});
if(value.floats)
karma::generate(osi, double_, string_view{value});
else
karma::generate(osi, long_, string_view{val});
karma::generate(osi, long_, string_view{value});
return;
}
if(val.floats)
karma::generate(osi, double_, val.floating);
if(value.floats)
karma::generate(osi, double_, value.floating);
else
karma::generate(osi, long_, val.integer);
karma::generate(osi, long_, value.integer);
});
const auto stream_member([&](const obj::member &member)
const auto stream_member([&](const index::member &member)
{
karma::generate(osi, ostreamer.name << ostreamer.name_sep, string_view(member.first));
@ -618,16 +631,16 @@ ircd::json::operator<<(std::ostream &s, const obj &obj)
return s;
}
ircd::json::obj
ircd::json::operator+(const doc &left, const doc &right)
ircd::json::index
ircd::json::operator+(const object &left, const object &right)
{
obj ret(left);
index ret(left);
ret += right;
return ret;
}
ircd::json::obj &
ircd::json::operator+=(obj &left, const doc &right)
ircd::json::index &
ircd::json::operator+=(index &left, const object &right)
{
for(const auto &b : right)
{
@ -646,7 +659,7 @@ ircd::json::operator+=(obj &left, const doc &right)
if(deletion) // prevents adding the empty indicator as the new key!
continue;
left.idx.emplace_back(obj::member{b});
left.idx.emplace_back(index::member{b});
continue;
}
@ -656,20 +669,20 @@ ircd::json::operator+=(obj &left, const doc &right)
continue;
}
auto &a(const_cast<obj::member &>(*it));
auto &a(const_cast<index::member &>(*it));
switch(type(a.second))
{
default:
{
a = obj::member{b};
a = index::member{b};
continue;
}
// merge recursively
case OBJECT:
{
auto merged(std::make_unique<obj>(json::doc{a.second}));
*merged += json::doc{b.second};
auto merged(std::make_unique<index>(json::object{a.second}));
*merged += json::object{b.second};
if(merged->empty())
{
// Child merge was empty value. Now we can also remove this empty parent.
@ -677,7 +690,7 @@ ircd::json::operator+=(obj &left, const doc &right)
continue;
}
a = obj::member{string_view{a.first}, std::move(merged)};
a = index::member{string_view{a.first}, std::move(merged)};
continue;
}
}
@ -686,35 +699,35 @@ ircd::json::operator+=(obj &left, const doc &right)
return left;
}
ircd::json::obj::obj(recursive_t recursive,
const doc &doc)
:idx{doc.count()}
ircd::json::index::index(recursive_t recursive,
const object &object)
:idx{object.count()}
{
std::transform(std::begin(doc), std::end(doc), std::begin(idx), [&]
(const doc::member &m) -> obj::member
std::transform(std::begin(object), std::end(object), std::begin(idx), [&]
(const object::member &m) -> index::member
{
switch(type(m.second))
{
case OBJECT:
return obj::member{m.first, std::make_unique<obj>(recursive, m.second)};
return index::member{m.first, std::make_unique<index>(recursive, m.second)};
default:
return obj::member{m};
return index::member{m};
};
});
}
ircd::json::obj::obj(const doc &doc)
:idx{doc.count()}
ircd::json::index::index(const object &object)
:idx{object.count()}
{
std::transform(std::begin(doc), std::end(doc), std::begin(idx), []
(const doc::member &m) -> obj::member
std::transform(std::begin(object), std::end(object), std::begin(idx), []
(const object::member &m) -> index::member
{
return obj::member{m};
return index::member{m};
});
}
ircd::json::obj::obj(std::initializer_list<member> builder)
ircd::json::index::index(std::initializer_list<member> builder)
:idx{builder.size()}
{
std::transform(std::begin(builder), std::end(builder), std::begin(idx), []
@ -732,7 +745,7 @@ ircd::json::obj::obj(std::initializer_list<member> builder)
}
bool
ircd::json::obj::erase(const string_view &name)
ircd::json::index::erase(const string_view &name)
{
const auto it(find(name));
if(it == end())
@ -743,20 +756,20 @@ ircd::json::obj::erase(const string_view &name)
}
void
ircd::json::obj::erase(const const_iterator &it)
ircd::json::index::erase(const const_iterator &it)
{
idx.erase(it);
}
ircd::json::obj::const_iterator
ircd::json::obj::erase(const const_iterator &start,
const const_iterator &stop)
ircd::json::index::const_iterator
ircd::json::index::erase(const const_iterator &start,
const const_iterator &stop)
{
return { idx.erase(start, stop) };
}
const ircd::json::val &
ircd::json::obj::at(const string_view &path)
const ircd::json::value &
ircd::json::index::at(const string_view &path)
const
{
const auto elem(split(path, '.'));
@ -797,7 +810,7 @@ const
}
size_t
ircd::json::obj::size()
ircd::json::index::size()
const
{
const size_t ret(1 + idx.empty());
@ -808,7 +821,7 @@ const
});
}
ircd::json::obj::operator std::string()
ircd::json::index::operator std::string()
const
{
std::string ret(size(), char());
@ -816,7 +829,7 @@ const
return ret;
}
ircd::json::val::~val()
ircd::json::value::~value()
noexcept
{
switch(type)
@ -828,7 +841,7 @@ noexcept
}
}
ircd::json::val::operator std::string()
ircd::json::value::operator std::string()
const
{
switch(type)
@ -858,10 +871,10 @@ const
return std::string(lex_cast(integer));
}
throw type_error("cannot stringify type[%d]", int(type));
throw type_error("cannot index type[%d]", int(type));
}
ircd::json::val::operator string_view()
ircd::json::value::operator string_view()
const
{
switch(type)
@ -883,7 +896,7 @@ const
}
bool
ircd::json::val::empty()
ircd::json::value::empty()
const
{
switch(type)
@ -899,7 +912,7 @@ const
}
size_t
ircd::json::val::size()
ircd::json::value::size()
const
{
switch(type)
@ -915,7 +928,7 @@ const
}
std::ostream &
ircd::json::operator<<(std::ostream &s, const val &v)
ircd::json::operator<<(std::ostream &s, const value &v)
{
switch(v.type)
{
@ -952,7 +965,7 @@ ircd::json::operator<<(std::ostream &s, const val &v)
}
bool
ircd::json::operator>(const val &a, const val &b)
ircd::json::operator>(const value &a, const value &b)
{
if(unlikely(type(a) != STRING || type(b) != STRING))
throw type_error("cannot compare values");
@ -961,7 +974,7 @@ ircd::json::operator>(const val &a, const val &b)
}
bool
ircd::json::operator<(const val &a, const val &b)
ircd::json::operator<(const value &a, const value &b)
{
if(unlikely(type(a) != STRING || type(b) != STRING))
throw type_error("cannot compare values");
@ -970,7 +983,7 @@ ircd::json::operator<(const val &a, const val &b)
}
bool
ircd::json::operator>=(const val &a, const val &b)
ircd::json::operator>=(const value &a, const value &b)
{
if(unlikely(type(a) != STRING || type(b) != STRING))
throw type_error("cannot compare values");
@ -979,7 +992,7 @@ ircd::json::operator>=(const val &a, const val &b)
}
bool
ircd::json::operator<=(const val &a, const val &b)
ircd::json::operator<=(const value &a, const value &b)
{
if(unlikely(type(a) != STRING || type(b) != STRING))
throw type_error("cannot compare values");
@ -988,7 +1001,7 @@ ircd::json::operator<=(const val &a, const val &b)
}
bool
ircd::json::operator!=(const val &a, const val &b)
ircd::json::operator!=(const value &a, const value &b)
{
if(unlikely(type(a) != STRING || type(b) != STRING))
throw type_error("cannot compare values");
@ -997,7 +1010,7 @@ ircd::json::operator!=(const val &a, const val &b)
}
bool
ircd::json::operator==(const val &a, const val &b)
ircd::json::operator==(const value &a, const value &b)
{
if(unlikely(type(a) != STRING || type(b) != STRING))
throw type_error("cannot compare values");
@ -1008,52 +1021,52 @@ ircd::json::operator==(const val &a, const val &b)
size_t
ircd::json::print(char *const &buf,
const size_t &max,
const doc &doc)
const object &object)
{
if(unlikely(!max))
return 0;
char *out(buf);
serialize(doc, out, out + (max - 1));
serialize(object, out, out + (max - 1));
*out = '\0';
return std::distance(buf, out);
}
ircd::json::doc
ircd::json::serialize(const doc &doc,
ircd::json::object
ircd::json::serialize(const object &object,
char *&out,
char *const &stop)
{
static const auto throws([]
{
throw print_error("The JSON generator failed to print document");
throw print_error("The JSON generator failed to print object");
});
char *const start(out);
karma::generate(out, maxwidth(stop - start)[printer.document] | eps[throws], doc);
karma::generate(out, maxwidth(stop - start)[printer.object] | eps[throws], object);
return string_view{start, out};
}
std::ostream &
ircd::json::operator<<(std::ostream &s, const doc &doc)
ircd::json::operator<<(std::ostream &s, const object &object)
{
const auto &os(ostreamer);
static const auto throws([]
{
throw print_error("The JSON generator failed to output document to stream");
throw print_error("The JSON generator failed to output object to stream");
});
karma::ostream_iterator<char> osi(s);
karma::generate(osi, os.document | eps[throws], doc);
karma::generate(osi, os.object | eps[throws], object);
return s;
}
std::ostream &
ircd::json::operator<<(std::ostream &s, const doc::member &member)
ircd::json::operator<<(std::ostream &s, const object::member &member)
{
static const auto throws([]
{
throw print_error("The JSON generator failed to output document member to stream");
throw print_error("The JSON generator failed to output object member to stream");
});
karma::ostream_iterator<char> osi(s);
@ -1061,15 +1074,15 @@ ircd::json::operator<<(std::ostream &s, const doc::member &member)
return s;
}
ircd::json::doc::const_iterator &
ircd::json::doc::const_iterator::operator++()
ircd::json::object::const_iterator &
ircd::json::object::const_iterator::operator++()
{
static const qi::rule<const char *, json::doc::member> member
static const qi::rule<const char *, json::object::member> member
{
parser.name >> parser.ws >> parser.name_sep >> parser.ws >> raw[parser.value]
};
static const qi::rule<const char *, json::doc::member> parse_next
static const qi::rule<const char *, json::object::member> parse_next
{
parser.object_end | (parser.value_sep >> parser.ws >> member)
};
@ -1082,7 +1095,7 @@ ircd::json::doc::const_iterator::operator++()
return *this;
}
ircd::json::doc::operator std::string()
ircd::json::object::operator std::string()
const
{
//TODO: tmp
@ -1091,16 +1104,16 @@ const
return ret.str();
}
ircd::json::doc::const_iterator
ircd::json::doc::begin()
ircd::json::object::const_iterator
ircd::json::object::begin()
const
{
static const qi::rule<const char *, json::doc::member> member
static const qi::rule<const char *, json::object::member> member
{
parser.name >> parser.ws >> parser.name_sep >> parser.ws >> raw[parser.value]
};
static const qi::rule<const char *, json::doc::member> parse_begin
static const qi::rule<const char *, json::object::member> parse_begin
{
parser.object_begin >> parser.ws >> (parser.object_end | member)
};
@ -1112,8 +1125,8 @@ const
return ret;
}
ircd::json::doc::const_iterator
ircd::json::doc::end()
ircd::json::object::const_iterator
ircd::json::object::end()
const
{
return { string_view::end(), string_view::end() };
@ -1122,7 +1135,7 @@ const
size_t
ircd::json::print(char *const &buf,
const size_t &max,
const arr &arr)
const array &arr)
{
if(unlikely(!max))
return 0;
@ -1133,8 +1146,8 @@ ircd::json::print(char *const &buf,
return std::distance(buf, out);
}
ircd::json::arr
ircd::json::serialize(const arr &a,
ircd::json::array
ircd::json::serialize(const array &a,
char *&out,
char *const &stop)
{
@ -1159,7 +1172,7 @@ ircd::json::serialize(const arr &a,
}
std::ostream &
ircd::json::operator<<(std::ostream &s, const arr &a)
ircd::json::operator<<(std::ostream &s, const array &a)
{
const auto &os(ostreamer);
static const auto throws([]
@ -1182,8 +1195,8 @@ ircd::json::operator<<(std::ostream &s, const arr &a)
return s;
}
ircd::json::arr::const_iterator &
ircd::json::arr::const_iterator::operator++()
ircd::json::array::const_iterator &
ircd::json::array::const_iterator::operator++()
{
static const qi::rule<const char *, string_view> parse_next
{
@ -1197,7 +1210,7 @@ ircd::json::arr::const_iterator::operator++()
return *this;
}
ircd::json::arr::operator std::string()
ircd::json::array::operator std::string()
const
{
//TODO: tmp
@ -1206,8 +1219,8 @@ const
return ret.str();
}
ircd::json::arr::const_iterator
ircd::json::arr::begin()
ircd::json::array::const_iterator
ircd::json::array::begin()
const
{
static const qi::rule<const char *, string_view> parse_begin
@ -1222,8 +1235,8 @@ const
return ret;
}
ircd::json::arr::const_iterator
ircd::json::arr::end()
ircd::json::array::const_iterator
ircd::json::array::end()
const
{
return { string_view::end(), string_view::end() };

View file

@ -120,7 +120,7 @@ try
/*
account(db::MERGE, "jzk", std::string
{
json::obj
json::index
{{
"password",
{

View file

@ -55,7 +55,7 @@ try
return resource::response
{
client, http::CREATED, json::obj
client, http::CREATED, json::index
{
{ "room_id", room_id }
}

View file

@ -44,7 +44,7 @@ logout(client &client, const resource::request &request)
resource::tokens.erase(it);
return resource::response
{
client, json::obj
client, json::index
{
{ }
}

View file

@ -78,7 +78,7 @@ get_publicrooms(client &client, const resource::request &request)
return resource::response
{
client, json::obj
client, json::index
{
{ }
}

View file

@ -36,7 +36,7 @@ try
{
return resource::response
{
client, json::obj
client, json::index
{
{ }
}

View file

@ -55,7 +55,7 @@ handle_post(client &client,
return resource::response
{
client, http::CREATED, json::obj
client, http::CREATED, json::index
{
{ "access_token", access_token },
{ "home_server", home_server },
@ -146,7 +146,7 @@ handle_post(client &client,
// Send response to user
return resource::response
{
client, http::CREATED, json::obj
client, http::CREATED, json::index
{
{ "access_token", access_token },
{ "home_server", home_server },

View file

@ -56,7 +56,7 @@ try
return resource::response
{
client, json::obj
client, json::index
{
{ }
}
@ -125,7 +125,7 @@ try
return resource::response
{
client, http::CREATED, json::obj
client, http::CREATED, json::index
{
{ "filter_id", "abc321" }
}

View file

@ -33,7 +33,7 @@ resource::method getter
(client &client, resource::request &request)
-> resource::response
{
static const json::doc object
static const json::object object
{
R"({"versions":["r2.0.0"]})"
};

View file

@ -38,7 +38,7 @@ get_turnserver(client &client, const resource::request &request)
{
return resource::response
{
client, json::obj
client, json::index
{
{ },
}