From 436ef67072acd5d50265b6676dbf55cea24b1ee7 Mon Sep 17 00:00:00 2001 From: rbock Date: Tue, 17 Feb 2015 07:05:41 +0100 Subject: [PATCH] Replaced recursive traits with local traits which are evaluated recursively Ok, that sounds weird... Earlier, each node in the SQL tree had a struct containing all recursive traits. This is now gone. It only contains a reference to all sub nodes and its own specific traits. --- include/sqlpp11/alias.h | 2 +- include/sqlpp11/any.h | 2 +- include/sqlpp11/assignment.h | 2 +- include/sqlpp11/avg.h | 2 +- include/sqlpp11/boolean_expression.h | 2 +- include/sqlpp11/column.h | 16 +-- include/sqlpp11/concat.h | 2 +- include/sqlpp11/count.h | 14 +-- include/sqlpp11/cte.h | 43 ++------ include/sqlpp11/custom_query.h | 4 +- include/sqlpp11/default_value.h | 2 +- include/sqlpp11/exists.h | 2 +- include/sqlpp11/expression.h | 10 +- include/sqlpp11/extra_tables.h | 16 +-- include/sqlpp11/field_spec.h | 2 +- include/sqlpp11/from.h | 4 +- include/sqlpp11/functions.h | 2 +- include/sqlpp11/group_by.h | 4 +- include/sqlpp11/having.h | 4 +- include/sqlpp11/in.h | 2 +- include/sqlpp11/insert_value.h | 2 +- include/sqlpp11/insert_value_list.h | 8 +- include/sqlpp11/into.h | 4 +- include/sqlpp11/is_not_null.h | 2 +- include/sqlpp11/is_null.h | 2 +- include/sqlpp11/join.h | 16 +-- include/sqlpp11/like.h | 2 +- include/sqlpp11/limit.h | 6 +- include/sqlpp11/max.h | 2 +- include/sqlpp11/min.h | 2 +- include/sqlpp11/multi_column.h | 4 +- include/sqlpp11/noop.h | 2 +- include/sqlpp11/not_in.h | 2 +- include/sqlpp11/null.h | 2 +- include/sqlpp11/offset.h | 6 +- include/sqlpp11/on.h | 2 +- include/sqlpp11/order_by.h | 4 +- include/sqlpp11/parameter.h | 15 +-- include/sqlpp11/prepared_execute.h | 2 +- include/sqlpp11/prepared_insert.h | 2 +- include/sqlpp11/prepared_remove.h | 2 +- include/sqlpp11/prepared_select.h | 2 +- include/sqlpp11/prepared_update.h | 2 +- include/sqlpp11/result_field_methods.h | 16 +-- include/sqlpp11/result_row.h | 2 +- include/sqlpp11/rhs_wrap.h | 2 +- include/sqlpp11/select_column_list.h | 4 +- include/sqlpp11/select_flag_list.h | 4 +- include/sqlpp11/select_flags.h | 6 +- include/sqlpp11/select_pseudo_table.h | 2 +- include/sqlpp11/simple_column.h | 2 +- include/sqlpp11/single_table.h | 4 +- include/sqlpp11/some.h | 2 +- include/sqlpp11/sort_order.h | 2 +- include/sqlpp11/statement.h | 27 ++--- include/sqlpp11/sum.h | 2 +- include/sqlpp11/table.h | 13 +-- include/sqlpp11/table_alias.h | 14 +-- include/sqlpp11/tvin.h | 4 +- include/sqlpp11/type_traits.h | 142 +++++++++++++------------ include/sqlpp11/union.h | 4 +- include/sqlpp11/update_list.h | 4 +- include/sqlpp11/using.h | 4 +- include/sqlpp11/value_or_null.h | 2 +- include/sqlpp11/verbatim.h | 6 +- include/sqlpp11/verbatim_table.h | 5 +- include/sqlpp11/where.h | 6 +- include/sqlpp11/with.h | 16 +-- include/sqlpp11/wrap_operand.h | 8 +- 69 files changed, 208 insertions(+), 325 deletions(-) diff --git a/include/sqlpp11/alias.h b/include/sqlpp11/alias.h index 5f565ea1..ecebe23b 100644 --- a/include/sqlpp11/alias.h +++ b/include/sqlpp11/alias.h @@ -36,7 +36,7 @@ namespace sqlpp struct expression_alias_t { using _traits = make_traits, tag::is_selectable, tag::is_alias>; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; static_assert(is_expression_t::value, "invalid argument for an expression alias"); static_assert(not is_alias_t::value, "cannot create an alias of an alias"); diff --git a/include/sqlpp11/any.h b/include/sqlpp11/any.h index a180835f..2c876397 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/any.h @@ -37,7 +37,7 @@ namespace sqlpp struct any_t { using _traits = make_traits, tag::is_multi_expression>; - using _recursive_traits = make_recursive_traits; struct _alias_t { diff --git a/include/sqlpp11/assignment.h b/include/sqlpp11/assignment.h index 2677bd00..1496a0e1 100644 --- a/include/sqlpp11/assignment.h +++ b/include/sqlpp11/assignment.h @@ -41,7 +41,7 @@ namespace sqlpp struct assignment_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _lhs_t = Lhs; using _rhs_t = rhs_wrap_t, trivial_value_is_null_t<_lhs_t>::value>; diff --git a/include/sqlpp11/avg.h b/include/sqlpp11/avg.h index d7827abd..d184ccb4 100644 --- a/include/sqlpp11/avg.h +++ b/include/sqlpp11/avg.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; static_assert(is_noop::value or std::is_same::value, "avg() used with flag other than 'distinct'"); static_assert(is_numeric_t::value, "avg() requires a value expression as argument"); diff --git a/include/sqlpp11/boolean_expression.h b/include/sqlpp11/boolean_expression.h index f60a610b..cc72e846 100644 --- a/include/sqlpp11/boolean_expression.h +++ b/include/sqlpp11/boolean_expression.h @@ -36,7 +36,7 @@ namespace sqlpp struct boolean_expression_t: public expression_operators, boolean> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; template boolean_expression_t(Expr expr): diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index 08d1a0f7..495e70c7 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -52,19 +52,9 @@ namespace sqlpp using _tags = detail::make_joined_set_t, typename ColumnSpec::_traits::_tags>; }; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = typename std::conditional::value, - detail::type_set, - detail::type_set<>>::type; - }; + using _nodes = std::tuple<>; + using _required_tables = detail::type_set
; + using _can_be_null = column_spec_can_be_null_t; using _spec_t = ColumnSpec; using _table = Table; diff --git a/include/sqlpp11/concat.h b/include/sqlpp11/concat.h index 57f113dd..24ebb046 100644 --- a/include/sqlpp11/concat.h +++ b/include/sqlpp11/concat.h @@ -42,7 +42,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); static_assert(logic::all_t::value, is_text_t::value...>::value, "at least one non-text argument detected in concat()"); diff --git a/include/sqlpp11/count.h b/include/sqlpp11/count.h index ceff0393..63c5f4c7 100644 --- a/include/sqlpp11/count.h +++ b/include/sqlpp11/count.h @@ -39,19 +39,9 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = required_ctes_of; - using _provided_ctes = detail::type_set<>; - using _required_tables = required_tables_of; - using _provided_tables = provided_tables_of; - using _provided_outer_tables = provided_outer_tables_of; - using _extra_tables = extra_tables_of; - using _parameters = parameters_of; - using _tags = detail::make_difference_set_t, recursive_tags_of>, - detail::type_set>; - }; + using _nodes = std::tuple; + using _can_be_null = std::false_type; static_assert(is_noop::value or std::is_same::value, "count() used with flag other than 'distinct'"); diff --git a/include/sqlpp11/cte.h b/include/sqlpp11/cte.h index c37f26d9..64ca2d66 100644 --- a/include/sqlpp11/cte.h +++ b/include/sqlpp11/cte.h @@ -43,17 +43,9 @@ namespace sqlpp template struct cte_union_t { - struct _recursive_traits - { - using _required_ctes = detail::make_joined_set_t, required_ctes_of>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = detail::make_parameter_tuple_t, parameters_of>; - using _tags = detail::type_set<>; - }; + using _nodes = std::tuple<>; + using _required_ctes = detail::make_joined_set_t, required_ctes_of>; + using _parameters = detail::make_parameter_tuple_t, parameters_of>; cte_union_t(Lhs lhs, Rhs rhs): _lhs(lhs), @@ -140,17 +132,10 @@ namespace sqlpp struct cte_t: public member_t, column_t>>... { using _traits = make_traits; // FIXME: is table? really? - struct _recursive_traits - { - using _required_ctes = detail::make_joined_set_t, detail::type_set>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = parameters_of; - using _tags = detail::type_set<>; - }; + using _nodes = std::tuple<>; + using _required_ctes = detail::make_joined_set_t, detail::type_set>; + using _parameters = parameters_of; + using _alias_t = typename AliasProvider::_alias_t; constexpr static bool _is_recursive = detail::is_element_of>::value; @@ -235,17 +220,9 @@ namespace sqlpp struct cte_ref_t { using _traits = make_traits; // FIXME: is table? really? - struct _recursive_traits - { - using _required_ctes = detail::make_type_set_t; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = detail::type_set<>; - }; + using _nodes = std::tuple<>; + using _required_ctes = detail::make_type_set_t; + using _provided_tables = detail::type_set; using _alias_t = typename AliasProvider::_alias_t; diff --git a/include/sqlpp11/custom_query.h b/include/sqlpp11/custom_query.h index ce332688..e9ecc0a9 100644 --- a/include/sqlpp11/custom_query.h +++ b/include/sqlpp11/custom_query.h @@ -54,9 +54,9 @@ namespace sqlpp { using _methods_t = typename detail::custom_parts_t::_result_methods_t; using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; - using _parameter_check = typename std::conditional::value == 0, + using _parameter_check = typename std::conditional>::value == 0, consistent_t, assert_no_parameters_t>::type; using _run_check = detail::get_first_if; diff --git a/include/sqlpp11/default_value.h b/include/sqlpp11/default_value.h index ede6bb87..be4ff565 100644 --- a/include/sqlpp11/default_value.h +++ b/include/sqlpp11/default_value.h @@ -34,7 +34,7 @@ namespace sqlpp struct default_value_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; static constexpr bool _is_trivial() { return false; } }; diff --git a/include/sqlpp11/exists.h b/include/sqlpp11/exists.h index ad1df80f..d1699a06 100644 --- a/include/sqlpp11/exists.h +++ b/include/sqlpp11/exists.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; static_assert(is_select_t
; + using _nodes = std::tuple
; using _data_t = into_data_t; @@ -108,7 +108,7 @@ namespace sqlpp struct no_into_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/is_not_null.h b/include/sqlpp11/is_not_null.h index f6467b18..ea34a892 100644 --- a/include/sqlpp11/is_not_null.h +++ b/include/sqlpp11/is_not_null.h @@ -40,7 +40,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; struct _alias_t { diff --git a/include/sqlpp11/is_null.h b/include/sqlpp11/is_null.h index 8bdc0196..fd788374 100644 --- a/include/sqlpp11/is_null.h +++ b/include/sqlpp11/is_null.h @@ -40,7 +40,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; struct _alias_t { diff --git a/include/sqlpp11/join.h b/include/sqlpp11/join.h index 160d1472..46eadd48 100644 --- a/include/sqlpp11/join.h +++ b/include/sqlpp11/join.h @@ -66,18 +66,8 @@ namespace sqlpp struct join_t { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = detail::make_joined_set_t, required_ctes_of>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::make_joined_set_t, required_tables_of>; - using _provided_tables = detail::make_joined_set_t, provided_tables_of>; - using _provided_outer_tables = typename JoinType::template _provided_outer_tables; - using _extra_tables = detail::make_joined_set_t, extra_tables_of>; - using _parameters = detail::make_parameter_tuple_t, parameters_of>; - using _tags = detail::type_set<>; - }; - + using _nodes = std::tuple; + using _can_be_null = std::false_type; static_assert(is_table_t::value, "lhs argument for join() has to be a table or join"); static_assert(is_table_t::value, "rhs argument for join() has to be a table"); @@ -86,7 +76,7 @@ namespace sqlpp static_assert(detail::is_disjunct_from, provided_tables_of>::value, "joined tables must not be identical"); - static_assert(_recursive_traits::_required_tables::size::value == 0, "joined tables must not depend on other tables"); + static_assert(required_tables_of::size::value == 0, "joined tables must not depend on other tables"); template using set_on_t = join_t; diff --git a/include/sqlpp11/like.h b/include/sqlpp11/like.h index 95d1e2b0..b8ea9952 100644 --- a/include/sqlpp11/like.h +++ b/include/sqlpp11/like.h @@ -40,7 +40,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; struct _alias_t { diff --git a/include/sqlpp11/limit.h b/include/sqlpp11/limit.h index 4b5dc564..013ff092 100644 --- a/include/sqlpp11/limit.h +++ b/include/sqlpp11/limit.h @@ -55,7 +55,7 @@ namespace sqlpp struct limit_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; // Data using _data_t = limit_data_t; @@ -118,7 +118,7 @@ namespace sqlpp struct dynamic_limit_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = dynamic_limit_data_t; @@ -163,7 +163,7 @@ namespace sqlpp struct no_limit_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/max.h b/include/sqlpp11/max.h index cfa43036..6dfcb593 100644 --- a/include/sqlpp11/max.h +++ b/include/sqlpp11/max.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; struct _alias_t { diff --git a/include/sqlpp11/min.h b/include/sqlpp11/min.h index e6d97348..f19a7e6f 100644 --- a/include/sqlpp11/min.h +++ b/include/sqlpp11/min.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; struct _alias_t { diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index c5c169b1..2e3ab96a 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -42,7 +42,7 @@ namespace sqlpp struct multi_column_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; static_assert(logic::all_t::value...>::value, "multi_column parameters need to be named expressions"); @@ -73,7 +73,7 @@ namespace sqlpp struct multi_column_alias_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; static_assert(logic::all_t::value...>::value, "multi_column parameters need to be named expressions"); diff --git a/include/sqlpp11/noop.h b/include/sqlpp11/noop.h index eb4315fb..8fd7ec86 100644 --- a/include/sqlpp11/noop.h +++ b/include/sqlpp11/noop.h @@ -37,7 +37,7 @@ namespace sqlpp struct noop { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; struct _alias_t {}; diff --git a/include/sqlpp11/not_in.h b/include/sqlpp11/not_in.h index a3b212de..fdf4ac44 100644 --- a/include/sqlpp11/not_in.h +++ b/include/sqlpp11/not_in.h @@ -41,7 +41,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; static_assert(sizeof...(Args) > 0, "not_in() requires at least one argument"); diff --git a/include/sqlpp11/null.h b/include/sqlpp11/null.h index 167da605..2a705bb5 100644 --- a/include/sqlpp11/null.h +++ b/include/sqlpp11/null.h @@ -34,7 +34,7 @@ namespace sqlpp struct null_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; }; template diff --git a/include/sqlpp11/offset.h b/include/sqlpp11/offset.h index d78d77b1..28e4d565 100644 --- a/include/sqlpp11/offset.h +++ b/include/sqlpp11/offset.h @@ -55,7 +55,7 @@ namespace sqlpp struct offset_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; static_assert(is_integral_t::value, "offset requires an integral value or integral parameter"); @@ -120,7 +120,7 @@ namespace sqlpp struct dynamic_offset_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = dynamic_offset_data_t; @@ -177,7 +177,7 @@ namespace sqlpp struct no_offset_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/on.h b/include/sqlpp11/on.h index 785e0a4f..db959026 100644 --- a/include/sqlpp11/on.h +++ b/include/sqlpp11/on.h @@ -38,7 +38,7 @@ namespace sqlpp struct on_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _is_dynamic = is_database; diff --git a/include/sqlpp11/order_by.h b/include/sqlpp11/order_by.h index 467930e5..bdd2c312 100644 --- a/include/sqlpp11/order_by.h +++ b/include/sqlpp11/order_by.h @@ -71,7 +71,7 @@ namespace sqlpp struct order_by_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _is_dynamic = is_database; @@ -141,7 +141,7 @@ namespace sqlpp struct no_order_by_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index 813f0b91..0acbba76 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -38,17 +38,10 @@ namespace sqlpp public expression_operators, ValueType> { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple; - using _tags = detail::type_set; - }; + + using _nodes = std::tuple<>; + using _parameters = std::tuple; + using _can_be_null = std::true_type; using _instance_t = member_t>; diff --git a/include/sqlpp11/prepared_execute.h b/include/sqlpp11/prepared_execute.h index a82287c8..56f935d6 100644 --- a/include/sqlpp11/prepared_execute.h +++ b/include/sqlpp11/prepared_execute.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_execute_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _parameter_list_t = make_parameter_list_t; using _prepared_statement_t = typename Db::_prepared_statement_t; diff --git a/include/sqlpp11/prepared_insert.h b/include/sqlpp11/prepared_insert.h index da87b5bf..a44b2214 100644 --- a/include/sqlpp11/prepared_insert.h +++ b/include/sqlpp11/prepared_insert.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_insert_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _parameter_list_t = make_parameter_list_t; using _prepared_statement_t = typename Db::_prepared_statement_t; diff --git a/include/sqlpp11/prepared_remove.h b/include/sqlpp11/prepared_remove.h index 1b488106..0c67cd61 100644 --- a/include/sqlpp11/prepared_remove.h +++ b/include/sqlpp11/prepared_remove.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_remove_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _parameter_list_t = make_parameter_list_t; using _prepared_statement_t = typename Db::_prepared_statement_t; diff --git a/include/sqlpp11/prepared_select.h b/include/sqlpp11/prepared_select.h index 3ee9eb26..112586f7 100644 --- a/include/sqlpp11/prepared_select.h +++ b/include/sqlpp11/prepared_select.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_select_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _result_row_t = typename Statement::template _result_row_t; using _parameter_list_t = make_parameter_list_t; diff --git a/include/sqlpp11/prepared_update.h b/include/sqlpp11/prepared_update.h index ee9ff791..c9190188 100644 --- a/include/sqlpp11/prepared_update.h +++ b/include/sqlpp11/prepared_update.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_update_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _parameter_list_t = make_parameter_list_t; using _prepared_statement_t = typename Db::_prepared_statement_t; diff --git a/include/sqlpp11/result_field_methods.h b/include/sqlpp11/result_field_methods.h index e3231e05..2e7ec984 100644 --- a/include/sqlpp11/result_field_methods.h +++ b/include/sqlpp11/result_field_methods.h @@ -81,20 +81,8 @@ namespace sqlpp tag::is_expression, tag_if>; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = typename std::conditional::value, - detail::type_set, - detail::type_set<>>::type; - }; - + using _nodes = std::tuple<>; + using _can_be_null = column_spec_can_be_null_t<_field_spec_t>; }; } diff --git a/include/sqlpp11/result_row.h b/include/sqlpp11/result_row.h index 32c4ad36..f814037e 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -185,7 +185,7 @@ namespace sqlpp struct _field_spec_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; struct _alias_t {}; }; diff --git a/include/sqlpp11/rhs_wrap.h b/include/sqlpp11/rhs_wrap.h index e9a0bad5..54c1e114 100644 --- a/include/sqlpp11/rhs_wrap.h +++ b/include/sqlpp11/rhs_wrap.h @@ -118,7 +118,7 @@ namespace sqlpp struct rhs_wrap_t { using _traits = typename Expr::_traits; - using _recursive_traits = typename Expr::_recursive_traits; + using _nodes = std::tuple; rhs_wrap_t(Expr expr): _expr(expr) diff --git a/include/sqlpp11/select_column_list.h b/include/sqlpp11/select_column_list.h index 86e14466..ea38d3a5 100644 --- a/include/sqlpp11/select_column_list.h +++ b/include/sqlpp11/select_column_list.h @@ -164,7 +164,7 @@ namespace sqlpp struct select_column_list_t { using _traits = typename detail::select_traits::_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _alias_t = typename detail::select_traits::_alias_t; @@ -353,7 +353,7 @@ namespace sqlpp struct no_select_column_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; struct _alias_t {}; diff --git a/include/sqlpp11/select_flag_list.h b/include/sqlpp11/select_flag_list.h index db66ea6f..1c3f84bf 100644 --- a/include/sqlpp11/select_flag_list.h +++ b/include/sqlpp11/select_flag_list.h @@ -60,7 +60,7 @@ namespace sqlpp struct select_flag_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _is_dynamic = is_database; @@ -128,7 +128,7 @@ namespace sqlpp struct no_select_flag_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/select_flags.h b/include/sqlpp11/select_flags.h index 5db6a0b6..65a75fb5 100644 --- a/include/sqlpp11/select_flags.h +++ b/include/sqlpp11/select_flags.h @@ -38,7 +38,7 @@ namespace sqlpp struct all_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; }; static constexpr all_t all = {}; @@ -57,7 +57,7 @@ namespace sqlpp struct distinct_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; }; static constexpr distinct_t distinct = {}; @@ -76,7 +76,7 @@ namespace sqlpp struct straight_join_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; }; static constexpr straight_join_t straight_join = {}; diff --git a/include/sqlpp11/select_pseudo_table.h b/include/sqlpp11/select_pseudo_table.h index 44ef4be7..5953ad30 100644 --- a/include/sqlpp11/select_pseudo_table.h +++ b/include/sqlpp11/select_pseudo_table.h @@ -58,7 +58,7 @@ namespace sqlpp NamedExpr...>, select_column_spec_t...> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; select_pseudo_table_t(Select select): _select(select) diff --git a/include/sqlpp11/simple_column.h b/include/sqlpp11/simple_column.h index d90f93be..26e7062f 100644 --- a/include/sqlpp11/simple_column.h +++ b/include/sqlpp11/simple_column.h @@ -39,7 +39,7 @@ namespace sqlpp _column_t _column; using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; }; template diff --git a/include/sqlpp11/single_table.h b/include/sqlpp11/single_table.h index 72f05877..c22c1aa4 100644 --- a/include/sqlpp11/single_table.h +++ b/include/sqlpp11/single_table.h @@ -58,7 +58,7 @@ namespace sqlpp struct single_table_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits
; + using _nodes = std::tuple
; static_assert(is_table_t
::value, "argument has to be a table"); static_assert(required_tables_of
::size::value == 0, "table depends on another table"); @@ -99,7 +99,7 @@ namespace sqlpp struct no_single_table_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/some.h b/include/sqlpp11/some.h index 6ad8bf40..9747ebcb 100644 --- a/include/sqlpp11/some.h +++ b/include/sqlpp11/some.h @@ -37,7 +37,7 @@ namespace sqlpp struct some_t { using _traits = make_traits, tag::is_multi_expression>; - using _recursive_traits = make_recursive_traits; struct _alias_t { diff --git a/include/sqlpp11/sort_order.h b/include/sqlpp11/sort_order.h index cd0d6357..546ff4f1 100644 --- a/include/sqlpp11/sort_order.h +++ b/include/sqlpp11/sort_order.h @@ -42,7 +42,7 @@ namespace sqlpp struct sort_order_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; Expression _expression; }; diff --git a/include/sqlpp11/statement.h b/include/sqlpp11/statement.h index d6acbbbf..59ef4a8f 100644 --- a/include/sqlpp11/statement.h +++ b/include/sqlpp11/statement.h @@ -146,34 +146,23 @@ namespace sqlpp no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value >::type; + using _traits = make_traits<_value_type, tag_if::value>>; + + using _nodes = std::tuple<>; using _can_be_null = logic::any_t< can_be_null_t<_result_type_provider>::value, detail::make_intersect_set_t< required_tables_of<_result_type_provider>, _all_provided_outer_tables >::size::value != 0>; - - using _traits = make_traits<_value_type, tag_if::value>>; - - struct _recursive_traits - { - using _required_ctes = statement_policies_t::_required_ctes; - using _provided_ctes = detail::type_set<>; - using _required_tables = statement_policies_t::_required_tables; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = detail::make_parameter_tuple_t...>; - using _tags = typename std::conditional<_can_be_null::value, - detail::type_set, - detail::type_set<>>::type; - }; + using _parameters = detail::make_parameter_tuple_t...>; + // required_tables and _required_ctes are defined above using _cte_check = typename std::conditional<_required_ctes::size::value == 0, consistent_t, assert_no_unknown_ctes_t>::type; using _table_check = typename std::conditional<_required_tables::size::value == 0, consistent_t, assert_no_unknown_tables_t>::type; - using _parameter_check = typename std::conditional::value == 0, + using _parameter_check = typename std::conditional::value == 0, consistent_t, assert_no_parameters_t>::type; }; } @@ -212,7 +201,7 @@ namespace sqlpp tag_if::value>, tag_if::value>::value>, tag::requires_braces>; - using _recursive_traits = typename _policies_t::_recursive_traits; + using _nodes = std::tuple<_policies_t>; using _used_outer_tables = typename _policies_t::_all_provided_outer_tables; using _alias_t = typename _result_type_provider::_alias_t; @@ -286,7 +275,7 @@ namespace sqlpp struct statement_name_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = NameData; diff --git a/include/sqlpp11/sum.h b/include/sqlpp11/sum.h index 91970f9a..e23f6fb9 100644 --- a/include/sqlpp11/sum.h +++ b/include/sqlpp11/sum.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; static_assert(is_noop::value or std::is_same::value, "sum() used with flag other than 'distinct'"); static_assert(is_numeric_t::value, "sum() requires a numeric expression as argument"); diff --git a/include/sqlpp11/table.h b/include/sqlpp11/table.h index 06724089..06b2aa93 100644 --- a/include/sqlpp11/table.h +++ b/include/sqlpp11/table.h @@ -46,17 +46,8 @@ namespace sqlpp { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set
; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = detail::type_set<>; - }; + using _nodes = std::tuple<>; + using _provided_tables = detail::type_set
; static_assert(sizeof...(ColumnSpec), "at least one column required per table"); using _required_insert_columns = typename detail::make_type_set_if...>::type; diff --git a/include/sqlpp11/table_alias.h b/include/sqlpp11/table_alias.h index 32324b71..44277b71 100644 --- a/include/sqlpp11/table_alias.h +++ b/include/sqlpp11/table_alias.h @@ -42,17 +42,9 @@ namespace sqlpp //FIXME: Need to add join functionality using _traits = make_traits, tag::is_table, tag::is_alias, tag_if::value>>; - struct _recursive_traits - { - using _required_ctes = required_ctes_of
; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = detail::type_set<>; - }; + using _nodes = std::tuple<>; + using _required_ctes = required_ctes_of
; + using _provided_tables = detail::type_set; static_assert(required_tables_of
::size::value == 0, "table aliases must not depend on external tables"); diff --git a/include/sqlpp11/tvin.h b/include/sqlpp11/tvin.h index ca2af06b..c5c1ad7d 100644 --- a/include/sqlpp11/tvin.h +++ b/include/sqlpp11/tvin.h @@ -40,7 +40,7 @@ namespace sqlpp struct tvin_arg_t { using _traits = make_traits, tag::is_expression>; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _operand_t = Operand; @@ -102,7 +102,7 @@ namespace sqlpp struct tvin_t { using _traits = make_traits, tag::is_expression>; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _operand_t = Operand; diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 322b655f..2a897c4b 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -38,29 +38,8 @@ namespace sqlpp namespace tag { struct can_be_null{}; - struct contains_aggregate_function{}; } - namespace detail - { - template - struct can_be_null_impl { using type = std::false_type; }; - template - struct can_be_null_impl::value>::type> { using type = std::true_type; }; - } - template - using can_be_null_t = typename detail::can_be_null_impl::type; - - namespace detail - { - template - struct contains_aggregate_function_impl { using type = std::false_type; }; - template - struct contains_aggregate_function_impl::value>::type> { using type = std::true_type; }; - } - template - using contains_aggregate_function_t = typename detail::contains_aggregate_function_impl::type; - namespace detail { template @@ -82,7 +61,7 @@ namespace sqlpp template struct is_expression_impl::value - and not detail::is_element_of::value + //and not detail::is_element_of::value FIXME: Needed here? >::type> { using type = std::true_type; }; } template @@ -186,29 +165,80 @@ namespace sqlpp template using cpp_value_type_of = typename value_type_of::_cpp_value_type; - template - using required_ctes_of = typename T::_recursive_traits::_required_ctes; +#define SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(trait) \ + namespace detail\ + {\ + template\ + struct trait##_of_impl\ + {\ + using type = typename trait##_of_impl::type;\ + };\ + template\ + struct trait##_of_impl::value>::type>\ + {\ + using type = typename T::_##trait;\ + };\ + template\ + struct trait##_of_impl, void>\ + {\ + using type = detail::make_joined_set_t::type...>;\ + };\ + }\ + template\ + using trait##_of = typename detail::trait##_of_impl::type; - template - using provided_ctes_of = typename T::_recursive_traits::_provided_ctes; + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(required_ctes) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_ctes) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(required_tables) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_tables) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_outer_tables) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(extra_tables) - template - using required_tables_of = typename T::_recursive_traits::_required_tables; +#define SQLPP_RECURSIVE_TRAIT_GENERATOR(trait) \ + namespace detail\ + {\ + template\ + struct trait##_impl\ + {\ + using type = typename trait##_impl::type;\ + };\ + template\ + struct trait##_impl::value>::type>\ + {\ + using type = typename T::_##trait;\ + };\ + template\ + struct trait##_impl, void>\ + {\ + using type = logic::any_t::type::value...>;\ + };\ + }\ + template\ + using trait##_t = typename detail::trait##_impl::type; - template - using provided_tables_of = typename T::_recursive_traits::_provided_tables; + SQLPP_RECURSIVE_TRAIT_GENERATOR(can_be_null) + SQLPP_RECURSIVE_TRAIT_GENERATOR(contains_aggregate_function) - template - using provided_outer_tables_of = typename T::_recursive_traits::_provided_outer_tables; - - template - using extra_tables_of = typename T::_recursive_traits::_extra_tables; - - template - using parameters_of = typename T::_recursive_traits::_parameters; - - template - using recursive_tags_of = typename T::_recursive_traits::_tags; + namespace detail + { + template + struct parameters_of_impl + { + using type = typename parameters_of_impl::type; + }; + template + struct parameters_of_impl::value>::type> + { + using type = typename T::_parameters; + }; + template + struct parameters_of_impl, void> + { + using type = detail::make_parameter_tuple_t::type...>; + }; + } + template\ + using parameters_of = typename detail::parameters_of_impl::type; template using alias_of = typename T::_alias_t; @@ -223,36 +253,10 @@ namespace sqlpp using _tags = detail::make_type_set_t; }; - template - struct make_recursive_traits - { - using _required_ctes = detail::make_joined_set_t...>; - using _provided_ctes = detail::make_joined_set_t...>; - using _required_tables = detail::make_joined_set_t...>; - using _provided_tables = detail::make_joined_set_t...>; - using _provided_outer_tables = detail::make_joined_set_t...>; - using _extra_tables = detail::make_joined_set_t...>; - using _parameters = detail::make_parameter_tuple_t...>; - using _tags = detail::make_joined_set_t...>; - }; - - template - struct recursive_tags - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = detail::type_set; - }; - struct aggregate_function { - struct _traits { using _value_type = void; using _tags = detail::type_set<>; }; - using _recursive_traits = recursive_tags; + using _nodes = std::tuple<>; + using _contains_aggregate_function = std::true_type; }; template diff --git a/include/sqlpp11/union.h b/include/sqlpp11/union.h index d0860c54..22023b32 100644 --- a/include/sqlpp11/union.h +++ b/include/sqlpp11/union.h @@ -66,7 +66,7 @@ namespace sqlpp struct union_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _alias_t = struct{}; @@ -114,7 +114,7 @@ namespace sqlpp struct no_union_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/update_list.h b/include/sqlpp11/update_list.h index 28df9045..324a8284 100644 --- a/include/sqlpp11/update_list.h +++ b/include/sqlpp11/update_list.h @@ -68,7 +68,7 @@ namespace sqlpp struct update_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _is_dynamic = is_database; // Data @@ -153,7 +153,7 @@ namespace sqlpp struct no_update_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/using.h b/include/sqlpp11/using.h index 16fd6875..7f8b78fd 100644 --- a/include/sqlpp11/using.h +++ b/include/sqlpp11/using.h @@ -58,7 +58,7 @@ namespace sqlpp struct using_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _is_dynamic = is_database; @@ -121,7 +121,7 @@ namespace sqlpp struct no_using_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/value_or_null.h b/include/sqlpp11/value_or_null.h index 9cb2f9b2..8c78c698 100644 --- a/include/sqlpp11/value_or_null.h +++ b/include/sqlpp11/value_or_null.h @@ -51,7 +51,7 @@ namespace sqlpp using _cpp_value_type = typename ValueType::_cpp_value_type; using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; value_or_null_t(_cpp_value_type value): _value(value), diff --git a/include/sqlpp11/verbatim.h b/include/sqlpp11/verbatim.h index 5cae04b4..b65ec3d8 100644 --- a/include/sqlpp11/verbatim.h +++ b/include/sqlpp11/verbatim.h @@ -39,10 +39,8 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - struct _recursive_traits : public make_recursive_traits<> - { - using _tags = detail::type_set; // since we do not know what's going on inside the verbatim, we assume it can be null - }; + using _nodes = std::tuple<>; + using _can_be_null = std::true_type; // since we do not know what's going on inside the verbatim, we assume it can be null verbatim_t(std::string verbatim): _verbatim(verbatim) {} verbatim_t(const verbatim_t&) = default; diff --git a/include/sqlpp11/verbatim_table.h b/include/sqlpp11/verbatim_table.h index 0eb63ce4..2b23e761 100644 --- a/include/sqlpp11/verbatim_table.h +++ b/include/sqlpp11/verbatim_table.h @@ -50,10 +50,7 @@ namespace sqlpp struct verbatim_table_t: public table_t { - struct _recursive_traits: public table_t::_recursive_traits - { - using _provided_outer_tables = detail::type_set; - }; + using _nodes = std::tuple<>; struct _alias_t { diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index d37519cb..a8145c06 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -71,7 +71,7 @@ namespace sqlpp struct where_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = std::tuple; using _is_dynamic = is_database; @@ -149,7 +149,7 @@ namespace sqlpp struct where_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = where_data_t; @@ -198,7 +198,7 @@ namespace sqlpp struct no_where_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/with.h b/include/sqlpp11/with.h index 10d881bb..e736f561 100644 --- a/include/sqlpp11/with.h +++ b/include/sqlpp11/with.h @@ -66,17 +66,9 @@ namespace sqlpp struct with_t { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::make_joined_set_t...>; // with provides common table expressions - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = detail::make_parameter_tuple_t...>; - using _tags = detail::type_set<>; - }; + using _nodes = std::tuple<>; + using _provided_ctes = detail::make_joined_set_t...>; // with provides common table expressions + using _parameters = detail::make_parameter_tuple_t...>; using _is_dynamic = is_database; @@ -116,7 +108,7 @@ namespace sqlpp struct no_with_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/wrap_operand.h b/include/sqlpp11/wrap_operand.h index 8728197d..7cbdcb9f 100644 --- a/include/sqlpp11/wrap_operand.h +++ b/include/sqlpp11/wrap_operand.h @@ -43,7 +43,7 @@ namespace sqlpp struct boolean_operand: public alias_operators { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _value_t = bool; @@ -82,7 +82,7 @@ namespace sqlpp struct integral_operand: public alias_operators { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _value_t = int64_t; @@ -122,7 +122,7 @@ namespace sqlpp struct floating_point_operand: public alias_operators { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _value_t = double; @@ -161,7 +161,7 @@ namespace sqlpp struct text_operand: public alias_operators { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = std::tuple<>; using _value_t = std::string;