diff --git a/include/sqlpp11/detail/logic.h b/include/sqlpp11/detail/logic.h index 72e3a318..152da35e 100644 --- a/include/sqlpp11/detail/logic.h +++ b/include/sqlpp11/detail/logic.h @@ -34,52 +34,52 @@ namespace sqlpp namespace detail { template - struct and_impl; + struct all_impl; template<> - struct and_impl<> + struct all_impl<> { static constexpr bool value = true; }; template - struct and_impl + struct all_impl { - static constexpr bool value = and_impl::value; + static constexpr bool value = all_impl::value; }; template - struct and_impl + struct all_impl { static constexpr bool value = false; }; template class Predicate, typename... T> - using and_t = and_impl::value...>; + using all_t = all_impl::value...>; template - struct or_impl; + struct any_impl; template<> - struct or_impl<> + struct any_impl<> { static constexpr bool value = false; }; template - struct or_impl + struct any_impl { - static constexpr bool value = or_impl::value; + static constexpr bool value = any_impl::value; }; template - struct or_impl + struct any_impl { static constexpr bool value = true; }; template class Predicate, typename... T> - using or_t = or_impl::value...>; + using any_t = any_impl::value...>; } } diff --git a/include/sqlpp11/detail/type_set.h b/include/sqlpp11/detail/type_set.h index 53450cbe..3388748a 100644 --- a/include/sqlpp11/detail/type_set.h +++ b/include/sqlpp11/detail/type_set.h @@ -38,7 +38,10 @@ namespace sqlpp { // some forward declarations and helpers template - struct make_set; + struct make_type_set; + + template + struct is_element_of; // A type set template @@ -47,118 +50,126 @@ namespace sqlpp using size = std::integral_constant; using _is_type_set = std::true_type; - static_assert(std::is_same::type>::value, "use make_set to construct a set"); - - template - struct count - { - template - using same = std::is_same; - static constexpr bool value = or_t::value; - }; - - template - struct is_superset_of - { - static_assert(::sqlpp::vendor::wrong_t::value, "invalid argument for is_superset_of"); - }; - - template - struct is_superset_of> - { - static constexpr bool value = and_t::value; - }; - - template - struct join - { - static_assert(::sqlpp::vendor::wrong_t::value, "invalid argument for type_set::join"); - }; - - template - struct join> - { - using type = typename make_set::type; - }; - - template - struct is_subset_of - { - static_assert(::sqlpp::vendor::wrong_t::value, "invalid argument for is_subset_of"); - }; - - template - struct is_subset_of> - { - static constexpr bool value = type_set::template is_superset_of::value; - }; - - template - struct is_disjunct_from - { - static_assert(::sqlpp::vendor::wrong_t::value, "invalid argument for is_disjunct_from"); - }; - - template - struct is_disjunct_from> - { - static constexpr bool value = not(or_t::value or or_t::template count, Elements...>::value); - }; + static_assert(std::is_same::type>::value, "use make_type_set to construct a set"); template struct insert { - using type = typename std::conditional::value, - type_set, - type_set>::type; + using type = typename std::conditional::value, + type_set, + type_set>::type; }; template class Predicate, typename T> struct insert_if { - using type = typename std::conditional::value, + using type = typename std::conditional::value and not is_element_of::value, type_set, type_set>::type; }; }; + + template + struct is_element_of + { + static_assert(::sqlpp::vendor::wrong_t::value, "SET has to be a type set"); + }; + + template + struct is_element_of> + { + template + using matchE = std::is_same; + static constexpr bool value = any_t::value; + }; + + template + struct is_superset_of + { + static_assert(::sqlpp::vendor::wrong_t::value, "L and R have to be type sets"); + }; + + template + struct is_superset_of, type_set> + { + template + using is_element_of_L = is_element_of>; + static constexpr bool value = all_t::value; + }; + + template + struct is_subset_of + { + static constexpr bool value = is_superset_of::value; + }; + + template + struct joined_set + { + static_assert(::sqlpp::vendor::wrong_t::value, "L and R have to be type sets"); + }; + + template + struct joined_set, type_set> + { + using type = typename make_type_set::type; + }; + + template + struct is_disjunct_from + { + static_assert(::sqlpp::vendor::wrong_t::value, "invalid argument for is_disjunct_from"); + }; + + template + struct is_disjunct_from, type_set> + { + template + using is_element_of_L = is_element_of>; + template + using is_element_of_R = is_element_of>; + static constexpr bool value = + not(any_t::value or any_t::value); + }; + template<> - struct make_set<> + struct make_type_set<> { using type = type_set<>; }; template - struct make_set + struct make_type_set { - using type = typename make_set::type::template insert::type; + using type = typename make_type_set::type::template insert::type; }; template class Predicate, typename... T> - struct make_set_if; + struct make_type_set_if; template class Predicate> - struct make_set_if + struct make_type_set_if { using type = type_set<>; }; template class Predicate, typename T, typename... Rest> - struct make_set_if + struct make_type_set_if { - using type = typename make_set_if::type::template insert_if::type; + using type = typename make_type_set_if::type::template insert_if::type; }; template class Predicate, typename... T> - struct make_set_if_not + struct make_type_set_if_not { template using InversePredicate = std::integral_constant::value>; - using type = typename make_set_if::type; + using type = typename make_type_set_if::type; }; template - using has_duplicates = std::integral_constant::type::size::value != sizeof...(T)>; + using has_duplicates = std::integral_constant::type::size::value != sizeof...(T)>; template struct make_joined_set @@ -172,20 +183,12 @@ namespace sqlpp using type = type_set<>; }; - /* - template - struct make_joined_set> - { - using type = type_set; - }; - */ - template struct make_joined_set, T...> { using _rest = typename make_joined_set::type; - using type = typename type_set::template join<_rest>::type; + using type = typename joined_set, _rest>::type; }; } diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index eb60554a..11bda07f 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -45,7 +45,7 @@ namespace sqlpp > struct insert_t { - static_assert(Table::_table_set::template is_superset_of::value, "columns do not match the table they are to be inserted into"); + static_assert(::sqlpp::detail::is_superset_of::value, "columns do not match the table they are to be inserted into"); using _database_t = Database; using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; diff --git a/include/sqlpp11/join.h b/include/sqlpp11/join.h index 23816184..4351bf58 100644 --- a/include/sqlpp11/join.h +++ b/include/sqlpp11/join.h @@ -82,11 +82,11 @@ namespace sqlpp static_assert(not is_join_t::value, "rhs argument for join must not be a join"); static_assert(vendor::is_noop::value or is_on_t::value, "invalid on expression in join().on()"); - static_assert(Lhs::_table_set::template is_disjunct_from::value, "joined tables must not be identical"); + static_assert(::sqlpp::detail::is_disjunct_from::value, "joined tables must not be identical"); using _is_table = std::true_type; using _is_join = std::true_type; - using _table_set = typename Lhs::_table_set::template join::type; + using _table_set = typename ::sqlpp::detail::make_joined_set::type; template using set_on_t = join_t; diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index c6260b30..cfe7c212 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -40,7 +40,7 @@ namespace sqlpp template struct multi_column_t { - static_assert(detail::and_t::value, "multi_column parameters need to be named expressions"); + static_assert(detail::all_t::value, "multi_column parameters need to be named expressions"); multi_column_t(std::tuple columns): _columns(columns) @@ -72,7 +72,7 @@ namespace sqlpp template struct multi_column_alias_t { - static_assert(detail::and_t::value, "multi_column parameters need to be named expressions"); + static_assert(detail::all_t::value, "multi_column parameters need to be named expressions"); using _name_t = typename AliasProvider::_name_t; diff --git a/include/sqlpp11/on.h b/include/sqlpp11/on.h index 96ade430..9db74885 100644 --- a/include/sqlpp11/on.h +++ b/include/sqlpp11/on.h @@ -41,7 +41,7 @@ namespace sqlpp using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in on()"); - static_assert(detail::and_t::value, "at least one argument is not an expression in on()"); + static_assert(detail::all_t::value, "at least one argument is not an expression in on()"); template void add(E expr) diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index d40ff72b..44df0227 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -497,9 +497,12 @@ namespace sqlpp template struct can_run_t { + /* static_assert(column_list::_table_set::template is_subset_t<_from_t::_table_set>::value + static_assert(detail::is_subset_of::value subset_of_t sollte ein eigenes template sein, das macht so etwas wie obiges sicher einfacher lesbar also: use any and all instead of and_t and or_t + */ //static_assert(is_where_t::value, "cannot select select without having a where condition, use .where(true) to remove all rows"); //static_assert(not vendor::is_noop::value, "cannot run select without having selected anything"); //static_assert(is_from_t::value, "cannot run select without a from()"); diff --git a/include/sqlpp11/table.h b/include/sqlpp11/table.h index 909074e4..ca694c0e 100644 --- a/include/sqlpp11/table.h +++ b/include/sqlpp11/table.h @@ -44,7 +44,7 @@ namespace sqlpp { using _table_set = detail::type_set; // Hint need a type_set here to be similar to a join (which always represents more than one table) static_assert(sizeof...(ColumnSpec), "at least one column required per table"); - using _required_insert_columns = typename detail::make_set_if...>::type; + using _required_insert_columns = typename detail::make_type_set_if...>::type; using _column_tuple_t = std::tuple...>; template using _alias_t = table_alias_t; diff --git a/include/sqlpp11/update.h b/include/sqlpp11/update.h index 9173a969..5c8be581 100644 --- a/include/sqlpp11/update.h +++ b/include/sqlpp11/update.h @@ -57,8 +57,8 @@ namespace sqlpp typename Where = vendor::no_where_t> struct update_t { - static_assert(Table::_table_set::template is_superset_of::value, "updated columns do not match the table"); - static_assert(Table::_table_set::template is_superset_of::value, "where condition does not match updated table"); + static_assert(::sqlpp::detail::is_superset_of::value, "updated columns do not match the table"); + static_assert(::sqlpp::detail::is_superset_of::value, "where condition does not match updated table"); using _database_t = Database; using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; diff --git a/include/sqlpp11/vendor/assignment.h b/include/sqlpp11/vendor/assignment.h index 5a21731b..c3e17156 100644 --- a/include/sqlpp11/vendor/assignment.h +++ b/include/sqlpp11/vendor/assignment.h @@ -69,7 +69,7 @@ namespace sqlpp using _column_t = Lhs; using value_type = Rhs; using _parameter_tuple_t = std::tuple<_column_t, Rhs>; - using _table_set = typename Lhs::_table_set::template join::type; + using _table_set = typename ::sqlpp::detail::make_joined_set::type; static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same::value, "column must not be null"); @@ -119,6 +119,7 @@ namespace sqlpp using _column_t = Lhs; using value_type = tvin_t; using _parameter_tuple_t = std::tuple<_column_t, Rhs>; + using _table_set = typename ::sqlpp::detail::make_joined_set::type; static_assert(can_be_null_t<_column_t>::value, "column cannot be null"); diff --git a/include/sqlpp11/vendor/concat.h b/include/sqlpp11/vendor/concat.h index 9d851da5..fb8e97b4 100644 --- a/include/sqlpp11/vendor/concat.h +++ b/include/sqlpp11/vendor/concat.h @@ -39,7 +39,7 @@ namespace sqlpp struct concat_t: public First::_value_type::template operators> { static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); - static_assert(sqlpp::detail::and_t::value, "at least one non-text argument detected in concat()"); + static_assert(sqlpp::detail::all_t::value, "at least one non-text argument detected in concat()"); using _table_set = typename ::sqlpp::detail::make_joined_set::type; struct _value_type: public First::_value_type::_base_value_type diff --git a/include/sqlpp11/vendor/expression.h b/include/sqlpp11/vendor/expression.h index 9d2a8868..455aebb7 100644 --- a/include/sqlpp11/vendor/expression.h +++ b/include/sqlpp11/vendor/expression.h @@ -209,6 +209,7 @@ namespace sqlpp { using _value_type = typename O::_value_type; using _parameter_tuple_t = std::tuple; + using _table_set = typename Rhs::_table_set; unary_expression_t(Rhs rhs): _rhs(rhs) diff --git a/include/sqlpp11/vendor/from.h b/include/sqlpp11/vendor/from.h index ce9dc50b..87ae0c7a 100644 --- a/include/sqlpp11/vendor/from.h +++ b/include/sqlpp11/vendor/from.h @@ -49,7 +49,7 @@ namespace sqlpp // FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in from()"); - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not a table or join in from()"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not a table or join in from()"); using _table_set = typename ::sqlpp::detail::make_joined_set; diff --git a/include/sqlpp11/vendor/group_by.h b/include/sqlpp11/vendor/group_by.h index d67764b7..cefd2c8d 100644 --- a/include/sqlpp11/vendor/group_by.h +++ b/include/sqlpp11/vendor/group_by.h @@ -51,7 +51,7 @@ namespace sqlpp static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in group_by()"); - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not an expression in group_by()"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not an expression in group_by()"); group_by_t(Expressions... expressions): _expressions(expressions...) diff --git a/include/sqlpp11/vendor/having.h b/include/sqlpp11/vendor/having.h index 0a3fd34e..904e13d8 100644 --- a/include/sqlpp11/vendor/having.h +++ b/include/sqlpp11/vendor/having.h @@ -47,7 +47,7 @@ namespace sqlpp using _parameter_tuple_t = std::tuple; static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()"); - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not an expression in having()"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not an expression in having()"); using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; diff --git a/include/sqlpp11/vendor/insert_value_list.h b/include/sqlpp11/vendor/insert_value_list.h index 74ffecdc..c04ed95a 100644 --- a/include/sqlpp11/vendor/insert_value_list.h +++ b/include/sqlpp11/vendor/insert_value_list.h @@ -61,15 +61,15 @@ namespace sqlpp static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); - static_assert(sqlpp::detail::and_t::value, "at least one argument is not an assignment in set()"); + static_assert(sqlpp::detail::all_t::value, "at least one argument is not an assignment in set()"); - static_assert(not sqlpp::detail::or_t::value, "at least one assignment is prohibited by its column definition in set()"); + static_assert(not sqlpp::detail::any_t::value, "at least one assignment is prohibited by its column definition in set()"); using _column_table_set = typename ::sqlpp::detail::make_joined_set::type; using _value_table_set = typename ::sqlpp::detail::make_joined_set::type; using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type; static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns"); - static_assert(_value_table_set::template is_subset_of<_column_table_set>::value, "set() contains values from foreign tables"); + static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables"); insert_list_t(Assignments... assignment): _assignments(assignment...), @@ -90,8 +90,8 @@ namespace sqlpp static_assert(not must_not_insert_t::value, "add_set() argument must not be used in insert"); using _column_table_set = typename Assignment::_column_t::_table_set; using _value_table_set = typename Assignment::value_type::_table_set; - static_assert(_value_table_set::template is_subset_of::value, "add_set() contains a column from a foreign table"); - static_assert(_column_table_set::template is_subset_of::value, "add_set() contains a value from a foreign table"); + static_assert(::sqlpp::detail::is_subset_of<_value_table_set, typename Insert::_table_set>::value, "add_set() contains a column from a foreign table"); + static_assert(::sqlpp::detail::is_subset_of<_column_table_set, typename Insert::_table_set>::value, "add_set() contains a value from a foreign table"); _dynamic_columns.emplace_back(simple_column_t{assignment._lhs}); _dynamic_values.emplace_back(assignment._rhs); } @@ -114,9 +114,9 @@ namespace sqlpp static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in columns()"); - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not a column in columns()"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not a column in columns()"); - static_assert(not ::sqlpp::detail::or_t::value, "at least one column argument has a must_not_insert flag in its definition"); + static_assert(not ::sqlpp::detail::any_t::value, "at least one column argument has a must_not_insert flag in its definition"); using _value_tuple_t = std::tuple...>; using _table_set = typename ::sqlpp::detail::make_joined_set::type; @@ -136,7 +136,7 @@ namespace sqlpp template void add_values(Assignments... assignments) { - static_assert(::sqlpp::detail::and_t::value, "add_values() arguments have to be assignments"); + static_assert(::sqlpp::detail::all_t::value, "add_values() arguments have to be assignments"); using _arg_value_tuple = std::tuple...>; using _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>; static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments"); diff --git a/include/sqlpp11/vendor/order_by.h b/include/sqlpp11/vendor/order_by.h index 391bd1dc..a96813c7 100644 --- a/include/sqlpp11/vendor/order_by.h +++ b/include/sqlpp11/vendor/order_by.h @@ -49,7 +49,7 @@ namespace sqlpp static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in order_by()"); - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not a sort order expression in order_by()"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not a sort order expression in order_by()"); order_by_t(Expressions... expressions): _expressions(expressions...) diff --git a/include/sqlpp11/vendor/select_column_list.h b/include/sqlpp11/vendor/select_column_list.h index 08ac6211..d3dd2130 100644 --- a/include/sqlpp11/vendor/select_column_list.h +++ b/include/sqlpp11/vendor/select_column_list.h @@ -143,7 +143,7 @@ namespace sqlpp template using is_valid_expression_t = std::integral_constant::value or is_multi_column_t::value>; - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not a named expression"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not a named expression"); static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate name detected"); diff --git a/include/sqlpp11/vendor/select_flag_list.h b/include/sqlpp11/vendor/select_flag_list.h index ea4ce0db..54975094 100644 --- a/include/sqlpp11/vendor/select_flag_list.h +++ b/include/sqlpp11/vendor/select_flag_list.h @@ -49,7 +49,7 @@ namespace sqlpp static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in select flag list"); - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not a select flag in select flag list"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not a select flag in select flag list"); select_flag_list_t(Flags... flags): _flags(flags...) diff --git a/include/sqlpp11/vendor/update_list.h b/include/sqlpp11/vendor/update_list.h index bd4530e0..f2684628 100644 --- a/include/sqlpp11/vendor/update_list.h +++ b/include/sqlpp11/vendor/update_list.h @@ -48,15 +48,15 @@ namespace sqlpp static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not an assignment in set()"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not an assignment in set()"); - static_assert(not ::sqlpp::detail::or_t::value, "at least one assignment is prohibited by its column definition in set()"); + static_assert(not ::sqlpp::detail::any_t::value, "at least one assignment is prohibited by its column definition in set()"); using _column_table_set = typename ::sqlpp::detail::make_joined_set::type; using _value_table_set = typename ::sqlpp::detail::make_joined_set::type; using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type; static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns"); - static_assert(_value_table_set::template is_subset_of<_column_table_set>::value, "set() contains values from foreign tables"); + static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables"); update_list_t(Assignments... assignments): _assignments(assignments...) diff --git a/include/sqlpp11/vendor/using.h b/include/sqlpp11/vendor/using.h index 3ef79454..940cfca9 100644 --- a/include/sqlpp11/vendor/using.h +++ b/include/sqlpp11/vendor/using.h @@ -49,7 +49,7 @@ namespace sqlpp static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in using()"); - static_assert(::sqlpp::detail::and_t::value, "at least one argument is not an table in using()"); + static_assert(::sqlpp::detail::all_t::value, "at least one argument is not an table in using()"); using_t(Tables... tables): _tables(tables...) diff --git a/include/sqlpp11/vendor/where.h b/include/sqlpp11/vendor/where.h index 63cf763b..2177ec59 100644 --- a/include/sqlpp11/vendor/where.h +++ b/include/sqlpp11/vendor/where.h @@ -47,8 +47,8 @@ namespace sqlpp using _parameter_tuple_t = std::tuple; static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()"); - static_assert(not sqlpp::detail::or_t::value, "at least one argument is an assignment in where()"); - static_assert(sqlpp::detail::and_t::value, "at least one argument is not valid expression in where()"); + static_assert(not sqlpp::detail::any_t::value, "at least one argument is an assignment in where()"); + static_assert(sqlpp::detail::all_t::value, "at least one argument is not valid expression in where()"); using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;