Merge branch 'release/0.15'

This commit is contained in:
rbock
2014-05-12 22:42:31 +02:00
22 changed files with 291 additions and 212 deletions
+2 -2
View File
@@ -134,14 +134,14 @@ namespace sqlpp
template<typename... T>
vendor::in_t<true, Base, vendor::wrap_operand_t<T>...> in(T... t) const
{
static_assert(detail::all_t<_is_valid_comparison_operand, vendor::wrap_operand_t<T>...>::value, "at least one operand of in() is not valid");
static_assert(detail::all_t<_is_valid_comparison_operand<vendor::wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
return { *static_cast<const Base*>(this), vendor::wrap_operand_t<T>{t}... };
}
template<typename... T>
vendor::in_t<false, Base, vendor::wrap_operand_t<T>...> not_in(T... t) const
{
static_assert(detail::all_t<_is_valid_comparison_operand, vendor::wrap_operand_t<T>...>::value, "at least one operand of in() is not valid");
static_assert(detail::all_t<_is_valid_comparison_operand<vendor::wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
return { *static_cast<const Base*>(this), vendor::wrap_operand_t<T>{t}... };
}
@@ -0,0 +1,70 @@
/*
* 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.
*/
#ifndef SQLPP_DETAIL_COLUMN_INDEX_SEQUENCE_H
#define SQLPP_DETAIL_COLUMN_INDEX_SEQUENCE_H
#include <type_traits>
namespace sqlpp
{
namespace detail
{
template<std::size_t LastIndex, std::size_t... Ints>
struct column_index_sequence
{
static constexpr std::size_t last_index = LastIndex;
};
template<typename T, typename... Fields>
struct make_column_index_sequence_impl;
template<std::size_t LastIndex, std::size_t... Ints, typename Column, typename... Rest>
struct make_column_index_sequence_impl<column_index_sequence<LastIndex, Ints...>, Column, Rest...>
{
using type = typename make_column_index_sequence_impl<column_index_sequence<LastIndex + 1, Ints..., LastIndex + 1>, Rest...>::type;
};
template<std::size_t LastIndex, std::size_t... Ints, typename AliasProvider, typename... Fields, typename... Rest>
struct make_column_index_sequence_impl<column_index_sequence<LastIndex, Ints...>, vendor::multi_field_t<AliasProvider, Fields...>, Rest...>
{
using type = typename make_column_index_sequence_impl<column_index_sequence<LastIndex + sizeof...(Fields), Ints..., LastIndex + sizeof...(Fields)>, Rest...>::type;
};
template<std::size_t LastIndex, std::size_t... Ints>
struct make_column_index_sequence_impl<column_index_sequence<LastIndex, Ints...>>
{
using type = column_index_sequence<LastIndex, Ints...>;
};
template<std::size_t StartIndex, typename... Fields>
using make_column_index_sequence = typename make_column_index_sequence_impl<column_index_sequence<StartIndex - 1>, Fields...>::type;
}
}
#endif
+64
View File
@@ -0,0 +1,64 @@
/*
* 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.
*/
#ifndef SQLPP_DETAIL_INDEX_SEQUENCE_H
#define SQLPP_DETAIL_INDEX_SEQUENCE_H
#include <type_traits>
namespace sqlpp
{
namespace detail
{
// Note: This is a minimalistic implementation of index_sequence available in C++14
// It should be replaced once the project is moved to C++14 or beyond
template<std::size_t... Ints>
struct index_sequence
{};
template<typename T, std::size_t N>
struct make_index_sequence_impl;
template<std::size_t N, std::size_t... Ints>
struct make_index_sequence_impl<index_sequence<Ints...>, N>
{
using type = typename make_index_sequence_impl<index_sequence<Ints..., sizeof...(Ints)>, N - 1>::type;
};
template<std::size_t... Ints>
struct make_index_sequence_impl<index_sequence<Ints...>, 0>
{
using type = index_sequence<Ints...>;
};
template<std::size_t N>
using make_index_sequence = typename make_index_sequence_impl<index_sequence<>, N>::type;
}
}
#endif
+15 -44
View File
@@ -33,53 +33,24 @@ namespace sqlpp
{
namespace detail
{
template<bool... b>
struct all_impl;
template<bool... B>
struct logic_helper;
template<>
struct all_impl<>
{
using type = std::true_type;
};
// see http://lists.boost.org/Archives/boost/2014/05/212946.php :-)
template<bool... B>
using all_t = std::integral_constant<
bool,
std::is_same<logic_helper<B...>, logic_helper<(true or B)...>>::value>;
template<bool... Rest>
struct all_impl<true, Rest...>
{
using type = typename all_impl<Rest...>::type;
};
template<bool... B>
using any_t = std::integral_constant<
bool,
not std::is_same<logic_helper<B...>, logic_helper<(false and B)...>>::value>;
template<bool... Rest>
struct all_impl<false, Rest...>
{
using type = std::false_type;
};
template<template<typename> class Predicate, typename... T>
using all_t = typename all_impl<Predicate<T>::value...>::type;
template<bool... b>
struct any_impl;
template<>
struct any_impl<>
{
using type = std::false_type;
};
template<bool... Rest>
struct any_impl<false, Rest...>
{
using type = typename any_impl<Rest...>::type;
};
template<bool... Rest>
struct any_impl<true, Rest...>
{
using type = std::true_type;
};
template<template<typename> class Predicate, typename... T>
using any_t = typename any_impl<Predicate<T>::value...>::type;
template<bool... B>
using none_t = std::integral_constant<
bool,
std::is_same<logic_helper<B...>, logic_helper<(false and B)...>>::value>;
template<bool>
struct not_impl;
+24 -30
View File
@@ -79,29 +79,7 @@ namespace sqlpp
template<typename E, typename... Elements>
struct is_element_of<E, type_set<Elements...>>
{
template<typename X>
using matchE = std::is_same<E, X>;
static constexpr bool value = any_t<matchE, Elements...>::value;
};
template<typename L, typename R>
struct is_superset_of
{
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "L and R have to be type sets");
};
template<typename... LElements, typename... RElements>
struct is_superset_of<type_set<LElements...>, type_set<RElements...>>
{
template<typename X>
using is_element_of_L = is_element_of<X, type_set<LElements...>>;
static constexpr bool value = all_t<is_element_of_L, RElements...>::value;
};
template<typename L, typename R>
struct is_subset_of
{
static constexpr bool value = is_superset_of<R, L>::value;
static constexpr bool value = any_t<std::is_same<E, Elements>::value...>::value;
};
template<typename L, typename R>
@@ -116,6 +94,27 @@ namespace sqlpp
using type = typename make_type_set<LElements..., RElements...>::type;
};
template<typename L, typename R>
using joined_set_t = typename joined_set<L, R>::type;
template<typename L, typename R>
struct is_superset_of
{
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "L and R have to be type sets");
};
template<typename... LElements, typename... RElements>
struct is_superset_of<type_set<LElements...>, type_set<RElements...>>
{
static constexpr bool value = joined_set_t<type_set<LElements...>, type_set<RElements...>>::size::value == sizeof...(LElements);
};
template<typename L, typename R>
struct is_subset_of
{
static constexpr bool value = is_superset_of<R, L>::value;
};
template<typename L, typename R>
struct is_disjunct_from
{
@@ -125,12 +124,7 @@ namespace sqlpp
template<typename... LElements, typename... RElements>
struct is_disjunct_from<type_set<LElements...>, type_set<RElements...>>
{
template<typename X>
using is_element_of_L = is_element_of<X, type_set<LElements...>>;
template<typename X>
using is_element_of_R = is_element_of<X, type_set<RElements...>>;
static constexpr bool value =
not(any_t<is_element_of_L, RElements...>::value or any_t<is_element_of_R, LElements...>::value);
static constexpr bool value = joined_set_t<type_set<LElements...>, type_set<RElements...>>::size::value == sizeof...(LElements) + sizeof...(RElements);
};
template<>
@@ -191,7 +185,7 @@ namespace sqlpp
{
using _rest = typename make_joined_set<T...>::type;
using type = typename joined_set<type_set<E...>, _rest>::type;
using type = joined_set_t<type_set<E...>, _rest>;
};
template<typename... Sets>
+2 -2
View File
@@ -41,7 +41,7 @@ namespace sqlpp
template<typename Unused, typename... Columns>
struct multi_column_t
{
static_assert(detail::all_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
static_assert(detail::all_t<is_named_expression_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
using _table_set = sqlpp::detail::make_joined_set_t<typename Columns::_table_set...>;
@@ -75,7 +75,7 @@ namespace sqlpp
template<typename AliasProvider, typename... Columns>
struct multi_column_alias_t
{
static_assert(detail::all_t<is_named_expression_t, Columns...>::value, "multi_column parameters need to be named expressions");
static_assert(detail::all_t<is_named_expression_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
using _name_t = typename AliasProvider::_name_t;
using _table_set = sqlpp::detail::make_joined_set_t<typename Columns::_table_set...>;
+1 -1
View File
@@ -41,7 +41,7 @@ namespace sqlpp
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in on()");
static_assert(detail::all_t<is_expression_t, Expr...>::value, "at least one argument is not an expression in on()");
static_assert(detail::all_t<is_expression_t<Expr>::value...>::value, "at least one argument is not an expression in on()");
template<typename E>
void add(E expr)
+7 -14
View File
@@ -27,8 +27,9 @@
#ifndef SQLPP_PARAMETER_LIST_H
#define SQLPP_PARAMETER_LIST_H
#include <sqlpp11/vendor/wrong.h>
#include <tuple>
#include <sqlpp11/vendor/wrong.h>
#include <sqlpp11/detail/index_sequence.h>
namespace sqlpp
{
@@ -50,23 +51,15 @@ namespace sqlpp
template<typename Target>
void _bind(Target& target) const
{
_bind_impl(target, index_t<0>());
_bind_impl(target, ::sqlpp::detail::make_index_sequence<size::value>{});
}
private:
template<size_t> struct index_t {}; // this is just for overloading
template<typename Target, size_t index>
void _bind_impl(Target& target, const index_t<index>&) const
{
const auto& parameter = static_cast<typename std::tuple_element<index, const _member_tuple_t>::type&>(*this)();
parameter._bind(target, index);
_bind_impl(target, index_t<index + 1>());
}
template<typename Target>
void _bind_impl(Target& target, const index_t<size::value>&) const
template<typename Target, size_t... Is>
void _bind_impl(Target& target, const ::sqlpp::detail::index_sequence<Is...>&) const
{
using swallow = int[]; // see interpret_tuple.h
(void) swallow{(static_cast<typename std::tuple_element<Is, const _member_tuple_t>::type&>(*this)()._bind(target, Is), 0)...};
}
};
+40 -46
View File
@@ -27,138 +27,132 @@
#ifndef SQLPP_RESULT_ROW_H
#define SQLPP_RESULT_ROW_H
#include <map>
#include <sqlpp11/vendor/char_result_row.h>
#include <sqlpp11/vendor/field.h>
#include <sqlpp11/text.h>
#include <map>
#include <sqlpp11/detail/column_index_sequence.h>
namespace sqlpp
{
namespace detail
{
template<size_t> struct index_t {}; // this is just for overloading
template<size_t level, size_t index, typename... NamedExpr>
template<typename Db, typename IndexSequence, typename... NamedExprs>
struct result_row_impl;
template<size_t level, size_t index, typename Db, typename NamedExpr, typename... Rest>
struct result_row_impl<level, index, Db, NamedExpr, Rest...>:
public NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>,
public result_row_impl<level, index + 1, Db, Rest...>
template<typename Db, std::size_t index, typename NamedExpr>
struct result_field:
public NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>
{
using _field = typename NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>;
using _rest = result_row_impl<level, index + 1, Db, Rest...>;
static constexpr size_t _last_index = _rest::_last_index;
result_row_impl() = default;
result_row_impl(const char_result_row_t& char_result_row_t):
_field({{char_result_row_t.data[index], char_result_row_t.len[index]}}),
_rest(char_result_row_t)
result_field() = default;
result_field(const char_result_row_t& char_result_row_t):
_field({{char_result_row_t.data[index], char_result_row_t.len[index]}})
{
}
result_row_impl& operator=(const char_result_row_t& char_result_row_t)
result_field& operator=(const char_result_row_t& char_result_row_t)
{
_field::operator()().assign(char_result_row_t.data[index], char_result_row_t.len[index]);
_rest::operator=(char_result_row_t);
return *this;
}
void validate()
{
_field::operator()().validate();
_rest::validate();
}
void invalidate()
{
_field::operator()().invalidate();
_rest::invalidate();
}
template<typename Target>
void _bind(Target& target)
{
_field::operator()()._bind(target, index);
_rest::_bind(target);
}
};
template<size_t level, size_t index, typename AliasProvider, typename Db, typename... Col, typename... Rest>
struct result_row_impl<level, index, Db, vendor::multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Db, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
public result_row_impl<level, index + sizeof...(Col), Db, Rest...>
template<std::size_t index, typename AliasProvider, typename Db, typename... NamedExprs>
struct result_field<Db, index, vendor::multi_field_t<AliasProvider, std::tuple<NamedExprs...>>>:
public AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>
{
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Db, Col...>>;
using _rest = result_row_impl<level, index + sizeof...(Col), Db, Rest...>;
static constexpr size_t _last_index = _rest::_last_index;
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>;
result_row_impl() = default;
result_row_impl(const char_result_row_t& char_result_row_t):
_multi_field({char_result_row_t}),
_rest(char_result_row_t)
result_field() = default;
result_field(const char_result_row_t& char_result_row_t):
_multi_field({char_result_row_t})
{}
result_row_impl& operator=(const char_result_row_t& char_result_row_t)
result_field& operator=(const char_result_row_t& char_result_row_t)
{
_multi_field::operator()() = char_result_row_t;
_rest::operator=(char_result_row_t);
return *this;
}
void validate()
{
_multi_field::operator()().validate();
_rest::validate();
}
void invalidate()
{
_multi_field::operator()().invalidate();
_rest::invalidate();
}
template<typename Target>
void _bind(Target& target)
{
_multi_field::operator()()._bind(target);
_rest::_bind(target);
}
};
template<size_t level, size_t index, typename Db>
struct result_row_impl<level, index, Db>
template<typename Db, std::size_t LastIndex, std::size_t... Is, typename... NamedExprs>
struct result_row_impl<Db, detail::column_index_sequence<LastIndex, Is...>, NamedExprs...>:
public result_field<Db, Is, NamedExprs>...
{
static constexpr size_t _last_index = index;
static constexpr std::size_t _last_index = LastIndex;
result_row_impl() = default;
result_row_impl(const char_result_row_t& char_result_row_t)
result_row_impl(const char_result_row_t& char_result_row):
result_field<Db, Is, NamedExprs>(char_result_row)...
{
}
result_row_impl& operator=(const char_result_row_t& char_result_row_t)
result_row_impl& operator=(const char_result_row_t& char_result_row)
{
using swallow = int[];
(void) swallow{(result_field<Db, Is, NamedExprs>::operator=(char_result_row), 0)...};
return *this;
}
void validate()
{
using swallow = int[];
(void) swallow{(result_field<Db, Is, NamedExprs>::validate(), 0)...};
}
void invalidate()
{
using swallow = int[];
(void) swallow{(result_field<Db, Is, NamedExprs>::invalidate(), 0)...};
}
template<typename Target>
void _bind(Target& target)
{
using swallow = int[];
(void) swallow{(result_field<Db, Is, NamedExprs>::_bind(target), 0)...};
}
};
}
template<typename Db, typename... NamedExpr>
struct result_row_t: public detail::result_row_impl<0, 0, Db, NamedExpr...>
template<typename Db, typename... NamedExprs>
struct result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>
{
using _impl = detail::result_row_impl<0, 0, Db, NamedExpr...>;
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>;
bool _is_valid;
static constexpr size_t _last_static_index = _impl::_last_index;
@@ -221,10 +215,10 @@ namespace sqlpp
}
};
template<typename Db, typename... NamedExpr>
struct dynamic_result_row_t: public detail::result_row_impl<0, 0, Db, NamedExpr...>
template<typename Db, typename... NamedExprs>
struct dynamic_result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>
{
using _impl = detail::result_row_impl<0, 0, Db, NamedExpr...>;
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>;
using _field_type = detail::text::_result_entry_t<Db, false>;
static constexpr size_t _last_static_index = _impl::_last_index;
+1 -1
View File
@@ -39,7 +39,7 @@ namespace sqlpp
struct concat_t: public First::_value_type::template expression_operators<concat_t<First, Args...>>
{
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
static_assert(sqlpp::detail::all_t<is_text_t, First, Args...>::value, "at least one non-text argument detected in concat()");
static_assert(sqlpp::detail::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");
using _table_set = typename ::sqlpp::detail::make_joined_set<typename First::_table_set, typename Args::_table_set...>::type;
struct _value_type: public First::_value_type::_base_value_type
+1 -1
View File
@@ -45,7 +45,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
static_assert(::sqlpp::detail::all_t<is_table_t, Tables...>::value, "at least one argument is not a table or join in extra_tables()");
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
using _table_set = ::sqlpp::detail::make_joined_set_t<typename Tables::_table_set...>;
+2 -2
View File
@@ -49,7 +49,7 @@ namespace sqlpp
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in from()");
static_assert(::sqlpp::detail::all_t<is_table_t, Tables...>::value, "at least one argument is not a table or join in from()");
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
using _table_set = ::sqlpp::detail::make_joined_set_t<typename Tables::_table_set...>;
@@ -73,7 +73,7 @@ namespace sqlpp
static_assert(_is_dynamic::value, "add_from must not be called for static from()");
static_assert(is_table_t<Table>::value, "invalid table argument in add_from()");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t, _is_dynamic, is_table_t<Table>>;
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
_add_from_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
}
+2 -2
View File
@@ -54,7 +54,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
static_assert(::sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in group_by()");
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
group_by_t(Expressions... expressions):
_expressions(expressions...)
@@ -82,7 +82,7 @@ namespace sqlpp
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_group_by()");
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_group_by()");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t, _is_dynamic, is_expression_t<Expression>>;
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
_add_group_by_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
}
+2 -2
View File
@@ -47,7 +47,7 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Expressions...>;
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
static_assert(::sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in having()");
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
@@ -79,7 +79,7 @@ namespace sqlpp
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_having()");
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_having()");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t, _is_dynamic, is_expression_t<Expression>>;
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
_add_having_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
}
+14 -14
View File
@@ -65,9 +65,9 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
static_assert(sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
static_assert(sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
static_assert(not sqlpp::detail::any_t<must_not_insert_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
@@ -101,12 +101,12 @@ namespace sqlpp
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, typename Policies::_table_set>::value, "add_set() contains a column from a foreign table");
static_assert(::sqlpp::detail::is_subset_of<_column_table_set, typename Policies::_table_set>::value, "add_set() contains a value from a foreign table");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t,
_is_dynamic,
is_assignment_t<Assignment>,
::sqlpp::detail::not_t<must_not_insert_t, typename Assignment::_column_t>,
::sqlpp::detail::is_subset_of<_value_table_set, typename Policies::_table_set>,
::sqlpp::detail::is_subset_of<_column_table_set, typename Policies::_table_set>>;
using ok = ::sqlpp::detail::all_t<
_is_dynamic::value,
is_assignment_t<Assignment>::value,
not must_not_insert_t<typename Assignment::_column_t>::value,
::sqlpp::detail::is_subset_of<_value_table_set, typename Policies::_table_set>::value,
::sqlpp::detail::is_subset_of<_column_table_set, typename Policies::_table_set>::value>;
_add_set_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
}
@@ -142,9 +142,9 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
static_assert(::sqlpp::detail::all_t<is_column_t, Columns...>::value, "at least one argument is not a column in columns()");
static_assert(::sqlpp::detail::all_t<is_column_t<Columns>::value...>::value, "at least one argument is not a column in columns()");
static_assert(not ::sqlpp::detail::any_t<must_not_insert_t, Columns...>::value, "at least one column argument has a must_not_insert flag in its definition");
static_assert(::sqlpp::detail::none_t<must_not_insert_t<Columns>::value...>::value, "at least one column argument has a must_not_insert flag in its definition");
using _value_tuple_t = std::tuple<vendor::insert_value_t<Columns>...>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Columns::_table_set...>::type;
@@ -167,14 +167,14 @@ namespace sqlpp
template<typename... Assignments>
void add_values(Assignments... assignments)
{
static_assert(::sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "add_values() arguments have to be assignments");
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "add_values() arguments have to be assignments");
using _arg_value_tuple = std::tuple<vendor::insert_value_t<typename Assignments::_column_t>...>;
using _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>;
static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t,
::sqlpp::detail::all_t<is_assignment_t, Assignments...>,
_args_correct>;
using ok = ::sqlpp::detail::all_t<
::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value,
_args_correct::value>;
_add_values_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert
}
+25 -32
View File
@@ -30,47 +30,40 @@
#include <tuple>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/serialize.h>
#include <sqlpp11/detail/index_sequence.h>
namespace sqlpp
{
template<typename Context, typename Tuple>
struct tuple_interpreter_t
template<typename Element, typename Separator, typename Context>
static void interpret_tuple_element(const Element& element, const Separator& separator, Context& context, size_t index)
{
template<typename Separator>
static void _(const Tuple& t, const Separator& separator, Context& context)
{
_impl(t, separator, context, type<0>());
};
if (index)
context << separator;
if (requires_braces_t<Element>::value)
context << "(";
serialize(element, context);
if (requires_braces_t<Element>::value)
context << ")";
}
private:
template<size_t> struct type {};
template<typename Separator, size_t index>
static void _impl(const Tuple& t, const Separator& separator, Context& context, const type<index>&)
{
if (index)
context << separator;
const auto& entry = std::get<index>(t);
using entry_type = typename std::tuple_element<index, Tuple>::type;
if (requires_braces_t<entry_type>::value)
context << "(";
serialize(entry, context);
if (requires_braces_t<entry_type>::value)
context << ")";
_impl(t, separator, context, type<index + 1>());
}
template<typename Separator>
static void _impl(const Tuple& t, const Separator& separator, Context& context, const type<std::tuple_size<Tuple>::value>&)
{
}
};
template<typename Tuple, typename Separator, typename Context, size_t... Is>
auto interpret_tuple_impl(const Tuple& t, const Separator& separator, Context& context, const ::sqlpp::detail::index_sequence<Is...>&)
-> Context&
{
// Note: A braced-init-list does guarantee the order of evaluation according to 12.6.1 [class.explicit.init] paragraph 2 and 8.5.4 [dcl.init.list] paragraph 4.
// See for example: "http://en.cppreference.com/w/cpp/utility/integer_sequence"
// See also: "http://stackoverflow.com/questions/6245735/pretty-print-stdtuple/6245777#6245777"
// Beware of gcc-bug: "http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253", otherwise an empty swallow struct could be used
using swallow = int[];
(void) swallow{(interpret_tuple_element(std::get<Is>(t), separator, context, Is), 0)...};
return context;
}
template<typename Tuple, typename Separator, typename Context>
auto interpret_tuple(const Tuple& t, const Separator& separator, Context& context)
-> decltype(tuple_interpreter_t<Context, Tuple>::_(t, separator, context))
-> Context&
{
return tuple_interpreter_t<Context, Tuple>::_(t, separator, context);
return interpret_tuple_impl(t, separator, context, ::sqlpp::detail::make_index_sequence<std::tuple_size<Tuple>::value>{});
}
}
+2 -2
View File
@@ -53,7 +53,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
static_assert(::sqlpp::detail::all_t<is_sort_order_t, Expressions...>::value, "at least one argument is not a sort order expression in order_by()");
static_assert(::sqlpp::detail::all_t<is_sort_order_t<Expressions>::value...>::value, "at least one argument is not a sort order expression in order_by()");
order_by_t(Expressions... expressions):
_expressions(expressions...)
@@ -81,7 +81,7 @@ namespace sqlpp
static_assert(is_sort_order_t<Expression>::value, "invalid expression argument in add_order_by()");
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_order_by()");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t, _is_dynamic, is_sort_order_t<Expression>>;
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_sort_order_t<Expression>::value>;
_add_order_by_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
}
+4 -4
View File
@@ -143,7 +143,7 @@ namespace sqlpp
template<typename T>
using is_valid_expression_t = std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value>;
static_assert(::sqlpp::detail::all_t<is_valid_expression_t, Columns...>::value, "at least one argument is not a named expression");
static_assert(::sqlpp::detail::all_t<is_valid_expression_t<Columns>::value...>::value, "at least one argument is not a named expression");
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");
@@ -206,9 +206,9 @@ namespace sqlpp
using column_names = ::sqlpp::detail::make_type_set_t<typename Columns::_name_t...>;
static_assert(not ::sqlpp::detail::is_element_of<typename NamedExpression::_name_t, column_names>::value, "a column of this name is present in the select already");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t,
_is_dynamic,
is_named_expression_t<NamedExpression>
using ok = ::sqlpp::detail::all_t<
_is_dynamic::value,
is_named_expression_t<NamedExpression>::value
>;
_add_column_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert
+2 -2
View File
@@ -50,7 +50,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
static_assert(::sqlpp::detail::all_t<is_select_flag_t, Flags...>::value, "at least one argument is not a select flag in select flag list");
static_assert(::sqlpp::detail::all_t<is_select_flag_t<Flags>::value...>::value, "at least one argument is not a select flag in select flag list");
select_flag_list_t(Flags... flags):
_flags(flags...)
@@ -78,7 +78,7 @@ namespace sqlpp
static_assert(is_select_flag_t<Flag>::value, "invalid select flag argument in add_flag()");
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Flag>::value, "flag uses tables unknown to this statement in add_flag()");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t, _is_dynamic, is_select_flag_t<Flag>>;
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value>;
_add_flag_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert
}
+6 -6
View File
@@ -48,9 +48,9 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
static_assert(::sqlpp::detail::all_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
static_assert(not ::sqlpp::detail::any_t<must_not_update_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
static_assert(::sqlpp::detail::none_t<must_not_update_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
@@ -85,10 +85,10 @@ namespace sqlpp
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add_set() argument must not be updated");
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "assignment uses tables unknown to this statement in add_set()");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t,
_is_dynamic,
is_assignment_t<Assignment>,
sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>>;
using ok = ::sqlpp::detail::all_t<
_is_dynamic::value,
is_assignment_t<Assignment>::value,
not must_not_update_t<typename Assignment::_column_t>::value>;
_add_set_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
}
+2 -2
View File
@@ -49,7 +49,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in using()");
static_assert(::sqlpp::detail::all_t<is_table_t, Tables...>::value, "at least one argument is not an table in using()");
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not an table in using()");
using _table_set = ::sqlpp::detail::make_joined_set_t<typename Tables::_table_set...>;
@@ -72,7 +72,7 @@ namespace sqlpp
static_assert(_is_dynamic::value, "add_using must not be called for static using()");
static_assert(is_table_t<Table>::value, "invalid table argument in add_using()");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t, _is_dynamic, is_table_t<Table>>;
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
_add_using_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
}
+3 -3
View File
@@ -47,8 +47,8 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Expressions...>;
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
static_assert(not sqlpp::detail::any_t<is_assignment_t, Expressions...>::value, "at least one argument is an assignment in where()");
static_assert(sqlpp::detail::all_t<is_expression_t, Expressions...>::value, "at least one argument is not valid expression in where()");
static_assert(sqlpp::detail::none_t<is_assignment_t<Expressions>::value...>::value, "at least one argument is an assignment in where()");
static_assert(sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not valid expression in where()");
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
@@ -80,7 +80,7 @@ namespace sqlpp
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_where()");
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_where()");
using ok = ::sqlpp::detail::all_t<sqlpp::detail::identity_t, _is_dynamic, is_expression_t<Expression>>;
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
_add_where_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
}