Moved operator and parameter templates out of value classes, added member template

These templates are nicer when used.
This commit is contained in:
rbock
2014-08-25 08:43:42 +02:00
parent 8d8b358092
commit 2c23769cdf
26 changed files with 509 additions and 395 deletions

View File

@@ -32,8 +32,9 @@
namespace sqlpp
{
template<typename Flag, typename Expr>
struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>>,
public alias_operators<avg_t<Flag, Expr>>
struct avg_t:
public expression_operators<avg_t<Flag, Expr>, floating_point>,
public alias_operators<avg_t<Flag, Expr>>
{
using _traits = make_traits<floating_point, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Expr>;

View File

@@ -27,6 +27,7 @@
#ifndef SQLPP_DETAIL_BASIC_EXPRESSION_OPERATORS_H
#define SQLPP_DETAIL_BASIC_EXPRESSION_OPERATORS_H
#include <sqlpp11/value_type_fwd.h>
#include <sqlpp11/alias.h>
#include <sqlpp11/sort_order.h>
#include <sqlpp11/expression_fwd.h>
@@ -38,7 +39,7 @@
namespace sqlpp
{
// basic operators
template<typename Base, template<typename> class IsCorrectValueType>
template<typename Expr, typename ValueType>
struct basic_expression_operators
{
template<typename T>
@@ -47,107 +48,107 @@ namespace sqlpp
static constexpr bool value =
(is_expression_t<T>::value // expressions are OK
or is_multi_expression_t<T>::value) // multi-expressions like ANY are OK for comparisons, too
and IsCorrectValueType<T>::value // the correct value type is required, of course
and ValueType::template _is_valid_operand<T>::value // the correct value type is required, of course
;
};
template<typename T>
equal_to_t<Base, wrap_operand_t<T>> operator==(T t) const
equal_to_t<Expr, wrap_operand_t<T>> operator==(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
return { *static_cast<const Base*>(this), {rhs{t}} };
return { *static_cast<const Expr*>(this), {rhs{t}} };
}
template<typename T>
not_equal_to_t<Base, wrap_operand_t<T>> operator!=(T t) const
not_equal_to_t<Expr, wrap_operand_t<T>> operator!=(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
return { *static_cast<const Base*>(this), {rhs{t}} };
return { *static_cast<const Expr*>(this), {rhs{t}} };
}
template<typename T>
less_than_t<Base, wrap_operand_t<T>> operator<(T t) const
less_than_t<Expr, wrap_operand_t<T>> operator<(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
return { *static_cast<const Base*>(this), rhs{t} };
return { *static_cast<const Expr*>(this), rhs{t} };
}
template<typename T>
less_equal_t<Base, wrap_operand_t<T>> operator<=(T t) const
less_equal_t<Expr, wrap_operand_t<T>> operator<=(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
return { *static_cast<const Base*>(this), rhs{t} };
return { *static_cast<const Expr*>(this), rhs{t} };
}
template<typename T>
greater_than_t<Base, wrap_operand_t<T>> operator>(T t) const
greater_than_t<Expr, wrap_operand_t<T>> operator>(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
return { *static_cast<const Base*>(this), rhs{t} };
return { *static_cast<const Expr*>(this), rhs{t} };
}
template<typename T>
greater_equal_t<Base, wrap_operand_t<T>> operator>=(T t) const
greater_equal_t<Expr, wrap_operand_t<T>> operator>=(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
return { *static_cast<const Base*>(this), rhs{t} };
return { *static_cast<const Expr*>(this), rhs{t} };
}
is_null_t<true, Base> is_null() const
is_null_t<true, Expr> is_null() const
{
return { *static_cast<const Base*>(this) };
return { *static_cast<const Expr*>(this) };
}
is_null_t<false, Base> is_not_null() const
is_null_t<false, Expr> is_not_null() const
{
return { *static_cast<const Base*>(this) };
return { *static_cast<const Expr*>(this) };
}
sort_order_t<Base, sort_type::asc> asc() const
sort_order_t<Expr, sort_type::asc> asc() const
{
return { *static_cast<const Base*>(this) };
return { *static_cast<const Expr*>(this) };
}
sort_order_t<Base, sort_type::desc> desc() const
sort_order_t<Expr, sort_type::desc> desc() const
{
return { *static_cast<const Base*>(this) };
return { *static_cast<const Expr*>(this) };
}
// Hint: use value_list wrapper for containers...
template<typename... T>
in_t<true, Base, wrap_operand_t<T>...> in(T... t) const
in_t<true, Expr, wrap_operand_t<T>...> in(T... t) const
{
static_assert(detail::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
return { *static_cast<const Base*>(this), wrap_operand_t<T>{t}... };
return { *static_cast<const Expr*>(this), wrap_operand_t<T>{t}... };
}
template<typename... T>
in_t<false, Base, wrap_operand_t<T>...> not_in(T... t) const
in_t<false, Expr, wrap_operand_t<T>...> not_in(T... t) const
{
static_assert(detail::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
return { *static_cast<const Base*>(this), wrap_operand_t<T>{t}... };
return { *static_cast<const Expr*>(this), wrap_operand_t<T>{t}... };
}
};
template<typename Base>
template<typename Expr>
struct alias_operators
{
template<typename alias_provider>
expression_alias_t<Base, alias_provider> as(const alias_provider&) const
expression_alias_t<Expr, alias_provider> as(const alias_provider&) const
{
return { *static_cast<const Base*>(this) };
return { *static_cast<const Expr*>(this) };
}
};

View File

@@ -44,28 +44,34 @@ namespace sqlpp
using _tag = ::sqlpp::tag::is_boolean;
using _cpp_value_type = bool;
struct _parameter_t
template<typename T>
using _is_valid_operand = is_boolean_t<T>;
};
template<>
struct parameter_value_t<boolean>
{
using _value_type = boolean; // FIXME
using _cpp_value_type = typename _value_type::_cpp_value_type;
_parameter_t():
parameter_value_t():
_value(false),
_is_null(true)
{}
_parameter_t(const _cpp_value_type& value):
parameter_value_t(const _cpp_value_type& value):
_value(value),
_is_null(false)
{}
_parameter_t& operator=(const _cpp_value_type& value)
parameter_value_t& operator=(const _cpp_value_type& value)
{
_value = value;
_is_null = false;
return *this;
}
_parameter_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
parameter_value_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
{
if (t._is_trivial())
{
@@ -80,7 +86,7 @@ namespace sqlpp
return *this;
}
_parameter_t& operator=(const std::nullptr_t&)
parameter_value_t& operator=(const std::nullptr_t&)
{
_value = false;
_is_null = true;
@@ -110,48 +116,41 @@ namespace sqlpp
bool _is_null;
};
template<typename Base>
struct expression_operators<Base, boolean>: public basic_expression_operators<Base, boolean>
{
template<typename T>
struct _is_valid_operand
using _is_valid_operand = is_valid_operand<boolean, T>;
template<typename T>
logical_and_t<Base, wrap_operand_t<T>> operator and(T t) const
{
static constexpr bool value =
is_expression_t<T>::value // expressions are OK
and is_boolean_t<T>::value // the correct value type is required, of course
;
};
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
template<typename Base>
struct expression_operators: public basic_expression_operators<Base, is_boolean_t>
{
template<typename T>
logical_and_t<Base, wrap_operand_t<T>> operator and(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), rhs{t} };
}
template<typename T>
logical_or_t<Base, wrap_operand_t<T>> operator or(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), rhs{t} };
}
logical_not_t<Base> operator not() const
{
return { *static_cast<const Base*>(this) };
return { *static_cast<const Base*>(this), rhs{t} };
}
};
template<typename Base>
struct column_operators
template<typename T>
logical_or_t<Base, wrap_operand_t<T>> operator or(T t) const
{
};
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), rhs{t} };
}
logical_not_t<Base> operator not() const
{
return { *static_cast<const Base*>(this) };
}
};
template<typename Base>
struct column_operators<Base, boolean>
{
};
template<typename Db, typename FieldSpec>
struct result_field_t<boolean, Db, FieldSpec>: public result_field_methods_t<result_field_t<boolean, Db, FieldSpec>>
{

View File

@@ -33,7 +33,7 @@
namespace sqlpp
{
template<typename Database>
struct boolean_expression_t: public boolean::template expression_operators<boolean_expression_t<Database>>
struct boolean_expression_t: public expression_operators<boolean_expression_t<Database>, boolean>
{
using _traits = make_traits<boolean, tag::is_expression>;
using _recursive_traits = make_recursive_traits<>;

View File

@@ -42,8 +42,9 @@
namespace sqlpp
{
template<typename Table, typename ColumnSpec>
struct column_t: public value_type_of<ColumnSpec>::template expression_operators<column_t<Table, ColumnSpec>>,
public value_type_of<ColumnSpec>::template column_operators<column_t<Table, ColumnSpec>>
struct column_t:
public expression_operators<column_t<Table, ColumnSpec>, value_type_of<ColumnSpec>>,
public column_operators<column_t<Table, ColumnSpec>, value_type_of<ColumnSpec>>
{
struct _traits
{
@@ -66,7 +67,7 @@ namespace sqlpp
using _name_t = typename _spec_t::_name_t;
template<typename T>
using _is_valid_operand = typename value_type_of<ColumnSpec>::template _is_valid_operand<T>;
using _is_valid_operand = is_valid_operand<value_type_of<ColumnSpec>, T>;
column_t() = default;
column_t(const column_t&) = default;

View File

@@ -36,8 +36,9 @@ namespace sqlpp
{
// FIXME: Remove First, inherit from text_t
template<typename First, typename... Args>
struct concat_t: public value_type_of<First>::template expression_operators<concat_t<First, Args...>>,
public alias_operators<concat_t<First, Args...>>
struct concat_t:
public expression_operators<concat_t<First, Args...>, value_type_of<First>>,
public alias_operators<concat_t<First, Args...>>
{
using _traits = make_traits<value_type_of<First>, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<First, Args...>;

View File

@@ -33,8 +33,9 @@
namespace sqlpp
{
template<typename Flag, typename Expr>
struct count_t: public sqlpp::integral::template expression_operators<count_t<Flag, Expr>>,
public alias_operators<count_t<Flag, Expr>>
struct count_t:
public expression_operators<count_t<Flag, Expr>, integral>,
public alias_operators<count_t<Flag, Expr>>
{
using _traits = make_traits<::sqlpp::integral, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Expr>;

View File

@@ -32,8 +32,9 @@
namespace sqlpp
{
template<typename Select>
struct exists_t: public boolean::template expression_operators<exists_t<Select>>,
public alias_operators<exists_t<Select>>
struct exists_t:
public expression_operators<exists_t<Select>, boolean>,
public alias_operators<exists_t<Select>>
{
using _traits = make_traits<boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Select>;

View File

@@ -39,8 +39,9 @@
namespace sqlpp
{
template<typename Lhs, typename Rhs>
struct binary_expression_t<Lhs, op::equal_to, Rhs>: public ::sqlpp::boolean::template expression_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>,
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
struct binary_expression_t<Lhs, op::equal_to, Rhs>:
public expression_operators<binary_expression_t<Lhs, op::equal_to, Rhs>, boolean>,
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
{
using _traits = make_traits<boolean, sqlpp::tag::is_expression>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
@@ -86,8 +87,9 @@ namespace sqlpp
};
template<typename Lhs, typename Rhs>
struct binary_expression_t<Lhs, op::not_equal_to, Rhs>: public ::sqlpp::boolean::template expression_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>,
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
struct binary_expression_t<Lhs, op::not_equal_to, Rhs>:
public expression_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>, boolean>,
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
{
using _traits = make_traits<boolean, sqlpp::tag::is_expression>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
@@ -133,8 +135,9 @@ namespace sqlpp
};
template<typename Rhs>
struct unary_expression_t<op::logical_not, Rhs>: public ::sqlpp::boolean::template expression_operators<unary_expression_t<op::logical_not, Rhs>>,
public alias_operators<unary_expression_t<op::logical_not, Rhs>>
struct unary_expression_t<op::logical_not, Rhs>:
public expression_operators<unary_expression_t<op::logical_not, Rhs>, boolean>,
public alias_operators<unary_expression_t<op::logical_not, Rhs>>
{
using _traits = make_traits<boolean, sqlpp::tag::is_expression>;
using _recursive_traits = make_recursive_traits<Rhs>;
@@ -177,8 +180,9 @@ namespace sqlpp
};
template<typename Lhs, typename O, typename Rhs>
struct binary_expression_t: public value_type_of<O>::template expression_operators<binary_expression_t<Lhs, O, Rhs>>,
public alias_operators<binary_expression_t<Lhs, O, Rhs>>
struct binary_expression_t:
public expression_operators<binary_expression_t<Lhs, O, Rhs>, value_type_of<O>>,
public alias_operators<binary_expression_t<Lhs, O, Rhs>>
{
using _traits = make_traits<value_type_of<O>, sqlpp::tag::is_expression>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
@@ -215,8 +219,9 @@ namespace sqlpp
};
template<typename O, typename Rhs>
struct unary_expression_t: public value_type_of<O>::template expression_operators<unary_expression_t<O, Rhs>>,
public alias_operators<unary_expression_t<O, Rhs>>
struct unary_expression_t:
public expression_operators<unary_expression_t<O, Rhs>, value_type_of<O>>,
public alias_operators<unary_expression_t<O, Rhs>>
{
using _traits = make_traits<value_type_of<O>, sqlpp::tag::is_expression>;
using _recursive_traits = make_recursive_traits<Rhs>;

View File

@@ -42,28 +42,34 @@ namespace sqlpp
using _tag = ::sqlpp::tag::is_floating_point;
using _cpp_value_type = double;
struct _parameter_t
template<typename T>
using _is_valid_operand = is_numeric_t<T>;
};
template<>
struct parameter_value_t<floating_point>
{
using _value_type = floating_point;
using _cpp_value_type = typename _value_type::_cpp_value_type;
_parameter_t():
parameter_value_t():
_value(0),
_is_null(true)
{}
_parameter_t(const _cpp_value_type& value):
parameter_value_t(const _cpp_value_type& value):
_value(value),
_is_null(false)
{}
_parameter_t& operator=(const _cpp_value_type& value)
parameter_value_t& operator=(const _cpp_value_type& value)
{
_value = value;
_is_null = false;
return *this;
}
_parameter_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
parameter_value_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
{
if (t._is_trivial())
{
@@ -78,7 +84,7 @@ namespace sqlpp
return *this;
}
_parameter_t& operator=(const std::nullptr_t&)
parameter_value_t& operator=(const std::nullptr_t&)
{
_value = 0;
_is_null = true;
@@ -108,104 +114,112 @@ namespace sqlpp
bool _is_null;
};
template<typename T>
struct _is_valid_operand
{
static constexpr bool value =
is_expression_t<T>::value // expressions are OK
and is_numeric_t<T>::value // the correct value type is required, of course
;
};
template<typename Base>
struct expression_operators: public basic_expression_operators<Base, is_numeric_t>
template<typename Expr>
struct expression_operators<Expr, floating_point>:
public basic_expression_operators<Expr, floating_point>
{
template<typename T>
plus_t<Base, floating_point, wrap_operand_t<T>> operator +(T t) const
struct _is_valid_operand
{
static constexpr bool value =
is_expression_t<T>::value // expressions are OK
and floating_point::template _is_valid_operand<T>::value // the correct value type is required, of course
;
};
template<typename T>
plus_t<Expr, floating_point, wrap_operand_t<T>> operator +(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), rhs{t} };
return { *static_cast<const Expr*>(this), rhs{t} };
}
template<typename T>
minus_t<Base, floating_point, wrap_operand_t<T>> operator -(T t) const
minus_t<Expr, floating_point, wrap_operand_t<T>> operator -(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), rhs{t} };
return { *static_cast<const Expr*>(this), rhs{t} };
}
template<typename T>
multiplies_t<Base, floating_point, wrap_operand_t<T>> operator *(T t) const
multiplies_t<Expr, floating_point, wrap_operand_t<T>> operator *(T t) const
{
using rhs = wrap_operand_t<T>;
return { *static_cast<const Base*>(this), rhs{t} };
return { *static_cast<const Expr*>(this), rhs{t} };
}
template<typename T>
divides_t<Base, wrap_operand_t<T>> operator /(T t) const
divides_t<Expr, wrap_operand_t<T>> operator /(T t) const
{
using rhs = wrap_operand_t<T>;
return { *static_cast<const Base*>(this), rhs{t} };
return { *static_cast<const Expr*>(this), rhs{t} };
}
unary_plus_t<floating_point, Base> operator +() const
unary_plus_t<floating_point, Expr> operator +() const
{
return { *static_cast<const Base*>(this) };
return { *static_cast<const Expr*>(this) };
}
unary_minus_t<floating_point, Base> operator -() const
unary_minus_t<floating_point, Expr> operator -() const
{
return { *static_cast<const Base*>(this) };
return { *static_cast<const Expr*>(this) };
}
};
template<typename Base>
struct column_operators
{
template<typename T>
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, floating_point, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
template<typename Column>
struct column_operators<Column, floating_point>
{
template<typename T>
struct _is_valid_operand
{
static constexpr bool value =
is_expression_t<T>::value // expressions are OK
and floating_point::template _is_valid_operand<T>::value // the correct value type is required, of course
;
};
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
}
template<typename T>
auto operator +=(T t) const -> assignment_t<Column, plus_t<Column, floating_point, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
template<typename T>
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, floating_point, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Column*>(this), { *static_cast<const Column*>(this), rhs{t} } };
}
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
}
template<typename T>
auto operator -=(T t) const -> assignment_t<Column, minus_t<Column, floating_point, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
template<typename T>
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Column*>(this), { *static_cast<const Column*>(this), rhs{t} } };
}
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
}
template<typename T>
auto operator /=(T t) const -> assignment_t<Column, divides_t<Column, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
template<typename T>
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, floating_point, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Column*>(this), { *static_cast<const Column*>(this), rhs{t} } };
}
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
}
};
};
template<typename T>
auto operator *=(T t) const -> assignment_t<Column, multiplies_t<Column, floating_point, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Column*>(this), { *static_cast<const Column*>(this), rhs{t} } };
}
};
template<typename Db, typename FieldSpec>
struct result_field_t<floating_point, Db, FieldSpec>: public result_field_methods_t<result_field_t<floating_point, Db, FieldSpec>>
{

View File

@@ -35,8 +35,9 @@
namespace sqlpp
{
template<bool NotInverted, typename Operand, typename... Args>
struct in_t: public boolean::template expression_operators<in_t<NotInverted, Operand, Args...>>,
public alias_operators<in_t<NotInverted, Operand, Args...>>
struct in_t:
public expression_operators<in_t<NotInverted, Operand, Args...>, boolean>,
public alias_operators<in_t<NotInverted, Operand, Args...>>
{
using _traits = make_traits<boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Operand, Args...>;

View File

@@ -44,199 +44,212 @@ namespace sqlpp
using _tag = ::sqlpp::tag::is_integral;
using _cpp_value_type = int64_t;
struct _parameter_t
template<typename T>
using _is_valid_operand = is_numeric_t<T>;
};
template<>
struct parameter_value_t<integral>
{
using _value_type = integral;
using _cpp_value_type = typename _value_type::_cpp_value_type;
parameter_value_t():
_value(0),
_is_null(true)
{}
explicit parameter_value_t(const _cpp_value_type& value):
_value(value),
_is_null(false)
{}
parameter_value_t& operator=(const _cpp_value_type& value)
{
using _value_type = integral;
_value = value;
_is_null = false;
return *this;
}
_parameter_t():
_value(0),
_is_null(true)
{}
explicit _parameter_t(const _cpp_value_type& value):
_value(value),
_is_null(false)
{}
_parameter_t& operator=(const _cpp_value_type& value)
{
_value = value;
_is_null = false;
return *this;
}
_parameter_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
{
if (t._is_trivial())
{
_value = 0;
_is_null = true;
}
else
{
_value = t._value._t;
_is_null = false;
}
return *this;
}
void set_null()
parameter_value_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
{
if (t._is_trivial())
{
_value = 0;
_is_null = true;
}
bool is_null() const
{
return _is_null;
}
const _cpp_value_type& value() const
else
{
return _value;
_value = t._value._t;
_is_null = false;
}
return *this;
}
void set_null()
{
_value = 0;
_is_null = true;
}
bool is_null() const
{
return _is_null;
}
const _cpp_value_type& value() const
{
return _value;
}
operator _cpp_value_type() const { return _value; }
template<typename Target>
void _bind(Target& target, size_t index) const
{
target._bind_integral_parameter(index, &_value, _is_null);
}
operator _cpp_value_type() const { return _value; }
template<typename Target>
void _bind(Target& target, size_t index) const
{
target._bind_integral_parameter(index, &_value, _is_null);
}
private:
_cpp_value_type _value;
bool _is_null;
};
private:
_cpp_value_type _value;
bool _is_null;
};
template<typename Base>
struct expression_operators<Base, integral>: public basic_expression_operators<Base, integral>
{
template<typename T>
struct _is_valid_operand
{
static constexpr bool value =
is_expression_t<T>::value // expressions are OK
and is_numeric_t<T>::value // the correct value type is required, of course
and integral::template _is_valid_operand<T>::value // the correct value type is required, of course
;
};
template<typename Base>
struct expression_operators: public basic_expression_operators<Base, is_numeric_t>
template<typename T>
plus_t<Base, value_type_t<T>, wrap_operand_t<T>> operator +(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
minus_t<Base, value_type_t<T>, wrap_operand_t<T>> operator -(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
multiplies_t<Base, value_type_t<T>, wrap_operand_t<T>> operator *(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
divides_t<Base, wrap_operand_t<T>> operator /(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
modulus_t<Base, wrap_operand_t<T>> operator %(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
unary_plus_t<integral, Base> operator +() const
{
template<typename T>
plus_t<Base, value_type_t<T>, wrap_operand_t<T>> operator +(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this) };
}
return { *static_cast<const Base*>(this), {t} };
}
unary_minus_t<integral, Base> operator -() const
{
return { *static_cast<const Base*>(this) };
}
template<typename T>
minus_t<Base, value_type_t<T>, wrap_operand_t<T>> operator -(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
multiplies_t<Base, value_type_t<T>, wrap_operand_t<T>> operator *(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
divides_t<Base, wrap_operand_t<T>> operator /(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
modulus_t<Base, wrap_operand_t<T>> operator %(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
unary_plus_t<integral, Base> operator +() const
template<typename T>
bitwise_and_t<Base, value_type_t<T>, wrap_operand_t<T>> operator &(T t) const
{
return { *static_cast<const Base*>(this) };
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
unary_minus_t<integral, Base> operator -() const
template<typename T>
bitwise_or_t<Base, value_type_t<T>, wrap_operand_t<T>> operator |(T t) const
{
return { *static_cast<const Base*>(this) };
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
bitwise_and_t<Base, value_type_t<T>, wrap_operand_t<T>> operator &(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
bitwise_or_t<Base, value_type_t<T>, wrap_operand_t<T>> operator |(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
};
template<typename Base>
struct column_operators
{
template<typename T>
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {{*static_cast<const Base*>(this), rhs{t}}}};
}
template<typename T>
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {{*static_cast<const Base*>(this), rhs{t}}}};
}
template<typename T>
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {{*static_cast<const Base*>(this), rhs{t}}}};
}
template<typename T>
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, value_type_t<T>, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {{*static_cast<const Base*>(this), rhs{t}}}};
}
};
};
template<typename Base>
struct column_operators<Base, integral>
{
template<typename T>
struct _is_valid_operand
{
static constexpr bool value =
is_expression_t<T>::value // expressions are OK
and integral::template _is_valid_operand<T>::value // the correct value type is required, of course
;
};
template<typename T>
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {{*static_cast<const Base*>(this), rhs{t}}}};
}
template<typename T>
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {{*static_cast<const Base*>(this), rhs{t}}}};
}
template<typename T>
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {{*static_cast<const Base*>(this), rhs{t}}}};
}
template<typename T>
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, value_type_t<T>, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {{*static_cast<const Base*>(this), rhs{t}}}};
}
};
template<typename Db, typename FieldSpec>
struct result_field_t<integral, Db, FieldSpec>: public result_field_methods_t<result_field_t<integral, Db, FieldSpec>>

