mirror of
https://github.com/matrix-construct/construct
synced 2024-11-25 08:12:37 +01:00
ircd::json::stack: Add internal convenience member instance in the object and array class.
This commit is contained in:
parent
af6fcb24f4
commit
f9ec33916c
2 changed files with 133 additions and 80 deletions
|
@ -83,77 +83,6 @@ struct ircd::json::stack
|
|||
~stack() noexcept;
|
||||
};
|
||||
|
||||
/// stack::object is constructed under the scope of either a stack::member,
|
||||
/// or a stack::array, or a stack itself. Only stack::member can be
|
||||
/// constructed directly under its scope.
|
||||
///
|
||||
/// For a stack::member parent, the named member is waiting for this value
|
||||
/// after leaving the stack at ':' after the name, this object will then
|
||||
/// print '{' and dtor with '}' and then return to the stack::member which
|
||||
/// will then return to its parent object.
|
||||
///
|
||||
/// For a stack::array parent, the stack may have been left at '[' or ','
|
||||
/// but either way this object will then print '{' and dtor with '}' and
|
||||
/// then return to the stack::array.
|
||||
///
|
||||
/// For a stack itself, this object is considered the "top object" and will
|
||||
/// open the stack with '{' and accept member instances under its scope
|
||||
/// until closing the stack with '}' after which the stack is done()
|
||||
///
|
||||
struct ircd::json::stack::object
|
||||
{
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
member *pm {nullptr}; ///< parent member (if value of one)
|
||||
array *pa {nullptr}; ///< parent array (if value in one)
|
||||
member *cm {nullptr}; ///< current child member
|
||||
size_t mc {0}; ///< members witnessed (monotonic)
|
||||
|
||||
public:
|
||||
object(stack &s); ///< Object is top
|
||||
object(array &pa); ///< Object is value in the array
|
||||
object(member &pm); ///< Object is value of named member
|
||||
object(object &&) noexcept;
|
||||
object(const object &) = delete;
|
||||
~object() noexcept;
|
||||
|
||||
static const object &top(const stack &);
|
||||
static object &top(stack &);
|
||||
};
|
||||
|
||||
/// stack::array is constructed under the scope of either a stack::member,
|
||||
/// or a stack::array, or a stack itself. stack::object and stack::array
|
||||
/// can be constructed directly under its scope, but not stack::member.
|
||||
///
|
||||
/// The same behavior as described by stack::object documentation applies
|
||||
/// here translated to arrays.
|
||||
///
|
||||
struct ircd::json::stack::array
|
||||
{
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
member *pm {nullptr}; ///< parent member (if value of one)
|
||||
array *pa {nullptr}; ///< parent array (if value in one)
|
||||
object *co {nullptr}; ///< current child object
|
||||
array *ca {nullptr}; ///< current child array
|
||||
size_t vc {0}; ///< values witnessed (monotonic)
|
||||
|
||||
void _pre_append();
|
||||
void _post_append();
|
||||
|
||||
public:
|
||||
template<class... T> void append(const json::tuple<T...> &);
|
||||
void append(const json::value &);
|
||||
|
||||
array(stack &s); ///< Array is top
|
||||
array(array &pa); ///< Array is value in the array
|
||||
array(member &pm); ///< Array is value of the named member
|
||||
array(const array &) = delete;
|
||||
array(array &&) noexcept;
|
||||
~array() noexcept;
|
||||
|
||||
static const array &top(const stack &);
|
||||
static array &top(stack &);
|
||||
};
|
||||
|
||||
/// stack::member is an intermediary that is constructed under the scope of
|
||||
/// a parent stack::object. It takes a name argument. It then requires one
|
||||
/// object or array be constructed under its scope as its value, or a
|
||||
|
@ -184,6 +113,7 @@ struct ircd::json::stack::member
|
|||
member(stack &s, const string_view &name, const json::value &);
|
||||
template<class... T> member(object &po, const string_view &name, const json::tuple<T...> &t);
|
||||
template<class... T> member(stack &s, const string_view &name, const json::tuple<T...> &t);
|
||||
member() = default;
|
||||
member(const member &) = delete;
|
||||
member(member &&) noexcept;
|
||||
~member() noexcept;
|
||||
|
@ -192,6 +122,83 @@ struct ircd::json::stack::member
|
|||
static member &top(stack &);
|
||||
};
|
||||
|
||||
/// stack::object is constructed under the scope of either a stack::member,
|
||||
/// or a stack::array, or a stack itself. Only stack::member can be
|
||||
/// constructed directly under its scope.
|
||||
///
|
||||
/// For a stack::member parent, the named member is waiting for this value
|
||||
/// after leaving the stack at ':' after the name, this object will then
|
||||
/// print '{' and dtor with '}' and then return to the stack::member which
|
||||
/// will then return to its parent object.
|
||||
///
|
||||
/// For a stack::array parent, the stack may have been left at '[' or ','
|
||||
/// but either way this object will then print '{' and dtor with '}' and
|
||||
/// then return to the stack::array.
|
||||
///
|
||||
/// For a stack itself, this object is considered the "top object" and will
|
||||
/// open the stack with '{' and accept member instances under its scope
|
||||
/// until closing the stack with '}' after which the stack is done()
|
||||
///
|
||||
struct ircd::json::stack::object
|
||||
{
|
||||
member m; ///< optional internal member
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
member *pm {nullptr}; ///< parent member (if value of one)
|
||||
array *pa {nullptr}; ///< parent array (if value in one)
|
||||
member *cm {nullptr}; ///< current child member
|
||||
size_t mc {0}; ///< members witnessed (monotonic)
|
||||
|
||||
public:
|
||||
object(stack &s); ///< Object is top
|
||||
object(array &pa); ///< Object is value in the array
|
||||
object(member &pm); ///< Object is value of named member
|
||||
object(object &po, const string_view &name);
|
||||
object(stack &s, const string_view &name);
|
||||
object(object &&) noexcept;
|
||||
object(const object &) = delete;
|
||||
~object() noexcept;
|
||||
|
||||
static const object &top(const stack &);
|
||||
static object &top(stack &);
|
||||
};
|
||||
|
||||
/// stack::array is constructed under the scope of either a stack::member,
|
||||
/// or a stack::array, or a stack itself. stack::object and stack::array
|
||||
/// can be constructed directly under its scope, but not stack::member.
|
||||
///
|
||||
/// The same behavior as described by stack::object documentation applies
|
||||
/// here translated to arrays.
|
||||
///
|
||||
struct ircd::json::stack::array
|
||||
{
|
||||
member m; ///< optional internal member
|
||||
stack *s {nullptr}; ///< root stack ref
|
||||
member *pm {nullptr}; ///< parent member (if value of one)
|
||||
array *pa {nullptr}; ///< parent array (if value in one)
|
||||
object *co {nullptr}; ///< current child object
|
||||
array *ca {nullptr}; ///< current child array
|
||||
size_t vc {0}; ///< values witnessed (monotonic)
|
||||
|
||||
void _pre_append();
|
||||
void _post_append();
|
||||
|
||||
public:
|
||||
template<class... T> void append(const json::tuple<T...> &);
|
||||
void append(const json::value &);
|
||||
|
||||
array(member &pm); ///< Array is value of the named member
|
||||
array(array &pa); ///< Array is value in the array
|
||||
array(object &po, const string_view &name);
|
||||
array(stack &s, const string_view &name);
|
||||
array(stack &s);
|
||||
array(const array &) = delete;
|
||||
array(array &&) noexcept;
|
||||
~array() noexcept;
|
||||
|
||||
static const array &top(const stack &);
|
||||
static array &top(stack &);
|
||||
};
|
||||
|
||||
/// This device chases the current active path by updating its member pointers.
|
||||
struct ircd::json::stack::chase
|
||||
{
|
||||
|
|
64
ircd/json.cc
64
ircd/json.cc
|
@ -612,7 +612,8 @@ ircd::json::stack::object::top(const stack &s)
|
|||
|
||||
ircd::json::stack::object::object(object &&other)
|
||||
noexcept
|
||||
:s{std::move(other.s)}
|
||||
:m{std::move(other.m)}
|
||||
,s{std::move(other.s)}
|
||||
,pm{std::move(other.pm)}
|
||||
,pa{std::move(other.pa)}
|
||||
,cm{std::move(other.cm)}
|
||||
|
@ -646,6 +647,28 @@ ircd::json::stack::object::object(stack &s)
|
|||
s.append("{"_sv);
|
||||
}
|
||||
|
||||
ircd::json::stack::object::object(stack &s,
|
||||
const string_view &name)
|
||||
:object{object::top(s), name}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::json::stack::object::object(object &po,
|
||||
const string_view &name)
|
||||
:m{po, name}
|
||||
,s{po.s}
|
||||
,pm{&m}
|
||||
{
|
||||
assert(s->opened());
|
||||
s->rethrow_exception();
|
||||
|
||||
assert(pm->co == nullptr);
|
||||
assert(pm->ca == nullptr);
|
||||
pm->co = this;
|
||||
s->append("{"_sv);
|
||||
pm->vc |= true;
|
||||
}
|
||||
|
||||
ircd::json::stack::object::object(member &pm)
|
||||
:s{pm.s}
|
||||
,pm{&pm}
|
||||
|
@ -760,7 +783,8 @@ ircd::json::stack::array::top(const stack &s)
|
|||
|
||||
ircd::json::stack::array::array(array &&other)
|
||||
noexcept
|
||||
:s{std::move(other.s)}
|
||||
:m{std::move(other.m)}
|
||||
,s{std::move(other.s)}
|
||||
,pm{std::move(other.pm)}
|
||||
,pa{std::move(other.pa)}
|
||||
,co{std::move(other.co)}
|
||||
|
@ -796,18 +820,26 @@ ircd::json::stack::array::array(stack &s)
|
|||
s.append("["_sv);
|
||||
}
|
||||
|
||||
ircd::json::stack::array::array(member &pm)
|
||||
:s{pm.s}
|
||||
,pm{&pm}
|
||||
ircd::json::stack::array::array(stack &s,
|
||||
const string_view &name)
|
||||
:array{object::top(s), name}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::json::stack::array::array(object &po,
|
||||
const string_view &name)
|
||||
:m{po, name}
|
||||
,s{po.s}
|
||||
,pm{&m}
|
||||
{
|
||||
assert(s->opened());
|
||||
s->rethrow_exception();
|
||||
|
||||
assert(pm.co == nullptr);
|
||||
assert(pm.ca == nullptr);
|
||||
pm.ca = this;
|
||||
assert(pm->co == nullptr);
|
||||
assert(pm->ca == nullptr);
|
||||
pm->ca = this;
|
||||
s->append("["_sv);
|
||||
pm.vc |= true;
|
||||
pm->vc |= true;
|
||||
}
|
||||
|
||||
ircd::json::stack::array::array(array &pa)
|
||||
|
@ -827,6 +859,20 @@ ircd::json::stack::array::array(array &pa)
|
|||
s->append("["_sv);
|
||||
}
|
||||
|
||||
ircd::json::stack::array::array(member &pm)
|
||||
:s{pm.s}
|
||||
,pm{&pm}
|
||||
{
|
||||
assert(s->opened());
|
||||
s->rethrow_exception();
|
||||
|
||||
assert(pm.co == nullptr);
|
||||
assert(pm.ca == nullptr);
|
||||
pm.ca = this;
|
||||
s->append("["_sv);
|
||||
pm.vc |= true;
|
||||
}
|
||||
|
||||
ircd::json::stack::array::~array()
|
||||
noexcept
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue