diff --git a/include/sqlpp11/core/operator/arithmetic_expression.h b/include/sqlpp11/core/operator/arithmetic_expression.h index bc660e8b..9c73bb56 100644 --- a/include/sqlpp11/core/operator/arithmetic_expression.h +++ b/include/sqlpp11/core/operator/arithmetic_expression.h @@ -93,55 +93,146 @@ namespace sqlpp template using check_arithmetic_args = ::sqlpp::enable_if_t::value and is_numeric::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). - namespace detail - { - template - struct result_type - { - using type = numeric; - }; - - template - struct result_type, Operator, R> : public result_type{}; - - template - struct result_type> : public result_type{}; - - template - struct result_type, Operator, sqlpp::optional> : public result_type{}; - - template - struct result_type - { - using type = ValueType; - }; - - template - struct result_type - { - using type = ValueType; - }; - - template - struct result_type - { - using type = floating_point; - }; - } - - template - struct value_type_of> - : public detail::result_type, Operator, value_type_of_t> - /* - : public std::conditional>::value or - sqlpp::is_optional>::value, - ::sqlpp::optional, - numeric> - */ +#warning: add boolean to numeric types + // L and R are expected to be numeric value types (boolen, integral, unsigned_integral, or floating_point). + template + struct arithmetic_value_type { + using type = numeric; }; + template + using arithmetic_value_type_t = typename arithmetic_value_type::type; + +#define SQLPP_ARITHMETIC_VALUE_TYPE(Op, Left, Right, ValueType)\ + template <>\ + struct arithmetic_value_type\ + {\ + using type = ValueType;\ + }; + + // Operator plus + 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 + struct arithmetic_value_type, R> + { + using type = sqlpp::optional>; + }; + + template + struct arithmetic_value_type> + { + using type = sqlpp::optional>; + }; + + template + struct arithmetic_value_type, sqlpp::optional> + { + using type = sqlpp::optional>; + }; + + template + struct value_type_of> + : public arithmetic_value_type, value_type_of_t>{}; + template struct value_type_of> : public std::conditional>::value or @@ -217,4 +308,6 @@ namespace sqlpp return {std::move(l), std::move(r)}; } +#warning: Add and test date/time/duration arithmetics + } // namespace sqlpp diff --git a/include/sqlpp11/core/type_traits.h b/include/sqlpp11/core/type_traits.h index 904c58bf..7692c31a 100644 --- a/include/sqlpp11/core/type_traits.h +++ b/include/sqlpp11/core/type_traits.h @@ -275,7 +275,7 @@ namespace sqlpp template struct is_numeric : public std::integral_constant::value or is_unsigned_integral::value or + is_boolean::value or is_integral::value or is_unsigned_integral::value or is_floating_point::value or std::is_same>, numeric>::value> { diff --git a/tests/core/types/operator/arithmetic_expression.cpp b/tests/core/types/operator/arithmetic_expression.cpp index ecf13937..94bcefcb 100644 --- a/tests/core/types/operator/arithmetic_expression.cpp +++ b/tests/core/types/operator/arithmetic_expression.cpp @@ -38,93 +38,167 @@ namespace } } -SQLPP_ALIAS_PROVIDER(r_not_null); -SQLPP_ALIAS_PROVIDER(r_maybe_null); -SQLPP_ALIAS_PROVIDER(r_opt_not_null); -SQLPP_ALIAS_PROVIDER(r_opt_maybe_null); - -template -void test_arithmetic_expressions(Value v) +template +void test_plus(Left raw_l, Right raw_r, ValueType) { - using ValueType = sqlpp::numeric; - using OptValueType = ::sqlpp::optional; + using OptValueType = ::sqlpp::optional; - auto value = sqlpp::value(v); - auto opt_value = sqlpp::value(::sqlpp::make_optional(v)); + auto l = sqlpp::value(raw_l); + auto r = sqlpp::value(raw_r); - // Arithmetically combining non-optional values - static_assert(is_same_type, ValueType>(), ""); - static_assert(is_same_type, ValueType>(), ""); - static_assert(is_same_type, ValueType>(), ""); - static_assert(is_same_type, ValueType>(), ""); + auto opt_l = sqlpp::value(::sqlpp::make_optional(raw_l)); + auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r)); - // Arithmetically combining non-optional with optional values - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - - // Arithmetically combining optional with non-optional values - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - - // Arithmetically combining optional with optional values - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); - - // Same with negate. - static_assert(is_same_type, ValueType>(), ""); - static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, ValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); // Arithmetic expressions enable the `as` member function. - static_assert(sqlpp::has_enabled_as::value, ""); - static_assert(sqlpp::has_enabled_as::value, ""); + static_assert(sqlpp::has_enabled_as::value, ""); // Arithmetic expressions enable comparison member functions. - static_assert(sqlpp::has_enabled_comparison::value, ""); + static_assert(sqlpp::has_enabled_comparison::value, ""); // Arithmetic expressions have their arguments as nodes - using L = typename std::decay::type; - using R = typename std::decay::type; - static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); - static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); } -template -void test_modulus_expressions(Value v) +template +void test_minus(Left raw_l, Right raw_r, ValueType) { - using ValueType = sqlpp::numeric; - using OptValueType = ::sqlpp::optional; + using OptValueType = ::sqlpp::optional; - auto value = sqlpp::value(v); - auto opt_value = sqlpp::value(::sqlpp::make_optional(v)); + auto l = sqlpp::value(raw_l); + auto r = sqlpp::value(raw_r); - // Modulus combining non-optional values - static_assert(is_same_type, ValueType>(), ""); + auto opt_l = sqlpp::value(::sqlpp::make_optional(raw_l)); + auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r)); - // Modulus combining non-optional with optional values - static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, ValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); - // Modulus combining optional with non-optional values - static_assert(is_same_type, OptValueType>(), ""); + // Arithmetic expressions enable the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); - // Modulus combining optional with optional values - static_assert(is_same_type, OptValueType>(), ""); + // Arithmetic expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); - // Modulus expressions enable the `as` member function. - static_assert(sqlpp::has_enabled_as::value, ""); + // Arithmetic expressions have their arguments as nodes + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); +} - // Modulus expressions enable comparison member functions. - static_assert(sqlpp::has_enabled_comparison::value, ""); +template +void test_multiplies(Left raw_l, Right raw_r, ValueType) +{ + using OptValueType = ::sqlpp::optional; - // Modulus expressions have their arguments as nodes - using L = typename std::decay::type; - using R = typename std::decay::type; - static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); + 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, ValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + + // Arithmetic expressions enable the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Arithmetic expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); + + // Arithmetic expressions have their arguments as nodes + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); +} + +template +void test_negate(Right raw_r, ValueType) +{ + using OptValueType = ::sqlpp::optional; + + auto r = sqlpp::value(raw_r); + + auto opt_r = sqlpp::value(::sqlpp::make_optional(raw_r)); + + static_assert(is_same_type, ValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + + // Arithmetic expressions enable the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Arithmetic expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); + + // Arithmetic expressions have their arguments as nodes + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); +} + +template +void test_divides(Left raw_l, Right raw_r, ValueType) +{ + using OptValueType = ::sqlpp::optional; + + 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, ValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + + // Arithmetic expressions enable the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Arithmetic expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); + + // Arithmetic expressions have their arguments as nodes + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); +} + +template +void test_modulus(Left raw_l, Right raw_r, ValueType) +{ + using OptValueType = ::sqlpp::optional; + + 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, ValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + + // Arithmetic expressions enable the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Arithmetic expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); + + // Arithmetic expressions have their arguments as nodes + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); } template @@ -162,31 +236,109 @@ void test_concatenation_expressions(Value v) int main() { - // integral - test_arithmetic_expressions(int8_t{7}); - test_arithmetic_expressions(int16_t{7}); - test_arithmetic_expressions(int32_t{7}); - 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}); + auto fp = float{7}; + auto in = int{7}; + auto ui = unsigned{7}; + auto bo = bool{1}; - // unsigned integral - test_arithmetic_expressions(uint8_t{7}); - test_arithmetic_expressions(uint16_t{7}); - test_arithmetic_expressions(uint32_t{7}); - test_arithmetic_expressions(uint64_t{7}); - test_modulus_expressions(uint8_t{7}); - test_modulus_expressions(uint16_t{7}); - test_modulus_expressions(uint32_t{7}); - test_modulus_expressions(uint64_t{7}); + // plus + test_plus(fp, fp, sqlpp::floating_point{}); + test_plus(fp, in, sqlpp::floating_point{}); + test_plus(fp, ui, sqlpp::floating_point{}); + test_plus(fp, bo, sqlpp::floating_point{}); - // floating point - test_arithmetic_expressions(float{7.7}); - test_arithmetic_expressions(double{7.7}); + test_plus(in, fp, sqlpp::floating_point{}); + test_plus(in, in, sqlpp::integral{}); + 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("seven"); test_concatenation_expressions(std::string("seven"));