From f32a98472265958c92ce91100c2b9c148e375d13 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 4 Oct 2017 16:25:15 -0700 Subject: [PATCH] ircd::json: Add support for tuple indexing by hash; add c++11 literal hasher. --- include/ircd/json/property.h | 6 +- include/ircd/json/tuple.h | 291 +++++++++++++++++++++-------------- 2 files changed, 182 insertions(+), 115 deletions(-) diff --git a/include/ircd/json/property.h b/include/ircd/json/property.h index 96aa480ef..fd78342dd 100644 --- a/include/ircd/json/property.h +++ b/include/ircd/json/property.h @@ -37,7 +37,11 @@ struct ircd::json::property using key_type = const char *const &; using value_type = T; - static constexpr auto &key{name}; + static constexpr auto &key + { + name + }; + T value; operator const T &() const; diff --git a/include/ircd/json/tuple.h b/include/ircd/json/tuple.h index 6a6ac32fd..10e0bc6f8 100644 --- a/include/ircd/json/tuple.h +++ b/include/ircd/json/tuple.h @@ -22,6 +22,19 @@ #pragma once #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 json { @@ -141,6 +154,29 @@ key(const tuple &t) return std::get(t).key; } +template +constexpr typename std::enable_if(), size_t>::type +indexof() +{ + return size(); +} + +template +constexpr typename std::enable_if(), size_t>::type +indexof() +{ + const auto equal + { + ircd::hash(key()) == hash + }; + + return equal? i : indexof(); +} + template constexpr typename std::enable_if(), size_t>::type @@ -193,17 +229,9 @@ key_exists(const string_view &key) template enable_if_tuple &> -get(tuple &t) +val(tuple &t) { - return std::get(t); -} - -template -enable_if_tuple &> -get(const tuple &t) -{ - return std::get(t); + return static_cast &>(std::get(t)); } template &> val(const tuple &t) { - using value_type = tuple_value_type; - return static_cast(get(t)); + return static_cast &>(std::get(t)); } -template -enable_if_tuple &> -val(tuple &t) +template +const tuple_value_type, indexof, hash>()> & +get(const tuple &t) { - using value_type = tuple_value_type; - return static_cast(get(t)); + constexpr size_t idx + { + indexof, hash>() + }; + + return val(t); } -template -enable_if_tuple(name)> &> -val(const tuple &t) +template +tuple_value_type, indexof, hash>()> +get(const tuple &t, + const tuple_value_type, indexof, hash>()> &def) { - return val(name)>(t); + constexpr size_t idx + { + indexof, hash>() + }; + + const auto &ret + { + val(t) + }; + + using value_type = tuple_value_type, idx>; + + //TODO: undefined + return ret != value_type{}? ret : def; } -template -enable_if_tuple(name)> &> -val(tuple &t) +template +tuple_value_type, indexof, hash>()> & +get(tuple &t) { - return val(name)>(t); + constexpr size_t idx + { + indexof, hash>() + }; + + return val(t); +} + +template +tuple_value_type, indexof, hash>()> & +get(tuple &t, + tuple_value_type, indexof, hash>()> &def) +{ + //TODO: undefined + auto &ret{get(t)}; + using value_type = decltype(ret); + return ret != value_type{}? ret : def; +} + +template +enable_if_tuple()> &> +at(const tuple &t) +{ + constexpr size_t idx + { + indexof() + }; + + auto &ret + { + val(t) + }; + + using value_type = tuple_value_type; + + //TODO: undefined + if(ret == value_type{}) + throw not_found("%s", key(t)); + + return ret; +} + +template +enable_if_tuple()> &> +at(tuple &t) +{ + constexpr size_t idx + { + indexof() + }; + + auto &ret + { + val(t) + }; + + using value_type = tuple_value_type; + + //TODO: undefined + if(ret == value_type{}) + throw not_found("%s", key(t)); + + return ret; } template -tuple_value_type, indexof>(name)> -get(const tuple &t, - const tuple_value_type, indexof>(name)> &def = {}) +template +typename std::enable_if(), void>::type +at(tuple &t, + const string_view &name, + function&& f) { - constexpr size_t idx - { - indexof>(name) - }; - - const auto &ret - { - val(t) - }; - - using value_type = tuple_value_type, idx>; - - //TODO: undefined - return ret != value_type{}? ret : def; } -template -tuple_value_type, indexof>(name)> & -get(tuple &t) +template +typename std::enable_if(), void>::type +at(tuple &t, + const string_view &name, + function&& f) { - constexpr size_t idx - { - indexof>(name) - }; - - return val(t); + if(indexof(name) == i) + f(val(t)); + else + at(t, name, std::forward(f)); } -template -tuple_value_type, indexof>(name)> & -get(tuple &t, - tuple_value_type, indexof>(name)> &def) +template +typename std::enable_if(), void>::type +at(const tuple &t, + const string_view &name, + function&& f) { - //TODO: undefined - auto &ret{get(t)}; - using value_type = decltype(ret); - return ret != value_type{}? ret : def; +} + +template +typename std::enable_if(), void>::type +at(const tuple &t, + const string_view &name, + function&& f) +{ + if(indexof(name) == i) + f(val(t)); + else + at(t, name, std::forward(f)); } template -typename std::enable_if(), void>::type -at(tuple &t, - const string_view &name, - function&& f) -{ -} - -template -typename std::enable_if(), void>::type -at(tuple &t, - const string_view &name, - function&& f) -{ - if(indexof(name) == i) - f(val(t)); - else - at(t, name, std::forward(f)); -} - -template -typename std::enable_if(), void>::type -at(const tuple &t, - const string_view &name, - function&& f) -{ -} - -template -typename std::enable_if(), void>::type -at(const tuple &t, - const string_view &name, - function&& f) -{ - if(indexof(name) == i) - f(val(t)); - else - at(t, name, std::forward(f)); -} - template typename std::enable_if