mirror of
https://github.com/boostorg/odeint.git
synced 2025-05-09 23:24:01 +00:00
Revert "Revert "Merge branch 'sfinae'""
This reverts commit 56a7c4040e4fc3d787d8df1d485f9a77d418e5a2.
This commit is contained in:
parent
56a7c4040e
commit
b94b3c1b29
@ -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;
|
||||
};
|
||||
|
@ -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 >
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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 )
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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 > ,
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 );
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user