0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 12:51:13 +08:00

More tests

This commit is contained in:
Roland Bock 2024-08-04 15:57:57 +02:00
parent 8e688f3c34
commit ed0d10b58b
3 changed files with 380 additions and 135 deletions

View File

@ -93,54 +93,145 @@ namespace sqlpp
template <typename L, typename R> template <typename L, typename R>
using check_arithmetic_args = ::sqlpp::enable_if_t<is_numeric<L>::value and is_numeric<R>::value>; using check_arithmetic_args = ::sqlpp::enable_if_t<is_numeric<L>::value and is_numeric<R>::value>;
#warning: need to document that this is on purpose (not integral, or unsigned integral, or floating_point) because it is difficult to know for the library to know what the actual result type will be (it is difficult to guess in C++ already, and it is probably different from DB vendor to vendor). #warning: add boolean to numeric types
namespace detail // L and R are expected to be numeric value types (boolen, integral, unsigned_integral, or floating_point).
{ template <typename Operator, typename L, typename R>
template <typename L, typename Operator, typename R> struct arithmetic_value_type
struct result_type
{ {
using type = numeric; using type = numeric;
}; };
template <typename L, typename Operator, typename R> template <typename Operator, typename L, typename R>
struct result_type<sqlpp::optional<L>, Operator, R> : public result_type<L, Operator, R>{}; using arithmetic_value_type_t = typename arithmetic_value_type<Operator, L, R>::type;
template <typename L, typename Operator, typename R> #define SQLPP_ARITHMETIC_VALUE_TYPE(Op, Left, Right, ValueType)\
struct result_type<L, Operator, sqlpp::optional<R>> : public result_type<L, Operator, R>{}; template <>\
struct arithmetic_value_type<Op, Left, Right>\
template <typename L, typename Operator, typename R> {\
struct result_type<sqlpp::optional<L>, Operator, sqlpp::optional<R>> : public result_type<L, Operator, R>{}; using type = ValueType;\
template <typename ValueType>
struct result_type<ValueType, plus, ValueType>
{
using type = ValueType;
}; };
template <typename ValueType> // Operator plus
struct result_type<ValueType, multiplies, ValueType> SQLPP_ARITHMETIC_VALUE_TYPE(plus, floating_point, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, floating_point, integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, floating_point, unsigned_integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, floating_point, boolean, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, integral, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, integral, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, integral, unsigned_integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, integral, boolean, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, unsigned_integral, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, unsigned_integral, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, unsigned_integral, unsigned_integral, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, unsigned_integral, boolean, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, boolean, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, boolean, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, boolean, unsigned_integral, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(plus, boolean, boolean, unsigned_integral);
// Operator minus
SQLPP_ARITHMETIC_VALUE_TYPE(minus, floating_point, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, floating_point, integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, floating_point, unsigned_integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, floating_point, boolean, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, integral, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, integral, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, integral, unsigned_integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, integral, boolean, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, unsigned_integral, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, unsigned_integral, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, unsigned_integral, unsigned_integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, unsigned_integral, boolean, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, boolean, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, boolean, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, boolean, unsigned_integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(minus, boolean, boolean, integral);
// Operator multiplies
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, floating_point, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, floating_point, integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, floating_point, unsigned_integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, floating_point, boolean, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, integral, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, integral, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, integral, unsigned_integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, integral, boolean, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, unsigned_integral, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, unsigned_integral, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, unsigned_integral, unsigned_integral, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, unsigned_integral, boolean, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, boolean, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, boolean, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, boolean, unsigned_integral, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(multiplies, boolean, boolean, boolean);
// Operator divides
SQLPP_ARITHMETIC_VALUE_TYPE(divides, floating_point, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, floating_point, integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, floating_point, unsigned_integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, floating_point, boolean, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, integral, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, integral, integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, integral, unsigned_integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, integral, boolean, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, unsigned_integral, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, unsigned_integral, integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, unsigned_integral, unsigned_integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, unsigned_integral, boolean, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, boolean, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, boolean, integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, boolean, unsigned_integral, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(divides, boolean, boolean, floating_point);
// Operator negate
SQLPP_ARITHMETIC_VALUE_TYPE(negate, no_value_t, floating_point, floating_point);
SQLPP_ARITHMETIC_VALUE_TYPE(negate, no_value_t, integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(negate, no_value_t, unsigned_integral, integral);
SQLPP_ARITHMETIC_VALUE_TYPE(negate, no_value_t, boolean, integral);
// Operator modulus
SQLPP_ARITHMETIC_VALUE_TYPE(modulus, integral, integral, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(modulus, integral, unsigned_integral, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(modulus, unsigned_integral, integral, unsigned_integral);
SQLPP_ARITHMETIC_VALUE_TYPE(modulus, unsigned_integral, unsigned_integral, unsigned_integral);
#undef SQLPP_ARITHMETIC_VALUE_TYPE
// Handle optional types
template <typename Operator, typename L, typename R>
struct arithmetic_value_type<Operator, sqlpp::optional<L>, R>
{ {
using type = ValueType; using type = sqlpp::optional<arithmetic_value_type_t<Operator, L, R>>;
}; };
template <typename L, typename R> template <typename Operator, typename L, typename R>
struct result_type<L, divides, R> struct arithmetic_value_type<Operator, L, sqlpp::optional<R>>
{ {
using type = floating_point; using type = sqlpp::optional<arithmetic_value_type_t<Operator, L, R>>;
}; };
}
template <typename L, typename Operator, typename R> template <typename Operator, typename L, typename R>
struct arithmetic_value_type<Operator, sqlpp::optional<L>, sqlpp::optional<R>>
{
using type = sqlpp::optional<arithmetic_value_type_t<Operator, L, R>>;
};
template <typename Operator, typename L, typename R>
struct value_type_of<arithmetic_expression<L, Operator, R>> struct value_type_of<arithmetic_expression<L, Operator, R>>
: public detail::result_type<value_type_of_t<L>, Operator, value_type_of_t<R>> : public arithmetic_value_type<Operator, value_type_of_t<L>, value_type_of_t<R>>{};
/*
: public std::conditional<sqlpp::is_optional<value_type_of_t<L>>::value or
sqlpp::is_optional<value_type_of_t<R>>::value,
::sqlpp::optional<numeric>,
numeric>
*/
{
};
template <typename L, typename R> template <typename L, typename R>
struct value_type_of<arithmetic_expression<L, concatenation, R>> struct value_type_of<arithmetic_expression<L, concatenation, R>>
@ -217,4 +308,6 @@ namespace sqlpp
return {std::move(l), std::move(r)}; return {std::move(l), std::move(r)};
} }
#warning: Add and test date/time/duration arithmetics
} // namespace sqlpp } // namespace sqlpp

View File

@ -275,7 +275,7 @@ namespace sqlpp
template <typename T> template <typename T>
struct is_numeric struct is_numeric
: public std::integral_constant<bool, : public std::integral_constant<bool,
is_integral<T>::value or is_unsigned_integral<T>::value or is_boolean<T>::value or is_integral<T>::value or is_unsigned_integral<T>::value or
is_floating_point<T>::value or is_floating_point<T>::value or
std::is_same<remove_optional_t<value_type_of_t<T>>, numeric>::value> std::is_same<remove_optional_t<value_type_of_t<T>>, numeric>::value>
{ {

View File

@ -38,93 +38,167 @@ namespace
} }
} }
SQLPP_ALIAS_PROVIDER(r_not_null); template<typename Left, typename Right, typename ValueType>
SQLPP_ALIAS_PROVIDER(r_maybe_null); void test_plus(Left raw_l, Right raw_r, ValueType)
SQLPP_ALIAS_PROVIDER(r_opt_not_null);
SQLPP_ALIAS_PROVIDER(r_opt_maybe_null);
template<typename Value>
void test_arithmetic_expressions(Value v)
{ {
using ValueType = sqlpp::numeric; using OptValueType = ::sqlpp::optional<ValueType>;
using OptValueType = ::sqlpp::optional<sqlpp::numeric>;
auto value = sqlpp::value(v); auto l = sqlpp::value(raw_l);
auto opt_value = sqlpp::value(::sqlpp::make_optional(v)); auto r = sqlpp::value(raw_r);
// Arithmetically combining non-optional values auto opt_l = sqlpp::value(::sqlpp::make_optional(raw_l));
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + value)>, ValueType>(), ""); auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r));
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value - value)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value * value)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value / value)>, ValueType>(), "");
// Arithmetically combining non-optional with optional values static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l + r)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + opt_value)>, OptValueType>(), ""); static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l + opt_r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value - opt_value)>, OptValueType>(), ""); static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l + r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value * opt_value)>, OptValueType>(), ""); static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l + opt_r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value / opt_value)>, OptValueType>(), "");
// Arithmetically combining optional with non-optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value - value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value * value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value / value)>, OptValueType>(), "");
// Arithmetically combining optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value - opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value * opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value / opt_value)>, OptValueType>(), "");
// Same with negate.
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-value)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-opt_value)>, OptValueType>(), "");
// Arithmetic expressions enable the `as` member function. // Arithmetic expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(value + opt_value)>::value, ""); static_assert(sqlpp::has_enabled_as<decltype(l + opt_r)>::value, "");
static_assert(sqlpp::has_enabled_as<decltype(-opt_value)>::value, "");
// Arithmetic expressions enable comparison member functions. // Arithmetic expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(-opt_value)>::value, ""); static_assert(sqlpp::has_enabled_comparison<decltype(l + opt_r)>::value, "");
// Arithmetic expressions have their arguments as nodes // Arithmetic expressions have their arguments as nodes
using L = typename std::decay<decltype(value)>::type; using L = typename std::decay<decltype(l)>::type;
using R = typename std::decay<decltype(opt_value)>::type; using R = typename std::decay<decltype(opt_r)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(value + opt_value)>, sqlpp::detail::type_vector<L, R>>::value, ""); static_assert(std::is_same<sqlpp::nodes_of_t<decltype(l + opt_r)>, sqlpp::detail::type_vector<L, R>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(-opt_value)>, sqlpp::detail::type_vector<sqlpp::noop, R>>::value, "");
} }
template<typename Value> template<typename Left, typename Right, typename ValueType>
void test_modulus_expressions(Value v) void test_minus(Left raw_l, Right raw_r, ValueType)
{ {
using ValueType = sqlpp::numeric; using OptValueType = ::sqlpp::optional<ValueType>;
using OptValueType = ::sqlpp::optional<sqlpp::numeric>;
auto value = sqlpp::value(v); auto l = sqlpp::value(raw_l);
auto opt_value = sqlpp::value(::sqlpp::make_optional(v)); auto r = sqlpp::value(raw_r);
// Modulus combining non-optional values auto opt_l = sqlpp::value(::sqlpp::make_optional(raw_l));
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value % value)>, ValueType>(), ""); auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r));
// Modulus combining non-optional with optional values static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l - r)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value % opt_value)>, OptValueType>(), ""); static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l - opt_r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l - r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l - opt_r)>, OptValueType>(), "");
// Modulus combining optional with non-optional values // Arithmetic expressions enable the `as` member function.
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value % value)>, OptValueType>(), ""); static_assert(sqlpp::has_enabled_as<decltype(l - opt_r)>::value, "");
// Modulus combining optional with optional values // Arithmetic expressions enable comparison member functions.
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value % opt_value)>, OptValueType>(), ""); static_assert(sqlpp::has_enabled_comparison<decltype(l - opt_r)>::value, "");
// Modulus expressions enable the `as` member function. // Arithmetic expressions have their arguments as nodes
static_assert(sqlpp::has_enabled_as<decltype(value % opt_value)>::value, ""); using L = typename std::decay<decltype(l)>::type;
using R = typename std::decay<decltype(opt_r)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(l - opt_r)>, sqlpp::detail::type_vector<L, R>>::value, "");
}
// Modulus expressions enable comparison member functions. template<typename Left, typename Right, typename ValueType>
static_assert(sqlpp::has_enabled_comparison<decltype(value % opt_value)>::value, ""); void test_multiplies(Left raw_l, Right raw_r, ValueType)
{
using OptValueType = ::sqlpp::optional<ValueType>;
// Modulus expressions have their arguments as nodes auto l = sqlpp::value(raw_l);
using L = typename std::decay<decltype(value)>::type; auto r = sqlpp::value(raw_r);
using R = typename std::decay<decltype(opt_value)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(value % opt_value)>, sqlpp::detail::type_vector<L, R>>::value, ""); auto opt_l = sqlpp::value(::sqlpp::make_optional(raw_l));
auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r));
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l * r)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l * opt_r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l * r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l * opt_r)>, OptValueType>(), "");
// Arithmetic expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(l * opt_r)>::value, "");
// Arithmetic expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(l * opt_r)>::value, "");
// Arithmetic expressions have their arguments as nodes
using L = typename std::decay<decltype(l)>::type;
using R = typename std::decay<decltype(opt_r)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(l * opt_r)>, sqlpp::detail::type_vector<L, R>>::value, "");
}
template<typename Right, typename ValueType>
void test_negate(Right raw_r, ValueType)
{
using OptValueType = ::sqlpp::optional<ValueType>;
auto r = sqlpp::value(raw_r);
auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r));
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-r)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-opt_r)>, OptValueType>(), "");
// Arithmetic expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(-opt_r)>::value, "");
// Arithmetic expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(-opt_r)>::value, "");
// Arithmetic expressions have their arguments as nodes
using R = typename std::decay<decltype(opt_r)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(-opt_r)>, sqlpp::detail::type_vector<sqlpp::noop, R>>::value, "");
}
template<typename Left, typename Right, typename ValueType>
void test_divides(Left raw_l, Right raw_r, ValueType)
{
using OptValueType = ::sqlpp::optional<ValueType>;
auto l = sqlpp::value(raw_l);
auto r = sqlpp::value(raw_r);
auto opt_l = sqlpp::value(::sqlpp::make_optional(raw_l));
auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r));
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l / r)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l / opt_r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l / r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l / opt_r)>, OptValueType>(), "");
// Arithmetic expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(l / opt_r)>::value, "");
// Arithmetic expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(l / opt_r)>::value, "");
// Arithmetic expressions have their arguments as nodes
using L = typename std::decay<decltype(l)>::type;
using R = typename std::decay<decltype(opt_r)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(l / opt_r)>, sqlpp::detail::type_vector<L, R>>::value, "");
}
template<typename Left, typename Right, typename ValueType>
void test_modulus(Left raw_l, Right raw_r, ValueType)
{
using OptValueType = ::sqlpp::optional<ValueType>;
auto l = sqlpp::value(raw_l);
auto r = sqlpp::value(raw_r);
auto opt_l = sqlpp::value(::sqlpp::make_optional(raw_l));
auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r));
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l % r)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(l % opt_r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l % r)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_l % opt_r)>, OptValueType>(), "");
// Arithmetic expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(l % opt_r)>::value, "");
// Arithmetic expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(l % opt_r)>::value, "");
// Arithmetic expressions have their arguments as nodes
using L = typename std::decay<decltype(l)>::type;
using R = typename std::decay<decltype(opt_r)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(l % opt_r)>, sqlpp::detail::type_vector<L, R>>::value, "");
} }
template<typename Value> template<typename Value>
@ -162,31 +236,109 @@ void test_concatenation_expressions(Value v)
int main() int main()
{ {
// integral auto fp = float{7};
test_arithmetic_expressions(int8_t{7}); auto in = int{7};
test_arithmetic_expressions(int16_t{7}); auto ui = unsigned{7};
test_arithmetic_expressions(int32_t{7}); auto bo = bool{1};
test_arithmetic_expressions(int64_t{7});
test_modulus_expressions(int8_t{7});
test_modulus_expressions(int16_t{7});
test_modulus_expressions(int32_t{7});
test_modulus_expressions(int64_t{7});
// unsigned integral // plus
test_arithmetic_expressions(uint8_t{7}); test_plus(fp, fp, sqlpp::floating_point{});
test_arithmetic_expressions(uint16_t{7}); test_plus(fp, in, sqlpp::floating_point{});
test_arithmetic_expressions(uint32_t{7}); test_plus(fp, ui, sqlpp::floating_point{});
test_arithmetic_expressions(uint64_t{7}); test_plus(fp, bo, sqlpp::floating_point{});
test_modulus_expressions(uint8_t{7});
test_modulus_expressions(uint16_t{7});
test_modulus_expressions(uint32_t{7});
test_modulus_expressions(uint64_t{7});
// floating point test_plus(in, fp, sqlpp::floating_point{});
test_arithmetic_expressions(float{7.7}); test_plus(in, in, sqlpp::integral{});
test_arithmetic_expressions(double{7.7}); test_plus(in, ui, sqlpp::integral{});
test_plus(in, bo, sqlpp::integral{});
// text test_plus(ui, fp, sqlpp::floating_point{});
test_plus(ui, in, sqlpp::integral{});
test_plus(ui, ui, sqlpp::unsigned_integral{});
test_plus(ui, bo, sqlpp::unsigned_integral{});
test_plus(bo, fp, sqlpp::floating_point{});
test_plus(bo, in, sqlpp::integral{});
test_plus(bo, ui, sqlpp::unsigned_integral{});
test_plus(bo, bo, sqlpp::unsigned_integral{});
// minus
test_minus(fp, fp, sqlpp::floating_point{});
test_minus(fp, in, sqlpp::floating_point{});
test_minus(fp, ui, sqlpp::floating_point{});
test_minus(fp, bo, sqlpp::floating_point{});
test_minus(in, fp, sqlpp::floating_point{});
test_minus(in, in, sqlpp::integral{});
test_minus(in, ui, sqlpp::integral{});
test_minus(in, bo, sqlpp::integral{});
test_minus(ui, fp, sqlpp::floating_point{});
test_minus(ui, in, sqlpp::integral{});
test_minus(ui, ui, sqlpp::integral{});
test_minus(ui, bo, sqlpp::integral{});
test_minus(bo, fp, sqlpp::floating_point{});
test_minus(bo, in, sqlpp::integral{});
test_minus(bo, ui, sqlpp::integral{});
test_minus(bo, bo, sqlpp::integral{});
// multiplies
test_multiplies(fp, fp, sqlpp::floating_point{});
test_multiplies(fp, in, sqlpp::floating_point{});
test_multiplies(fp, ui, sqlpp::floating_point{});
test_multiplies(fp, bo, sqlpp::floating_point{});
test_multiplies(in, fp, sqlpp::floating_point{});
test_multiplies(in, in, sqlpp::integral{});
test_multiplies(in, ui, sqlpp::integral{});
test_multiplies(in, bo, sqlpp::integral{});
test_multiplies(ui, fp, sqlpp::floating_point{});
test_multiplies(ui, in, sqlpp::integral{});
test_multiplies(ui, ui, sqlpp::unsigned_integral{});
test_multiplies(ui, bo, sqlpp::unsigned_integral{});
test_multiplies(bo, fp, sqlpp::floating_point{});
test_multiplies(bo, in, sqlpp::integral{});
test_multiplies(bo, ui, sqlpp::unsigned_integral{});
test_multiplies(bo, bo, sqlpp::boolean{});
// divides
test_divides(fp, fp, sqlpp::floating_point{});
test_divides(fp, in, sqlpp::floating_point{});
test_divides(fp, ui, sqlpp::floating_point{});
test_divides(fp, bo, sqlpp::floating_point{});
test_divides(in, fp, sqlpp::floating_point{});
test_divides(in, in, sqlpp::floating_point{});
test_divides(in, ui, sqlpp::floating_point{});
test_divides(in, bo, sqlpp::floating_point{});
test_divides(ui, fp, sqlpp::floating_point{});
test_divides(ui, in, sqlpp::floating_point{});
test_divides(ui, ui, sqlpp::floating_point{});
test_divides(ui, bo, sqlpp::floating_point{});
test_divides(bo, fp, sqlpp::floating_point{});
test_divides(bo, in, sqlpp::floating_point{});
test_divides(bo, ui, sqlpp::floating_point{});
test_divides(bo, bo, sqlpp::floating_point{});
// negate
test_negate(fp, sqlpp::floating_point{});
test_negate(in, sqlpp::integral{});
test_negate(ui, sqlpp::integral{});
test_negate(bo, sqlpp::integral{});
// modulus
test_modulus(in, in, sqlpp::unsigned_integral{});
test_modulus(in, ui, sqlpp::unsigned_integral{});
test_modulus(ui, in, sqlpp::unsigned_integral{});
test_modulus(ui, ui, sqlpp::unsigned_integral{});
// concatenation
test_concatenation_expressions('7'); test_concatenation_expressions('7');
test_concatenation_expressions("seven"); test_concatenation_expressions("seven");
test_concatenation_expressions(std::string("seven")); test_concatenation_expressions(std::string("seven"));