View File

@@ -34,8 +34,9 @@
namespace sqlpp
{
template<bool NotInverted, typename Operand>
struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>>,
public alias_operators<is_null_t<NotInverted, Operand>>
struct is_null_t:
public expression_operators<is_null_t<NotInverted, Operand>, boolean>,
public alias_operators<is_null_t<NotInverted, Operand>>
{
using _traits = make_traits<boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Operand>;

View File

@@ -34,8 +34,9 @@
namespace sqlpp
{
template<typename Operand, typename Pattern>
struct like_t: public boolean::template expression_operators<like_t<Operand, Pattern>>,
public alias_operators<like_t<Operand, Pattern>>
struct like_t:
public expression_operators<like_t<Operand, Pattern>, boolean>,
public alias_operators<like_t<Operand, Pattern>>
{
using _traits = make_traits<boolean, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Operand, Pattern>;

View File

@@ -32,8 +32,9 @@
namespace sqlpp
{
template<typename Expr>
struct max_t: public value_type_of<Expr>::template expression_operators<max_t<Expr>>,
public alias_operators<max_t<Expr>>
struct max_t:
public expression_operators<max_t<Expr>, value_type_of<Expr>>,
public alias_operators<max_t<Expr>>
{
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Expr>;

View File

@@ -32,8 +32,9 @@
namespace sqlpp
{
template<typename Expr>
struct min_t: public value_type_of<Expr>::template expression_operators<min_t<Expr>>,
public alias_operators<min_t<Expr>>
struct min_t:
public expression_operators<min_t<Expr>, value_type_of<Expr>>,
public alias_operators<min_t<Expr>>
{
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Expr>;

View File

@@ -28,28 +28,24 @@
#define SQLPP_NO_VALUE_H
#include <type_traits>
#include <sqlpp11/value_type_fwd.h>
namespace sqlpp
{
struct no_value_t
{
using _tag = void;
template<typename T>
struct _is_valid_operand
{
static constexpr bool value = false;
};
template<typename Base>
struct expression_operators
{
};
template<typename Base>
struct column_operators
{
};
};
template<typename Base>
struct expression_operators<Base, no_value_t>
{
};
template<typename Base>
struct column_operators<Base, no_value_t>
{
};
}
#endif

View File

@@ -34,7 +34,8 @@
namespace sqlpp
{
template<typename ValueType, typename NameType>
struct parameter_t: public ValueType::template expression_operators<parameter_t<ValueType, NameType>>
struct parameter_t:
public expression_operators<parameter_t<ValueType, NameType>, ValueType>
{
using _traits = make_traits<ValueType, tag::is_parameter, tag::is_expression>;
struct _recursive_traits
@@ -47,7 +48,7 @@ namespace sqlpp
using _can_be_null = std::true_type;
};
using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>;
using _instance_t = member_t<NameType, parameter_value_t<ValueType>>;
parameter_t()
{}

View File

@@ -122,7 +122,7 @@ namespace sqlpp
>
struct statement_t:
public Policies::template _member_t<detail::statement_policies_t<Db, Policies...>>...,
public detail::statement_policies_t<Db, Policies...>::_value_type::template expression_operators<statement_t<Db, Policies...>>,
public expression_operators<statement_t<Db, Policies...>, value_type_of<detail::statement_policies_t<Db, Policies...>>>,
public detail::statement_policies_t<Db, Policies...>::_result_methods_t,
public Policies::template _methods_t<detail::statement_policies_t<Db, Policies...>>...
{

View File

@@ -32,8 +32,9 @@
namespace sqlpp
{
template<typename Flag, typename Expr>
struct sum_t: public value_type_of<Expr>::template expression_operators<sum_t<Flag, Expr>>,
public alias_operators<sum_t<Flag, Expr>>
struct sum_t:
public expression_operators<sum_t<Flag, Expr>, value_type_of<Expr>>,
public alias_operators<sum_t<Flag, Expr>>
{
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::is_expression, ::sqlpp::tag::is_named_expression>;
using _recursive_traits = make_recursive_traits<Expr>;

View File

@@ -40,7 +40,10 @@ namespace sqlpp
struct table_base_t {};
template<typename Table, typename... ColumnSpec>
struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>...
struct table_t:
public table_base_t,
//public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>...
public member_t<ColumnSpec, column_t<Table, ColumnSpec>>...
{
using _traits = make_traits<no_value_t, tag::is_table>;

View File

@@ -43,28 +43,34 @@ namespace sqlpp
using _tag = ::sqlpp::tag::is_text;
using _cpp_value_type = std::string;
struct _parameter_t
template<typename T>
using _is_valid_operand = is_text_t<T>;
};
template<>
struct parameter_value_t<text>
{
using _value_type = text;
using _cpp_value_type = typename _value_type::_cpp_value_type;
_parameter_t():
parameter_value_t():
_value(""),
_is_null(true)
{}
_parameter_t(const _cpp_value_type& value):
parameter_value_t(const _cpp_value_type& value):
_value(value),
_is_null(false)
{}
_parameter_t& operator=(const _cpp_value_type& value)
parameter_value_t& operator=(const _cpp_value_type& value)
{
_value = value;
_is_null = false;
return *this;
}
_parameter_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
parameter_value_t& operator=(const tvin_t<wrap_operand_t<_cpp_value_type>>& t)
{
if (t._is_trivial())
{
@@ -79,7 +85,7 @@ namespace sqlpp
return *this;
}
_parameter_t& operator=(const std::nullptr_t&)
parameter_value_t& operator=(const std::nullptr_t&)
{
_value = "";
_is_null = true;
@@ -110,51 +116,47 @@ namespace sqlpp
};
template<typename Base>
struct expression_operators<Base, text>: public basic_expression_operators<Base, text>
{
template<typename T>
struct _is_valid_operand
{
static constexpr bool value =
is_expression_t<T>::value // expressions are OK
and is_text_t<T>::value // the correct value type is required, of course
;
};
using _is_valid_operand = is_valid_operand<text, T>;
template<typename Base>
struct expression_operators: public basic_expression_operators<Base, is_text_t>
template<typename T>
concat_t<Base, wrap_operand_t<T>> operator+(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
template<typename T>
like_t<Base, wrap_operand_t<T>> like(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid argument for like()");
return { *static_cast<const Base*>(this), {t} };
}
};
template<typename Base>
struct column_operators<Base, text>
{
template<typename T>
concat_t<Base, wrap_operand_t<T>> operator+(T t) const
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
return { *static_cast<const Base*>(this), {t} };
}
using _is_valid_operand = is_valid_operand<text, T>;
template<typename T>
like_t<Base, wrap_operand_t<T>> like(T t) const
auto operator +=(T t) const -> assignment_t<Base, concat_t<Base, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid argument for like()");
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), {t} };
return { *static_cast<const Base*>(this), concat_t<Base, wrap_operand_t<T>>{ *static_cast<const Base*>(this), rhs{t} } };
}
};
template<typename Base>
struct column_operators
{
template<typename T>
auto operator +=(T t) const -> assignment_t<Base, concat_t<Base, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return { *static_cast<const Base*>(this), concat_t<Base, wrap_operand_t<T>>{ *static_cast<const Base*>(this), rhs{t} } };
}
};
};
template<typename Db, typename FieldSpec>
struct result_field_t<text, Db, FieldSpec>: public result_field_methods_t<result_field_t<text, Db, FieldSpec>>
{

View File

@@ -232,6 +232,9 @@ namespace sqlpp
using _can_be_null = detail::any_t<can_be_null_t<Arguments>::value...>;
};
template<typename NameProvider, typename Member>
using member_t = typename NameProvider::_name_t::template _member_t<Member>;
}
#endif

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2013-2014, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_VALUE_TYPE_FWD_H
#define SQLPP_VALUE_TYPE_FWD_H
#include <sqlpp11/wrong.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
template<typename ValueType>
struct parameter_value_t
{
static_assert(wrong_t<parameter_value_t>::value, "Missing parameter value type for ValueType");
};
template<typename Column, typename ValueType>
struct column_operators
{
static_assert(wrong_t<column_operators>::value, "Missing column operators for ValueType");
};
template<typename Expr, typename ValueType>
struct expression_operators
{
static_assert(wrong_t<expression_operators>::value, "Missing expression operators for ValueType");
};
template<typename ValueType, typename T>
struct is_valid_operand
{
static constexpr bool value =
is_expression_t<T>::value // expressions are OK
and ValueType::template _is_valid_operand<T>::value // the correct value type is required, of course
;
};
}
#endif

View File

@@ -33,8 +33,9 @@
namespace sqlpp
{
template<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim
struct verbatim_t: public ValueType::template expression_operators<verbatim_t<ValueType>>,
public alias_operators<verbatim_t<ValueType>>
struct verbatim_t:
public expression_operators<verbatim_t<ValueType>, ValueType>,
public alias_operators<verbatim_t<ValueType>>
{
using _traits = make_traits<ValueType, ::sqlpp::tag::is_expression>;
struct _recursive_traits : public make_recursive_traits<>

View File

@@ -81,9 +81,9 @@ int main()
using Exp = decltype((t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha)) or t.gamma != parameter(t.gamma));
using T = sqlpp::make_parameter_list_t<Exp>;
T npl;
static_assert(std::is_same<typename sqlpp::value_type_of<decltype(t.alpha)>::_parameter_t, decltype(npl.alpha)>::value, "type requirement");
static_assert(std::is_same<typename sqlpp::value_type_of<decltype(t.beta)>::_parameter_t, decltype(npl.beta)>::value, "type requirement");
static_assert(std::is_same<typename sqlpp::value_type_of<decltype(t.gamma)>::_parameter_t, decltype(npl.gamma)>::value, "type requirement");
static_assert(std::is_same<sqlpp::parameter_value_t<sqlpp::value_type_of<decltype(t.alpha)>>, decltype(npl.alpha)>::value, "type requirement");
static_assert(std::is_same<sqlpp::parameter_value_t<sqlpp::value_type_of<decltype(t.beta)>>, decltype(npl.beta)>::value, "type requirement");
static_assert(std::is_same<sqlpp::parameter_value_t<sqlpp::value_type_of<decltype(t.gamma)>>, decltype(npl.gamma)>::value, "type requirement");
}
// Wonderful, now take a look at the parameter list of a select
@@ -96,9 +96,9 @@ int main()
using T = sqlpp::make_parameter_list_t<S>;
T npl;
static_assert(std::is_same<typename sqlpp::value_type_of<decltype(t.alpha)>::_parameter_t, decltype(npl.alpha)>::value, "type requirement");
static_assert(std::is_same<typename sqlpp::value_type_of<decltype(t.beta)>::_parameter_t, decltype(npl.beta)>::value, "type requirement");
static_assert(std::is_same<typename sqlpp::value_type_of<decltype(t.gamma)>::_parameter_t, decltype(npl.gamma)>::value, "type requirement");
static_assert(std::is_same<sqlpp::parameter_value_t<sqlpp::value_type_of<decltype(t.alpha)>>, decltype(npl.alpha)>::value, "type requirement");
static_assert(std::is_same<sqlpp::parameter_value_t<sqlpp::value_type_of<decltype(t.beta)>>, decltype(npl.beta)>::value, "type requirement");
static_assert(std::is_same<sqlpp::parameter_value_t<sqlpp::value_type_of<decltype(t.gamma)>>, decltype(npl.gamma)>::value, "type requirement");
npl.alpha = 7;
auto x = npl;
x = npl;