mirror of
https://github.com/boostorg/odeint.git
synced 2025-05-11 13:34:09 +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 boost {
|
||||||
namespace numeric {
|
namespace numeric {
|
||||||
namespace odeint {
|
namespace odeint {
|
||||||
|
|
||||||
template< class StateType , class Enabler = void >
|
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;
|
typedef range_algebra algebra_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template< class StateType >
|
||||||
|
struct algebra_dispatcher : algebra_dispatcher_sfinae< StateType > { };
|
||||||
|
|
||||||
//specialize for array
|
//specialize for array
|
||||||
template< class T , size_t N >
|
template< class T , size_t N >
|
||||||
struct algebra_dispatcher< boost::array< 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
|
//specialize for some integral types
|
||||||
template< typename T >
|
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;
|
typedef vector_space_algebra algebra_type;
|
||||||
};
|
};
|
||||||
|
@ -32,7 +32,7 @@ namespace odeint {
|
|||||||
|
|
||||||
// specialization for fusion sequences
|
// specialization for fusion sequences
|
||||||
template< class FusionSequence >
|
template< class FusionSequence >
|
||||||
struct algebra_dispatcher< FusionSequence ,
|
struct algebra_dispatcher_sfinae< FusionSequence ,
|
||||||
typename boost::enable_if<
|
typename boost::enable_if<
|
||||||
typename boost::fusion::traits::is_sequence< FusionSequence >::type >::type >
|
typename boost::fusion::traits::is_sequence< FusionSequence >::type >::type >
|
||||||
{
|
{
|
||||||
|
@ -22,14 +22,16 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace numeric {
|
namespace numeric {
|
||||||
namespace odeint {
|
namespace odeint {
|
||||||
|
|
||||||
template< class StateType , class Enabler = void >
|
template< class StateType , class Enabler = void >
|
||||||
struct operations_dispatcher
|
struct operations_dispatcher_sfinae
|
||||||
{
|
{
|
||||||
// default_operations are the standard operations
|
|
||||||
typedef default_operations operations_type;
|
typedef default_operations operations_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template< class StateType >
|
||||||
|
struct operations_dispatcher : operations_dispatcher_sfinae< StateType > {};
|
||||||
|
|
||||||
// no further specializations required
|
// no further specializations required
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ namespace odeint {
|
|||||||
|
|
||||||
|
|
||||||
template< class Derived >
|
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 >
|
typename boost::enable_if< typename boost::is_base_of< Eigen::MatrixBase< Derived > , Derived >::type >::type >
|
||||||
{
|
{
|
||||||
typedef boost::true_type type;
|
typedef boost::true_type type;
|
||||||
@ -44,7 +44,7 @@ struct is_resizeable< Derived ,
|
|||||||
|
|
||||||
|
|
||||||
template < class 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 >
|
typename boost::enable_if< typename boost::is_base_of< Eigen::ArrayBase< Derived > , Derived >::type >::type >
|
||||||
{
|
{
|
||||||
typedef boost::true_type type;
|
typedef boost::true_type type;
|
||||||
@ -54,7 +54,7 @@ struct is_resizeable< Derived ,
|
|||||||
|
|
||||||
|
|
||||||
template< class 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 >
|
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 )
|
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 >
|
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 >
|
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 )
|
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 >
|
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 >
|
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 )
|
static void resize( Eigen::MatrixBase< Derived > &m1 , const Eigen::MatrixBase< Derived > &m2 )
|
||||||
@ -88,7 +88,7 @@ struct resize_impl< Derived , Derived ,
|
|||||||
};
|
};
|
||||||
|
|
||||||
template< class 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 >
|
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 )
|
static void resize( Eigen::ArrayBase< Derived > &v1 , const Eigen::ArrayBase< Derived > &v2 )
|
||||||
|
@ -46,18 +46,29 @@ namespace detail {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default implementation of the copy operation used the assign operator
|
* Default implementation of the copy operation used the assign operator
|
||||||
* gsl_vector must copied differently
|
* gsl_vector must copied differently
|
||||||
*/
|
*/
|
||||||
template< class Container1, class Container2 , class Enabler = void >
|
template< class Container1 , class Container2 , class Enabler = void >
|
||||||
struct copy_impl
|
struct copy_impl_sfinae
|
||||||
{
|
{
|
||||||
static void copy( const Container1 &from , Container2 &to )
|
static void copy( const Container1 &from , Container2 &to )
|
||||||
{
|
{
|
||||||
typedef typename boost::numeric::odeint::detail::is_range< Container1 >::type is_range_type;
|
typedef typename boost::numeric::odeint::detail::is_range< Container1 >::type is_range_type;
|
||||||
detail::do_copying( from , to , 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"
|
// 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/find_if.hpp>
|
||||||
#include <boost/mpl/end.hpp>
|
#include <boost/mpl/end.hpp>
|
||||||
#include <boost/mpl/placeholders.hpp>
|
#include <boost/mpl/placeholders.hpp>
|
||||||
// #include <boost/mpl/not.hpp>
|
|
||||||
#include <boost/mpl/if.hpp>
|
#include <boost/mpl/if.hpp>
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace numeric {
|
namespace numeric {
|
||||||
namespace odeint {
|
namespace odeint {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* by default any type is not resizable
|
* by default any type is not resizable
|
||||||
*/
|
*/
|
||||||
template< class Container , class Enabler = void >
|
template< typename Container , typename Enabler = void >
|
||||||
struct is_resizeable
|
struct is_resizeable_sfinae : boost::false_type {};
|
||||||
{
|
|
||||||
//struct type : public boost::false_type { };
|
template< typename Container >
|
||||||
typedef boost::false_type type;
|
struct is_resizeable : is_resizeable_sfinae< Container > {};
|
||||||
const static bool value = type::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* specialization for std::vector
|
* specialization for std::vector
|
||||||
*/
|
*/
|
||||||
template< class V, class A >
|
template< class V, class A >
|
||||||
struct is_resizeable< std::vector< V , A > >
|
struct is_resizeable< std::vector< V , A > > : boost::true_type {};
|
||||||
{
|
|
||||||
//struct type : public boost::true_type { };
|
|
||||||
typedef boost::true_type type;
|
|
||||||
const static bool value = type::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* specialization for fusion sequences
|
* sfinae specialization for fusion sequences
|
||||||
*/
|
*/
|
||||||
template< class FusionSequence >
|
template< typename FusionSequence >
|
||||||
struct is_resizeable< FusionSequence , typename boost::enable_if< typename boost::fusion::traits::is_sequence< FusionSequence >::type >::type >
|
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::find_if< FusionSequence , is_resizeable< boost::mpl::_1 > >::type iter;
|
||||||
typedef typename boost::mpl::end< FusionSequence >::type last;
|
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 >
|
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;
|
typedef boost::true_type type;
|
||||||
const static bool value = type::value;
|
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 >
|
template< typename T1 , typename T2 >
|
||||||
struct same_size_impl< T1 , T2 ,
|
struct same_size_impl_sfinae< T1 , T2 ,
|
||||||
typename boost::enable_if<
|
typename boost::enable_if<
|
||||||
typename boost::mpl::and_<
|
typename boost::mpl::and_<
|
||||||
is_multi_array< T1 > ,
|
is_multi_array< T1 > ,
|
||||||
@ -100,7 +100,7 @@ struct same_size_impl< T1 , T2 ,
|
|||||||
|
|
||||||
|
|
||||||
template< typename T1 , typename T2 >
|
template< typename T1 , typename T2 >
|
||||||
struct resize_impl< T1 , T2 ,
|
struct resize_impl_sfinae< T1 , T2 ,
|
||||||
typename boost::enable_if<
|
typename boost::enable_if<
|
||||||
typename boost::mpl::and_<
|
typename boost::mpl::and_<
|
||||||
is_resizeable_multi_array< T1 > ,
|
is_resizeable_multi_array< T1 > ,
|
||||||
|
@ -33,11 +33,10 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace numeric {
|
namespace numeric {
|
||||||
namespace odeint {
|
namespace odeint {
|
||||||
|
|
||||||
// resize function
|
|
||||||
// standard implementation relies on boost.range and resize member function
|
|
||||||
template< class StateOut , class StateIn , class Enabler = void >
|
template< class StateOut , class StateIn , class Enabler = void >
|
||||||
struct resize_impl
|
struct resize_impl_sfinae
|
||||||
{
|
{
|
||||||
static void resize( StateOut &x1 , const StateIn &x2 )
|
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
|
// do not overload or specialize this function, specialize resize_impl<> instead
|
||||||
template< class StateOut , class StateIn >
|
template< class StateOut , class StateIn >
|
||||||
@ -85,7 +95,8 @@ namespace detail {
|
|||||||
* specialization for fusion sequences
|
* specialization for fusion sequences
|
||||||
*/
|
*/
|
||||||
template< class FusionSeq >
|
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 )
|
static void resize( FusionSeq &x1 , const FusionSeq &x2 )
|
||||||
{
|
{
|
||||||
|
@ -34,16 +34,26 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace numeric {
|
namespace numeric {
|
||||||
namespace odeint {
|
namespace odeint {
|
||||||
|
|
||||||
// same_size function
|
template< typename State1 , typename State2 , class Enabler = void >
|
||||||
// standard implementation relies on boost.range
|
struct same_size_impl_sfinae
|
||||||
template< class State1 , class State2 , class Enabler = void >
|
|
||||||
struct same_size_impl
|
|
||||||
{
|
{
|
||||||
static bool same_size( const State1 &x1 , const State2 &x2 )
|
static bool same_size( const State1 &x1 , const State2 &x2 )
|
||||||
{
|
{
|
||||||
return ( boost::size( x1 ) == boost::size( 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 >
|
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 )
|
static bool same_size( const FusionSeq &x1 , const FusionSeq &x2 )
|
||||||
{
|
{
|
||||||
|
@ -39,6 +39,24 @@
|
|||||||
using namespace boost::unit_test;
|
using namespace boost::unit_test;
|
||||||
using namespace boost::numeric::odeint;
|
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_AUTO_TEST_CASE( test_vector )
|
||||||
{
|
{
|
||||||
BOOST_CHECK( is_resizeable< std::vector< int > >::value );
|
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_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