mirror of
https://github.com/matrix-construct/construct
synced 2024-10-04 06:38:58 +02:00
ircd::json: Preliminary rough splitup of tuple headers.
This commit is contained in:
parent
456f8e7ac1
commit
671622d778
8 changed files with 915 additions and 761 deletions
132
include/ircd/json/tuple/at.h
Normal file
132
include/ircd/json/tuple/at.h
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
// 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_AT_H
|
||||||
|
|
||||||
|
namespace ircd {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
template<size_t hash,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
||||||
|
at(const tuple &t)
|
||||||
|
{
|
||||||
|
constexpr size_t idx
|
||||||
|
{
|
||||||
|
indexof<tuple, hash>()
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto &ret
|
||||||
|
{
|
||||||
|
val<idx>(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
using value_type = tuple_value_type<tuple, idx>;
|
||||||
|
if(!defined(json::value(ret)))
|
||||||
|
throw not_found
|
||||||
|
{
|
||||||
|
"%s", key<idx>(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t hash,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
||||||
|
at(tuple &t)
|
||||||
|
{
|
||||||
|
constexpr size_t idx
|
||||||
|
{
|
||||||
|
indexof<tuple, hash>()
|
||||||
|
};
|
||||||
|
|
||||||
|
auto &ret
|
||||||
|
{
|
||||||
|
val<idx>(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
using value_type = tuple_value_type<tuple, idx>;
|
||||||
|
if(!defined(json::value(ret)))
|
||||||
|
throw not_found
|
||||||
|
{
|
||||||
|
"%s", key<idx>(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<const char *const &name,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple, name>()> &>
|
||||||
|
at(const tuple &t)
|
||||||
|
{
|
||||||
|
return at<name_hash(name), tuple>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<const char *const &name,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, name>()> &>
|
||||||
|
at(tuple &t)
|
||||||
|
{
|
||||||
|
return at<name_hash(name), tuple>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
size_t i>
|
||||||
|
typename std::enable_if<i == size<tuple>(), void>::type
|
||||||
|
at(tuple &t,
|
||||||
|
const string_view &name,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
size_t i = 0>
|
||||||
|
typename std::enable_if<i < size<tuple>(), void>::type
|
||||||
|
at(tuple &t,
|
||||||
|
const string_view &name,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
if(indexof<tuple>(name) == i)
|
||||||
|
f(val<i>(t));
|
||||||
|
else
|
||||||
|
at<tuple, function, i + 1>(t, name, std::forward<function>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
size_t i>
|
||||||
|
typename std::enable_if<i == size<tuple>(), void>::type
|
||||||
|
at(const tuple &t,
|
||||||
|
const string_view &name,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
size_t i = 0>
|
||||||
|
typename std::enable_if<i < size<tuple>(), void>::type
|
||||||
|
at(const tuple &t,
|
||||||
|
const string_view &name,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
if(indexof<tuple>(name) == i)
|
||||||
|
f(val<i>(t));
|
||||||
|
else
|
||||||
|
at<tuple, function, i + 1>(t, name, std::forward<function>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace ircd
|
130
include/ircd/json/tuple/for_each.h
Normal file
130
include/ircd/json/tuple/for_each.h
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
// 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_FOR_EACH_H
|
||||||
|
|
||||||
|
namespace ircd {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
template<size_t i,
|
||||||
|
class tuple,
|
||||||
|
class function>
|
||||||
|
typename std::enable_if<i == size<tuple>(), void>::type
|
||||||
|
for_each(const tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<size_t i,
|
||||||
|
class tuple,
|
||||||
|
class function>
|
||||||
|
typename std::enable_if<i == size<tuple>(), void>::type
|
||||||
|
for_each(tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<size_t i = 0,
|
||||||
|
class tuple,
|
||||||
|
class function>
|
||||||
|
typename std::enable_if<i < size<tuple>(), void>::type
|
||||||
|
for_each(const tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
f(key<i>(t), val<i>(t));
|
||||||
|
for_each<i + 1>(t, std::forward<function>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t i = 0,
|
||||||
|
class tuple,
|
||||||
|
class function>
|
||||||
|
typename std::enable_if<i < size<tuple>(), void>::type
|
||||||
|
for_each(tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
f(key<i>(t), val<i>(t));
|
||||||
|
for_each<i + 1>(t, std::forward<function>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function>
|
||||||
|
void
|
||||||
|
for_each(const tuple &t,
|
||||||
|
const vector_view<const string_view> &mask,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
std::for_each(std::begin(mask), std::end(mask), [&t, &f]
|
||||||
|
(const auto &key)
|
||||||
|
{
|
||||||
|
at(t, key, [&f, &key]
|
||||||
|
(auto&& val)
|
||||||
|
{
|
||||||
|
f(key, val);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function>
|
||||||
|
void
|
||||||
|
for_each(tuple &t,
|
||||||
|
const vector_view<const string_view> &mask,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
std::for_each(std::begin(mask), std::end(mask), [&t, &f]
|
||||||
|
(const auto &key)
|
||||||
|
{
|
||||||
|
at(t, key, [&f, &key]
|
||||||
|
(auto&& val)
|
||||||
|
{
|
||||||
|
f(key, val);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
ssize_t i>
|
||||||
|
typename std::enable_if<(i < 0), void>::type
|
||||||
|
rfor_each(const tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
ssize_t i>
|
||||||
|
typename std::enable_if<(i < 0), void>::type
|
||||||
|
rfor_each(tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
ssize_t i = size<tuple>() - 1>
|
||||||
|
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>
|
||||||
|
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
|
123
include/ircd/json/tuple/get.h
Normal file
123
include/ircd/json/tuple/get.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
// 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_GET_H
|
||||||
|
|
||||||
|
namespace ircd {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
template<size_t hash,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
||||||
|
get(const tuple &t)
|
||||||
|
{
|
||||||
|
constexpr size_t idx
|
||||||
|
{
|
||||||
|
indexof<tuple, hash>()
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto &ret
|
||||||
|
{
|
||||||
|
val<idx>(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t hash,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, hash>()>>
|
||||||
|
get(const tuple &t,
|
||||||
|
const tuple_value_type<tuple, indexof<tuple, hash>()> &def)
|
||||||
|
{
|
||||||
|
constexpr size_t idx
|
||||||
|
{
|
||||||
|
indexof<tuple, hash>()
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto &ret
|
||||||
|
{
|
||||||
|
val<idx>(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
using value_type = tuple_value_type<tuple, idx>;
|
||||||
|
return defined(json::value(ret))? ret : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t hash,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
||||||
|
get(tuple &t)
|
||||||
|
{
|
||||||
|
constexpr size_t idx
|
||||||
|
{
|
||||||
|
indexof<tuple, hash>()
|
||||||
|
};
|
||||||
|
|
||||||
|
auto &ret
|
||||||
|
{
|
||||||
|
val<idx>(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t hash,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
||||||
|
get(tuple &t,
|
||||||
|
tuple_value_type<tuple, indexof<tuple, hash>()> &def)
|
||||||
|
{
|
||||||
|
auto &ret
|
||||||
|
{
|
||||||
|
get<hash, tuple>(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
using value_type = decltype(ret);
|
||||||
|
return defined(json::value(ret))? ret : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<const char *const &name,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple, name>()> &>
|
||||||
|
get(const tuple &t)
|
||||||
|
{
|
||||||
|
return get<name_hash(name), tuple>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<const char *const &name,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, name>()>>
|
||||||
|
get(const tuple &t,
|
||||||
|
const tuple_value_type<tuple, indexof<tuple, name>()> &def)
|
||||||
|
{
|
||||||
|
return get<name_hash(name), tuple>(t, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<const char *const &name,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, name>()>>
|
||||||
|
get(tuple &t)
|
||||||
|
{
|
||||||
|
return get<name_hash(name), tuple>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<const char *const &name,
|
||||||
|
class tuple>
|
||||||
|
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, name>()>>
|
||||||
|
get(tuple &t,
|
||||||
|
tuple_value_type<tuple, indexof<tuple, hash>()> &def)
|
||||||
|
{
|
||||||
|
return get<name_hash(name), tuple>(t, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace ircd
|
101
include/ircd/json/tuple/indexof.h
Normal file
101
include/ircd/json/tuple/indexof.h
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
// 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_INDEXOF_H
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
return size<tuple>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
size_t hash,
|
||||||
|
size_t i = 0>
|
||||||
|
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
||||||
|
indexof()
|
||||||
|
{
|
||||||
|
constexpr auto equal
|
||||||
|
{
|
||||||
|
ircd::hash(key<tuple, i>()) == hash
|
||||||
|
};
|
||||||
|
|
||||||
|
return equal? i : 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()
|
||||||
|
{
|
||||||
|
return size<tuple>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
const char *const &name,
|
||||||
|
size_t i = 0>
|
||||||
|
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
||||||
|
indexof()
|
||||||
|
{
|
||||||
|
return indexof<tuple, name_hash(name)>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
size_t i>
|
||||||
|
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
|
||||||
|
indexof(const char *const &name)
|
||||||
|
{
|
||||||
|
return size<tuple>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
size_t i = 0>
|
||||||
|
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
||||||
|
indexof(const char *const &name)
|
||||||
|
{
|
||||||
|
constexpr auto equal
|
||||||
|
{
|
||||||
|
_constexpr_equal(key<tuple, i>(), name)
|
||||||
|
};
|
||||||
|
|
||||||
|
return equal? i : 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)
|
||||||
|
{
|
||||||
|
return size<tuple>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
size_t i = 0>
|
||||||
|
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
||||||
|
indexof(const string_view &name)
|
||||||
|
{
|
||||||
|
const auto equal
|
||||||
|
{
|
||||||
|
name == key<tuple, i>()
|
||||||
|
};
|
||||||
|
|
||||||
|
return equal? i : indexof<tuple, i + 1>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace ircd
|
96
include/ircd/json/tuple/keys.h
Normal file
96
include/ircd/json/tuple/keys.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// 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_KEYS_H
|
||||||
|
|
||||||
|
namespace ircd {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
template<class... T>
|
||||||
|
struct tuple<T...>::keys
|
||||||
|
:std::array<string_view, tuple<T...>::size()>
|
||||||
|
{
|
||||||
|
struct selection;
|
||||||
|
struct include;
|
||||||
|
struct exclude;
|
||||||
|
|
||||||
|
constexpr keys()
|
||||||
|
{
|
||||||
|
_key_transform<tuple<T...>>(this->begin(), this->end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class... T>
|
||||||
|
struct tuple<T...>::keys::selection
|
||||||
|
:std::bitset<tuple<T...>::size()>
|
||||||
|
{
|
||||||
|
template<class closure>
|
||||||
|
constexpr bool until(closure &&function) const
|
||||||
|
{
|
||||||
|
for(size_t i(0); i < this->size(); ++i)
|
||||||
|
if(this->test(i))
|
||||||
|
if(!function(key<tuple<T...>, i>()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class closure>
|
||||||
|
constexpr void for_each(closure &&function) const
|
||||||
|
{
|
||||||
|
this->until([&function](auto&& key)
|
||||||
|
{
|
||||||
|
function(key);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class it_a,
|
||||||
|
class it_b>
|
||||||
|
constexpr auto transform(it_a it, const it_b end) const
|
||||||
|
{
|
||||||
|
this->until([&it, &end](auto&& key)
|
||||||
|
{
|
||||||
|
if(it == end)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*it = key;
|
||||||
|
++it;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class... T>
|
||||||
|
struct tuple<T...>::keys::include
|
||||||
|
:selection
|
||||||
|
{
|
||||||
|
constexpr include(const std::initializer_list<string_view> &list)
|
||||||
|
{
|
||||||
|
for(const auto &key : list)
|
||||||
|
this->set(indexof<tuple<T...>>(key), true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class... T>
|
||||||
|
struct tuple<T...>::keys::exclude
|
||||||
|
:selection
|
||||||
|
{
|
||||||
|
constexpr exclude(const std::initializer_list<string_view> &list)
|
||||||
|
{
|
||||||
|
this->set();
|
||||||
|
for(const auto &key : list)
|
||||||
|
this->set(indexof<tuple<T...>>(key), false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace ircd
|
180
include/ircd/json/tuple/set.h
Normal file
180
include/ircd/json/tuple/set.h
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
// 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_SET_H
|
||||||
|
|
||||||
|
namespace ircd {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
template<class dst,
|
||||||
|
class src>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
std::is_base_of<json::string, dst>() &&
|
||||||
|
std::is_convertible<src, ircd::string_view>(),
|
||||||
|
void>::type
|
||||||
|
_assign(dst &d,
|
||||||
|
src&& s)
|
||||||
|
{
|
||||||
|
d = unquote(string_view{std::forward<src>(s)});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class dst,
|
||||||
|
class src>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
!std::is_base_of<json::string, dst>() &&
|
||||||
|
std::is_convertible<src, dst>() &&
|
||||||
|
!ircd::json::is_tuple<dst>() &&
|
||||||
|
!std::is_same<bool, dst>(),
|
||||||
|
void>::type
|
||||||
|
_assign(dst &d,
|
||||||
|
src&& s)
|
||||||
|
{
|
||||||
|
d = std::forward<src>(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class dst,
|
||||||
|
class src>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
!std::is_base_of<json::string, dst>() &&
|
||||||
|
std::is_convertible<src, dst>() &&
|
||||||
|
!ircd::json::is_tuple<dst>() &&
|
||||||
|
std::is_same<bool, dst>(),
|
||||||
|
void>::type
|
||||||
|
_assign(dst &d,
|
||||||
|
src&& s)
|
||||||
|
{
|
||||||
|
static const is_zero test{};
|
||||||
|
d = !test(std::forward<src>(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class dst,
|
||||||
|
class src>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
std::is_arithmetic<dst>() &&
|
||||||
|
std::is_base_of<std::string_view, typename std::remove_reference<src>::type>() &&
|
||||||
|
!std::is_base_of<ircd::byte_view<ircd::string_view>, typename std::remove_reference<src>::type>(),
|
||||||
|
void>::type
|
||||||
|
_assign(dst &d,
|
||||||
|
src&& s)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d = lex_cast<dst>(std::forward<src>(s));
|
||||||
|
}
|
||||||
|
catch(const bad_lex_cast &e)
|
||||||
|
{
|
||||||
|
throw parse_error("cannot convert '%s' to '%s'",
|
||||||
|
demangle<src>(),
|
||||||
|
demangle<dst>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class dst,
|
||||||
|
class src>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
std::is_arithmetic<dst>() &&
|
||||||
|
std::is_base_of<ircd::byte_view<ircd::string_view>, typename std::remove_reference<src>::type>(),
|
||||||
|
void>::type
|
||||||
|
_assign(dst &d,
|
||||||
|
src&& s)
|
||||||
|
{
|
||||||
|
assert(!s.empty());
|
||||||
|
d = byte_view<dst>(std::forward<src>(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class dst,
|
||||||
|
class src>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
std::is_base_of<std::string_view, dst>() &&
|
||||||
|
std::is_pod<typename std::remove_reference<src>::type>(),
|
||||||
|
void>::type
|
||||||
|
_assign(dst &d,
|
||||||
|
src&& s)
|
||||||
|
{
|
||||||
|
d = byte_view<string_view>(std::forward<src>(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class dst,
|
||||||
|
class src>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
ircd::json::is_tuple<dst>(),
|
||||||
|
void>::type
|
||||||
|
_assign(dst &d,
|
||||||
|
src&& s)
|
||||||
|
{
|
||||||
|
d = dst{std::forward<src>(s)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class V,
|
||||||
|
class... T>
|
||||||
|
tuple<T...> &
|
||||||
|
set(tuple<T...> &t,
|
||||||
|
const string_view &key,
|
||||||
|
V&& val)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
at(t, key, [&key, &val]
|
||||||
|
(auto &target)
|
||||||
|
{
|
||||||
|
_assign(target, std::forward<V>(val));
|
||||||
|
});
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
throw parse_error("failed to set member '%s' (from %s): %s",
|
||||||
|
key,
|
||||||
|
demangle<V>(),
|
||||||
|
e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... T>
|
||||||
|
tuple<T...> &
|
||||||
|
set(tuple<T...> &t,
|
||||||
|
const string_view &key,
|
||||||
|
const json::value &value)
|
||||||
|
{
|
||||||
|
switch(type(value))
|
||||||
|
{
|
||||||
|
case type::STRING:
|
||||||
|
case type::LITERAL:
|
||||||
|
set(t, key, string_view{value});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case type::NUMBER:
|
||||||
|
if(value.floats)
|
||||||
|
set(t, key, value.floating);
|
||||||
|
else
|
||||||
|
set(t, key, value.integer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case type::OBJECT:
|
||||||
|
case type::ARRAY:
|
||||||
|
if(unlikely(!value.serial))
|
||||||
|
throw print_error("Type %s must be JSON to be used by tuple member '%s'",
|
||||||
|
reflect(type(value)),
|
||||||
|
key);
|
||||||
|
|
||||||
|
set(t, key, string_view{value});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace ircd
|
|
@ -134,95 +134,13 @@ key(const tuple &t)
|
||||||
return std::get<i>(t).key;
|
return std::get<i>(t).key;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class tuple,
|
} // namespace json
|
||||||
size_t hash,
|
} // namespace ircd
|
||||||
size_t i>
|
|
||||||
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
|
|
||||||
indexof()
|
|
||||||
{
|
|
||||||
return size<tuple>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
#include "indexof.h"
|
||||||
size_t hash,
|
|
||||||
size_t i = 0>
|
|
||||||
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
|
||||||
indexof()
|
|
||||||
{
|
|
||||||
constexpr auto equal
|
|
||||||
{
|
|
||||||
ircd::hash(key<tuple, i>()) == hash
|
|
||||||
};
|
|
||||||
|
|
||||||
return equal? i : indexof<tuple, hash, i + 1>();
|
namespace ircd {
|
||||||
}
|
namespace json {
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
const char *const &name,
|
|
||||||
size_t i>
|
|
||||||
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
|
|
||||||
indexof()
|
|
||||||
{
|
|
||||||
return size<tuple>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
const char *const &name,
|
|
||||||
size_t i = 0>
|
|
||||||
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
|
||||||
indexof()
|
|
||||||
{
|
|
||||||
return indexof<tuple, name_hash(name)>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
size_t i>
|
|
||||||
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
|
|
||||||
indexof(const char *const &name)
|
|
||||||
{
|
|
||||||
return size<tuple>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
size_t i = 0>
|
|
||||||
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
|
||||||
indexof(const char *const &name)
|
|
||||||
{
|
|
||||||
constexpr auto equal
|
|
||||||
{
|
|
||||||
_constexpr_equal(key<tuple, i>(), name)
|
|
||||||
};
|
|
||||||
|
|
||||||
return equal? i : 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)
|
|
||||||
{
|
|
||||||
return size<tuple>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
size_t i = 0>
|
|
||||||
constexpr typename std::enable_if<i < size<tuple>(), size_t>::type
|
|
||||||
indexof(const string_view &name)
|
|
||||||
{
|
|
||||||
const auto equal
|
|
||||||
{
|
|
||||||
name == key<tuple, i>()
|
|
||||||
};
|
|
||||||
|
|
||||||
return equal? i : indexof<tuple, i + 1>(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple>
|
|
||||||
constexpr bool
|
|
||||||
key_exists(const string_view &key)
|
|
||||||
{
|
|
||||||
return indexof<tuple>(key) < size<tuple>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t i,
|
template<size_t i,
|
||||||
class tuple>
|
class tuple>
|
||||||
|
@ -240,610 +158,24 @@ val(const tuple &t)
|
||||||
return static_cast<const tuple_value_type<tuple, i> &>(std::get<i>(t));
|
return static_cast<const tuple_value_type<tuple, i> &>(std::get<i>(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class dst,
|
template<class tuple>
|
||||||
class src>
|
constexpr bool
|
||||||
typename std::enable_if
|
key_exists(const string_view &key)
|
||||||
<
|
|
||||||
std::is_base_of<json::string, dst>() &&
|
|
||||||
std::is_convertible<src, ircd::string_view>(),
|
|
||||||
void>::type
|
|
||||||
_assign(dst &d,
|
|
||||||
src&& s)
|
|
||||||
{
|
{
|
||||||
d = unquote(string_view{std::forward<src>(s)});
|
return indexof<tuple>(key) < size<tuple>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class dst,
|
} // namespace json
|
||||||
class src>
|
} // namespace ircd
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
!std::is_base_of<json::string, dst>() &&
|
|
||||||
std::is_convertible<src, dst>() &&
|
|
||||||
!ircd::json::is_tuple<dst>() &&
|
|
||||||
!std::is_same<bool, dst>(),
|
|
||||||
void>::type
|
|
||||||
_assign(dst &d,
|
|
||||||
src&& s)
|
|
||||||
{
|
|
||||||
d = std::forward<src>(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class dst,
|
#include "get.h"
|
||||||
class src>
|
#include "at.h"
|
||||||
typename std::enable_if
|
#include "for_each.h"
|
||||||
<
|
#include "until.h"
|
||||||
!std::is_base_of<json::string, dst>() &&
|
#include "set.h"
|
||||||
std::is_convertible<src, dst>() &&
|
|
||||||
!ircd::json::is_tuple<dst>() &&
|
|
||||||
std::is_same<bool, dst>(),
|
|
||||||
void>::type
|
|
||||||
_assign(dst &d,
|
|
||||||
src&& s)
|
|
||||||
{
|
|
||||||
static const is_zero test{};
|
|
||||||
d = !test(std::forward<src>(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class dst,
|
namespace ircd {
|
||||||
class src>
|
namespace json {
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
std::is_arithmetic<dst>() &&
|
|
||||||
std::is_base_of<std::string_view, typename std::remove_reference<src>::type>() &&
|
|
||||||
!std::is_base_of<ircd::byte_view<ircd::string_view>, typename std::remove_reference<src>::type>(),
|
|
||||||
void>::type
|
|
||||||
_assign(dst &d,
|
|
||||||
src&& s)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
d = lex_cast<dst>(std::forward<src>(s));
|
|
||||||
}
|
|
||||||
catch(const bad_lex_cast &e)
|
|
||||||
{
|
|
||||||
throw parse_error("cannot convert '%s' to '%s'",
|
|
||||||
demangle<src>(),
|
|
||||||
demangle<dst>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class dst,
|
|
||||||
class src>
|
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
std::is_arithmetic<dst>() &&
|
|
||||||
std::is_base_of<ircd::byte_view<ircd::string_view>, typename std::remove_reference<src>::type>(),
|
|
||||||
void>::type
|
|
||||||
_assign(dst &d,
|
|
||||||
src&& s)
|
|
||||||
{
|
|
||||||
assert(!s.empty());
|
|
||||||
d = byte_view<dst>(std::forward<src>(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class dst,
|
|
||||||
class src>
|
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
std::is_base_of<std::string_view, dst>() &&
|
|
||||||
std::is_pod<typename std::remove_reference<src>::type>(),
|
|
||||||
void>::type
|
|
||||||
_assign(dst &d,
|
|
||||||
src&& s)
|
|
||||||
{
|
|
||||||
d = byte_view<string_view>(std::forward<src>(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class dst,
|
|
||||||
class src>
|
|
||||||
typename std::enable_if
|
|
||||||
<
|
|
||||||
ircd::json::is_tuple<dst>(),
|
|
||||||
void>::type
|
|
||||||
_assign(dst &d,
|
|
||||||
src&& s)
|
|
||||||
{
|
|
||||||
d = dst{std::forward<src>(s)};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t hash,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
|
||||||
get(const tuple &t)
|
|
||||||
{
|
|
||||||
constexpr size_t idx
|
|
||||||
{
|
|
||||||
indexof<tuple, hash>()
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto &ret
|
|
||||||
{
|
|
||||||
val<idx>(t)
|
|
||||||
};
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t hash,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, hash>()>>
|
|
||||||
get(const tuple &t,
|
|
||||||
const tuple_value_type<tuple, indexof<tuple, hash>()> &def)
|
|
||||||
{
|
|
||||||
constexpr size_t idx
|
|
||||||
{
|
|
||||||
indexof<tuple, hash>()
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto &ret
|
|
||||||
{
|
|
||||||
val<idx>(t)
|
|
||||||
};
|
|
||||||
|
|
||||||
using value_type = tuple_value_type<tuple, idx>;
|
|
||||||
return defined(json::value(ret))? ret : def;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t hash,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
|
||||||
get(tuple &t)
|
|
||||||
{
|
|
||||||
constexpr size_t idx
|
|
||||||
{
|
|
||||||
indexof<tuple, hash>()
|
|
||||||
};
|
|
||||||
|
|
||||||
auto &ret
|
|
||||||
{
|
|
||||||
val<idx>(t)
|
|
||||||
};
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t hash,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
|
||||||
get(tuple &t,
|
|
||||||
tuple_value_type<tuple, indexof<tuple, hash>()> &def)
|
|
||||||
{
|
|
||||||
auto &ret
|
|
||||||
{
|
|
||||||
get<hash, tuple>(t)
|
|
||||||
};
|
|
||||||
|
|
||||||
using value_type = decltype(ret);
|
|
||||||
return defined(json::value(ret))? ret : def;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<const char *const &name,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple, name>()> &>
|
|
||||||
get(const tuple &t)
|
|
||||||
{
|
|
||||||
return get<name_hash(name), tuple>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<const char *const &name,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, name>()>>
|
|
||||||
get(const tuple &t,
|
|
||||||
const tuple_value_type<tuple, indexof<tuple, name>()> &def)
|
|
||||||
{
|
|
||||||
return get<name_hash(name), tuple>(t, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<const char *const &name,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, name>()>>
|
|
||||||
get(tuple &t)
|
|
||||||
{
|
|
||||||
return get<name_hash(name), tuple>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<const char *const &name,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, name>()>>
|
|
||||||
get(tuple &t,
|
|
||||||
tuple_value_type<tuple, indexof<tuple, hash>()> &def)
|
|
||||||
{
|
|
||||||
return get<name_hash(name), tuple>(t, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t hash,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
|
||||||
at(const tuple &t)
|
|
||||||
{
|
|
||||||
constexpr size_t idx
|
|
||||||
{
|
|
||||||
indexof<tuple, hash>()
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto &ret
|
|
||||||
{
|
|
||||||
val<idx>(t)
|
|
||||||
};
|
|
||||||
|
|
||||||
using value_type = tuple_value_type<tuple, idx>;
|
|
||||||
if(!defined(json::value(ret)))
|
|
||||||
throw not_found
|
|
||||||
{
|
|
||||||
"%s", key<idx>(t)
|
|
||||||
};
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t hash,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, hash>()> &>
|
|
||||||
at(tuple &t)
|
|
||||||
{
|
|
||||||
constexpr size_t idx
|
|
||||||
{
|
|
||||||
indexof<tuple, hash>()
|
|
||||||
};
|
|
||||||
|
|
||||||
auto &ret
|
|
||||||
{
|
|
||||||
val<idx>(t)
|
|
||||||
};
|
|
||||||
|
|
||||||
using value_type = tuple_value_type<tuple, idx>;
|
|
||||||
if(!defined(json::value(ret)))
|
|
||||||
throw not_found
|
|
||||||
{
|
|
||||||
"%s", key<idx>(t)
|
|
||||||
};
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<const char *const &name,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple, name>()> &>
|
|
||||||
at(const tuple &t)
|
|
||||||
{
|
|
||||||
return at<name_hash(name), tuple>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<const char *const &name,
|
|
||||||
class tuple>
|
|
||||||
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple, name>()> &>
|
|
||||||
at(tuple &t)
|
|
||||||
{
|
|
||||||
return at<name_hash(name), tuple>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
size_t i>
|
|
||||||
typename std::enable_if<i == size<tuple>(), void>::type
|
|
||||||
at(tuple &t,
|
|
||||||
const string_view &name,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
size_t i = 0>
|
|
||||||
typename std::enable_if<i < size<tuple>(), void>::type
|
|
||||||
at(tuple &t,
|
|
||||||
const string_view &name,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
if(indexof<tuple>(name) == i)
|
|
||||||
f(val<i>(t));
|
|
||||||
else
|
|
||||||
at<tuple, function, i + 1>(t, name, std::forward<function>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
size_t i>
|
|
||||||
typename std::enable_if<i == size<tuple>(), void>::type
|
|
||||||
at(const tuple &t,
|
|
||||||
const string_view &name,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
size_t i = 0>
|
|
||||||
typename std::enable_if<i < size<tuple>(), void>::type
|
|
||||||
at(const tuple &t,
|
|
||||||
const string_view &name,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
if(indexof<tuple>(name) == i)
|
|
||||||
f(val<i>(t));
|
|
||||||
else
|
|
||||||
at<tuple, function, i + 1>(t, name, std::forward<function>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t i,
|
|
||||||
class tuple,
|
|
||||||
class function>
|
|
||||||
typename std::enable_if<i == size<tuple>(), void>::type
|
|
||||||
for_each(const tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<size_t i,
|
|
||||||
class tuple,
|
|
||||||
class function>
|
|
||||||
typename std::enable_if<i == size<tuple>(), void>::type
|
|
||||||
for_each(tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<size_t i = 0,
|
|
||||||
class tuple,
|
|
||||||
class function>
|
|
||||||
typename std::enable_if<i < size<tuple>(), void>::type
|
|
||||||
for_each(const tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
f(key<i>(t), val<i>(t));
|
|
||||||
for_each<i + 1>(t, std::forward<function>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t i = 0,
|
|
||||||
class tuple,
|
|
||||||
class function>
|
|
||||||
typename std::enable_if<i < size<tuple>(), void>::type
|
|
||||||
for_each(tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
f(key<i>(t), val<i>(t));
|
|
||||||
for_each<i + 1>(t, std::forward<function>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function>
|
|
||||||
void
|
|
||||||
for_each(const tuple &t,
|
|
||||||
const vector_view<const string_view> &mask,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
std::for_each(std::begin(mask), std::end(mask), [&t, &f]
|
|
||||||
(const auto &key)
|
|
||||||
{
|
|
||||||
at(t, key, [&f, &key]
|
|
||||||
(auto&& val)
|
|
||||||
{
|
|
||||||
f(key, val);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function>
|
|
||||||
void
|
|
||||||
for_each(tuple &t,
|
|
||||||
const vector_view<const string_view> &mask,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
std::for_each(std::begin(mask), std::end(mask), [&t, &f]
|
|
||||||
(const auto &key)
|
|
||||||
{
|
|
||||||
at(t, key, [&f, &key]
|
|
||||||
(auto&& val)
|
|
||||||
{
|
|
||||||
f(key, val);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
ssize_t i>
|
|
||||||
typename std::enable_if<(i < 0), void>::type
|
|
||||||
rfor_each(const tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
ssize_t i>
|
|
||||||
typename std::enable_if<(i < 0), void>::type
|
|
||||||
rfor_each(tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
ssize_t i = size<tuple>() - 1>
|
|
||||||
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>
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t i,
|
|
||||||
class tuple,
|
|
||||||
class function>
|
|
||||||
typename std::enable_if<i == size<tuple>(), bool>::type
|
|
||||||
until(const tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t i,
|
|
||||||
class tuple,
|
|
||||||
class function>
|
|
||||||
typename std::enable_if<i == size<tuple>(), bool>::type
|
|
||||||
until(tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t i = 0,
|
|
||||||
class tuple,
|
|
||||||
class function>
|
|
||||||
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>
|
|
||||||
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>
|
|
||||||
typename std::enable_if<i == size<tuple>(), bool>::type
|
|
||||||
until(const tuple &a,
|
|
||||||
const tuple &b,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<size_t i = 0,
|
|
||||||
class tuple,
|
|
||||||
class function>
|
|
||||||
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>
|
|
||||||
typename std::enable_if<(i < 0), bool>::type
|
|
||||||
runtil(const tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
ssize_t i>
|
|
||||||
typename std::enable_if<(i < 0), bool>::type
|
|
||||||
runtil(tuple &t,
|
|
||||||
function&& f)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class tuple,
|
|
||||||
class function,
|
|
||||||
ssize_t i = size<tuple>() - 1>
|
|
||||||
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>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class V,
|
|
||||||
class... T>
|
|
||||||
tuple<T...> &
|
|
||||||
set(tuple<T...> &t,
|
|
||||||
const string_view &key,
|
|
||||||
V&& val)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
at(t, key, [&key, &val]
|
|
||||||
(auto &target)
|
|
||||||
{
|
|
||||||
_assign(target, std::forward<V>(val));
|
|
||||||
});
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
catch(const std::exception &e)
|
|
||||||
{
|
|
||||||
throw parse_error("failed to set member '%s' (from %s): %s",
|
|
||||||
key,
|
|
||||||
demangle<V>(),
|
|
||||||
e.what());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class... T>
|
|
||||||
tuple<T...> &
|
|
||||||
set(tuple<T...> &t,
|
|
||||||
const string_view &key,
|
|
||||||
const json::value &value)
|
|
||||||
{
|
|
||||||
switch(type(value))
|
|
||||||
{
|
|
||||||
case type::STRING:
|
|
||||||
case type::LITERAL:
|
|
||||||
set(t, key, string_view{value});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::NUMBER:
|
|
||||||
if(value.floats)
|
|
||||||
set(t, key, value.floating);
|
|
||||||
else
|
|
||||||
set(t, key, value.integer);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::OBJECT:
|
|
||||||
case type::ARRAY:
|
|
||||||
if(unlikely(!value.serial))
|
|
||||||
throw print_error("Type %s must be JSON to be used by tuple member '%s'",
|
|
||||||
reflect(type(value)),
|
|
||||||
key);
|
|
||||||
|
|
||||||
set(t, key, string_view{value});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class... T>
|
template<class... T>
|
||||||
tuple<T...>::tuple(const json::object &object)
|
tuple<T...>::tuple(const json::object &object)
|
||||||
|
@ -948,83 +280,13 @@ _key_transform(const tuple<T...> &tuple,
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class... T>
|
} // namespace json
|
||||||
struct tuple<T...>::keys
|
} // namespace ircd
|
||||||
:std::array<string_view, tuple<T...>::size()>
|
|
||||||
{
|
|
||||||
struct selection;
|
|
||||||
struct include;
|
|
||||||
struct exclude;
|
|
||||||
|
|
||||||
constexpr keys()
|
#include "keys.h"
|
||||||
{
|
|
||||||
_key_transform<tuple<T...>>(this->begin(), this->end());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class... T>
|
namespace ircd {
|
||||||
struct tuple<T...>::keys::selection
|
namespace json {
|
||||||
:std::bitset<tuple<T...>::size()>
|
|
||||||
{
|
|
||||||
template<class closure>
|
|
||||||
constexpr bool until(closure &&function) const
|
|
||||||
{
|
|
||||||
for(size_t i(0); i < this->size(); ++i)
|
|
||||||
if(this->test(i))
|
|
||||||
if(!function(key<tuple<T...>, i>()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class closure>
|
|
||||||
constexpr void for_each(closure &&function) const
|
|
||||||
{
|
|
||||||
this->until([&function](auto&& key)
|
|
||||||
{
|
|
||||||
function(key);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class it_a,
|
|
||||||
class it_b>
|
|
||||||
constexpr auto transform(it_a it, const it_b end) const
|
|
||||||
{
|
|
||||||
this->until([&it, &end](auto&& key)
|
|
||||||
{
|
|
||||||
if(it == end)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*it = key;
|
|
||||||
++it;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class... T>
|
|
||||||
struct tuple<T...>::keys::include
|
|
||||||
:selection
|
|
||||||
{
|
|
||||||
constexpr include(const std::initializer_list<string_view> &list)
|
|
||||||
{
|
|
||||||
for(const auto &key : list)
|
|
||||||
this->set(indexof<tuple<T...>>(key), true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class... T>
|
|
||||||
struct tuple<T...>::keys::exclude
|
|
||||||
:selection
|
|
||||||
{
|
|
||||||
constexpr exclude(const std::initializer_list<string_view> &list)
|
|
||||||
{
|
|
||||||
this->set();
|
|
||||||
for(const auto &key : list)
|
|
||||||
this->set(indexof<tuple<T...>>(key), false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class it_a,
|
template<class it_a,
|
||||||
class it_b,
|
class it_b,
|
||||||
|
|
130
include/ircd/json/tuple/until.h
Normal file
130
include/ircd/json/tuple/until.h
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
// 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>
|
||||||
|
typename std::enable_if<i == size<tuple>(), bool>::type
|
||||||
|
until(const tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t i,
|
||||||
|
class tuple,
|
||||||
|
class function>
|
||||||
|
typename std::enable_if<i == size<tuple>(), bool>::type
|
||||||
|
until(tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t i = 0,
|
||||||
|
class tuple,
|
||||||
|
class function>
|
||||||
|
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>
|
||||||
|
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>
|
||||||
|
typename std::enable_if<i == size<tuple>(), bool>::type
|
||||||
|
until(const tuple &a,
|
||||||
|
const tuple &b,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t i = 0,
|
||||||
|
class tuple,
|
||||||
|
class function>
|
||||||
|
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>
|
||||||
|
typename std::enable_if<(i < 0), bool>::type
|
||||||
|
runtil(const tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
ssize_t i>
|
||||||
|
typename std::enable_if<(i < 0), bool>::type
|
||||||
|
runtil(tuple &t,
|
||||||
|
function&& f)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class tuple,
|
||||||
|
class function,
|
||||||
|
ssize_t i = size<tuple>() - 1>
|
||||||
|
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>
|
||||||
|
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
|
Loading…
Reference in a new issue