0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Rewrote type-set operations to look more like free functions

This commit is contained in:
rbock 2014-03-19 18:59:39 +01:00
parent 82dc280b1b
commit 555aba3f14
22 changed files with 132 additions and 124 deletions

View File

@ -34,52 +34,52 @@ namespace sqlpp
namespace detail
{
template<bool... b>
struct and_impl;
struct all_impl;
template<>
struct and_impl<>
struct all_impl<>
{
static constexpr bool value = true;
};
template<bool... Rest>
struct and_impl<true, Rest...>
struct all_impl<true, Rest...>
{
static constexpr bool value = and_impl<Rest...>::value;
static constexpr bool value = all_impl<Rest...>::value;
};
template<bool... Rest>
struct and_impl<false, Rest...>
struct all_impl<false, Rest...>
{
static constexpr bool value = false;
};
template<template<typename> class Predicate, typename... T>
using and_t = and_impl<Predicate<T>::value...>;
using all_t = all_impl<Predicate<T>::value...>;
template<bool... b>
struct or_impl;
struct any_impl;
template<>
struct or_impl<>
struct any_impl<>
{
static constexpr bool value = false;
};
template<bool... Rest>
struct or_impl<false, Rest...>
struct any_impl<false, Rest...>
{
static constexpr bool value = or_impl<Rest...>::value;
static constexpr bool value = any_impl<Rest...>::value;
};
template<bool... Rest>
struct or_impl<true, Rest...>
struct any_impl<true, Rest...>
{
static constexpr bool value = true;
};
template<template<typename> class Predicate, typename... T>
using or_t = or_impl<Predicate<T>::value...>;
using any_t = any_impl<Predicate<T>::value...>;
}
}

View File

