0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-24 12:58:21 +02:00

ircd::json::tuple: Remove until(); refactor templates w/ if constexpr.

This commit is contained in:
Jason Volk 2022-06-26 15:29:21 -07:00
parent 3a4b5aa819
commit dcbab1999a
12 changed files with 201 additions and 309 deletions

View file

@ -58,7 +58,6 @@ namespace ircd
using json::operator<<;
using json::defined;
using json::for_each;
using json::until;
using json::get;
}

View file

@ -24,7 +24,7 @@ _member_transform_if(const tuple<T...> &tuple,
const it_b end,
closure&& lambda)
{
until(tuple, [&it, &end, &lambda]
for_each(tuple, [&it, &end, &lambda]
(const auto &key, auto&& val)
{
if(it == end)

View file

@ -78,52 +78,46 @@ at(tuple &t)
return at<name_hash(name), tuple>(t);
}
template<class tuple,
class function,
size_t i>
constexpr typename std::enable_if<i == size<tuple>(), void>::type
at(tuple &t,
const string_view &name,
function&& f)
noexcept
{}
template<class tuple,
class function,
size_t i = 0>
inline typename std::enable_if<i < size<tuple>(), void>::type
inline enable_if_tuple<tuple, void>
at(tuple &t,
const string_view &name,
function&& f)
{
if(indexof<tuple>(name) == i)
return f(val<i>(t));
at<tuple, function, i + 1>(t, name, std::forward<function>(f));
if constexpr(i < size<tuple>())
{
if(_constexpr_equal(name, key<tuple, i>()))
f(val<i>(t));
else
at<tuple, function, i + 1>(t, name, std::forward<function>(f));
}
else throw not_found
{
"%s", name
};
}
template<class tuple,
class function,
size_t i>
constexpr typename std::enable_if<i == size<tuple>(), void>::type
at(const tuple &t,
const string_view &name,
function&& f)
noexcept
{}
template<class tuple,
class function,
size_t i = 0>
inline typename std::enable_if<i < size<tuple>(), void>::type
inline enable_if_tuple<tuple, void>
at(const tuple &t,
const string_view &name,
function&& f)
{
if(indexof<tuple>(name) == i)
return f(val<i>(t));
at<tuple, function, i + 1>(t, name, std::forward<function>(f));
if constexpr(i < size<tuple>())
{
if(_constexpr_equal(name, key<tuple, i>()))
f(val<i>(t));
else
at<tuple, function, i + 1>(t, name, std::forward<function>(f));
}
else throw not_found
{
"%s", name
};
}
template<class R,
@ -133,9 +127,7 @@ at(const tuple &t,
const string_view &name)
{
const R *ret;
at(t, name, [&ret]
(auto&& val)
noexcept
at(t, name, [&ret](auto&& val) noexcept
{
//XXX is_pointer_interconvertible_base_of? (C++20)
if constexpr(std::is_assignable<R, decltype(val)>())

View file

@ -14,44 +14,66 @@
namespace ircd {
namespace json {
template<size_t i,
class tuple,
class function>
constexpr typename std::enable_if<i == size<tuple>(), void>::type
for_each(const tuple &t,
function&& f)
noexcept
{}
template<size_t i,
class tuple,
class function>
constexpr typename std::enable_if<i == size<tuple>(), void>::type
for_each(tuple &t,
function&& f)
noexcept
{}
template<size_t i = 0,
class tuple,
class function>
inline typename std::enable_if<i < size<tuple>(), void>::type
inline enable_if_tuple<tuple, bool>
for_each(const tuple &t,
function&& f)
{
f(key<i>(t), val<i>(t));
for_each<i + 1>(t, std::forward<function>(f));
if constexpr(i < size<tuple>())
{
using closure_result = std::invoke_result_t
<
decltype(f), decltype(key<i>(t)), decltype(val<i>(t))
>;
constexpr bool terminable
{
std::is_same<closure_result, bool>()
};
if constexpr(terminable)
{
if(!f(key<i>(t), val<i>(t)))
return false;
}
else f(key<i>(t), val<i>(t));
return for_each<i + 1>(t, std::forward<function>(f));
}
else return true;
}
template<size_t i = 0,
class tuple,
class function>
inline typename std::enable_if<i < size<tuple>(), void>::type
inline enable_if_tuple<tuple, bool>
for_each(tuple &t,
function&& f)
{
f(key<i>(t), val<i>(t));
for_each<i + 1>(t, std::forward<function>(f));
if constexpr(i < size<tuple>())
{
using closure_result = std::invoke_result_t
<
decltype(f), decltype(key<i>(t)), decltype(val<i>(t))
>;
constexpr bool terminable
{
std::is_same<closure_result, bool>()
};
if constexpr(terminable)
{
if(!f(key<i>(t), val<i>(t)))
return false;
}
else f(key<i>(t), val<i>(t));
return for_each<i + 1>(t, std::forward<function>(f));
}
else return true;
}
template<class tuple,
@ -90,45 +112,5 @@ for_each(tuple &t,
});
}
template<class tuple,
class function,
ssize_t i>
constexpr typename std::enable_if<(i < 0), void>::type
rfor_each(const tuple &t,
function&& f)
noexcept
{}
template<class tuple,
class function,
ssize_t i>
constexpr typename std::enable_if<(i < 0), void>::type
rfor_each(tuple &t,
function&& f)
noexcept
{}
template<class tuple,
class function,
ssize_t i = size<tuple>() - 1>
inline typename std::enable_if<i < tuple_size<tuple>(), void>::type
rfor_each(const tuple &t,
function&& f)
{
f(key<i>(t), val<i>(t));
rfor_each<tuple, function, i - 1>(t, std::forward<function>(f));
}
template<class tuple,
class function,
ssize_t i = size<tuple>() - 1>
inline typename std::enable_if<i < tuple_size<tuple>(), void>::type
rfor_each(tuple &t,
function&& f)
{
f(key<i>(t), val<i>(t));
rfor_each<tuple, function, i - 1>(t, std::forward<function>(f));
}
} // namespace json
} // namespace ircd

View file

@ -25,6 +25,11 @@ noexcept
indexof<tuple, hash>()
};
static_assert
(
idx < size<tuple>(), "out of range"
);
const auto &ret
{
val<idx>(t)
@ -45,6 +50,11 @@ noexcept
indexof<tuple, hash>()
};
static_assert
(
idx < size<tuple>(), "out of range"
);
const auto &ret
{
val<idx>(t)
@ -64,6 +74,11 @@ noexcept
indexof<tuple, hash>()
};
static_assert
(
idx < size<tuple>(), "out of range"
);
auto &ret
{
val<idx>(t)
@ -133,7 +148,7 @@ get(const tuple &t,
R ret)
noexcept
{
until(t, [&name, &ret]
for_each(t, [&name, &ret]
(const auto &key, auto&& val)
noexcept
{

View file

@ -14,91 +14,62 @@
namespace ircd {
namespace json {
template<class tuple,
size_t hash,
size_t i>
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
indexof()
noexcept
{
return size<tuple>();
}
template<class tuple,
size_t hash,
size_t i = 0>
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
constexpr enable_if_tuple<tuple, size_t>
indexof()
noexcept
{
if constexpr(name_hash(key<tuple, i>()) == hash)
return i;
if constexpr(i < size<tuple>())
if constexpr(name_hash(key<tuple, i>()) != hash)
return indexof<tuple, hash, i + 1>();
return indexof<tuple, hash, i + 1>();
}
template<class tuple,
const char *const &name,
size_t i>
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
indexof()
noexcept
{
return size<tuple>();
return i;
}
template<class tuple,
const char *const &name,
size_t i = 0>
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
constexpr enable_if_tuple<tuple, size_t>
indexof()
noexcept
{
return indexof<tuple, name_hash(name)>();
}
template<class tuple,
size_t i,
size_t N>
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
indexof(const char (&name)[N])
noexcept
{
return size<tuple>();
}
template<class tuple,
size_t i = 0,
size_t N>
inline constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
inline enable_if_tuple<tuple, size_t>
indexof(const char (&name)[N])
noexcept
{
if(_constexpr_equal(key<tuple, i>(), name))
return i;
if constexpr(i < size<tuple>())
if(!_constexpr_equal(key<tuple, i>(), name))
return indexof<tuple, i + 1>(name);
return indexof<tuple, i + 1>(name);
}
template<class tuple,
size_t i>
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
indexof(const string_view &name)
noexcept
{
return size<tuple>();
return i;
}
template<class tuple,
size_t i = 0>
inline constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
inline enable_if_tuple<tuple, size_t>
indexof(const string_view &name)
noexcept
{
if(name == key<tuple, i>())
return i;
if constexpr(i < size<tuple>())
{
constexpr string_view key_name
{
key<tuple, i>()
};
return indexof<tuple, i + 1>(name);
if(!_constexpr_equal(name, key_name))
return indexof<tuple, i + 1>(name);
}
return i;
}
} // namespace json

View file

@ -39,8 +39,7 @@ template<class T>
struct ircd::json::keys<T>::selection
:std::bitset<T::size()>
{
template<class closure> constexpr bool until(closure&&) const;
template<class closure> constexpr void for_each(closure&&) const;
template<class closure> constexpr bool for_each(closure&&) const;
template<class it> constexpr it transform(it, const it end) const;
bool has(const string_view &) const;
void set(const string_view &, const bool & = true);
@ -129,7 +128,7 @@ ircd::json::keys<T>::selection::transform(it i,
const it end)
const
{
this->until([&i, &end](auto&& key)
this->for_each([&i, &end](auto&& key)
{
if(i == end)
return false;
@ -142,23 +141,10 @@ const
return i;
}
template<class T>
template<class closure>
inline constexpr void
ircd::json::keys<T>::selection::for_each(closure&& function)
const
{
this->until([&function](auto&& key)
{
function(key);
return true;
});
}
template<class T>
template<class closure>
inline constexpr bool
ircd::json::keys<T>::selection::until(closure&& function)
ircd::json::keys<T>::selection::for_each(closure&& function)
const
{
for(size_t i(0); i < T::size(); ++i)

View file

@ -0,0 +1,80 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2022 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_RFOR_EACH_H
namespace ircd {
namespace json {
template<class tuple,
class function,
ssize_t i = size<tuple>() - 1>
inline enable_if_tuple<tuple, bool>
rfor_each(const tuple &t,
function&& f)
{
if constexpr(i >= 0)
{
using closure_result = std::invoke_result_t
<
decltype(f), decltype(key<i>(t)), decltype(val<i>(t))
>;
constexpr bool terminable
{
std::is_same<closure_result, bool>()
};
if constexpr(terminable)
{
if(!f(key<i>(t), val<i>(t)))
return false;
}
else f(key<i>(t), val<i>(t));
return rfor_each<tuple, function, i - 1>(t, std::forward<function>(f));
}
else return true;
}
template<class tuple,
class function,
ssize_t i = size<tuple>() - 1>
inline enable_if_tuple<tuple, bool>
rfor_each(tuple &t,
function&& f)
{
if constexpr(i >= 0)
{
using closure_result = std::invoke_result_t
<
decltype(f), decltype(key<i>(t)), decltype(val<i>(t))
>;
constexpr bool terminable
{
std::is_same<closure_result, bool>()
};
if constexpr(terminable)
{
if(!f(key<i>(t), val<i>(t)))
return false;
}
else f(key<i>(t), val<i>(t));
return rfor_each<tuple, function, i - 1>(t, std::forward<function>(f));
}
else return true;
}
} // namespace json
} // namespace ircd

View file

@ -211,7 +211,7 @@ has_key(const tuple &t,
} // namespace ircd
#include "for_each.h"
#include "until.h"
#include "rfor_each.h"
#include "get.h"
#include "at.h"
#include "set.h"
@ -243,7 +243,8 @@ tuple<T...>::tuple(const json::object &object)
}
{
for(const auto &[key, val] : object)
set(*this, key, val);
if(has_key(*this, key))
set(*this, key, val);
}
template<class... T>
@ -292,7 +293,8 @@ tuple<T...>::tuple(const tuple<U...> &t)
for_each(t, [this]
(const auto &key, const auto &val)
{
set(*this, key, val);
if(has_key(*this, key))
set(*this, key, val);
});
}

View file

@ -1,135 +0,0 @@
// 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.
#pragma once
#define HAVE_IRCD_JSON_TUPLE_UNTIL_H
namespace ircd {
namespace json {
template<size_t i,
class tuple,
class function>
constexpr typename std::enable_if<i == size<tuple>(), bool>::type
until(const tuple &t,
function&& f)
noexcept
{
return true;
}
template<size_t i,
class tuple,
class function>
constexpr typename std::enable_if<i == size<tuple>(), bool>::type
until(tuple &t,
function&& f)
noexcept
{
return true;
}
template<size_t i = 0,
class tuple,
class function>
inline typename std::enable_if<i < size<tuple>(), bool>::type
until(const tuple &t,
function&& f)
{
return f(key<i>(t), val<i>(t))?
until<i + 1>(t, std::forward<function>(f)):
false;
}
template<size_t i = 0,
class tuple,
class function>
inline typename std::enable_if<i < size<tuple>(), bool>::type
until(tuple &t,
function&& f)
{
return f(key<i>(t), val<i>(t))?
until<i + 1>(t, std::forward<function>(f)):
false;
}
template<size_t i,
class tuple,
class function>
constexpr typename std::enable_if<i == size<tuple>(), bool>::type
until(const tuple &a,
const tuple &b,
function&& f)
noexcept
{
return true;
}
template<size_t i = 0,
class tuple,
class function>
inline typename std::enable_if<i < size<tuple>(), bool>::type
until(const tuple &a,
const tuple &b,
function&& f)
{
return f(key<i>(a), val<i>(a), val<i>(b))?
until<i + 1>(a, b, std::forward<function>(f)):
false;
}
template<class tuple,
class function,
ssize_t i>
constexpr typename std::enable_if<(i < 0), bool>::type
runtil(const tuple &t,
function&& f)
noexcept
{
return true;
}
template<class tuple,
class function,
ssize_t i>
constexpr typename std::enable_if<(i < 0), bool>::type
runtil(tuple &t,
function&& f)
noexcept
{
return true;
}
template<class tuple,
class function,
ssize_t i = size<tuple>() - 1>
inline typename std::enable_if<i < size<tuple>(), bool>::type
runtil(const tuple &t,
function&& f)
{
return f(key<i>(t), val<i>(t))?
runtil<tuple, function, i - 1>(t, std::forward<function>(f)):
false;
}
template<class tuple,
class function,
ssize_t i = size<tuple>() - 1>
inline typename std::enable_if<i < size<tuple>(), bool>::type
runtil(tuple &t,
function&& f)
{
return f(key<i>(t), val<i>(t))?
runtil<tuple, function, i - 1>(t, std::forward<function>(f)):
false;
}
} // namespace json
} // namespace ircd

View file

@ -12,7 +12,7 @@ bool
ircd::m::for_each(const event::auth &auth,
const event::id::closure_bool &closure)
{
return json::until(auth, [&closure]
return json::for_each(auth, [&closure]
(const auto &key, const json::array &prevs)
{
for(const string_view &prev_ : prevs)

View file

@ -12,7 +12,7 @@ bool
ircd::m::for_each(const event::prev &prev,
const event::id::closure_bool &closure)
{
return json::until(prev, [&closure]
return json::for_each(prev, [&closure]
(const auto &key, const json::array &prevs)
{
for(const string_view &prev_ : prevs)