0
0
Fork 0
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:
Jason Volk 2019-08-14 22:54:53 -07:00
parent 08120bb194
commit 7fb0958080
6 changed files with 188 additions and 116 deletions

View 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

View file

@ -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

View file

@ -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

View file

@ -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_))

View file

@ -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]

View file

@ -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