0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-17 15:30:52 +01:00

ircd::json: Add support for tuple indexing by hash; add c++11 literal hasher.

This commit is contained in:
Jason Volk 2017-10-04 16:25:15 -07:00
parent 55a4377d49
commit f32a984722
2 changed files with 182 additions and 115 deletions

View file

@ -37,7 +37,11 @@ struct ircd::json::property
using key_type = const char *const &; using key_type = const char *const &;
using value_type = T; using value_type = T;
static constexpr auto &key{name}; static constexpr auto &key
{
name
};
T value; T value;
operator const T &() const; operator const T &() const;

View file

@ -22,6 +22,19 @@
#pragma once #pragma once
#define HAVE_IRCD_JSON_TUPLE_H #define HAVE_IRCD_JSON_TUPLE_H
namespace ircd::json
{
constexpr size_t operator ""_(const char *const text, const size_t len)
{
return ircd::hash(text);
}
}
namespace ircd
{
using json::operator ""_;
}
namespace ircd { namespace ircd {
namespace json { namespace json {
@ -141,6 +154,29 @@ key(const tuple &t)
return std::get<i>(t).key; return std::get<i>(t).key;
} }
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()
{
const auto equal
{
ircd::hash(key<tuple, i>()) == hash
};
return equal? i : indexof<tuple, hash, i + 1>();
}
template<class tuple, template<class tuple,
size_t i> size_t i>
constexpr typename std::enable_if<i == size<tuple>(), size_t>::type constexpr typename std::enable_if<i == size<tuple>(), size_t>::type
@ -193,17 +229,9 @@ key_exists(const string_view &key)
template<size_t i, template<size_t i,
class tuple> class tuple>
enable_if_tuple<tuple, tuple_value_type<tuple, i> &> enable_if_tuple<tuple, tuple_value_type<tuple, i> &>
get(tuple &t) val(tuple &t)
{ {
return std::get<i>(t); return static_cast<tuple_value_type<tuple, i> &>(std::get<i>(t));
}
template<size_t i,
class tuple>
enable_if_tuple<tuple, const tuple_value_type<tuple, i> &>
get(const tuple &t)
{
return std::get<i>(t);
} }
template<size_t i, template<size_t i,
@ -211,33 +239,115 @@ template<size_t i,
enable_if_tuple<tuple, const tuple_value_type<tuple, i> &> enable_if_tuple<tuple, const tuple_value_type<tuple, i> &>
val(const tuple &t) val(const tuple &t)
{ {
using value_type = tuple_value_type<tuple, i>; return static_cast<const tuple_value_type<tuple, i> &>(std::get<i>(t));
return static_cast<const value_type &>(get<i>(t));
} }
template<size_t i, template<size_t hash,
class tuple> class... T>
enable_if_tuple<tuple, tuple_value_type<tuple, i> &> const tuple_value_type<tuple<T...>, indexof<tuple<T...>, hash>()> &
val(tuple &t) get(const tuple<T...> &t)
{ {
using value_type = tuple_value_type<tuple, i>; constexpr size_t idx
return static_cast<value_type &>(get<i>(t)); {
indexof<tuple<T...>, hash>()
};
return val<idx>(t);
} }
template<const char *const &name, template<size_t hash,
class tuple> class... T>
enable_if_tuple<tuple, const tuple_value_type<tuple, indexof<tuple>(name)> &> tuple_value_type<tuple<T...>, indexof<tuple<T...>, hash>()>
val(const tuple &t) get(const tuple<T...> &t,
const tuple_value_type<tuple<T...>, indexof<tuple<T...>, hash>()> &def)
{ {
return val<indexof<tuple>(name)>(t); constexpr size_t idx
{
indexof<tuple<T...>, hash>()
};
const auto &ret
{
val<idx>(t)
};
using value_type = tuple_value_type<tuple<T...>, idx>;
//TODO: undefined
return ret != value_type{}? ret : def;
} }
template<const char *const &name, template<size_t hash,
class tuple> class... T>
enable_if_tuple<tuple, tuple_value_type<tuple, indexof<tuple>(name)> &> tuple_value_type<tuple<T...>, indexof<tuple<T...>, hash>()> &
val(tuple &t) get(tuple<T...> &t)
{ {
return val<indexof<tuple>(name)>(t); constexpr size_t idx
{
indexof<tuple<T...>, hash>()
};
return val<idx>(t);
}
template<size_t hash,
class... T>
tuple_value_type<tuple<T...>, indexof<tuple<T...>, hash>()> &
get(tuple<T...> &t,
tuple_value_type<tuple<T...>, indexof<tuple<T...>, hash>()> &def)
{
//TODO: undefined
auto &ret{get<hash, T...>(t)};
using value_type = decltype(ret);
return ret != value_type{}? ret : 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>()
};
auto &ret
{
val<idx>(t)
};
using value_type = tuple_value_type<tuple, idx>;
//TODO: undefined
if(ret == value_type{})
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>;
//TODO: undefined
if(ret == value_type{})
throw not_found("%s", key<idx>(t));
return ret;
} }
template<const char *const &name, template<const char *const &name,
@ -288,51 +398,52 @@ at(tuple &t)
return ret; return ret;
} }
template<const char *const &name, template<class tuple,
class... T> class function,
tuple_value_type<tuple<T...>, indexof<tuple<T...>>(name)> size_t i>
get(const tuple<T...> &t, typename std::enable_if<i == size<tuple>(), void>::type
const tuple_value_type<tuple<T...>, indexof<tuple<T...>>(name)> &def = {}) at(tuple &t,
const string_view &name,
function&& f)
{ {
constexpr size_t idx
{
indexof<tuple<T...>>(name)
};
const auto &ret
{
val<idx>(t)
};
using value_type = tuple_value_type<tuple<T...>, idx>;
//TODO: undefined
return ret != value_type{}? ret : def;
} }
template<const char *const &name, template<class tuple,
class... T> class function,
tuple_value_type<tuple<T...>, indexof<tuple<T...>>(name)> & size_t i = 0>
get(tuple<T...> &t) typename std::enable_if<i < size<tuple>(), void>::type
at(tuple &t,
const string_view &name,
function&& f)
{ {
constexpr size_t idx if(indexof<tuple>(name) == i)
{ f(val<i>(t));
indexof<tuple<T...>>(name) else
}; at<tuple, function, i + 1>(t, name, std::forward<function>(f));
return val<idx>(t);
} }
template<const char *const &name, template<class tuple,
class... T> class function,
tuple_value_type<tuple<T...>, indexof<tuple<T...>>(name)> & size_t i>
get(tuple<T...> &t, typename std::enable_if<i == size<tuple>(), void>::type
tuple_value_type<tuple<T...>, indexof<tuple<T...>>(name)> &def) at(const tuple &t,
const string_view &name,
function&& f)
{ {
//TODO: undefined }
auto &ret{get<name, T...>(t)};
using value_type = decltype(ret); template<class tuple,
return ret != value_type{}? ret : def; 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, template<size_t i,
@ -523,54 +634,6 @@ runtil(tuple &t,
false; false;
} }
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<class dst, template<class dst,
class src> class src>
typename std::enable_if typename std::enable_if