Initial commit.

This commit is contained in:
2018-12-06 16:01:56 +01:00
parent 10867b60c2
commit 18eb3f6047
1011 changed files with 345688 additions and 10 deletions

View File

@@ -0,0 +1,43 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_ADAPTABLE_TYPE_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_ADAPTABLE_TYPE_HPP
#include <boost/numeric/bindings/detail/adaptor.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename Derived >
struct adaptable_type {
inline
Derived& derived() {
return *static_cast<Derived*>(this);
}
inline
Derived const& derived() const {
return *static_cast<Derived const*>(this);
}
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
template< typename T >
std::ostream& operator<<( std::ostream& os,
boost::numeric::bindings::detail::adaptable_type<T> const& object );
#endif

View File

@@ -0,0 +1,51 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_ADAPTOR_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_ADAPTOR_HPP
#include <boost/mpl/map.hpp>
#include <boost/numeric/bindings/detail/copy_const.hpp>
#include <boost/numeric/bindings/is_numeric.hpp>
#include <boost/numeric/bindings/tag.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename T, typename Id, typename Enable = void >
struct adaptor {
typedef mpl::map<
mpl::pair< tag::value_type, void >
> property_map;
};
template< typename T >
struct is_adaptable: is_numeric< typename mpl::at<
typename adaptor< typename boost::remove_const<T>::type, T >::property_map,
tag::value_type >::type > {};
template< typename T, typename Enable = void >
struct adaptor_access {};
template< typename T >
struct adaptor_access< T, typename boost::enable_if< is_adaptable<T> >::type >:
adaptor< typename boost::remove_const<T>::type, T > {};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#include <boost/numeric/bindings/detail/pod.hpp>
#include <boost/numeric/bindings/detail/property_map.hpp>
#endif

View File

@@ -0,0 +1,127 @@
//
// Copyright (c) 2003 Kresimir Fresl
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_ARRAY_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_ARRAY_HPP
#include <new>
#include <boost/noncopyable.hpp>
#include <boost/numeric/bindings/detail/adaptor.hpp>
/*
very simple dynamic array class which is used in `higher level'
bindings functions for pivot and work arrays
Namely, there are (at least) two versions of all bindings functions
where called LAPACK function expects work and/or pivot array, e.g.
`lower' level (user should provide work and pivot arrays):
int sysv (SymmA& a, IVec& i, MatrB& b, Work& w);
`higher' level (with `internal' work and pivot arrays):
int sysv (SymmA& a, MatrB& b);
Probably you ask why I didn't use std::vector. There are two reasons.
First is efficiency -- std::vector's constructor initialises vector
elements. Second is consistency. LAPACK functions use `info' parameter
as an error indicator. On the other hand, std::vector's allocator can
throw an exception if memory allocation fails. detail::array's
constructor uses `new (nothrow)' which returns 0 if allocation fails.
So I can check whether array::storage == 0 and return appropriate error
in `info'.*/
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template <typename T>
class array : private noncopyable {
public:
typedef std::ptrdiff_t size_type ;
array (size_type n) {
stg = new (std::nothrow) T[n];
sz = (stg != 0) ? n : 0;
}
~array() {
delete[] stg;
}
size_type size() const {
return sz;
}
bool valid() const {
return stg != 0;
}
void resize (int n) {
delete[] stg;
stg = new (std::nothrow) T[n];
sz = (stg != 0) ? n : 0;
}
T* storage() {
return stg;
}
T const* storage() const {
return stg;
}
T& operator[] (int i) {
return stg[i];
}
T const& operator[] (int i) const {
return stg[i];
}
private:
size_type sz;
T* stg;
};
template< typename T, typename Id, typename Enable >
struct adaptor< array< T >, Id, Enable > {
typedef typename copy_const< Id, T >::type value_type;
typedef mpl::map<
mpl::pair< tag::value_type, value_type >,
mpl::pair< tag::entity, tag::vector >,
mpl::pair< tag::size_type<1>, std::ptrdiff_t >,
mpl::pair< tag::data_structure, tag::linear_array >,
mpl::pair< tag::stride_type<1>, tag::contiguous >
> property_map;
static std::ptrdiff_t size1( const Id& t ) {
return t.size();
}
static value_type* begin_value( Id& t ) {
return t.storage();
}
static value_type* end_value( Id& t ) {
return t.storage() + t.size();
}
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,56 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_BASIC_UNWRAPPER_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_BASIC_UNWRAPPER_HPP
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/end.hpp>
#include <boost/numeric/bindings/size.hpp>
#include <boost/numeric/bindings/stride.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename T, typename Id >
struct basic_unwrapper {
static typename result_of::size1< T >::type size1( const Id& id ) {
return bindings::size1( id.get() );
}
static typename result_of::size2< T >::type size2( const Id& id ) {
return bindings::size2( id.get() );
}
static typename result_of::stride1< T >::type stride1( const Id& id ) {
return bindings::stride1( id.get() );
}
static typename result_of::stride2< T >::type stride2( const Id& id ) {
return bindings::stride2( id.get() );
}
static typename result_of::begin_value< T >::type begin_value( Id& id ) {
return bindings::begin_value( id.get() );
}
static typename result_of::end_value< T >::type end_value( Id& id ) {
return bindings::end_value( id.get() );
}
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,41 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_BASIC_WRAPPER_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_BASIC_WRAPPER_HPP
#include <boost/ref.hpp>
#include <boost/numeric/bindings/detail/adaptor.hpp>
#include <boost/numeric/bindings/detail/basic_unwrapper.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename T, typename P1 = mpl::void_, typename P2 = mpl::void_,
typename P3 = mpl::void_, typename P4 = mpl::void_ >
struct basic_wrapper: reference_wrapper<T> {
basic_wrapper( T& t ): reference_wrapper<T>( t ) {}
};
template< typename T, typename P1, typename P2, typename P3, typename P4,
typename Id, typename Enable >
struct adaptor< basic_wrapper<T, P1, P2, P3, P4>, Id, Enable >:
basic_unwrapper< T, Id > {
typedef typename property_insert< T, P1, P2, P3, P4 >::type property_map;
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,182 @@
//
// Copyright (c) 2003 Kresimir Fresl
// Copyright (c) 2010 Thomas Klimpel
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_COMPLEX_UTILS_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_COMPLEX_UTILS_HPP
#include <iterator>
#include <boost/numeric/bindings/begin.hpp>
#include <boost/numeric/bindings/end.hpp>
#include <boost/numeric/bindings/is_complex.hpp>
#include <boost/numeric/bindings/remove_imaginary.hpp>
#include <boost/numeric/bindings/value_type.hpp>
#include <boost/numeric/bindings/vector_view.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
#ifdef BOOST_NUMERIC_BINDINGS_BY_THE_BOOK
template <typename It>
void inshuffle(It it, std::size_t n) {
if (n==0) return;
for (std::size_t i = 0; 2*i < n; ++i) {
std::size_t k = 2*i + 1;
while (2*k <= n) k *= 2;
typename std::iterator_traits<It>::value_type tmp = it[n+i];
it[n+i] = it[k-1];
while (k % 2 == 0) {
it[k-1] = it[(k/2)-1];
k /= 2;
}
it[k-1] = tmp;
}
std::size_t kmin = 1;
while (2*kmin <= n) kmin *= 2;
for (std::size_t i = 0; 4*i+1 < n; ++i) {
std::size_t k = 2*i + 1;
while (2*k <= n) k *= 2;
std::size_t k1 = 2*(i+1) + 1;
while (2*k1 <= n) k1 *= 2;
if (k > k1) {
if (k1 < kmin) {
kmin = k1;
inshuffle(it+n, i+1);
}
else
inshuffle(it+n+1, i);
}
}
return inshuffle(it+n+(n%2), n/2);
}
#else
template <typename It>
void inshuffle(It it, std::size_t n) {
while (n > 0) {
std::size_t kmin = 1;
while (kmin <= n)
kmin *= 2;
{
std::size_t kk = kmin/2;
It itn = it + n;
for (std::size_t i = 0, s = (n+1)/2; i < s; ++i) {
std::size_t k = (2*i+1)*kk;
while (k > n) {
k /= 2;
kk /= 2;
}
// apply the cyclic permutation
typename std::iterator_traits<It>::value_type tmp = itn[i];
itn[i] = it[k-1];
while (k % 2 == 0) {
it[k-1] = it[(k/2)-1];
k /= 2;
}
it[k-1] = tmp;
}
}
// the optimized computation of k fails for n=2,
// so skip the 'normalization' loop when possible
if (n > 3) {
std::size_t kk = kmin/4;
for (std::size_t i = 1; 4*i < n+3; ++i) {
std::size_t k = (2*i+1)*kk;
if (k > n) {
kk /= 2;
if (k < kmin) {
kmin = k;
// if kmin is updated, do an in-shuffle
inshuffle(it+n, i);
}
else
// otherwise do an out-shuffle
inshuffle(it+n+1, i-1);
}
}
}
// implement the tail recursion as an iteration
it += n+(n%2);
n /= 2;
}
}
#endif
// Reorders a real array followed by an imaginary array to a true complex array
// where real and imaginary part of each number directly follow each other.
template <typename VectorW>
typename boost::enable_if< is_complex< typename bindings::value_type< VectorW >::type >, void >::type
interlace (VectorW& w) {
typedef typename bindings::value_type< VectorW >::type value_type;
typedef typename bindings::remove_imaginary< value_type >::type real_type;
value_type* pw = bindings::begin_value(w);
std::ptrdiff_t n = bindings::end_value(w) - pw;
if (n < 2) return;
inshuffle(reinterpret_cast<real_type*> (pw)+1, n-1);
}
} // namespace detail
namespace result_of {
template< typename VectorW >
struct real_part_view {
typedef typename bindings::result_of::vector_view< typename
bindings::remove_imaginary< typename
bindings::value_type< VectorW >::type
>::type >::type type;
};
template< typename VectorW >
struct imag_part_view {
typedef typename bindings::result_of::vector_view< typename
bindings::remove_imaginary< typename
bindings::value_type< VectorW >::type
>::type >::type type;
};
} // namespace result_of
namespace detail {
// Creates a real vector_view to the first half of the complex array,
// which is intended to be filled by the real part
template <typename VectorW>
typename boost::enable_if< is_complex< typename bindings::value_type< VectorW >::type >,
typename result_of::real_part_view< VectorW >::type const >::type
real_part_view (VectorW& w) {
typedef typename bindings::value_type< VectorW >::type value_type;
typedef typename bindings::remove_imaginary< value_type >::type real_type;
value_type* pw = bindings::begin_value(w);
std::ptrdiff_t n = bindings::end_value(w) - pw;
return bindings::vector_view(reinterpret_cast<real_type*> (pw), n);
}
// Creates a real vector_view to the second half of the complex array,
// which is intended to be filled by the imaginary part
template <typename VectorW>
typename boost::enable_if< is_complex< typename bindings::value_type< VectorW >::type >,
typename result_of::imag_part_view< VectorW >::type const >::type
imag_part_view (VectorW& w) {
typedef typename bindings::value_type< VectorW >::type value_type;
typedef typename bindings::remove_imaginary< value_type >::type real_type;
value_type* pw = bindings::begin_value(w);
std::ptrdiff_t n = bindings::end_value(w) - pw;
return bindings::vector_view(reinterpret_cast<real_type*> (pw)+n, n);
}
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,88 @@
//
// Copyright (C) 2002, 2003 Si-Lab b.v.b.a., Toon Knapen and Kresimir Fresl
// 2010 Thomas Klimpel
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_CONFIG_FORTRAN_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_CONFIG_FORTRAN_HPP
#if defined(BIND_FORTRAN_LOWERCASE_UNDERSCORE) || defined(BIND_FORTRAN_LOWERCASE) || defined(BIND_FORTRAN_UPPERCASE_UNDERSCORE) || defined(BIND_FORTRAN_UPPERCASE)
// Allow manual override of the defaults, e.g. if you want to use a fortran
// lib compiled with gcc from MSVC
#else
// We have no chance of determining the conventions for linking C with Fortran
// here, because they only depend on the fortran compiler and it's command line
// switches, but not on the C++ compiler which compiles these lines.
// We default to lowercase underscore, because this is much more common than
// the other option. (The previous automatic configuration only selected the
// other option in case of "defined(__IBMCPP__) || defined(_MSC_VER)".)
#define BIND_FORTRAN_LOWERCASE_UNDERSCORE
#endif
// Next we define macro's to convert our symbols to
// the current convention
#if defined(BIND_FORTRAN_LOWERCASE_UNDERSCORE)
#define FORTRAN_ID( id ) id##_
#define FORTRAN_ID2( id, ID2 ) id##_
#elif defined(BIND_FORTRAN_LOWERCASE)
#define FORTRAN_ID( id ) id
#define FORTRAN_ID2( id, ID2 ) id
#elif defined(BIND_FORTRAN_UPPERCASE_UNDERSCORE)
#define FORTRAN_ID2( id, ID2 ) ID2##_
#elif defined(BIND_FORTRAN_UPPERCASE)
#define FORTRAN_ID2( id, ID2 ) ID2
#else
#error do not know how to bind to fortran calling convention
#endif
#ifdef BIND_FORTRAN_F2C_RETURN_CONVENTIONS
// "g77" or clapack or "gfortran -ff2c"
#define BIND_FORTRAN_RETURN_REAL_DOUBLE
#define BIND_FORTRAN_RETURN_COMPLEX_FIRST_ARG
#elif BIND_FORTRAN_MKL_RETURN_CONVENTIONS
// mkl
#define BIND_FORTRAN_RETURN_COMPLEX_FIRST_ARG
#elif BIND_FORTRAN_OSX_RETURN_CONVENTIONS
// OS X
#define BIND_FORTRAN_RETURN_COMPLEX_LAST_ARG
#else
// "g77 -fno-f2c" or "gfortran"
#endif
// "g77" or "gfortran" or mkl_intel_lp64
//#undef BIND_FORTRAN_INTEGER_8
// clapack or "gfortran -fdefault-integer-8" or mkl_intel_ilp64
//#define BIND_FORTRAN_INTEGER_8
// Most fortran compilers use fortran_int_t := int by default, so we follow
// this default, even so f2c (=clapack) uses "typedef long int integer;"
#ifndef BIND_FORTRAN_INTEGER_8
typedef int fortran_int_t;
#else
typedef std::ptrdiff_t fortran_int_t;
#endif
// Looks like fortran_int_t and fortran_bool_t should be identical, the unsigned is
// required so overloads can distinguish between fortran_bool_t and fortran_int_t.
#ifndef BIND_FORTRAN_INTEGER_8
typedef unsigned int fortran_bool_t;
#else
typedef std::size_t fortran_bool_t;
#endif
// This definition of external_fp is identical to the definition of L_fp from
// f2c, and it seems to work more or less. These functions return fortran_bool_t,
// but they don't all take the same type of arguments. A reinterpret_cast will
// probably work for most compilers to extend the allowed function signatures.
typedef fortran_bool_t (*external_fp)(...);
#endif // BOOST_NUMERIC_BINDINGS_TRAITS_FORTRAN_H

View File

@@ -0,0 +1,25 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_CONVERT_TO_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_CONVERT_TO_HPP
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename Target, typename Source >
struct convert_to {};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,32 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_COPY_CONST_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_COPY_CONST_HPP
#include <boost/mpl/if.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/is_const.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename Source, typename Target >
struct copy_const {
typedef typename mpl::if_< is_const<Source>,
typename add_const<Target>::type, Target >::type type;
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,48 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_GENERATE_FUNCTIONS_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_GENERATE_FUNCTIONS_HPP
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/cat.hpp>
//
// Macro used to generate convenience functions
//
#define GENERATE_FUNCTIONS( function_name, suffix, tag ) \
\
namespace result_of {\
\
template< typename T > \
struct BOOST_PP_CAT( function_name, suffix ) { \
typedef typename detail::\
BOOST_PP_CAT( function_name, _impl ) \
<T, tag >::result_type type; \
}; \
\
}\
\
template< typename T >\
typename result_of:: BOOST_PP_CAT( function_name, suffix )<T>::type \
BOOST_PP_CAT( function_name, suffix )( T& t ) {\
return detail:: \
BOOST_PP_CAT( function_name, _impl ) \
<T, tag >::invoke( t );\
}\
\
template< typename T >\
typename result_of:: BOOST_PP_CAT( function_name, suffix )<const T>::type \
BOOST_PP_CAT( function_name, suffix )( const T& t ) {\
return detail:: \
BOOST_PP_CAT( function_name, _impl ) \
<const T, tag >::invoke( t );\
}
#endif

View File

@@ -0,0 +1,96 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_GET_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_GET_HPP
#include <boost/numeric/bindings/detail/adaptor.hpp>
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/cat.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename Key >
struct get_dispatch {};
#define GENERATE_GET( z, which, unused ) \
template<> \
struct get_dispatch< tag::size_type<which> > { \
template< typename T > \
static std::ptrdiff_t invoke( const T& t ) { \
return detail::adaptor_access<T>:: \
BOOST_PP_CAT( size, which )( t ); \
} \
};\
\
template<> \
struct get_dispatch< tag::stride_type<which> > { \
template< typename T > \
static std::ptrdiff_t invoke( const T& t ) { \
return detail::adaptor_access<T>:: \
BOOST_PP_CAT( stride, which )( t ); \
} \
};\
\
template<> \
struct get_dispatch< tag::bandwidth_type<which> > { \
template< typename T > \
static std::ptrdiff_t invoke( const T& t ) { \
return detail::adaptor_access<T>:: \
BOOST_PP_CAT( bandwidth, which )( t ); \
} \
};
BOOST_PP_REPEAT_FROM_TO(1,3,GENERATE_GET,~)
template< typename T, typename Key, typename Enable = void >
struct get_impl {};
template< typename T, typename Key >
struct get_impl< T, Key, typename boost::enable_if<
is_same_at< T, Key, std::ptrdiff_t > >::type > {
typedef std::ptrdiff_t result_type;
static std::ptrdiff_t invoke( const T& t ) {
return get_dispatch<Key>::invoke( t );
}
};
template< typename T, typename Key >
struct get_impl< T, Key, typename boost::enable_if<
mpl::not_< is_same_at< T, Key, std::ptrdiff_t > > >::type > {
typedef typename property_at< T, Key >::type result_type;
static result_type invoke( const T& ) {
return result_type();
}
};
template< typename T, typename Key >
struct result_of_get {
typedef typename get_impl< T, Key >::result_type type;
};
template< typename Key, typename T >
typename result_of_get< T, Key >::type get( const T& t ) {
return get_impl< T, Key >::invoke( t );
}
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,53 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_IF_LEFT_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_IF_LEFT_HPP
#include <boost/numeric/bindings/tag.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename Side, typename Left, typename Right >
struct if_left_impl {
typedef Right result_type;
static result_type invoke( Left, Right right ) {
return right;
}
};
template< typename Left, typename Right >
struct if_left_impl< tag::left, Left, Right > {
typedef Left result_type;
static result_type invoke( Left left, Right ) {
return left;
}
};
// by-value
template< typename Side, typename Left, typename Right >
typename if_left_impl< Side, const Left, const Right >::result_type
if_left( const Side, const Left left, const Right right ) {
return if_left_impl< Side, const Left, const Right >::invoke( left, right );
}
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,34 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_IF_ROW_MAJOR_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_IF_ROW_MAJOR_HPP
#include <boost/numeric/bindings/tag.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename Order, typename True, typename False >
struct if_row_major {
typedef False type;
};
template< typename True, typename False >
struct if_row_major< tag::row_major, True, False > {
typedef True type;
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,89 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_LINEAR_ITERATOR_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_LINEAR_ITERATOR_HPP
#include <boost/iterator/iterator_adaptor.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename T, typename StrideType >
class linear_iterator: public boost::iterator_adaptor<
linear_iterator<T, StrideType >,
T*, use_default, random_access_traversal_tag > {
public:
typedef mpl::int_<StrideType::value> stride_type;
linear_iterator():
linear_iterator::iterator_adaptor_(0) {}
explicit linear_iterator( T* p, StrideType ignore ):
linear_iterator::iterator_adaptor_(p) {}
private:
friend class boost::iterator_core_access;
void advance( int n ) {
(this->base_reference()) += n * stride_type::value;
}
void decrement() {
(this->base_reference()) -= stride_type::value;
}
void increment() {
(this->base_reference()) += stride_type::value;
}
};
template< typename T >
class linear_iterator< T, std::ptrdiff_t >: public boost::iterator_adaptor<
linear_iterator< T, std::ptrdiff_t >,
T*, use_default, random_access_traversal_tag > {
public:
typedef std::ptrdiff_t stride_type;
linear_iterator():
linear_iterator::iterator_adaptor_(0),
m_stride(0) {}
explicit linear_iterator( T* p, std::ptrdiff_t stride ):
linear_iterator::iterator_adaptor_(p),
m_stride( stride ) {}
private:
friend class boost::iterator_core_access;
void advance( int n ) {
(this->base_reference()) += n * m_stride;
}
void decrement() {
(this->base_reference()) -= m_stride;
}
void increment() {
(this->base_reference()) += m_stride;
}
std::ptrdiff_t m_stride;
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,72 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_OFFSET_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_OFFSET_HPP
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/numeric/bindings/is_column_major.hpp>
#include <boost/numeric/bindings/has_linear_array.hpp>
#include <boost/numeric/bindings/has_band_array.hpp>
#include <boost/numeric/bindings/stride.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename T, typename Enable = void >
struct offset_impl {};
template< typename T >
struct offset_impl< T, typename boost::enable_if< has_linear_array< T > >::type > {
static std::ptrdiff_t invoke( const T& t, std::ptrdiff_t i1 ) {
return i1 * bindings::stride1( t );
}
static std::ptrdiff_t invoke( const T& t, std::ptrdiff_t i1, std::ptrdiff_t i2 ) {
return i1 * bindings::stride1( t ) +
i2 * bindings::stride2( t );
}
};
template< typename T >
struct offset_impl< T,
typename boost::enable_if<
mpl::and_<
has_band_array< T >,
is_column_major< T >
>
>::type > {
static std::ptrdiff_t invoke( const T& t, std::ptrdiff_t i1, std::ptrdiff_t i2 ) {
return i1 * bindings::stride1( t ) +
i2 * (bindings::stride2( t )-1);
}
};
template< typename T >
std::ptrdiff_t offset( const T& t, std::ptrdiff_t i1 ) {
return offset_impl< T >::invoke( t, i1 );
}
template< typename T >
std::ptrdiff_t offset( const T& t, std::ptrdiff_t i1, std::ptrdiff_t i2 ) {
return offset_impl< T >::invoke( t, i1, i2 );
}
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,90 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_POD_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_POD_HPP
#include <boost/numeric/bindings/is_numeric.hpp>
#include <boost/numeric/bindings/detail/adaptor.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename T, typename Id >
struct adaptor< T, Id, typename boost::enable_if< is_numeric<T> >::type > {
typedef typename copy_const< Id, T >::type value_type;
typedef mpl::map<
mpl::pair< tag::value_type, value_type >,
mpl::pair< tag::entity, tag::scalar >,
mpl::pair< tag::size_type<1>, mpl::int_<1> >,
mpl::pair< tag::data_structure, tag::linear_array >
> property_map;
static value_type* begin_value( Id& t ) {
return &t;
}
};
template< typename T, std::size_t N, typename Id >
struct adaptor< T[N], Id, typename boost::enable_if< is_numeric<T> >::type > {
typedef typename copy_const< Id, T >::type value_type;
typedef mpl::map<
mpl::pair< tag::value_type, value_type >,
mpl::pair< tag::entity, tag::vector >,
mpl::pair< tag::size_type<1>, mpl::int_<N> >,
mpl::pair< tag::data_structure, tag::linear_array >,
mpl::pair< tag::stride_type<1>, tag::contiguous >
> property_map;
static value_type* begin_value( Id& t ) {
return &t[0];
}
static value_type* end_value( Id& t ) {
return &t[N];
}
};
template< typename T, std::size_t M, std::size_t N, typename Id >
struct adaptor< T[M][N], Id, typename boost::enable_if< is_numeric<T> >::type > {
typedef typename copy_const< Id, T >::type value_type;
typedef mpl::map<
mpl::pair< tag::value_type, value_type >,
mpl::pair< tag::entity, tag::matrix >,
mpl::pair< tag::size_type<1>, mpl::int_<M> >,
mpl::pair< tag::size_type<2>, mpl::int_<N> >,
mpl::pair< tag::matrix_type, tag::general >,
mpl::pair< tag::data_structure, tag::linear_array >,
mpl::pair< tag::data_order, tag::row_major >,
mpl::pair< tag::stride_type<1>, mpl::int_<N> >,
mpl::pair< tag::stride_type<2>, tag::contiguous >
> property_map;
static value_type* begin_value( Id& t ) {
return &t[0][0];
}
static value_type* end_value( Id& t ) {
return &t[M][N];
}
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif

View File

@@ -0,0 +1,73 @@
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NUMERIC_BINDINGS_DETAIL_PROPERTY_MAP_HPP
#define BOOST_NUMERIC_BINDINGS_DETAIL_PROPERTY_MAP_HPP
#include <boost/mpl/at.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/has_key.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/numeric/bindings/detail/adaptor.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost {
namespace numeric {
namespace bindings {
namespace detail {
template< typename T, typename Key >
struct property_has_key: mpl::has_key< typename adaptor_access<T>::property_map, Key > {};
template< typename T, typename Key >
struct property_at {
typedef typename mpl::at< typename adaptor_access<T>::property_map, Key >::type type;
};
template< typename T >
struct property_map_of {
typedef typename adaptor_access<T>::property_map type;
};
template< typename T, typename Key, typename Value >
struct is_same_at: is_same< typename property_at< T, Key >::type, Value > {};
//
// Meta-function to insert multiple pairs into a map by using fold. Using the
// provided mpl::insert can (only) insert elements in a map one-by-one.
//
template< typename T,
typename P1 = mpl::na, typename P2 = mpl::na, typename P3 = mpl::na,
typename P4 = mpl::na, typename P5 = mpl::na, typename P6 = mpl::na,
typename P7 = mpl::na, typename P8 = mpl::na, typename P9 = mpl::na,
typename P10 = mpl::na >
struct property_insert {
typedef mpl::vector< P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 > pair_vector;
typedef typename property_map_of< T >::type properties;
typedef typename mpl::fold<
pair_vector,
properties,
mpl::if_<
is_same< mpl::_2, mpl::void_ >,
mpl::_1,
mpl::insert< mpl::_1, mpl::_2 >
>
>::type type;
};
} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost
#endif