From 553dc5b016283b8f6d53e5a9cfa2d4bf0fa6c604 Mon Sep 17 00:00:00 2001 From: rbock Date: Fri, 9 Oct 2015 07:24:05 +0200 Subject: [PATCH] Using portable static asserts for the basic expression operators now The return type yet needs to be adjusted --- include/sqlpp11/basic_expression_operators.h | 50 ++++++----- include/sqlpp11/consistent.h | 43 +++++++++ include/sqlpp11/insert_value_list.h | 59 +------------ include/sqlpp11/portable_static_assert.h | 91 ++++++++++++++++++++ include/sqlpp11/type_traits.h | 9 +- 5 files changed, 164 insertions(+), 88 deletions(-) create mode 100644 include/sqlpp11/consistent.h create mode 100644 include/sqlpp11/portable_static_assert.h diff --git a/include/sqlpp11/basic_expression_operators.h b/include/sqlpp11/basic_expression_operators.h index 032ecd34..eea5a364 100644 --- a/include/sqlpp11/basic_expression_operators.h +++ b/include/sqlpp11/basic_expression_operators.h @@ -28,6 +28,8 @@ #define SQLPP_DETAIL_BASIC_EXPRESSION_OPERATORS_H #include +#include +#include #include #include #include @@ -38,27 +40,33 @@ namespace sqlpp { + SQLPP_PORTABLE_STATIC_ASSERT(assert_valid_rhs_comparison_operand_t, "invalid rhs operand in comparison"); + + template + using check_rhs_comparison_operand_t = static_check_t< + (is_expression_t::value // expressions are OK + or + is_multi_expression_t::value) // multi-expressions like ANY are OK for comparisons, too + and + LhsValueType::template _is_valid_operand::value, // the correct value type is required, of course + assert_valid_rhs_comparison_operand_t>; + + SQLPP_PORTABLE_STATIC_ASSERT(assert_valid_in_arguments_t, "at least one operand of in() is not valid"); + + template + using check_rhs_in_arguments_t = + static_check_t::value...>::value, + assert_valid_in_arguments_t>; + // basic operators template struct basic_expression_operators { - template - struct _is_valid_comparison_operand - { - static constexpr bool value = - (is_expression_t::value // expressions are OK - or - is_multi_expression_t::value) // multi-expressions like ANY are OK for comparisons, too - and - ValueType::template _is_valid_operand::value // the correct value type is required, of course - ; - }; - template equal_to_t> operator==(T t) const { using rhs = wrap_operand_t; - static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); + check_rhs_comparison_operand_t{}._(); return {*static_cast(this), {rhs{t}}}; } @@ -67,7 +75,7 @@ namespace sqlpp not_equal_to_t> operator!=(T t) const { using rhs = wrap_operand_t; - static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); + check_rhs_comparison_operand_t{}._(); return {*static_cast(this), {rhs{t}}}; } @@ -76,7 +84,7 @@ namespace sqlpp less_than_t> operator<(T t) const { using rhs = wrap_operand_t; - static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); + check_rhs_comparison_operand_t{}._(); return {*static_cast(this), rhs{t}}; } @@ -85,7 +93,7 @@ namespace sqlpp less_equal_t> operator<=(T t) const { using rhs = wrap_operand_t; - static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); + check_rhs_comparison_operand_t{}._(); return {*static_cast(this), rhs{t}}; } @@ -94,7 +102,7 @@ namespace sqlpp greater_than_t> operator>(T t) const { using rhs = wrap_operand_t; - static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); + check_rhs_comparison_operand_t{}._(); return {*static_cast(this), rhs{t}}; } @@ -103,7 +111,7 @@ namespace sqlpp greater_equal_t> operator>=(T t) const { using rhs = wrap_operand_t; - static_assert(_is_valid_comparison_operand::value, "invalid rhs operand in comparison"); + check_rhs_comparison_operand_t{}._(); return {*static_cast(this), rhs{t}}; } @@ -132,16 +140,14 @@ namespace sqlpp template in_t...> in(T... t) const { - static_assert(logic::all_t<_is_valid_comparison_operand>::value...>::value, - "at least one operand of in() is not valid"); + check_rhs_in_arguments_t...>::_(); return {*static_cast(this), wrap_operand_t{t}...}; } template not_in_t...> not_in(T... t) const { - static_assert(logic::all_t<_is_valid_comparison_operand>::value...>::value, - "at least one operand of in() is not valid"); + check_rhs_in_arguments_t...>::_(); return {*static_cast(this), wrap_operand_t{t}...}; } }; diff --git a/include/sqlpp11/consistent.h b/include/sqlpp11/consistent.h new file mode 100644 index 00000000..7f6e765c --- /dev/null +++ b/include/sqlpp11/consistent.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013-2015, 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_CONSISTENT_H +#define SQLPP_CONSISTENT_H + +#include + +namespace sqlpp +{ + struct consistent_t + { + static constexpr bool value = true; + using type = std::true_type; + + static void _(){}; + }; +} + +#endif diff --git a/include/sqlpp11/insert_value_list.h b/include/sqlpp11/insert_value_list.h index f366bafa..ae7be67f 100644 --- a/include/sqlpp11/insert_value_list.h +++ b/include/sqlpp11/insert_value_list.h @@ -28,6 +28,7 @@ #define SQLPP_INSERT_VALUE_LIST_H #include +#include #include #include #include @@ -127,64 +128,6 @@ namespace sqlpp interpretable_list_t _dynamic_values; }; -#define SQLPP_PORTABLE_STATIC_ASSERT(name, message) \ - struct name \ - { \ - static constexpr bool value = false; \ - using type = std::false_type; \ - \ - template \ - static void _() \ - { \ - static_assert(wrong_t::value, message); \ - } \ - } - - namespace detail - { - template - struct static_check_impl - { - using type = Assert; - }; - - template - struct static_check_impl - { - using type = consistent_t; - }; - } - - template - using static_check_t = typename detail::static_check_impl::type; - - namespace detail - { - template - struct static_combined_check_impl; - - template - struct static_combined_check_impl - { - using type = Assert; - }; - - template - struct static_combined_check_impl - { - using type = typename static_combined_check_impl::type; - }; - - template <> - struct static_combined_check_impl<> - { - using type = consistent_t; - }; - } - - template - using static_combined_check_t = typename detail::static_combined_check_impl::type; - SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_set_assignments_t, "at least one argument is not an assignment in set()"); SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_set_no_duplicates_t, "at least one duplicate column detected in set()"); SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_set_prohibited_t, diff --git a/include/sqlpp11/portable_static_assert.h b/include/sqlpp11/portable_static_assert.h new file mode 100644 index 00000000..06732f10 --- /dev/null +++ b/include/sqlpp11/portable_static_assert.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015-2015, 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_PORTABLE_STATIC_ASSERT_H +#define SQLPP_PORTABLE_STATIC_ASSERT_H + +namespace sqlpp +{ +#define SQLPP_PORTABLE_STATIC_ASSERT(name, message) \ + struct name \ + { \ + static constexpr bool value = false; \ + using type = std::false_type; \ + \ + template \ + static void _() \ + { \ + static_assert(wrong_t::value, message); \ + } \ + } + + namespace detail + { + template + struct static_check_impl + { + using type = Assert; + }; + + template + struct static_check_impl + { + using type = consistent_t; + }; + } + + template + using static_check_t = typename detail::static_check_impl::type; + + namespace detail + { + template + struct static_combined_check_impl; + + template + struct static_combined_check_impl + { + using type = Assert; + }; + + template + struct static_combined_check_impl + { + using type = typename static_combined_check_impl::type; + }; + + template <> + struct static_combined_check_impl<> + { + using type = consistent_t; + }; + } + + template + using static_combined_check_t = typename detail::static_combined_check_impl::type; +} + +#endif diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 06f1ee40..98bc1b35 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -306,14 +307,6 @@ namespace sqlpp template using derived_statement_t = typename Policies::_statement_t; - struct consistent_t - { - static constexpr bool value = true; - using type = std::true_type; - - static void _(){}; - }; - template using is_inconsistent_t = typename std::conditional::value, std::false_type, std::true_type>::type;