2018-01-22 10:07:09 +01:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2018 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. The
|
|
|
|
// full license for this software is available in the LICENSE file.
|
2017-08-23 23:32:28 +02:00
|
|
|
|
|
|
|
#pragma once
|
2017-08-26 06:39:36 +02:00
|
|
|
#define HAVE_IRCD_JSON_TUPLE_H
|
2017-08-23 23:32:28 +02:00
|
|
|
|
2018-02-01 04:06:31 +01:00
|
|
|
#include "property.h"
|
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
namespace ircd::json
|
|
|
|
{
|
|
|
|
struct tuple_base;
|
2017-08-23 23:32:28 +02:00
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class...>
|
|
|
|
struct tuple;
|
|
|
|
|
|
|
|
template<class>
|
|
|
|
struct keys;
|
|
|
|
}
|
2018-05-20 02:32:31 +02:00
|
|
|
|
2017-09-12 18:37:44 +02:00
|
|
|
/// All tuple templates inherit from this non-template type for tagging.
|
2020-10-29 08:08:06 +01:00
|
|
|
struct ircd::json::tuple_base
|
2017-09-08 21:29:21 +02:00
|
|
|
{
|
2020-10-29 08:08:06 +01:00
|
|
|
// EBO
|
2017-09-08 21:29:21 +02:00
|
|
|
};
|
2017-09-08 12:15:58 +02:00
|
|
|
|
2017-09-12 18:37:44 +02:00
|
|
|
/// A compile-time construct to describe a JSON object's members and types.
|
|
|
|
///
|
2017-09-14 20:30:06 +02:00
|
|
|
/// Member access by name is O(1) because of recursive constexpr function
|
|
|
|
/// inlining when translating a name to the index number which is then used
|
|
|
|
/// as the template argument to std::get() for the value.
|
|
|
|
///
|
2017-09-12 18:37:44 +02:00
|
|
|
/// Here we represent a JSON object with a named tuple, allowing the programmer
|
|
|
|
/// to create a structure specifying all of the potentially valid members of the
|
2020-04-06 01:10:55 +02:00
|
|
|
/// object. Thus at runtime, the tuple carries around its values like a
|
2017-09-12 18:37:44 +02:00
|
|
|
/// `struct`. Unlike a `struct`, the tuple is abstractly iterable and we have
|
|
|
|
/// implemented logic operating on all JSON tuples regardless of their makeup
|
2017-09-14 20:30:06 +02:00
|
|
|
/// without any effort from a developer when creating a new tuple.
|
2017-09-12 18:37:44 +02:00
|
|
|
///
|
|
|
|
/// The member structure for the tuple is called `property` because json::member
|
2017-09-14 20:30:06 +02:00
|
|
|
/// is already used to pair together runtime oriented json::values.
|
2017-09-12 18:37:44 +02:00
|
|
|
///
|
|
|
|
/// Create and use a tuple to efficiently extract members from a json::object.
|
|
|
|
/// The tuple will populate its own members during a single-pass iteration of
|
2017-09-19 11:09:19 +02:00
|
|
|
/// the JSON input.
|
|
|
|
///
|
|
|
|
/// But remember, the tuple carries very little information for you at runtime
|
|
|
|
/// which may make it difficult to represent all JS phenomena like "undefined"
|
|
|
|
/// and "null".
|
2017-09-12 18:37:44 +02:00
|
|
|
///
|
2017-08-23 23:32:28 +02:00
|
|
|
template<class... T>
|
2020-10-29 08:08:06 +01:00
|
|
|
struct ircd::json::tuple
|
2017-09-08 12:15:58 +02:00
|
|
|
:std::tuple<T...>
|
2017-09-08 21:29:21 +02:00
|
|
|
,tuple_base
|
2017-08-23 23:32:28 +02:00
|
|
|
{
|
|
|
|
using tuple_type = std::tuple<T...>;
|
2017-08-27 01:30:49 +02:00
|
|
|
using super_type = tuple<T...>;
|
2017-08-23 23:32:28 +02:00
|
|
|
|
2019-08-15 08:16:38 +02:00
|
|
|
static constexpr size_t size() noexcept;
|
2017-12-12 21:23:20 +01:00
|
|
|
|
2017-09-19 11:09:19 +02:00
|
|
|
operator json::value() const;
|
2017-10-16 06:22:52 +02:00
|
|
|
operator crh::sha256::buf() const;
|
2017-09-19 11:09:19 +02:00
|
|
|
|
2020-04-06 01:10:55 +02:00
|
|
|
/// For json::object constructions, the source JSON (string_view) is
|
|
|
|
/// carried with the instance. This is important to convey additional
|
|
|
|
/// keys not enumerated in the tuple. This will be default-initialized
|
|
|
|
/// for other constructions when no source JSON buffer is available.
|
|
|
|
json::object source;
|
|
|
|
|
2019-08-15 08:16:38 +02:00
|
|
|
template<class name> constexpr decltype(auto) get(name&&) const noexcept;
|
|
|
|
template<class name> constexpr decltype(auto) get(name&&) noexcept;
|
2019-08-15 07:54:53 +02:00
|
|
|
template<class name> constexpr decltype(auto) at(name&&) const;
|
|
|
|
template<class name> constexpr decltype(auto) at(name&&);
|
|
|
|
|
2020-03-19 23:13:02 +01:00
|
|
|
template<class R, class name> R get(name&&, R def = {}) const noexcept;
|
|
|
|
template<class R, class name> const R &at(name&&) const;
|
|
|
|
template<class R, class name> R &at(name&&);
|
|
|
|
|
2019-01-17 02:22:09 +01:00
|
|
|
template<class... U> explicit tuple(const tuple<U...> &);
|
|
|
|
template<class U> explicit tuple(const json::object &, const json::keys<U> &);
|
2019-01-17 03:35:30 +01:00
|
|
|
template<class U> explicit tuple(const tuple &, const json::keys<U> &);
|
2017-08-27 01:30:49 +02:00
|
|
|
tuple(const json::object &);
|
2017-09-09 21:20:00 +02:00
|
|
|
tuple(const json::iov &);
|
2019-03-29 04:15:22 +01:00
|
|
|
tuple(const json::members &);
|
2017-08-27 01:30:49 +02:00
|
|
|
tuple() = default;
|
2017-08-23 23:32:28 +02:00
|
|
|
};
|
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
namespace ircd {
|
|
|
|
namespace json {
|
|
|
|
|
|
|
|
template<class T>
|
2017-09-08 21:29:21 +02:00
|
|
|
constexpr bool
|
|
|
|
is_tuple()
|
|
|
|
{
|
2020-10-29 08:08:06 +01:00
|
|
|
return std::is_base_of<tuple_base, T>::value;
|
2017-09-08 21:29:21 +02:00
|
|
|
}
|
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T,
|
2017-11-25 22:07:10 +01:00
|
|
|
class R>
|
2020-10-29 08:08:06 +01:00
|
|
|
using enable_if_tuple = typename std::enable_if<is_tuple<T>(), R>::type;
|
2017-09-08 21:29:21 +02:00
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T,
|
2017-11-25 22:07:10 +01:00
|
|
|
class test,
|
|
|
|
class R>
|
2020-10-29 08:08:06 +01:00
|
|
|
using enable_if_tuple_and = typename std::enable_if<is_tuple<T>() && test(), R>::type;
|
2017-11-25 22:07:10 +01:00
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T>
|
|
|
|
using tuple_type = typename T::tuple_type;
|
2017-08-23 23:32:28 +02:00
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T>
|
|
|
|
using tuple_size = std::tuple_size<tuple_type<T>>;
|
2017-08-23 23:32:28 +02:00
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T,
|
2017-08-27 01:30:49 +02:00
|
|
|
size_t i>
|
2020-10-29 08:08:06 +01:00
|
|
|
using tuple_element = typename std::tuple_element<i, tuple_type<T>>::type;
|
2017-08-23 23:32:28 +02:00
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T,
|
2017-08-27 01:30:49 +02:00
|
|
|
size_t i>
|
2020-10-29 08:08:06 +01:00
|
|
|
using tuple_value_type = typename tuple_element<T, i>::value_type;
|
2017-08-27 01:30:49 +02:00
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T>
|
2020-04-03 21:07:45 +02:00
|
|
|
inline auto &
|
2020-10-29 08:08:06 +01:00
|
|
|
stdcast(const T &o)
|
2017-08-23 23:32:28 +02:00
|
|
|
{
|
2020-10-29 08:08:06 +01:00
|
|
|
return static_cast<const typename T::tuple_type &>(o);
|
2017-08-23 23:32:28 +02:00
|
|
|
}
|
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T>
|
2020-04-03 21:07:45 +02:00
|
|
|
inline auto &
|
2020-10-29 08:08:06 +01:00
|
|
|
stdcast(T &o)
|
2017-08-23 23:32:28 +02:00
|
|
|
{
|
2020-10-29 08:08:06 +01:00
|
|
|
return static_cast<typename T::tuple_type &>(o);
|
2017-08-23 23:32:28 +02:00
|
|
|
}
|
|
|
|
|
2020-10-29 08:08:06 +01:00
|
|
|
template<class T>
|
|
|
|
constexpr enable_if_tuple<T, size_t>
|
2017-08-27 01:30:49 +02:00
|
|
|
size()
|
2017-08-23 23:32:28 +02:00
|
|
|
{
|
2020-10-29 08:08:06 +01:00
|
|
|
return tuple_size<T>::value;
|
2017-08-27 01:30:49 +02:00
|
|
|
}
|
|
|
|
|
2022-06-26 23:18:13 +02:00
|
|
|
/// Reference to the json::property wrapper of the key and value
|
|
|
|
template<size_t i,
|
|
|
|
class tuple>
|
|
|
|
inline enable_if_tuple<tuple, tuple_element<tuple, i> &>
|
|
|
|
prop(tuple &t)
|
|
|
|
{
|
|
|
|
return std::get<i>(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Reference to the json::property wrapper of the key and value
|
|
|
|
template<size_t i,
|
|
|
|
class tuple>
|
|
|
|
inline enable_if_tuple<tuple, const tuple_element<tuple, i> &>
|
|
|
|
prop(const tuple &t)
|
|
|
|
{
|
|
|
|
return std::get<i>(t);
|
|
|
|
}
|
|
|
|
|
2018-05-07 06:31:32 +02:00
|
|
|
} // namespace json
|
|
|
|
} // namespace ircd
|
2017-10-05 01:25:15 +02:00
|
|
|
|
2018-05-20 02:33:28 +02:00
|
|
|
#include "key.h"
|
2018-05-07 06:31:32 +02:00
|
|
|
#include "indexof.h"
|
2017-10-05 01:25:15 +02:00
|
|
|
|
2018-05-07 06:31:32 +02:00
|
|
|
namespace ircd {
|
|
|
|
namespace json {
|
2017-09-19 11:09:19 +02:00
|
|
|
|
2022-06-26 23:18:13 +02:00
|
|
|
/// Reference to the payload value directly at index
|
2017-08-27 01:30:49 +02:00
|
|
|
template<size_t i,
|
2017-09-08 21:29:21 +02:00
|
|
|
class tuple>
|
2020-04-03 21:07:45 +02:00
|
|
|
inline enable_if_tuple<tuple, tuple_value_type<tuple, i> &>
|
2017-10-05 01:25:15 +02:00
|
|
|
val(tuple &t)
|
2017-08-23 23:32:28 +02:00
|
|
|
{
|
2022-06-26 23:18:13 +02:00
|
|
|
return static_cast<tuple_value_type<tuple, i> &>(prop<i>(t));
|
2017-08-23 23:32:28 +02:00
|
|
|
}
|
|
|
|
|
2022-06-26 23:18:13 +02:00
|
|
|
/// Reference to the payload value directly at index
|
2017-08-23 23:32:28 +02:00
|
|
|
template<size_t i,
|
2017-09-08 21:29:21 +02:00
|
|
|
class tuple>
|
2020-04-03 21:07:45 +02:00
|
|
|
inline enable_if_tuple<tuple, const tuple_value_type<tuple, i> &>
|
2017-10-05 01:25:15 +02:00
|
|
|
val(const tuple &t)
|
2017-08-23 23:32:28 +02:00
|
|
|
{
|
2022-06-26 23:18:13 +02:00
|
|
|
return static_cast<const tuple_value_type<tuple, i> &>(prop<i>(t));
|
2017-08-23 23:32:28 +02:00
|
|
|
}
|
|
|
|
|
2022-06-26 23:18:13 +02:00
|
|
|
/// Convenience to determine if tuple has property by name.
|
2018-05-07 06:31:32 +02:00
|
|
|
template<class tuple>
|
2020-08-06 03:16:16 +02:00
|
|
|
inline bool
|
2022-06-26 23:18:13 +02:00
|
|
|
has_key(const string_view &key)
|
2017-09-21 04:33:50 +02:00
|
|
|
{
|
2018-05-07 06:31:32 +02:00
|
|
|
return indexof<tuple>(key) < size<tuple>();
|
2017-09-21 04:33:50 +02:00
|
|
|
}
|
|
|
|
|
2022-06-26 23:18:13 +02:00
|
|
|
/// Convenience to determine if tuple has property by name.
|
|
|
|
template<class tuple>
|
|
|
|
inline bool
|
|
|
|
has_key(const tuple &t,
|
|
|
|
const string_view &key)
|
|
|
|
{
|
|
|
|
return has_key<tuple>(key);
|
|
|
|
}
|
|
|
|
|
2018-05-07 06:31:32 +02:00
|
|
|
} // namespace json
|
|
|
|
} // namespace ircd
|
2017-09-21 04:33:50 +02:00
|
|
|
|
2018-05-07 06:31:32 +02:00
|
|
|
#include "for_each.h"
|
|
|
|
#include "until.h"
|
2020-03-19 23:13:02 +01:00
|
|
|
#include "get.h"
|
|
|
|
#include "at.h"
|
2018-05-07 06:31:32 +02:00
|
|
|
#include "set.h"
|
2017-09-21 04:33:50 +02:00
|
|
|
|
2018-05-07 06:31:32 +02:00
|
|
|
namespace ircd {
|
|
|
|
namespace json {
|
2017-08-23 23:32:28 +02:00
|
|
|
|
2019-01-16 23:49:07 +01:00
|
|
|
template<class... T>
|
|
|
|
template<class U>
|
2020-08-05 00:50:04 +02:00
|
|
|
inline
|
2019-01-16 23:49:07 +01:00
|
|
|
tuple<T...>::tuple(const json::object &object,
|
|
|
|
const json::keys<U> &keys)
|
2020-04-06 01:10:55 +02:00
|
|
|
:source
|
|
|
|
{
|
|
|
|
object
|
|
|
|
}
|
2019-01-16 23:49:07 +01:00
|
|
|
{
|
2020-08-05 00:09:58 +02:00
|
|
|
for(const auto &[key, val] : object)
|
|
|
|
if(keys.has(key))
|
|
|
|
set(*this, key, val);
|
2019-01-16 23:49:07 +01:00
|
|
|
}
|
|
|
|
|
2017-08-27 01:30:49 +02:00
|
|
|
template<class... T>
|
2020-08-05 00:50:04 +02:00
|
|
|
inline
|
2017-08-27 01:30:49 +02:00
|
|
|
tuple<T...>::tuple(const json::object &object)
|
2020-04-06 01:10:55 +02:00
|
|
|
:source
|
|
|
|
{
|
|
|
|
object
|
|
|
|
}
|
2017-08-26 06:39:36 +02:00
|
|
|
{
|
2020-08-05 00:09:58 +02:00
|
|
|
for(const auto &[key, val] : object)
|
|
|
|
set(*this, key, val);
|
2017-08-26 06:39:36 +02:00
|
|
|
}
|
|
|
|
|
2017-09-08 21:29:21 +02:00
|
|
|
template<class... T>
|
2020-08-05 00:50:04 +02:00
|
|
|
inline
|
2017-09-09 21:20:00 +02:00
|
|
|
tuple<T...>::tuple(const json::iov &iov)
|
2017-09-08 21:29:21 +02:00
|
|
|
{
|
2020-08-05 00:09:58 +02:00
|
|
|
for(const auto &[key, val] : iov)
|
|
|
|
set(*this, key, val);
|
2017-09-08 21:29:21 +02:00
|
|
|
}
|
|
|
|
|
2017-09-08 10:41:02 +02:00
|
|
|
template<class... T>
|
2020-08-05 00:50:04 +02:00
|
|
|
inline
|
2019-03-29 04:15:22 +01:00
|
|
|
tuple<T...>::tuple(const json::members &members)
|
2017-09-08 10:41:02 +02:00
|
|
|
{
|
2020-08-05 00:09:58 +02:00
|
|
|
for(const auto &[key, val] : members)
|
|
|
|
set(*this, key, val);
|
2017-09-08 10:41:02 +02:00
|
|
|
}
|
|
|
|
|
2019-01-17 03:35:30 +01:00
|
|
|
template<class... T>
|
|
|
|
template<class U>
|
2020-08-05 00:50:04 +02:00
|
|
|
inline
|
2019-01-17 03:35:30 +01:00
|
|
|
tuple<T...>::tuple(const tuple &t,
|
|
|
|
const keys<U> &keys)
|
2020-04-06 01:10:55 +02:00
|
|
|
:source
|
|
|
|
{
|
|
|
|
t.source
|
|
|
|
}
|
2019-01-17 03:35:30 +01:00
|
|
|
{
|
|
|
|
for_each(t, [this, &keys]
|
|
|
|
(const auto &key, const auto &val)
|
|
|
|
{
|
|
|
|
if(keys.has(key))
|
|
|
|
set(*this, key, val);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-10-27 21:25:39 +02:00
|
|
|
template<class... T>
|
|
|
|
template<class... U>
|
2020-08-05 00:50:04 +02:00
|
|
|
inline
|
2017-10-27 21:25:39 +02:00
|
|
|
tuple<T...>::tuple(const tuple<U...> &t)
|
2020-04-06 01:10:55 +02:00
|
|
|
:source
|
|
|
|
{
|
|
|
|
t.source
|
|
|
|
}
|
2017-10-27 21:25:39 +02:00
|
|
|
{
|
|
|
|
for_each(t, [this]
|
|
|
|
(const auto &key, const auto &val)
|
|
|
|
{
|
|
|
|
set(*this, key, val);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-12-13 22:32:35 +01:00
|
|
|
template<class... T>
|
2019-08-15 07:54:53 +02:00
|
|
|
template<class name>
|
|
|
|
constexpr decltype(auto)
|
|
|
|
tuple<T...>::at(name&& n)
|
2017-12-13 22:32:35 +01:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
constexpr const size_t hash
|
2017-10-12 03:15:09 +02:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
name_hash(n)
|
2017-10-12 03:15:09 +02:00
|
|
|
};
|
|
|
|
|
2019-08-15 07:54:53 +02:00
|
|
|
return json::at<hash>(*this);
|
2017-09-08 10:41:02 +02:00
|
|
|
}
|
|
|
|
|
2018-02-28 11:23:32 +01:00
|
|
|
template<class... T>
|
2019-08-15 07:54:53 +02:00
|
|
|
template<class name>
|
|
|
|
constexpr decltype(auto)
|
|
|
|
tuple<T...>::at(name&& n)
|
|
|
|
const
|
2018-02-28 11:23:32 +01:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
constexpr const size_t hash
|
2018-02-28 11:23:32 +01:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
name_hash(n)
|
|
|
|
};
|
|
|
|
|
|
|
|
return json::at<hash>(*this);
|
2018-02-28 11:23:32 +01:00
|
|
|
}
|
|
|
|
|
2017-09-08 10:41:02 +02:00
|
|
|
template<class... T>
|
2019-08-15 07:54:53 +02:00
|
|
|
template<class name>
|
|
|
|
constexpr decltype(auto)
|
|
|
|
tuple<T...>::get(name&& n)
|
2019-08-15 08:16:38 +02:00
|
|
|
noexcept
|
2017-09-08 10:41:02 +02:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
constexpr const size_t hash
|
2019-06-24 07:09:41 +02:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
name_hash(n)
|
2019-06-24 07:09:41 +02:00
|
|
|
};
|
|
|
|
|
2019-08-15 07:54:53 +02:00
|
|
|
return json::get<hash>(*this);
|
2017-09-08 10:41:02 +02:00
|
|
|
}
|
|
|
|
|
2018-02-28 11:23:32 +01:00
|
|
|
template<class... T>
|
2019-08-15 07:54:53 +02:00
|
|
|
template<class name>
|
|
|
|
constexpr decltype(auto)
|
|
|
|
tuple<T...>::get(name&& n)
|
2019-08-15 08:16:38 +02:00
|
|
|
const noexcept
|
2018-02-28 11:23:32 +01:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
constexpr const size_t hash
|
2018-02-28 11:23:32 +01:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
name_hash(n)
|
|
|
|
};
|
|
|
|
|
|
|
|
return json::get<hash>(*this);
|
2018-02-28 11:23:32 +01:00
|
|
|
}
|
|
|
|
|
2020-03-19 23:13:02 +01:00
|
|
|
template<class... T>
|
|
|
|
template<class R,
|
|
|
|
class name>
|
2020-04-03 21:07:45 +02:00
|
|
|
inline R
|
2020-03-19 23:13:02 +01:00
|
|
|
tuple<T...>::get(name&& n,
|
|
|
|
R ret)
|
|
|
|
const noexcept
|
|
|
|
{
|
|
|
|
return json::get<R>(*this, n, ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class... T>
|
|
|
|
template<class R,
|
|
|
|
class name>
|
2020-04-03 21:07:45 +02:00
|
|
|
inline const R &
|
2020-03-19 23:13:02 +01:00
|
|
|
tuple<T...>::at(name&& n)
|
|
|
|
const
|
|
|
|
{
|
|
|
|
return json::at<R>(*this, n);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class... T>
|
|
|
|
template<class R,
|
|
|
|
class name>
|
2020-04-03 21:07:45 +02:00
|
|
|
inline R &
|
2020-03-19 23:13:02 +01:00
|
|
|
tuple<T...>::at(name&& n)
|
|
|
|
{
|
|
|
|
return json::at<R>(*this, n);
|
|
|
|
}
|
|
|
|
|
2017-09-08 10:41:02 +02:00
|
|
|
template<class... T>
|
2019-08-15 07:54:53 +02:00
|
|
|
constexpr size_t
|
|
|
|
tuple<T...>::size()
|
2019-08-15 08:16:38 +02:00
|
|
|
noexcept
|
2017-09-08 10:41:02 +02:00
|
|
|
{
|
2019-08-15 07:54:53 +02:00
|
|
|
return std::tuple_size<tuple_type>();
|
2017-09-08 10:41:02 +02:00
|
|
|
}
|
|
|
|
|
2019-08-15 07:54:53 +02:00
|
|
|
} // namespace json
|
|
|
|
} // namespace ircd
|
|
|
|
|
|
|
|
#include "_key_transform.h"
|
|
|
|
#include "keys.h"
|
|
|
|
#include "_member_transform.h"
|
|
|
|
#include "tool.h"
|
|
|
|
|
2017-10-16 06:22:52 +02:00
|
|
|
template<class... T>
|
2020-08-05 00:50:04 +02:00
|
|
|
inline ircd::json::tuple<T...>::operator
|
2017-10-16 06:22:52 +02:00
|
|
|
crh::sha256::buf()
|
|
|
|
const
|
|
|
|
{
|
|
|
|
//TODO: XXX
|
|
|
|
const auto preimage
|
|
|
|
{
|
|
|
|
json::strung(*this)
|
|
|
|
};
|
|
|
|
|
|
|
|
return crh::sha256::buf
|
|
|
|
{
|
2020-10-29 08:08:06 +01:00
|
|
|
[&preimage](auto&& buf)
|
2017-10-16 06:22:52 +02:00
|
|
|
{
|
2018-02-03 08:20:26 +01:00
|
|
|
sha256{buf, const_buffer{preimage}};
|
2017-10-16 06:22:52 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-09-19 11:09:19 +02:00
|
|
|
template<class... T>
|
2020-08-05 00:50:04 +02:00
|
|
|
inline ircd::json::tuple<T...>::operator
|
2017-09-19 11:09:19 +02:00
|
|
|
json::value()
|
|
|
|
const
|
|
|
|
{
|
|
|
|
json::value ret;
|
|
|
|
ret.type = OBJECT;
|
|
|
|
ret.create_string(serialized(*this), [this]
|
|
|
|
(mutable_buffer buffer)
|
|
|
|
{
|
|
|
|
stringify(buffer, *this);
|
|
|
|
});
|
|
|
|
|
2018-11-14 09:58:19 +01:00
|
|
|
return ret;
|
2017-09-19 11:09:19 +02:00
|
|
|
}
|