diff --git a/include/sqlpp11/count.h b/include/sqlpp11/count.h index 3dee29ac..c937120f 100644 --- a/include/sqlpp11/count.h +++ b/include/sqlpp11/count.h @@ -51,7 +51,6 @@ namespace sqlpp static_assert(is_noop::value or std::is_same::value, "count() used with flag other than 'distinct'"); - static_assert(is_expression_t::value, "count() requires a sql expression as argument"); struct _name_t { @@ -100,7 +99,6 @@ namespace sqlpp template auto count(T t) -> count_t> { - static_assert(not contains_aggregate_function_t>::value, "count() cannot be used on an aggregate function"); static_assert(is_expression_t>::value, "count() requires an expression as argument"); return { t }; } @@ -108,7 +106,6 @@ namespace sqlpp template auto count(const distinct_t&, T t) -> count_t> { - static_assert(not contains_aggregate_function_t>::value, "count() cannot be used on an aggregate function"); static_assert(is_expression_t>::value, "count() requires an expression as argument"); return { t }; } diff --git a/include/sqlpp11/max.h b/include/sqlpp11/max.h index 95b182a5..fbe971da 100644 --- a/include/sqlpp11/max.h +++ b/include/sqlpp11/max.h @@ -39,8 +39,6 @@ namespace sqlpp using _traits = make_traits, tag::is_expression, tag::is_named_expression>; using _recursive_traits = make_recursive_traits; - static_assert(is_expression_t::value, "max() requires a value expression as argument"); - struct _name_t { static constexpr const char* _get_name() { return "MAX"; } @@ -83,8 +81,7 @@ namespace sqlpp template auto max(T t) -> max_t> { - static_assert(not contains_aggregate_function_t>::value, "max() cannot be used on an aggregate function"); - static_assert(is_expression_t>::value, "max() requires a value expression as argument"); + static_assert(is_expression_t>::value, "max() requires an expression as argument"); return { t }; } diff --git a/include/sqlpp11/min.h b/include/sqlpp11/min.h index 27c923ad..356a6763 100644 --- a/include/sqlpp11/min.h +++ b/include/sqlpp11/min.h @@ -39,8 +39,6 @@ namespace sqlpp using _traits = make_traits, tag::is_expression, tag::is_named_expression>; using _recursive_traits = make_recursive_traits; - static_assert(is_expression_t::value, "min() requires a value expression as argument"); - struct _name_t { static constexpr const char* _get_name() { return "MIN"; } @@ -83,8 +81,7 @@ namespace sqlpp template auto min(T t) -> min_t> { - static_assert(not contains_aggregate_function_t>::value, "min() cannot be used on an aggregate function"); - static_assert(is_expression_t>::value, "min() requires a value expression as argument"); + static_assert(is_expression_t>::value, "min() requires an expression as argument"); return { t }; } diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index cfc54987..a75e4329 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -68,6 +68,23 @@ namespace sqlpp template using column_spec_can_be_null_t = typename detail::column_spec_can_be_null_impl::type; + namespace tag + { + struct is_expression{}; + }; + namespace detail + { + template + struct is_expression_impl { using type = std::false_type; }; + template + struct is_expression_impl::value + and not detail::is_element_of::value + >::type> { using type = std::true_type; }; + } + template + using is_expression_t = typename detail::is_expression_impl::type; + #define SQLPP_VALUE_TRAIT_GENERATOR(name) \ namespace tag\ {\ @@ -94,7 +111,6 @@ namespace sqlpp detail::is_element_of::value>; SQLPP_VALUE_TRAIT_GENERATOR(is_text); SQLPP_VALUE_TRAIT_GENERATOR(is_wrapped_value); - SQLPP_VALUE_TRAIT_GENERATOR(is_expression); SQLPP_VALUE_TRAIT_GENERATOR(is_named_expression); SQLPP_VALUE_TRAIT_GENERATOR(is_multi_expression); SQLPP_VALUE_TRAIT_GENERATOR(is_alias); diff --git a/test_constraints/CMakeLists.txt b/test_constraints/CMakeLists.txt index cfa55c46..61634af7 100644 --- a/test_constraints/CMakeLists.txt +++ b/test_constraints/CMakeLists.txt @@ -24,7 +24,8 @@ function(test_constraint name pattern) endfunction(test_constraint) -test_constraint(count_of_count "cannot be used on an aggregate function") +test_constraint(count_of_count "requires an expression as argument") +test_constraint(max_of_max "requires an expression as argument") test_constraint(no_conversion_operator_if_null_not_trivial "int i = row.alpha") test_constraint(require_insert "required column is missing") test_constraint(must_not_insert "one assignment is prohibited") diff --git a/test_constraints/max_of_max.cpp b/test_constraints/max_of_max.cpp new file mode 100644 index 00000000..96483e9b --- /dev/null +++ b/test_constraints/max_of_max.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013-2014, 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 "MockDb.h" +#include +#include + +MockDb db; + +int main() +{ + test::TabBar t; + + max(max(t.alpha)); +}