@ -38,7 +38,10 @@ namespace sqlpp
{
// some forward declarations and helpers
template<typename... T>
struct make_set;
struct make_type_set;
template<typename E, typename SET>
struct is_element_of;
// A type set
template<typename... Elements>
@ -47,118 +50,126 @@ namespace sqlpp
using size = std::integral_constant<size_t, sizeof...(Elements)>;
using _is_type_set = std::true_type;
static_assert(std::is_same<type_set, typename make_set<Elements...>::type>::value, "use make_set to construct a set");
template<typename T>
struct count
{
template<typename E>
using same = std::is_same<T, E>;
static constexpr bool value = or_t<same, Elements...>::value;
};
template<typename T>
struct is_superset_of
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_superset_of");
};
template<typename... T>
struct is_superset_of<type_set<T...>>
{
static constexpr bool value = and_t<count, T...>::value;
};
template<typename T>
struct join
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for type_set::join");
};
template<typename... T>
struct join<type_set<T...>>
{
using type = typename make_set<Elements..., T...>::type;
};
template<typename T>
struct is_subset_of
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_subset_of");
};
template<typename... T>
struct is_subset_of<type_set<T...>>
{
static constexpr bool value = type_set<T...>::template is_superset_of<type_set>::value;
};
template<typename T>
struct is_disjunct_from
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_disjunct_from");
};
template<typename... T>
struct is_disjunct_from<type_set<T...>>
{
static constexpr bool value = not(or_t<type_set::count, T...>::value or or_t<type_set<T...>::template count, Elements...>::value);
};
static_assert(std::is_same<type_set, typename make_type_set<Elements...>::type>::value, "use make_type_set to construct a set");
template<typename T>
struct insert
{
using type = typename std::conditional<count<T>::value,
type_set,
type_set<T, Elements...>>::type;
using type = typename std::conditional<not is_element_of<T, type_set>::value,
type_set<T, Elements...>,
type_set>::type;
};
template<template<typename A> class Predicate, typename T>
struct insert_if
{
using type = typename std::conditional<Predicate<T>::value,
using type = typename std::conditional<Predicate<T>::value and not is_element_of<T, type_set>::value,
type_set<Elements..., T>,
type_set>::type;
};
};
template<typename E, typename SET>
struct is_element_of
{
static_assert(::sqlpp::vendor::wrong_t<E, SET>::value, "SET has to be a type set");
};
template<typename E, typename... Elements>
struct is_element_of<E, type_set<Elements...>>
{
template<typename X>
using matchE = std::is_same<E, X>;
static constexpr bool value = any_t<matchE, Elements...>::value;
};
template<typename L, typename R>
struct is_superset_of
{
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "L and R have to be type sets");
};
template<typename... LElements, typename... RElements>
struct is_superset_of<type_set<LElements...>, type_set<RElements...>>
{
template<typename X>
using is_element_of_L = is_element_of<X, type_set<LElements...>>;
static constexpr bool value = all_t<is_element_of_L, RElements...>::value;
};
template<typename L, typename R>
struct is_subset_of
{
static constexpr bool value = is_superset_of<R, L>::value;
};
template<typename L, typename R>
struct joined_set
{
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "L and R have to be type sets");
};
template<typename... LElements, typename... RElements>
struct joined_set<type_set<LElements...>, type_set<RElements...>>
{
using type = typename make_type_set<LElements..., RElements...>::type;
};
template<typename L, typename R>
struct is_disjunct_from
{
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "invalid argument for is_disjunct_from");
};
template<typename... LElements, typename... RElements>
struct is_disjunct_from<type_set<LElements...>, type_set<RElements...>>
{
template<typename X>
using is_element_of_L = is_element_of<X, type_set<LElements...>>;
template<typename X>
using is_element_of_R = is_element_of<X, type_set<RElements...>>;
static constexpr bool value =
not(any_t<is_element_of_L, RElements...>::value or any_t<is_element_of_R, LElements...>::value);
};
template<>
struct make_set<>
struct make_type_set<>
{
using type = type_set<>;
};
template<typename T, typename... Rest>
struct make_set<T, Rest...>
struct make_type_set<T, Rest...>
{
using type = typename make_set<Rest...>::type::template insert<T>::type;
using type = typename make_type_set<Rest...>::type::template insert<T>::type;
};
template<template<typename> class Predicate, typename... T>
struct make_set_if;
struct make_type_set_if;
template<template<typename> class Predicate>
struct make_set_if<Predicate>
struct make_type_set_if<Predicate>
{
using type = type_set<>;
};
template<template<typename> class Predicate, typename T, typename... Rest>
struct make_set_if<Predicate, T, Rest...>
struct make_type_set_if<Predicate, T, Rest...>
{
using type = typename make_set_if<Predicate, Rest...>::type::template insert_if<Predicate, T>::type;
using type = typename make_type_set_if<Predicate, Rest...>::type::template insert_if<Predicate, T>::type;
};
template<template<typename> class Predicate, typename... T>
struct make_set_if_not
struct make_type_set_if_not
{
template<typename X>
using InversePredicate = std::integral_constant<bool, not Predicate<X>::value>;
using type = typename make_set_if<InversePredicate, T...>::type;
using type = typename make_type_set_if<InversePredicate, T...>::type;
};
template<typename... T>
using has_duplicates = std::integral_constant<bool, make_set<T...>::type::size::value != sizeof...(T)>;
using has_duplicates = std::integral_constant<bool, make_type_set<T...>::type::size::value != sizeof...(T)>;
template<typename... T>
struct make_joined_set
@ -172,20 +183,12 @@ namespace sqlpp
using type = type_set<>;
};
/*
template<typename... E>
struct make_joined_set<type_set<E...>>
{
using type = type_set<E...>;
};
*/
template<typename... E, typename... T>
struct make_joined_set<type_set<E...>, T...>
{
using _rest = typename make_joined_set<T...>::type;
using type = typename type_set<E...>::template join<_rest>::type;
using type = typename joined_set<type_set<E...>, _rest>::type;
};
}

View File

