diff --git a/include/sqlpp11/detail/copy_tuple_args.h b/include/sqlpp11/detail/copy_tuple_args.h new file mode 100644 index 00000000..caac57d8 --- /dev/null +++ b/include/sqlpp11/detail/copy_tuple_args.h @@ -0,0 +1,67 @@ +/* + * 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_DETAIL_COPY_TUPLE_ARGS_H +#define SQLPP_DETAIL_COPY_TUPLE_ARGS_H + +#include + +namespace sqlpp +{ + namespace detail + { + template + struct as_tuple + { + static std::tuple _(T t) { return { t }; }; + }; + + template + struct as_tuple> + { + static std::tuple _(std::tuple t) { return t; } + }; + + template class Target, typename First, typename T> + struct copy_tuple_args_impl + { + static_assert(vendor::wrong_t::value, "copy_tuple_args must be called with a tuple"); + }; + + template class Target, typename First, typename... Args> + struct copy_tuple_args_impl> + { + using type = Target; + }; + + template class Target, typename First, typename T> + using copy_tuple_args_t = typename copy_tuple_args_impl::type; + + } +} + + +#endif diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index 61d1f5f2..c60ee57d 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -30,36 +30,47 @@ #include #include +#include + namespace sqlpp { - template + template struct multi_column_t { - static_assert(vendor::wrong_t::value, "invalid argument for multicolumn_t"); - }; - - template - struct multi_column_t> - { - static_assert(detail::and_t::value, "multi_column parameters need to be named expressions"); + static_assert(detail::and_t::value, "multi_column parameters need to be named expressions"); using _name_t = typename AliasProvider::_name_t; + multi_column_t(std::tuple columns): + _columns(columns) + {} + + multi_column_t(Columns... columns): + _columns(columns...) + {} + + multi_column_t(const multi_column_t&) = default; + multi_column_t(multi_column_t&&) = default; + multi_column_t& operator=(const multi_column_t&) = default; + multi_column_t& operator=(multi_column_t&&) = default; + ~multi_column_t() = default; + + struct _value_type: public no_value_t { using _is_named_expression = std::true_type; }; using _is_multi_column = std::true_type; - std::tuple _columns; + std::tuple _columns; }; namespace vendor { - template - struct interpreter_t> + template + struct interpreter_t> { - using T = multi_column_t; + using T = multi_column_t; static Context& _(const T& t, Context& context) { @@ -71,18 +82,20 @@ namespace sqlpp namespace detail { -#warning need to handle all_of here. - template + template using make_multi_column_t = - multi_column_t>; + detail::copy_tuple_args_t::_(std::declval())...))>; } - template - detail::make_multi_column_t multi_column(const AliasProvider& aliasProvider, NamedExpr... namedExpr) + template + auto multi_column(const AliasProvider&, Columns... columns) + -> detail::make_multi_column_t { - return { std::tuple(namedExpr...)}; + return detail::make_multi_column_t(std::tuple_cat(detail::as_tuple::_(columns)...)); } + } #endif diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index 98795f71..7c6ba00d 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -48,6 +48,8 @@ #include #include +#include + namespace sqlpp { namespace detail @@ -217,37 +219,13 @@ namespace sqlpp vendor::no_limit_t, vendor::no_offset_t>; - template - struct as_tuple - { - static std::tuple _(T t) { return { t }; }; - }; - - template - struct as_tuple> - { - static std::tuple _(std::tuple t) { return t; } - }; - - template class Target, typename First, typename T> - struct copy_tuple_args_impl - { - static_assert(vendor::wrong_t::value, "copy_tuple_args must be called with a tuple"); - }; - - template class Target, typename First, typename... Args> - struct copy_tuple_args_impl> - { - using type = Target; - }; - - template class Target, typename First, typename T> - using copy_tuple_args_t = typename copy_tuple_args_impl::type; - - template - using make_select_column_list_t = - copy_tuple_args_t::_(std::declval())...))>; + namespace detail + { + template + using make_select_column_list_t = + copy_tuple_args_t::_(std::declval())...))>; + } blank_select_t select() // FIXME: These should be constexpr @@ -259,9 +237,9 @@ namespace sqlpp auto select(Columns... columns) -> vendor::update_policies_t, vendor::no_select_column_list_t, - make_select_column_list_t> + detail::make_select_column_list_t> { - return { blank_select_t(), make_select_column_list_t(std::tuple_cat(as_tuple::_(columns)...)) }; + return { blank_select_t(), detail::make_select_column_list_t(std::tuple_cat(detail::as_tuple::_(columns)...)) }; } template @@ -272,9 +250,9 @@ namespace sqlpp template auto dynamic_select(const Database&, Columns... columns) - -> vendor::update_policies_t, vendor::no_select_column_list_t, make_select_column_list_t> + -> vendor::update_policies_t, vendor::no_select_column_list_t, detail::make_select_column_list_t> { - return { blank_select_t(), make_select_column_list_t(std::tuple_cat(as_tuple::_(columns)...)) }; + return { blank_select_t(), detail::make_select_column_list_t(std::tuple_cat(detail::as_tuple::_(columns)...)) }; } } diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index 098710cc..f8a7e208 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -133,6 +133,7 @@ int main() // multi_column */ interpret(multi_column(t.alpha, t.alpha, (t.beta + "cake").as(t.gamma)), printer).flush(); + interpret(multi_column(t, all_of(t)), printer).flush(); // dynamic select {