Revert "Revert "Merge branch 'sfinae'""

This reverts commit 56a7c4040e4fc3d787d8df1d485f9a77d418e5a2.
This commit is contained in:
Karsten Ahnert 2014-06-29 22:21:36 +02:00
parent 56a7c4040e
commit b94b3c1b29
10 changed files with 109 additions and 48 deletions

View File

@ -34,14 +34,17 @@
namespace boost {
namespace numeric {
namespace odeint {
template< class StateType , class Enabler = void >
struct algebra_dispatcher
struct algebra_dispatcher_sfinae
{
// range_algebra is the standard algebra
// range_algebra is the standard algebra^
typedef range_algebra algebra_type;
};
template< class StateType >
struct algebra_dispatcher : algebra_dispatcher_sfinae< StateType > { };
//specialize for array
template< class T , size_t N >
struct algebra_dispatcher< boost::array< T , N > >
@ -51,7 +54,7 @@ struct algebra_dispatcher< boost::array< T , N > >
//specialize for some integral types
template< typename T >
struct algebra_dispatcher< T , typename boost::enable_if< typename boost::is_floating_point< T >::type >::type >
struct algebra_dispatcher_sfinae< T , typename boost::enable_if< typename boost::is_floating_point< T >::type >::type >
{
typedef vector_space_algebra algebra_type;
};

View File

@ -32,7 +32,7 @@ namespace odeint {
// specialization for fusion sequences
template< class FusionSequence >
struct algebra_dispatcher< FusionSequence ,
struct algebra_dispatcher_sfinae< FusionSequence ,
typename boost::enable_if<
typename boost::fusion::traits::is_sequence< FusionSequence >::type >::type >
{

View File

@ -22,14 +22,16 @@
namespace boost {
namespace numeric {
namespace odeint {
template< class StateType , class Enabler = void >
struct operations_dispatcher
struct operations_dispatcher_sfinae
{
// default_operations are the standard operations
typedef default_operations operations_type;
};
template< class StateType >
struct operations_dispatcher : operations_dispatcher_sfinae< StateType > {};
// no further specializations required
}

View File

@ -35,7 +35,7 @@ namespace odeint {
template< class Derived >
struct is_resizeable< Derived ,
struct is_resizeable_sfinae< Derived ,
typename boost::enable_if< typename boost::is_base_of< Eigen::MatrixBase< Derived > , Derived >::type >::type >
{
typedef boost::true_type type;
@ -44,7 +44,7 @@ struct is_resizeable< Derived ,
template < class Derived >
struct is_resizeable< Derived ,
struct is_resizeable_sfinae< Derived ,
typename boost::enable_if< typename boost::is_base_of< Eigen::ArrayBase< Derived > , Derived >::type >::type >
{
typedef boost::true_type type;
@ -54,7 +54,7 @@ struct is_resizeable< Derived ,
template< class Derived >
struct same_size_impl< Derived , Derived ,
struct same_size_impl_sfinae< Derived , Derived ,
typename boost::enable_if< typename boost::is_base_of< Eigen::MatrixBase< Derived > , Derived >::type >::type >
{
static bool same_size( const Eigen::MatrixBase< Derived > &m1 , const Eigen::MatrixBase< Derived > &m2 )
@ -65,7 +65,7 @@ struct same_size_impl< Derived , Derived ,
};
template< class Derived >
struct same_size_impl< Derived , Derived ,
struct same_size_impl_sfinae< Derived , Derived ,
typename boost::enable_if< typename boost::is_base_of< Eigen::ArrayBase< Derived > , Derived >::type >::type >
{
static bool same_size( const Eigen::ArrayBase< Derived > &v1 , const Eigen::ArrayBase< Derived > &v2 )
@ -78,7 +78,7 @@ struct same_size_impl< Derived , Derived ,
template< class Derived >
struct resize_impl< Derived , Derived ,
struct resize_impl_sfinae< Derived , Derived ,
typename boost::enable_if< typename boost::is_base_of< Eigen::MatrixBase< Derived > , Derived >::type >::type >
{
static void resize( Eigen::MatrixBase< Derived > &m1 , const Eigen::MatrixBase< Derived > &m2 )
@ -88,7 +88,7 @@ struct resize_impl< Derived , Derived ,
};
template< class Derived >
struct resize_impl< Derived , Derived ,
struct resize_impl_sfinae< Derived , Derived ,
typename boost::enable_if< typename boost::is_base_of< Eigen::ArrayBase< Derived > , Derived >::type >::type >
{
static void resize( Eigen::ArrayBase< Derived > &v1 , const Eigen::ArrayBase< Derived > &v2 )

View File

@ -46,18 +46,29 @@ namespace detail {
} // namespace detail
/*
* Default implementation of the copy operation used the assign operator
* gsl_vector must copied differently
*/
template< class Container1, class Container2 , class Enabler = void >
struct copy_impl
template< class Container1 , class Container2 , class Enabler = void >
struct copy_impl_sfinae
{
static void copy( const Container1 &from , Container2 &to )
{
typedef typename boost::numeric::odeint::detail::is_range< Container1 >::type is_range_type;
detail::do_copying( from , to , is_range_type() );
}
};
template< class Container1, class Container2 >
struct copy_impl
{
static void copy( const Container1 &from , Container2 &to )
{
copy_impl_sfinae< Container1 , Container2 >::copy( from , to );
}
};
// ToDo: allow also to copy INTO a range, not only from a range! Needs "const Container2 &to"

View File

@ -29,42 +29,38 @@
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/placeholders.hpp>
// #include <boost/mpl/not.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost {
namespace numeric {
namespace odeint {
/*
* by default any type is not resizable
*/
template< class Container , class Enabler = void >
struct is_resizeable
{
//struct type : public boost::false_type { };
typedef boost::false_type type;
const static bool value = type::value;
};
template< typename Container , typename Enabler = void >
struct is_resizeable_sfinae : boost::false_type {};
template< typename Container >
struct is_resizeable : is_resizeable_sfinae< Container > {};
/*
* specialization for std::vector
*/
template< class V, class A >
struct is_resizeable< std::vector< V , A > >
{
//struct type : public boost::true_type { };
typedef boost::true_type type;
const static bool value = type::value;
};
struct is_resizeable< std::vector< V , A > > : boost::true_type {};
/*
* specialization for fusion sequences
* sfinae specialization for fusion sequences
*/
template< class FusionSequence >
struct is_resizeable< FusionSequence , typename boost::enable_if< typename boost::fusion::traits::is_sequence< FusionSequence >::type >::type >
template< typename FusionSequence >
struct is_resizeable_sfinae<
FusionSequence ,
typename boost::enable_if< typename boost::fusion::traits::is_sequence< FusionSequence >::type >::type >
{
typedef typename boost::mpl::find_if< FusionSequence , is_resizeable< boost::mpl::_1 > >::type iter;
typedef typename boost::mpl::end< FusionSequence >::type last;

View File

@ -67,7 +67,7 @@ struct is_resizeable_multi_array< boost::multi_array< V , Dim , A > >
template< typename T >
struct is_resizeable< T , typename boost::enable_if< typename is_resizeable_multi_array< T >::type >::type >
struct is_resizeable_sfinae< T , typename boost::enable_if< typename is_resizeable_multi_array< T >::type >::type >
{
typedef boost::true_type type;
const static bool value = type::value;
@ -78,7 +78,7 @@ struct is_resizeable< T , typename boost::enable_if< typename is_resizeable_mult
template< typename T1 , typename T2 >
struct same_size_impl< T1 , T2 ,
struct same_size_impl_sfinae< T1 , T2 ,
typename boost::enable_if<
typename boost::mpl::and_<
is_multi_array< T1 > ,
@ -100,7 +100,7 @@ struct same_size_impl< T1 , T2 ,
template< typename T1 , typename T2 >
struct resize_impl< T1 , T2 ,
struct resize_impl_sfinae< T1 , T2 ,
typename boost::enable_if<
typename boost::mpl::and_<
is_resizeable_multi_array< T1 > ,

View File

@ -33,11 +33,10 @@
namespace boost {
namespace numeric {
namespace odeint {
// resize function
// standard implementation relies on boost.range and resize member function
template< class StateOut , class StateIn , class Enabler = void >
struct resize_impl
struct resize_impl_sfinae
{
static void resize( StateOut &x1 , const StateIn &x2 )
{
@ -45,6 +44,17 @@ struct resize_impl
}
};
// resize function
// standard implementation relies on boost.range and resize member function
template< class StateOut , class StateIn >
struct resize_impl
{
static void resize( StateOut &x1 , const StateIn &x2 )
{
resize_impl_sfinae< StateOut , StateIn >::resize( x1 , x2 );
}
};
// do not overload or specialize this function, specialize resize_impl<> instead
template< class StateOut , class StateIn >
@ -85,7 +95,8 @@ namespace detail {
* specialization for fusion sequences
*/
template< class FusionSeq >
struct resize_impl< FusionSeq , FusionSeq , typename boost::enable_if< typename boost::fusion::traits::is_sequence< FusionSeq >::type >::type >
struct resize_impl_sfinae< FusionSeq , FusionSeq ,
typename boost::enable_if< typename boost::fusion::traits::is_sequence< FusionSeq >::type >::type >
{
static void resize( FusionSeq &x1 , const FusionSeq &x2 )
{

View File

@ -34,16 +34,26 @@
namespace boost {
namespace numeric {
namespace odeint {
// same_size function
// standard implementation relies on boost.range
template< class State1 , class State2 , class Enabler = void >
struct same_size_impl
template< typename State1 , typename State2 , class Enabler = void >
struct same_size_impl_sfinae
{
static bool same_size( const State1 &x1 , const State2 &x2 )
{
return ( boost::size( x1 ) == boost::size( x2 ) );
}
};
// same_size function
// standard implementation relies on boost.range
template< class State1 , class State2 >
struct same_size_impl
{
static bool same_size( const State1 &x1 , const State2 &x2 )
{
return same_size_impl_sfinae< State1 , State2 >::same_size( x1 , x2 );
}
};
@ -84,7 +94,7 @@ struct same_size_fusion
template< class FusionSeq >
struct same_size_impl< FusionSeq , FusionSeq , typename boost::enable_if< typename boost::fusion::traits::is_sequence< FusionSeq >::type >::type >
struct same_size_impl_sfinae< FusionSeq , FusionSeq , typename boost::enable_if< typename boost::fusion::traits::is_sequence< FusionSeq >::type >::type >
{
static bool same_size( const FusionSeq &x1 , const FusionSeq &x2 )
{

View File

@ -39,6 +39,24 @@
using namespace boost::unit_test;
using namespace boost::numeric::odeint;
template< typename T > struct my_seq1 {};
template< typename T > struct my_seq2 {};
namespace boost { namespace fusion { namespace traits {
template< typename T > struct is_sequence< my_seq1< T > > : boost::true_type {};
template< typename T > struct is_sequence< my_seq2< T > > : boost::true_type {};
} } } // boost::fusion::traits
namespace boost { namespace numeric { namespace odeint {
template< typename T >
struct is_resizeable< my_seq2< T > > : boost::true_type {};
} } } // boost::numeric::odeint
BOOST_AUTO_TEST_CASE( test_vector )
{
BOOST_CHECK( is_resizeable< std::vector< int > >::value );
@ -86,3 +104,13 @@ BOOST_AUTO_TEST_CASE( test_fusion_quantity_sequence )
BOOST_CHECK( !( is_resizeable< state_type >::value ) );
}
BOOST_AUTO_TEST_CASE( test_my_seq1 )
{
BOOST_CHECK( !is_resizeable< my_seq1< double > >::value );
}
BOOST_AUTO_TEST_CASE( test_my_seq2 )
{
BOOST_CHECK( is_resizeable< my_seq2< double > >::value );
}