@ -45,7 +45,7 @@ namespace sqlpp
>
struct insert_t
{
static_assert(Table::_table_set::template is_superset_of<typename InsertValueList::_table_set>::value, "columns do not match the table they are to be inserted into");
static_assert(::sqlpp::detail::is_superset_of<typename Table::_table_set, typename InsertValueList::_table_set>::value, "columns do not match the table they are to be inserted into");
using _database_t = Database;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;

View File

@ -82,11 +82,11 @@ namespace sqlpp
static_assert(not is_join_t<Rhs>::value, "rhs argument for join must not be a join");
static_assert(vendor::is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
static_assert(Lhs::_table_set::template is_disjunct_from<typename Rhs::_table_set>::value, "joined tables must not be identical");
static_assert(::sqlpp::detail::is_disjunct_from<typename Lhs::_table_set, typename Rhs::_table_set>::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<typename Rhs::_table_set>::type;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
template<typename OnT>
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;

View File

@ -40,7 +40,7 @@ namespace sqlpp
template<typename Unused, typename... Columns>
struct multi_column_t
{
static_assert(detail::and_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
static_assert(detail::all_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
multi_column_t(std::tuple<Columns...> columns):
_columns(columns)
@ -72,7 +72,7 @@ namespace sqlpp
template<typename AliasProvider, typename... Columns>
struct multi_column_alias_t
{
static_assert(detail::and_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
static_assert(detail::all_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
using _name_t = typename AliasProvider::_name_t;

View File

@ -41,7 +41,7 @@ namespace sqlpp
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::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<is_expression_t, Expr...>::value, "at least one argument is not an expression in on()");
static_assert(detail::all_t<is_expression_t, Expr...>::value, "at least one argument is not an expression in on()");
template<typename E>
void add(E expr)

View File

@ -497,9 +497,12 @@ namespace sqlpp
template<typename Db>
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<column_list::_table_set, _from_t::_table_set>::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<Where>::value, "cannot select select without having a where condition, use .where(true) to remove all rows");
//static_assert(not vendor::is_noop<ColumnList>::value, "cannot run select without having selected anything");
//static_assert(is_from_t<From>::value, "cannot run select without a from()");

View File

@ -44,7 +44,7 @@ namespace sqlpp
{
using _table_set = detail::type_set<Table>; // 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<require_insert_t, column_t<Table, ColumnSpec>...>::type;
using _required_insert_columns = typename detail::make_type_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type;
using _column_tuple_t = std::tuple<column_t<Table, ColumnSpec>...>;
template<typename AliasProvider>
using _alias_t = table_alias_t<AliasProvider, Table, ColumnSpec...>;

View File

@ -57,8 +57,8 @@ namespace sqlpp
typename Where = vendor::no_where_t>
struct update_t
{
static_assert(Table::_table_set::template is_superset_of<typename UpdateList::_table_set>::value, "updated columns do not match the table");
static_assert(Table::_table_set::template is_superset_of<typename Where::_table_set>::value, "where condition does not match updated table");
static_assert(::sqlpp::detail::is_superset_of<typename Table::_table_set, typename UpdateList::_table_set>::value, "updated columns do not match the table");
static_assert(::sqlpp::detail::is_superset_of<typename Table::_table_set, typename Where::_table_set>::value, "where condition does not match updated table");
using _database_t = Database;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;

View File

@ -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<typename Rhs::_table_set>::type;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same<Rhs, null_t>::value, "column must not be null");
@ -119,6 +119,7 @@ namespace sqlpp
using _column_t = Lhs;
using value_type = tvin_t<Rhs>;
using _parameter_tuple_t = std::tuple<_column_t, Rhs>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
static_assert(can_be_null_t<_column_t>::value, "column cannot be null");

View File

@ -39,7 +39,7 @@ namespace sqlpp
struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>>
{
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
static_assert(sqlpp::detail::and_t<is_text_t, First, Args...>::value, "at least one non-text argument detected in concat()");
static_assert(sqlpp::detail::all_t<is_text_t, First, Args...>::value, "at least one non-text argument detected in concat()");
using _table_set = typename ::sqlpp::detail::make_joined_set<typename First::_table_set, typename Args::_table_set...>::type;
struct _value_type: public First::_value_type::_base_value_type

View File

@ -209,6 +209,7 @@ namespace sqlpp
{
using _value_type = typename O::_value_type;
using _parameter_tuple_t = std::tuple<Rhs>;
using _table_set = typename Rhs::_table_set;
unary_expression_t(Rhs rhs):
_rhs(rhs)

View File

@ -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<Tables...>::value, "at least one duplicate argument detected in from()");
static_assert(::sqlpp::detail::and_t<is_table_t, Tables...>::value, "at least one argument is not a table or join in from()");
static_assert(::sqlpp::detail::all_t<is_table_t, Tables...>::value, "at least one argument is not a table or join in from()");
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Tables::_table_set...>;

View File

@ -51,7 +51,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
static_assert(::sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in group_by()");
static_assert(::sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in group_by()");
group_by_t(Expressions... expressions):
_expressions(expressions...)

View File

@ -47,7 +47,7 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Expressions...>;
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
static_assert(::sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in having()");
static_assert(::sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in having()");
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;

View File

@ -61,15 +61,15 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
static_assert(sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
static_assert(sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
static_assert(not sqlpp::detail::or_t<must_not_insert_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
static_assert(not sqlpp::detail::any_t<must_not_insert_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_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<Assignment>::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<typename Insert::_table_set>::value, "add_set() contains a column from a foreign table");
static_assert(_column_table_set::template is_subset_of<typename Insert::_table_set>::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<typename Assignment::_column_t>{assignment._lhs});
_dynamic_values.emplace_back(assignment._rhs);
}
@ -114,9 +114,9 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
static_assert(::sqlpp::detail::and_t<is_column_t, Columns...>::value, "at least one argument is not a column in columns()");
static_assert(::sqlpp::detail::all_t<is_column_t, Columns...>::value, "at least one argument is not a column in columns()");
static_assert(not ::sqlpp::detail::or_t<must_not_insert_t, Columns...>::value, "at least one column argument has a must_not_insert flag in its definition");
static_assert(not ::sqlpp::detail::any_t<must_not_insert_t, Columns...>::value, "at least one column argument has a must_not_insert flag in its definition");
using _value_tuple_t = std::tuple<vendor::insert_value_t<Columns>...>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Columns::_table_set...>::type;
@ -136,7 +136,7 @@ namespace sqlpp
template<typename... Assignments>
void add_values(Assignments... assignments)
{
static_assert(::sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "add_values() arguments have to be assignments");
static_assert(::sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "add_values() arguments have to be assignments");
using _arg_value_tuple = std::tuple<vendor::insert_value_t<typename Assignments::_column_t>...>;
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");

View File

@ -49,7 +49,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
static_assert(::sqlpp::detail::and_t<is_sort_order_t, Expressions...>::value, "at least one argument is not a sort order expression in order_by()");
static_assert(::sqlpp::detail::all_t<is_sort_order_t, Expressions...>::value, "at least one argument is not a sort order expression in order_by()");
order_by_t(Expressions... expressions):
_expressions(expressions...)

View File

@ -143,7 +143,7 @@ namespace sqlpp
template<typename T>
using is_valid_expression_t = std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value>;
static_assert(::sqlpp::detail::and_t<is_valid_expression_t, Columns...>::value, "at least one argument is not a named expression");
static_assert(::sqlpp::detail::all_t<is_valid_expression_t, Columns...>::value, "at least one argument is not a named expression");
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");

View File

@ -49,7 +49,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
static_assert(::sqlpp::detail::and_t<is_select_flag_t, Flags...>::value, "at least one argument is not a select flag in select flag list");
static_assert(::sqlpp::detail::all_t<is_select_flag_t, Flags...>::value, "at least one argument is not a select flag in select flag list");
select_flag_list_t(Flags... flags):
_flags(flags...)

View File

@ -48,15 +48,15 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
static_assert(::sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
static_assert(::sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
static_assert(not ::sqlpp::detail::or_t<must_not_update_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
static_assert(not ::sqlpp::detail::any_t<must_not_update_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_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...)

View File

@ -49,7 +49,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in using()");
static_assert(::sqlpp::detail::and_t<is_table_t, Tables...>::value, "at least one argument is not an table in using()");
static_assert(::sqlpp::detail::all_t<is_table_t, Tables...>::value, "at least one argument is not an table in using()");
using_t(Tables... tables):
_tables(tables...)

View File

@ -47,8 +47,8 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Expressions...>;
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
static_assert(not sqlpp::detail::or_t<is_assignment_t, Expressions...>::value, "at least one argument is an assignment in where()");
static_assert(sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not valid expression in where()");
static_assert(not sqlpp::detail::any_t<is_assignment_t, Expressions...>::value, "at least one argument is an assignment in where()");
static_assert(sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not valid expression in where()");
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;