2013-08-14 04:43:10 +08:00
/*
2014-03-27 23:43:36 +08:00
* Copyright ( c ) 2013 - 2014 , Roland Bock
2013-08-14 04:43:10 +08:00
* 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 .
*/
2014-06-14 00:51:51 +08:00
# ifndef SQLPP_SELECT_FLAG_LIST_H
# define SQLPP_SELECT_FLAG_LIST_H
2013-08-14 04:43:10 +08:00
2014-02-08 05:52:02 +08:00
# include <tuple>
2013-08-14 04:43:10 +08:00
# include <sqlpp11/type_traits.h>
2014-06-15 02:25:11 +08:00
# include <sqlpp11/no_data.h>
2014-01-22 06:42:27 +08:00
# include <sqlpp11/select_flags.h>
2014-02-02 21:58:08 +08:00
# include <sqlpp11/detail/type_set.h>
2014-06-14 00:51:51 +08:00
# include <sqlpp11/interpret_tuple.h>
# include <sqlpp11/policy_update.h>
2013-08-14 04:43:10 +08:00
namespace sqlpp
{
2014-06-14 13:45:10 +08:00
// SELECTED FLAGS DATA
template < typename Database , typename . . . Flags >
struct select_flag_list_data_t
{
select_flag_list_data_t ( Flags . . . flags ) :
_flags ( flags . . . )
{ }
select_flag_list_data_t ( const select_flag_list_data_t & ) = default ;
select_flag_list_data_t ( select_flag_list_data_t & & ) = default ;
select_flag_list_data_t & operator = ( const select_flag_list_data_t & ) = default ;
select_flag_list_data_t & operator = ( select_flag_list_data_t & & ) = default ;
~ select_flag_list_data_t ( ) = default ;
std : : tuple < Flags . . . > _flags ;
interpretable_list_t < Database > _dynamic_flags ;
} ;
2014-02-08 05:52:02 +08:00
2014-06-14 13:45:10 +08:00
// SELECT FLAGS
template < typename Database , typename . . . Flags >
struct select_flag_list_t
{
2014-08-28 02:43:09 +08:00
using _traits = make_traits < no_value_t , tag : : is_select_flag_list > ;
2014-06-14 13:45:10 +08:00
using _recursive_traits = make_recursive_traits < Flags . . . > ;
2013-08-14 04:43:10 +08:00
2014-06-15 02:25:11 +08:00
using _is_dynamic = is_database < Database > ;
2013-08-14 04:43:10 +08:00
2014-05-30 18:48:51 +08:00
// Data
2014-06-14 13:45:10 +08:00
using _data_t = select_flag_list_data_t < Database , Flags . . . > ;
2014-05-30 18:48:51 +08:00
// Member implementation with data and methods
template < typename Policies >
struct _impl_t
{
2014-06-14 13:45:10 +08:00
template < typename Flag >
void add_ntc ( Flag flag )
{
add < Flag , std : : false_type > ( flag ) ;
}
template < typename Flag , typename TableCheckRequired = std : : true_type >
void add ( Flag flag )
{
static_assert ( _is_dynamic : : value , " select_flags::add() must not be called for static select flags " ) ;
static_assert ( is_select_flag_t < Flag > : : value , " invalid select flag argument in select_flags::add() " ) ;
static_assert ( TableCheckRequired : : value or Policies : : template _no_unknown_tables < Flag > : : value , " flag uses tables unknown to this statement in select_flags::add() " ) ;
2014-11-26 17:02:48 +08:00
using _serialize_check = sqlpp : : serialize_check_t < typename Database : : _serializer_context_t , Flag > ;
_serialize_check : : _ ( ) ;
2014-06-14 13:45:10 +08:00
2014-11-26 17:02:48 +08:00
using ok = detail : : all_t < _is_dynamic : : value , is_select_flag_t < Flag > : : value , _serialize_check : : type : : value > ;
2014-06-14 13:45:10 +08:00
_add_impl ( flag , ok ( ) ) ; // dispatch to prevent compile messages after the static_assert
}
private :
template < typename Flag >
void _add_impl ( Flag flag , const std : : true_type & )
{
return _data . _dynamic_flags . emplace_back ( flag ) ;
}
template < typename Flag >
void _add_impl ( Flag flag , const std : : false_type & ) ;
public :
2014-05-30 18:48:51 +08:00
_data_t _data ;
} ;
2014-11-29 18:10:01 +08:00
// Base template to be inherited by the statement
2014-05-30 18:48:51 +08:00
template < typename Policies >
2014-11-29 18:10:01 +08:00
struct _base_t
2014-05-30 18:48:51 +08:00
{
2014-06-14 13:45:10 +08:00
using _data_t = select_flag_list_data_t < Database , Flags . . . > ;
2014-05-30 18:48:51 +08:00
2014-06-14 13:45:10 +08:00
_impl_t < Policies > select_flags ;
_impl_t < Policies > & operator ( ) ( ) { return select_flags ; }
const _impl_t < Policies > & operator ( ) ( ) const { return select_flags ; }
2014-05-30 18:48:51 +08:00
template < typename T >
2014-06-14 13:45:10 +08:00
static auto _get_member ( T t ) - > decltype ( t . select_flags )
2014-05-30 18:48:51 +08:00
{
2014-06-14 13:45:10 +08:00
return t . select_flags ;
2014-05-30 18:48:51 +08:00
}
2014-11-18 02:05:22 +08:00
using _consistency_check = consistent_t ;
2014-04-09 04:45:19 +08:00
} ;
2014-06-14 13:45:10 +08:00
2014-02-08 05:52:02 +08:00
} ;
2014-06-14 13:45:10 +08:00
struct no_select_flag_list_t
{
2014-08-28 02:43:09 +08:00
using _traits = make_traits < no_value_t , tag : : is_noop > ;
2014-06-14 13:45:10 +08:00
using _recursive_traits = make_recursive_traits < > ;
2014-02-08 05:52:02 +08:00
2014-06-14 13:45:10 +08:00
// Data
using _data_t = no_data_t ;
// Member implementation with data and methods
template < typename Policies >
struct _impl_t
2014-02-08 05:52:02 +08:00
{
2014-06-14 13:45:10 +08:00
_data_t _data ;
} ;
2014-01-18 22:50:16 +08:00
2014-11-29 18:10:01 +08:00
// Base template to be inherited by the statement
2014-06-14 13:45:10 +08:00
template < typename Policies >
2014-11-29 18:10:01 +08:00
struct _base_t
2014-06-14 13:45:10 +08:00
{
using _data_t = no_data_t ;
_impl_t < Policies > no_select_flags ;
_impl_t < Policies > & operator ( ) ( ) { return no_select_flags ; }
const _impl_t < Policies > & operator ( ) ( ) const { return no_select_flags ; }
template < typename T >
static auto _get_member ( T t ) - > decltype ( t . no_select_flags )
{
return t . no_select_flags ;
}
2014-02-08 05:52:02 +08:00
2014-06-14 13:45:10 +08:00
using _database_t = typename Policies : : _database_t ;
2014-11-28 18:20:27 +08:00
template < typename . . . T >
using _check = detail : : all_t < is_select_flag_t < T > : : value . . . > ;
template < typename Check , typename T >
using _new_statement_t = new_statement_t < Check : : value , Policies , no_select_flag_list_t , T > ;
2014-06-14 13:45:10 +08:00
2014-11-18 02:05:22 +08:00
using _consistency_check = consistent_t ;
2014-06-25 03:53:25 +08:00
2014-11-28 05:16:12 +08:00
template < typename . . . Flags >
auto flags ( Flags . . . flags ) const
2014-11-28 18:20:27 +08:00
- > _new_statement_t < _check < Flags . . . > , select_flag_list_t < void , Flags . . . > >
2014-06-14 13:45:10 +08:00
{
2014-11-28 18:20:27 +08:00
static_assert ( _check < Flags . . . > : : value , " at least one argument is not a select flag in select flag list " ) ;
return _flags_impl < void > ( _check < Flags . . . > { } , flags . . . ) ;
2014-06-14 13:45:10 +08:00
}
2014-11-28 05:16:12 +08:00
template < typename . . . Flags >
auto dynamic_flags ( Flags . . . flags ) const
2014-11-28 18:20:27 +08:00
- > _new_statement_t < _check < Flags . . . > , select_flag_list_t < _database_t , Flags . . . > >
2014-06-14 13:45:10 +08:00
{
static_assert ( not std : : is_same < _database_t , void > : : value , " dynamic_flags must not be called in a static statement " ) ;
2014-11-28 18:20:27 +08:00
static_assert ( _check < Flags . . . > : : value , " at least one argument is not a select flag in select flag list " ) ;
return _flags_impl < _database_t > ( _check < Flags . . . > { } , flags . . . ) ;
2014-06-14 13:45:10 +08:00
}
2014-11-28 05:16:12 +08:00
private :
template < typename Database , typename . . . Flags >
2014-11-28 18:20:27 +08:00
auto _flags_impl ( const std : : false_type & , Flags . . . flags ) const
- > bad_statement ;
template < typename Database , typename . . . Flags >
auto _flags_impl ( const std : : true_type & , Flags . . . flags ) const
- > _new_statement_t < std : : true_type , select_flag_list_t < Database , Flags . . . > >
2014-11-28 05:16:12 +08:00
{
static_assert ( not detail : : has_duplicates < Flags . . . > : : value , " at least one duplicate argument detected in select flag list " ) ;
return { static_cast < const derived_statement_t < Policies > & > ( * this ) , select_flag_list_data_t < Database , Flags . . . > { flags . . . } } ;
}
2014-06-14 13:45:10 +08:00
} ;
} ;
// Interpreters
template < typename Context , typename Database , typename . . . Flags >
struct serializer_t < Context , select_flag_list_data_t < Database , Flags . . . > >
{
2014-11-26 00:43:55 +08:00
using _serialize_check = serialize_check_of < Context , Flags . . . > ;
2014-06-14 13:45:10 +08:00
using T = select_flag_list_data_t < Database , Flags . . . > ;
static Context & _ ( const T & t , Context & context )
{
interpret_tuple ( t . _flags , ' ' , context ) ;
if ( sizeof . . . ( Flags ) )
context < < ' ' ;
interpret_list ( t . _dynamic_flags , ' , ' , context ) ;
if ( not t . _dynamic_flags . empty ( ) )
context < < ' ' ;
return context ;
}
} ;
2014-01-12 19:22:15 +08:00
2013-08-14 04:43:10 +08:00
}
# endif