diff --git a/include/sqlpp11/basic_expression_operators.h b/include/sqlpp11/basic_expression_operators.h index 6613940d..ba0a94ff 100644 --- a/include/sqlpp11/basic_expression_operators.h +++ b/include/sqlpp11/basic_expression_operators.h @@ -299,6 +299,20 @@ namespace sqlpp return_type_unary_minus::check::verify(); return {*static_cast(this)}; } + + template + auto operator<<(const R& r) const -> return_type_shift_left_t + { + typename return_type_shift_left::check{}; + return {*static_cast(this), wrap_operand_t{r}}; + } + + template + auto operator>>(const R& r) const -> return_type_shift_right_t + { + typename return_type_shift_right::check{}; + return {*static_cast(this), wrap_operand_t{r}}; + } }; } // namespace sqlpp diff --git a/include/sqlpp11/data_types/integral/expression_operators.h b/include/sqlpp11/data_types/integral/expression_operators.h index 79006c2b..b8cd39a9 100644 --- a/include/sqlpp11/data_types/integral/expression_operators.h +++ b/include/sqlpp11/data_types/integral/expression_operators.h @@ -132,5 +132,19 @@ namespace sqlpp using check = consistent_t; using type = bitwise_or_t, integral, wrap_operand_t>; }; + + template + struct return_type_shift_left> + { + using check = consistent_t; + using type = shift_left_t, integral, wrap_operand_t>; + }; + + template + struct return_type_shift_right> + { + using check = consistent_t; + using type = shift_right_t, integral, wrap_operand_t>; + }; } // namespace sqlpp #endif diff --git a/include/sqlpp11/data_types/unsigned_integral/expression_operators.h b/include/sqlpp11/data_types/unsigned_integral/expression_operators.h index 49f2a2f4..dca8529e 100644 --- a/include/sqlpp11/data_types/unsigned_integral/expression_operators.h +++ b/include/sqlpp11/data_types/unsigned_integral/expression_operators.h @@ -113,5 +113,19 @@ namespace sqlpp using check = consistent_t; using type = bitwise_or_t, unsigned_integral, wrap_operand_t>; }; + + template + struct return_type_shift_left> + { + using check = consistent_t; + using type = shift_left_t, unsigned_integral, wrap_operand_t>; + }; + + template + struct return_type_shift_right> + { + using check = consistent_t; + using type = shift_right_t, unsigned_integral, wrap_operand_t>; + }; } // namespace sqlpp #endif diff --git a/include/sqlpp11/expression_fwd.h b/include/sqlpp11/expression_fwd.h index a4b55700..dac17abb 100644 --- a/include/sqlpp11/expression_fwd.h +++ b/include/sqlpp11/expression_fwd.h @@ -157,6 +157,20 @@ namespace sqlpp using _traits = make_traits; static constexpr const char* _name = "|"; }; + + template + struct shift_left + { + using _traits = make_traits; + static constexpr const char* _name = "<<"; + }; + + template + struct shift_right + { + using _traits = make_traits; + static constexpr const char* _name = ">>"; + }; } // namespace op template @@ -219,6 +233,12 @@ namespace sqlpp template using bitwise_or_t = binary_expression_t, Rhs>; + template + using shift_left_t = binary_expression_t, Rhs>; + + template + using shift_right_t = binary_expression_t, Rhs>; + namespace detail { template diff --git a/include/sqlpp11/expression_return_types.h b/include/sqlpp11/expression_return_types.h index 95ac4619..88d408b9 100644 --- a/include/sqlpp11/expression_return_types.h +++ b/include/sqlpp11/expression_return_types.h @@ -49,6 +49,24 @@ namespace sqlpp template using return_type_bitwise_and_t = typename return_type_bitwise_and::type; + template + struct return_type_shift_left + { + using check = assert_valid_operands; + using type = bad_expression; + }; + template + using return_type_shift_left_t = typename return_type_shift_left::type; + + template + struct return_type_shift_right + { + using check = assert_valid_operands; + using type = bad_expression; + }; + template + using return_type_shift_right_t = typename return_type_shift_right::type; + template struct return_type_or { diff --git a/include/sqlpp11/value.h b/include/sqlpp11/value.h index b2b0a24b..d40bd868 100644 --- a/include/sqlpp11/value.h +++ b/include/sqlpp11/value.h @@ -32,7 +32,13 @@ namespace sqlpp { template - auto value(T t) -> wrap_operand_t + struct value_t : public wrap_operand_t, public expression_operators, value_type_of>> + { + using _base_t = wrap_operand_t; + using _base_t::_base_t; + }; + template + auto value(T t) -> value_t { static_assert(is_wrapped_value_t>::value, "value() is to be called with non-sql-type like int, or string"); diff --git a/tests/core/serialize/CMakeLists.txt b/tests/core/serialize/CMakeLists.txt index d7d9d145..8c6d4e45 100644 --- a/tests/core/serialize/CMakeLists.txt +++ b/tests/core/serialize/CMakeLists.txt @@ -31,7 +31,8 @@ set(test_serializer_names From In Insert - Over + Operator + Over TableAlias Where ParameterizedVerbatim diff --git a/tests/core/serialize/Operator.cpp b/tests/core/serialize/Operator.cpp new file mode 100644 index 00000000..1fe8a09e --- /dev/null +++ b/tests/core/serialize/Operator.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021-2021, 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. + */ + +#include "Sample.h" +#include "compare.h" +#include + +#include + +SQLPP_ALIAS_PROVIDER(sample) + +int Operator(int, char* []) +{ + const auto foo = test::TabFoo{}; + const auto bar = test::TabBar{}; + + // Plus + compare(__LINE__, bar.alpha + 3u, "(tab_bar.alpha+3)"); + compare(__LINE__, sqlpp::value(3) + foo.psi, "(3+tab_foo.psi)"); + + // Shift left + compare(__LINE__, sqlpp::value(3) << foo.psi, "(3<> foo.psi, "(3>>tab_foo.psi)"); + compare(__LINE__, bar.alpha >> 3u, "(tab_bar.alpha>>3)"); + + return 0; +}