From 31127812a055df097e53da173224fd43ae80acea Mon Sep 17 00:00:00 2001 From: rbock Date: Sun, 19 Jan 2014 18:11:05 +0100 Subject: [PATCH] Added some template aliases to ease specialization and added a few more operator overloads --- include/sqlpp11/basic_operators.h | 36 +------ include/sqlpp11/boolean.h | 18 +--- include/sqlpp11/floating_point.h | 44 +++----- include/sqlpp11/integral.h | 55 +++++----- include/sqlpp11/vendor/expression.h | 52 ++++++++-- include/sqlpp11/vendor/expression_fwd.h | 131 +++++++++++++++++++++++- include/sqlpp11/vendor/value_type.h | 41 ++++++++ tests/InterpretTest.cpp | 3 + 8 files changed, 264 insertions(+), 116 deletions(-) create mode 100644 include/sqlpp11/vendor/value_type.h diff --git a/include/sqlpp11/basic_operators.h b/include/sqlpp11/basic_operators.h index a7340a9f..6fb3d893 100644 --- a/include/sqlpp11/basic_operators.h +++ b/include/sqlpp11/basic_operators.h @@ -41,34 +41,6 @@ namespace sqlpp struct boolean; } - namespace vendor - { - // operators - struct lt_ - { - using _value_type = detail::boolean; - static constexpr const char* _name = "<"; - }; - - struct le_ - { - using _value_type = detail::boolean; - static constexpr const char* _name = "<="; - }; - - struct ge_ - { - using _value_type = detail::boolean; - static constexpr const char* _name = ">="; - }; - - struct gt_ - { - using _value_type = detail::boolean; - static constexpr const char* _name = ">"; - }; - } - // basic operators template class Constraint> struct basic_operators @@ -87,28 +59,28 @@ namespace sqlpp return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator<(T&& t) const + vendor::less_than_t::type> operator<(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator<=(T&& t) const + vendor::less_equal_t::type> operator<=(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator>=(T&& t) const + vendor::greater_than_t::type> operator>(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator>(T&& t) const + vendor::greater_equal_t::type> operator>=(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index 29253d4e..8aefdb30 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -38,18 +38,6 @@ namespace sqlpp // boolean operators namespace detail { - struct or_ - { - using _value_type = boolean; - static constexpr const char* _name = " OR "; - }; - - struct and_ - { - using _value_type = boolean; - static constexpr const char* _name = " AND "; - }; - // boolean value type struct boolean { @@ -178,20 +166,20 @@ namespace sqlpp struct operators: public basic_operators { template - vendor::binary_expression_t::type> operator and(T&& t) const + vendor::logical_and_t::type> operator and(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator or(T&& t) const + vendor::logical_or_t::type> operator or(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } - vendor::not_t operator not() const + vendor::logical_not_t operator not() const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be as operand for operator not"); return { *static_cast(this) }; diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index c7b757e9..ea1bce12 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -161,30 +161,6 @@ namespace sqlpp _cpp_value_type _value; }; - struct plus_ - { - using _value_type = floating_point; - static constexpr const char* _name = "+"; - }; - - struct minus_ - { - using _value_type = floating_point; - static constexpr const char* _name = "-"; - }; - - struct multiplies_ - { - using _value_type = floating_point; - static constexpr const char* _name = "*"; - }; - - struct divides_ - { - using _value_type = floating_point; - static constexpr const char* _name = "/"; - }; - template using _constraint = operand_t; @@ -192,33 +168,45 @@ namespace sqlpp struct operators: public basic_operators { template - vendor::binary_expression_t::type> operator +(T&& t) const + vendor::plus_t::type> operator +(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator -(T&& t) const + vendor::minus_t::type> operator -(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator *(T&& t) const + vendor::multiplies_t::type> operator *(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator /(T&& t) const + vendor::divides_t::type> operator /(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } + vendor::unary_plus_t operator +() const + { + static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as unary operand"); + return { *static_cast(this) }; + } + + vendor::unary_minus_t operator -() const + { + static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as unary operand"); + return { *static_cast(this) }; + } + template auto operator +=(T&& t) const -> decltype(std::declval() = std::declval() + std::forward(t)) { diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index d6fb4e26..308014dc 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace sqlpp { @@ -160,33 +161,6 @@ namespace sqlpp _cpp_value_type _value; }; - template - struct plus_ - { - using _value_type = typename vendor::wrap_operand::type>::type::_value_type; - static constexpr const char* _name = "+"; - }; - - template - struct minus_ - { - using _value_type = typename vendor::wrap_operand::type>::type::_value_type; - static constexpr const char* _name = "-"; - }; - - template - struct multiplies_ - { - using _value_type = typename vendor::wrap_operand::type>::type::_value_type; - static constexpr const char* _name = "*"; - }; - - struct divides_ - { - using _value_type = floating_point; - static constexpr const char* _name = "/"; - }; - template using _constraint = operand_t; @@ -194,33 +168,52 @@ namespace sqlpp struct operators: public basic_operators { template - vendor::binary_expression_t, typename _constraint::type> operator +(T&& t) const + vendor::plus_t, typename _constraint::type> operator +(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t, typename _constraint::type> operator -(T&& t) const + vendor::minus_t, typename _constraint::type> operator -(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t, typename _constraint::type> operator *(T&& t) const + vendor::multiplies_t, typename _constraint::type> operator *(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::binary_expression_t::type> operator /(T&& t) const + vendor::divides_t::type> operator /(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } + template + vendor::modulus_t::type> operator %(T&& t) const + { + static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); + return { *static_cast(this), {std::forward(t)} }; + } + + vendor::unary_plus_t operator +() const + { + static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as unary operand"); + return { *static_cast(this) }; + } + + vendor::unary_minus_t operator -() const + { + static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as unary operand"); + return { *static_cast(this) }; + } + template auto operator +=(T&& t) const -> decltype(std::declval() = std::declval() + std::forward(t)) { diff --git a/include/sqlpp11/vendor/expression.h b/include/sqlpp11/vendor/expression.h index 5d63e506..ba66ef85 100644 --- a/include/sqlpp11/vendor/expression.h +++ b/include/sqlpp11/vendor/expression.h @@ -173,28 +173,28 @@ namespace sqlpp }; template - struct not_t: public detail::boolean::template operators> + struct logical_not_t: public detail::boolean::template operators> { using _value_type = detail::boolean; using _parameter_tuple_t = std::tuple; - not_t(Lhs l): + logical_not_t(Lhs l): _lhs(l) {} - not_t(const not_t&) = default; - not_t(not_t&&) = default; - not_t& operator=(const not_t&) = default; - not_t& operator=(not_t&&) = default; - ~not_t() = default; + logical_not_t(const logical_not_t&) = default; + logical_not_t(logical_not_t&&) = default; + logical_not_t& operator=(const logical_not_t&) = default; + logical_not_t& operator=(logical_not_t&&) = default; + ~logical_not_t() = default; Lhs _lhs; }; template - struct interpreter_t> + struct interpreter_t> { - using T = not_t; + using T = logical_not_t; static Context& _(const T& t, Context& context) { @@ -242,6 +242,40 @@ namespace sqlpp return context; } }; + + template + struct unary_expression_t: public O::_value_type::template operators> + { + using _value_type = typename O::_value_type; + using _parameter_tuple_t = std::tuple; + + unary_expression_t(Rhs rhs): + _rhs(rhs) + {} + + unary_expression_t(const unary_expression_t&) = default; + unary_expression_t(unary_expression_t&&) = default; + unary_expression_t& operator=(const unary_expression_t&) = default; + unary_expression_t& operator=(unary_expression_t&&) = default; + ~unary_expression_t() = default; + + Rhs _rhs; + }; + + template + struct interpreter_t> + { + using T = unary_expression_t; + + static Context& _(const T& t, Context& context) + { + context << "("; + context << O::_name; + interpret(t._rhs, context); + context << ")"; + return context; + } + }; } } diff --git a/include/sqlpp11/vendor/expression_fwd.h b/include/sqlpp11/vendor/expression_fwd.h index 9fef78fc..988ae2a7 100644 --- a/include/sqlpp11/vendor/expression_fwd.h +++ b/include/sqlpp11/vendor/expression_fwd.h @@ -41,10 +41,139 @@ namespace sqlpp struct not_equal_t; template - struct not_t; + struct logical_not_t; + + namespace tag + { + struct less_than + { + using _value_type = detail::boolean; + static constexpr const char* _name = "<"; + }; + + struct less_equal + { + using _value_type = detail::boolean; + static constexpr const char* _name = "<="; + }; + + struct greater_equal + { + using _value_type = detail::boolean; + static constexpr const char* _name = ">="; + }; + + struct greater_than + { + using _value_type = detail::boolean; + static constexpr const char* _name = ">"; + }; + + struct logical_or + { + using _value_type = detail::boolean; + static constexpr const char* _name = " OR "; + }; + + struct logical_and + { + using _value_type = detail::boolean; + static constexpr const char* _name = " AND "; + }; + + template + struct plus + { + using _value_type = ValueType; + static constexpr const char* _name = "+"; + }; + + template + struct minus + { + using _value_type = ValueType; + static constexpr const char* _name = "-"; + }; + + template + struct multiplies + { + using _value_type = ValueType; + static constexpr const char* _name = "*"; + }; + + struct divides + { + using _value_type = detail::floating_point; + static constexpr const char* _name = "/"; + }; + + struct modulus + { + using _value_type = detail::integral; + static constexpr const char* _name = "%"; + }; + + template + struct unary_minus + { + using _value_type = ValueType; + static constexpr const char* _name = "-"; + }; + + template + struct unary_plus + { + using _value_type = ValueType; + static constexpr const char* _name = "+"; + }; + } template struct binary_expression_t; + + template + struct unary_expression_t; + + template + using less_than_t = binary_expression_t; + + template + using less_equal_t = binary_expression_t; + + template + using greater_than_t = binary_expression_t; + + template + using greater_equal_t = binary_expression_t; + + template + using logical_and_t = binary_expression_t; + + template + using logical_or_t = binary_expression_t; + + template + using plus_t = binary_expression_t, Rhs>; + + template + using minus_t = binary_expression_t, Rhs>; + + template + using multiplies_t = binary_expression_t, Rhs>; + + template + using divides_t = binary_expression_t; + + template + using modulus_t = binary_expression_t; + + template + using unary_plus_t = unary_expression_t, Rhs>; + + template + using unary_minus_t = unary_expression_t, Rhs>; + } } diff --git a/include/sqlpp11/vendor/value_type.h b/include/sqlpp11/vendor/value_type.h new file mode 100644 index 00000000..39ca78fb --- /dev/null +++ b/include/sqlpp11/vendor/value_type.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, 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_H +#define SQLPP_VALUE_TYPE_H + +#include +#include + +namespace sqlpp +{ + namespace vendor + { + template + using value_type_t = typename wrap_operand::type>::type::_value_type; + } +} +#endif diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index eb8c137e..da620dba 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -43,6 +43,9 @@ int main() TabSample t; interpret(t.alpha, printer).flush(); + interpret(-t.alpha, printer).flush(); + interpret(+t.alpha, printer).flush(); + interpret(-(t.alpha + 7), printer).flush(); interpret(t.alpha = 0, printer).flush(); interpret(t.alpha = sqlpp::tvin(0), printer).flush(); interpret(t.alpha == 0, printer).flush();