mirror of
https://github.com/matrix-construct/construct
synced 2024-06-02 10:08:56 +02:00
ircd::json::tuple: Split additional non-member templates into header; constexpr member get()/at().
This commit is contained in:
parent
08120bb194
commit
7fb0958080
116
include/ircd/json/tuple/tool.h
Normal file
116
include/ircd/json/tuple/tool.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 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.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_JSON_TUPLE_TOOL_H
|
||||
|
||||
namespace ircd {
|
||||
namespace json {
|
||||
|
||||
template<class... T>
|
||||
size_t
|
||||
serialized(const tuple<T...> &t)
|
||||
{
|
||||
constexpr const size_t member_count
|
||||
{
|
||||
tuple<T...>::size()
|
||||
};
|
||||
|
||||
std::array<size_t, member_count> sizes {0};
|
||||
const auto e{_member_transform_if(t, begin(sizes), end(sizes), []
|
||||
(auto &ret, const string_view &key, auto&& val)
|
||||
{
|
||||
const json::value value(val);
|
||||
if(!defined(value))
|
||||
return false;
|
||||
|
||||
ret = 1 + key.size() + 1 + 1 + serialized(value) + 1;
|
||||
return true;
|
||||
})};
|
||||
|
||||
// Subtract one to get the final size when an extra comma is
|
||||
// accumulated on non-empty objects.
|
||||
const auto overhead
|
||||
{
|
||||
1 + std::all_of(begin(sizes), e, is_zero{})
|
||||
};
|
||||
|
||||
return std::accumulate(begin(sizes), e, size_t(overhead));
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
size_t
|
||||
serialized(const tuple<T...> *const &b,
|
||||
const tuple<T...> *const &e)
|
||||
{
|
||||
size_t ret(1 + (b == e));
|
||||
return std::accumulate(b, e, ret, []
|
||||
(size_t ret, const tuple<T...> &t)
|
||||
{
|
||||
return ret += serialized(t) + 1;
|
||||
});
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
string_view
|
||||
stringify(mutable_buffer &buf,
|
||||
const tuple<T...> &tuple)
|
||||
{
|
||||
static constexpr const size_t member_count
|
||||
{
|
||||
json::tuple_size<json::tuple<T...>>()
|
||||
};
|
||||
|
||||
std::array<member, member_count> members;
|
||||
const auto e{_member_transform_if(tuple, begin(members), end(members), []
|
||||
(auto &ret, const string_view &key, auto&& val)
|
||||
{
|
||||
json::value value(val);
|
||||
if(!defined(value))
|
||||
return false;
|
||||
|
||||
ret = member { key, std::move(value) };
|
||||
return true;
|
||||
})};
|
||||
|
||||
return stringify(buf, begin(members), e);
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
string_view
|
||||
stringify(mutable_buffer &buf,
|
||||
const tuple<T...> *b,
|
||||
const tuple<T...> *e)
|
||||
{
|
||||
const auto start(begin(buf));
|
||||
consume(buf, copy(buf, "["_sv));
|
||||
if(b != e)
|
||||
{
|
||||
stringify(buf, *b);
|
||||
for(++b; b != e; ++b)
|
||||
{
|
||||
consume(buf, copy(buf, ","_sv));
|
||||
stringify(buf, *b);
|
||||
}
|
||||
}
|
||||
consume(buf, copy(buf, "]"_sv));
|
||||
return { start, begin(buf) };
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
std::ostream &
|
||||
operator<<(std::ostream &s, const tuple<T...> &t)
|
||||
{
|
||||
s << json::strung(t);
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
} // namespace ircd
|
|
@ -62,6 +62,11 @@ struct tuple
|
|||
operator json::value() const;
|
||||
operator crh::sha256::buf() const;
|
||||
|
||||
template<class name> constexpr decltype(auto) get(name&&) const;
|
||||
template<class name> constexpr decltype(auto) get(name&&);
|
||||
template<class name> constexpr decltype(auto) at(name&&) const;
|
||||
template<class name> constexpr decltype(auto) at(name&&);
|
||||
|
||||
template<class... U> explicit tuple(const tuple<U...> &);
|
||||
template<class U> explicit tuple(const json::object &, const json::keys<U> &);
|
||||
template<class U> explicit tuple(const tuple &, const json::keys<U> &);
|
||||
|
@ -233,6 +238,60 @@ tuple<T...>::tuple(const tuple<U...> &t)
|
|||
});
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
template<class name>
|
||||
constexpr decltype(auto)
|
||||
tuple<T...>::at(name&& n)
|
||||
{
|
||||
constexpr const size_t hash
|
||||
{
|
||||
name_hash(n)
|
||||
};
|
||||
|
||||
return json::at<hash>(*this);
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
template<class name>
|
||||
constexpr decltype(auto)
|
||||
tuple<T...>::at(name&& n)
|
||||
const
|
||||
{
|
||||
constexpr const size_t hash
|
||||
{
|
||||
name_hash(n)
|
||||
};
|
||||
|
||||
return json::at<hash>(*this);
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
template<class name>
|
||||
constexpr decltype(auto)
|
||||
tuple<T...>::get(name&& n)
|
||||
{
|
||||
constexpr const size_t hash
|
||||
{
|
||||
name_hash(n)
|
||||
};
|
||||
|
||||
return json::get<hash>(*this);
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
template<class name>
|
||||
constexpr decltype(auto)
|
||||
tuple<T...>::get(name&& n)
|
||||
const
|
||||
{
|
||||
constexpr const size_t hash
|
||||
{
|
||||
name_hash(n)
|
||||
};
|
||||
|
||||
return json::get<hash>(*this);
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
constexpr size_t
|
||||
tuple<T...>::size()
|
||||
|
@ -246,110 +305,10 @@ tuple<T...>::size()
|
|||
#include "_key_transform.h"
|
||||
#include "keys.h"
|
||||
#include "_member_transform.h"
|
||||
|
||||
namespace ircd {
|
||||
namespace json {
|
||||
#include "tool.h"
|
||||
|
||||
template<class... T>
|
||||
size_t
|
||||
serialized(const tuple<T...> &t)
|
||||
{
|
||||
constexpr const size_t member_count
|
||||
{
|
||||
tuple<T...>::size()
|
||||
};
|
||||
|
||||
std::array<size_t, member_count> sizes {0};
|
||||
const auto e{_member_transform_if(t, begin(sizes), end(sizes), []
|
||||
(auto &ret, const string_view &key, auto&& val)
|
||||
{
|
||||
const json::value value(val);
|
||||
if(!defined(value))
|
||||
return false;
|
||||
|
||||
ret = 1 + key.size() + 1 + 1 + serialized(value) + 1;
|
||||
return true;
|
||||
})};
|
||||
|
||||
// Subtract one to get the final size when an extra comma is
|
||||
// accumulated on non-empty objects.
|
||||
const auto overhead
|
||||
{
|
||||
1 + std::all_of(begin(sizes), e, is_zero{})
|
||||
};
|
||||
|
||||
return std::accumulate(begin(sizes), e, size_t(overhead));
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
size_t
|
||||
serialized(const tuple<T...> *const &b,
|
||||
const tuple<T...> *const &e)
|
||||
{
|
||||
size_t ret(1 + (b == e));
|
||||
return std::accumulate(b, e, ret, []
|
||||
(size_t ret, const tuple<T...> &t)
|
||||
{
|
||||
return ret += serialized(t) + 1;
|
||||
});
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
string_view
|
||||
stringify(mutable_buffer &buf,
|
||||
const tuple<T...> &tuple)
|
||||
{
|
||||
static constexpr const size_t member_count
|
||||
{
|
||||
json::tuple_size<json::tuple<T...>>()
|
||||
};
|
||||
|
||||
std::array<member, member_count> members;
|
||||
const auto e{_member_transform_if(tuple, begin(members), end(members), []
|
||||
(auto &ret, const string_view &key, auto&& val)
|
||||
{
|
||||
json::value value(val);
|
||||
if(!defined(value))
|
||||
return false;
|
||||
|
||||
ret = member { key, std::move(value) };
|
||||
return true;
|
||||
})};
|
||||
|
||||
return stringify(buf, begin(members), e);
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
string_view
|
||||
stringify(mutable_buffer &buf,
|
||||
const tuple<T...> *b,
|
||||
const tuple<T...> *e)
|
||||
{
|
||||
const auto start(begin(buf));
|
||||
consume(buf, copy(buf, "["_sv));
|
||||
if(b != e)
|
||||
{
|
||||
stringify(buf, *b);
|
||||
for(++b; b != e; ++b)
|
||||
{
|
||||
consume(buf, copy(buf, ","_sv));
|
||||
stringify(buf, *b);
|
||||
}
|
||||
}
|
||||
consume(buf, copy(buf, "]"_sv));
|
||||
return { start, begin(buf) };
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
std::ostream &
|
||||
operator<<(std::ostream &s, const tuple<T...> &t)
|
||||
{
|
||||
s << json::strung(t);
|
||||
return s;
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
tuple<T...>::operator
|
||||
ircd::json::tuple<T...>::operator
|
||||
crh::sha256::buf()
|
||||
const
|
||||
{
|
||||
|
@ -369,7 +328,7 @@ const
|
|||
}
|
||||
|
||||
template<class... T>
|
||||
tuple<T...>::operator
|
||||
ircd::json::tuple<T...>::operator
|
||||
json::value()
|
||||
const
|
||||
{
|
||||
|
@ -383,6 +342,3 @@ const
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
} // namespace ircd
|
||||
|
|
12
ircd/m.cc
12
ircd/m.cc
|
@ -3162,7 +3162,7 @@ const
|
|||
};
|
||||
|
||||
thread_local char x_matrix[2_KiB];
|
||||
if(startswith(at<"uri"_>(*this), "/_matrix/federation"))
|
||||
if(startswith(json::at<"uri"_>(*this), "/_matrix/federation"))
|
||||
{
|
||||
const auto &sk{self::secret_key};
|
||||
const auto &pkid{self::public_key_id};
|
||||
|
@ -3191,9 +3191,9 @@ const
|
|||
http::request
|
||||
{
|
||||
sb,
|
||||
at<"destination"_>(*this),
|
||||
at<"method"_>(*this),
|
||||
at<"uri"_>(*this),
|
||||
json::at<"destination"_>(*this),
|
||||
json::at<"method"_>(*this),
|
||||
json::at<"uri"_>(*this),
|
||||
content_length,
|
||||
content_type,
|
||||
{ header, headers }
|
||||
|
@ -3241,7 +3241,7 @@ const
|
|||
|
||||
const auto &origin
|
||||
{
|
||||
unquote(string_view{at<"origin"_>(*this)})
|
||||
unquote(string_view{json::at<"origin"_>(*this)})
|
||||
};
|
||||
|
||||
thread_local char sigb64[1_KiB];
|
||||
|
@ -3269,7 +3269,7 @@ const
|
|||
|
||||
const json::string &origin
|
||||
{
|
||||
at<"origin"_>(*this)
|
||||
json::at<"origin"_>(*this)
|
||||
};
|
||||
|
||||
const m::node node
|
||||
|
|
|
@ -2608,7 +2608,7 @@ const
|
|||
{
|
||||
const string_view &prev_
|
||||
{
|
||||
at<"auth_events"_>(*this).at(idx)
|
||||
json::at<"auth_events"_>(*this).at(idx)
|
||||
};
|
||||
|
||||
switch(json::type(prev_))
|
||||
|
@ -2641,7 +2641,7 @@ const
|
|||
{
|
||||
const string_view &prev_
|
||||
{
|
||||
at<"prev_events"_>(*this).at(idx)
|
||||
json::at<"prev_events"_>(*this).at(idx)
|
||||
};
|
||||
|
||||
switch(json::type(prev_))
|
||||
|
|
|
@ -67,7 +67,7 @@ ircd::m::device::set(const m::user &user,
|
|||
const user::room user_room{user};
|
||||
const string_view &device_id
|
||||
{
|
||||
at<"device_id"_>(device)
|
||||
json::at<"device_id"_>(device)
|
||||
};
|
||||
|
||||
json::for_each(device, [&user, &user_room, &device_id]
|
||||
|
|
|
@ -259,7 +259,7 @@ ircd::m::presence::set(const m::presence &content)
|
|||
{
|
||||
const m::user user
|
||||
{
|
||||
at<"user_id"_>(content)
|
||||
json::at<"user_id"_>(content)
|
||||
};
|
||||
|
||||
//TODO: ABA
|
||||
|
|
Loading…
Reference in a new issue