diff --git a/include/sqlpp11/assignment_list.h b/include/sqlpp11/assignment_list.h index 756a2436..3cf598fd 100644 --- a/include/sqlpp11/assignment_list.h +++ b/include/sqlpp11/assignment_list.h @@ -27,29 +27,13 @@ #ifndef SQLPP_ASSIGNMENT_LIST_H #define SQLPP_ASSIGNMENT_LIST_H -#include #include #include #include -#include +#include namespace sqlpp { - namespace detail - { - template - struct dynamic_assignment_list - { - using type = std::vector>; - }; - - template<> - struct dynamic_assignment_list - { - using type = std::vector; - }; - }; - template class ProhibitPredicate, typename... Assignments> struct assignment_list_t { @@ -75,7 +59,7 @@ namespace sqlpp { static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); static_assert(not ProhibitPredicate::type::column_type>::value, "set() argument must not be updated"); - _dynamic_assignments.push_back(std::forward(assignment)); + _dynamic_assignments.emplace_back(std::forward(assignment)); } template @@ -83,18 +67,11 @@ namespace sqlpp { os << " SET "; detail::serialize_tuple(os, db, _assignments, ','); - bool first = sizeof...(Assignments) == 0; - for (const auto& assignment : _dynamic_assignments) - { - if (not first) - os << ','; - assignment.serialize(os, db); - first = false; - } + _dynamic_assignments.serialize(os, db, sizeof...(Assignments) == 0); } - std::tuple _assignments; - typename detail::dynamic_assignment_list::type _dynamic_assignments; + std::tuple::type...> _assignments; + typename detail::serializable_list _dynamic_assignments; }; } diff --git a/include/sqlpp11/detail/named_serializable.h b/include/sqlpp11/detail/named_serializable.h index 45f0d383..1aaa7f17 100644 --- a/include/sqlpp11/detail/named_serializable.h +++ b/include/sqlpp11/detail/named_serializable.h @@ -38,7 +38,9 @@ namespace sqlpp template struct named_serializable_t { - template + template::type, named_serializable_t>::value, int>::type = 0 // prevent accidental overload for copy constructor + > named_serializable_t(T&& t): _impl(std::make_shared<_impl_t::type>>(std::forward(t))) {} @@ -84,7 +86,7 @@ namespace sqlpp std::string _get_name() const { - T::_name_t::_get_name(); + return T::_name_t::_get_name(); } T _t; diff --git a/include/sqlpp11/detail/serializable.h b/include/sqlpp11/detail/serializable.h index 8746a20c..99c78454 100644 --- a/include/sqlpp11/detail/serializable.h +++ b/include/sqlpp11/detail/serializable.h @@ -38,7 +38,9 @@ namespace sqlpp template struct serializable_t { - template + template::type, serializable_t>::value, int>::type = 0 // prevent accidental overload for copy constructor + > serializable_t(T&& t): _impl(std::make_shared<_impl_t::type>>(std::forward(t))) {} diff --git a/include/sqlpp11/detail/serializable_list.h b/include/sqlpp11/detail/serializable_list.h new file mode 100644 index 00000000..60aa2bdc --- /dev/null +++ b/include/sqlpp11/detail/serializable_list.h @@ -0,0 +1,108 @@ +/* + * 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_SERIALIZABLE_LIST_H +#define SQLPP_SERIALIZABLE_LIST_H + +#include +#include + +namespace sqlpp +{ + namespace detail + { + template + struct serializable_list + { + std::vector> _serializables; + + std::size_t size() const + { + return _serializables.size(); + } + + bool empty() const + { + return _serializables.empty(); + } + + template + void emplace_back(Expr&& expr) + { + _serializables.emplace_back(std::forward(expr)); + } + + void serialize(std::ostream& os, Db& db, bool first) const + { + for (const auto entry : _serializables) + { + if (not first) + os << ','; + entry.serialize(os, db); + first = false; + } + } + + void serialize(std::ostream& os, Db& db, const std::string& separator, bool first) const + { + for (const auto entry : _serializables) + { + if (not first) + os << separator; + entry.serialize(os, db); + first = false; + } + } + + }; + + template<> + struct serializable_list + { + template + void emplace_back(const T&) {} + + constexpr std::size_t size() const + { + return 0; + } + + constexpr bool empty() const + { + return true; + } + + template + void serialize(std::ostream&, Db&, bool) const + { + } + + }; + + } +} + +#endif diff --git a/include/sqlpp11/in.h b/include/sqlpp11/in.h index 5653a3dc..9a864363 100644 --- a/include/sqlpp11/in.h +++ b/include/sqlpp11/in.h @@ -76,8 +76,8 @@ namespace sqlpp template void serialize(std::ostream& os, Db& db) const { - static_assert(NotInverted and Db::_supports_in - or _inverted and Db::_supports_not_in, "in() and/or not_in() not supported by current database"); + static_assert((NotInverted and Db::_supports_in) + or (_inverted and Db::_supports_not_in), "in() and/or not_in() not supported by current database"); _operand.serialize(os, db); os << (_inverted ? " NOT IN(" : " IN("); detail::serialize_tuple(os, db, _args, ','); diff --git a/include/sqlpp11/insert_list.h b/include/sqlpp11/insert_list.h index 78feb6e0..e7e02270 100644 --- a/include/sqlpp11/insert_list.h +++ b/include/sqlpp11/insert_list.h @@ -27,11 +27,10 @@ #ifndef SQLPP_INSERT_LIST_H #define SQLPP_INSERT_LIST_H -#include #include #include #include -#include +#include namespace sqlpp { @@ -47,18 +46,6 @@ namespace sqlpp os << " DEFAULT VALUES"; } - template - struct dynamic_column_list - { - using type = std::vector>; - }; - - template<> - struct dynamic_column_list - { - using type = std::vector; - }; - template struct insert_column { @@ -107,8 +94,8 @@ namespace sqlpp { static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); static_assert(not ProhibitPredicate::type>::value, "set() argument must not be used in insert"); - _dynamic_columns.push_back(std::forward(assignment._lhs)); - _dynamic_values.push_back(std::forward(assignment._rhs)); + _dynamic_columns.emplace_back(detail::insert_column{std::forward(assignment._lhs)}); + _dynamic_values.emplace_back(std::forward(assignment._rhs)); } template @@ -120,38 +107,22 @@ namespace sqlpp } else { + constexpr bool first = sizeof...(Assignments) == 0; + os << " ("; detail::serialize_tuple(os, db, _columns, ','); - { - bool first = sizeof...(Assignments) == 0; - for (const auto column : _dynamic_columns) - { - if (not first) - os << ','; - column.serialize(os, db); - first = false; - } - } + _dynamic_columns.serialize(os, db, first); os << ") VALUES ("; detail::serialize_tuple(os, db, _values, ','); - { - bool first = sizeof...(Assignments) == 0; - for (const auto column : _dynamic_values) - { - if (not first) - os << ','; - column.serialize(os, db); - first = false; - } - } + _dynamic_values.serialize(os, db, first); os << ")"; } } std::tuple...> _columns; std::tuple _values; - typename detail::dynamic_column_list::type _dynamic_columns; - typename detail::dynamic_column_list::type _dynamic_values; + typename detail::serializable_list _dynamic_columns; + typename detail::serializable_list _dynamic_values; }; } diff --git a/include/sqlpp11/is_null.h b/include/sqlpp11/is_null.h index a9dc2d93..6da8b1ba 100644 --- a/include/sqlpp11/is_null.h +++ b/include/sqlpp11/is_null.h @@ -73,8 +73,8 @@ namespace sqlpp template void serialize(std::ostream& os, Db& db) const { - static_assert(NotInverted and Db::_supports_is_null - or _inverted and Db::_supports_is_not_null, "is_null() and/or is_not_null() not supported by current database"); + static_assert((NotInverted and Db::_supports_is_null) + or (_inverted and Db::_supports_is_not_null), "is_null() and/or is_not_null() not supported by current database"); _operand.serialize(os, db); os << (_inverted ? " IS NOT NULL" : " IS NULL"); } diff --git a/include/sqlpp11/select_expression_list.h b/include/sqlpp11/select_expression_list.h index 27cb1ea7..f39b57c7 100644 --- a/include/sqlpp11/select_expression_list.h +++ b/include/sqlpp11/select_expression_list.h @@ -69,7 +69,7 @@ namespace sqlpp void push_back(Expr&& expr) { _dynamic_expression_names.push_back(std::decay::type::_name_t::_get_name()); - _dynamic_expressions.push_back(std::forward(expr)); + _dynamic_expressions.emplace_back(std::forward(expr)); } void serialize(std::ostream& os, Db& db, bool first) const { diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index 0edf896c..6c03f95f 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -28,12 +28,11 @@ #define SQLPP_WHERE_H #include -#include #include #include #include #include -#include +#include namespace sqlpp { @@ -65,7 +64,7 @@ namespace sqlpp void add(Expr&& expr) { static_assert(is_expression_t::type>::value, "invalid expression argument in where()"); - _conditions.push_back(std::forward(expr)); + _conditions.emplace_back(std::forward(expr)); } void serialize(std::ostream& os, Db& db) const @@ -75,16 +74,10 @@ namespace sqlpp os << " WHERE "; bool first = true; - for (const auto& condition : _conditions) - { - if (not first) - os << " AND "; - condition.serialize(os, db); - first = false; - } + _conditions.serialize(os, db, " AND ", true); } - std::vector> _conditions; + detail::serializable_list _conditions; }; }