Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,290 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// 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)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_CONFIG_
#define _BOOST_UBLAS_CONFIG_
#include <cassert>
#include <cstddef>
#include <algorithm>
#include <limits>
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
// Microsoft Visual C++
#if defined (BOOST_MSVC) && ! defined (BOOST_STRICT_CONFIG)
// Version 6.0 and 7.0
#if BOOST_MSVC <= 1300
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
// Version 7.1
#if BOOST_MSVC == 1310
// One of these workarounds is needed for MSVC 7.1 AFAIK
// (thanks to John Maddock and Martin Lauer).
#if !(defined(BOOST_UBLAS_NO_NESTED_CLASS_RELATION) || defined(BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION))
#define BOOST_UBLAS_NO_NESTED_CLASS_RELATION
#endif
#endif
#endif
// GNU Compiler Collection
#if defined (__GNUC__) && ! defined (BOOST_STRICT_CONFIG)
#if __GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)
// Specified by ABI definition see GCC bug id 9982
#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
#endif
#if __GNUC__ < 3
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
#endif
// Intel Compiler
#if defined (BOOST_INTEL) && ! defined (BOOST_STRICT_CONFIG)
#if defined (BOOST_INTEL_LINUX) && (BOOST_INTEL_LINUX >= 800)
// By inspection of compiler results
#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
#endif
#if (BOOST_INTEL < 700)
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
// Define swap for index_pair and triple.
#if (BOOST_INTEL <= 800)
namespace boost { namespace numeric { namespace ublas {
template<class C, class IC>
class indexed_iterator;
template<class V>
class index_pair;
template<class M>
class index_triple;
}}}
namespace std {
template<class V>
inline
void swap (boost::numeric::ublas::index_pair<V> i1, boost::numeric::ublas::index_pair<V> i2) {
i1.swap (i2);
}
template<class M>
inline
void swap (boost::numeric::ublas::index_triple<M> i1, boost::numeric::ublas::index_triple<M> i2) {
i1.swap (i2);
}
// iter_swap also needed for ICC on Itanium?
template<class C, class IC>
inline
void iter_swap (boost::numeric::ublas::indexed_iterator<C, IC> it1,
boost::numeric::ublas::indexed_iterator<C, IC> it2) {
swap (*it1, *it2);
}
}
#endif
#endif
// Comeau compiler - thanks to Kresimir Fresl
#if defined (__COMO__) && ! defined (BOOST_STRICT_CONFIG)
// Missing std::abs overloads for float types in <cmath> are in <cstdlib>
#if defined(__LIBCOMO__) && (__LIBCOMO_VERSION__ <= 31)
#include <cstdlib>
#endif
#endif
// HP aCC C++ compiler
#if defined (__HP_aCC) && ! defined (BOOST_STRICT_CONFIG)
# if (__HP_aCC >= 60000 )
# define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
#endif
#endif
// SGI MIPSpro C++ compiler
#if defined (__sgi) && ! defined (BOOST_STRICT_CONFIG)
// Missing std::abs overloads for float types in <cmath> are in <cstdlib>
// This test should be library version specific.
#include <cstdlib>
#if __COMPILER_VERSION >=650
// By inspection of compiler results - thanks to Peter Schmitteckert
#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
#endif
#endif
// Metrowerks Codewarrior
#if defined (__MWERKS__) && ! defined (BOOST_STRICT_CONFIG)
// 8.x
#if __MWERKS__ <= 0x3003
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
#endif
// Detect other compilers with serious defects - override by defineing BOOST_UBLAS_UNSUPPORTED_COMPILER=0
#ifndef BOOST_UBLAS_UNSUPPORTED_COMPILER
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STDC_NAMESPACE)
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
#endif
// Cannot continue with an unsupported compiler
#if defined(BOOST_UBLAS_UNSUPPORTED_COMPILER) && (BOOST_UBLAS_UNSUPPORTED_COMPILER != 0)
#error Your compiler and/or configuration is unsupported by this verions of uBLAS. Define BOOST_UBLAS_UNSUPPORTED_COMPILER=0 to override this message. Boost 1.32.0 includes uBLAS with support for many older compilers.
#endif
// Enable performance options in RELEASE mode
#if defined (NDEBUG) || defined (BOOST_UBLAS_NDEBUG)
#ifndef BOOST_UBLAS_INLINE
#define BOOST_UBLAS_INLINE inline
#endif
// Do not check sizes!
#define BOOST_UBLAS_USE_FAST_SAME
// NO runtime error checks with BOOST_UBLAS_CHECK macro
#ifndef BOOST_UBLAS_CHECK_ENABLE
#define BOOST_UBLAS_CHECK_ENABLE 0
#endif
// NO type compatibility numeric checks
#ifndef BOOST_UBLAS_TYPE_CHECK
#define BOOST_UBLAS_TYPE_CHECK 0
#endif
// Disable performance options in DEBUG mode
#else
#ifndef BOOST_UBLAS_INLINE
#define BOOST_UBLAS_INLINE
#endif
// Enable runtime error checks with BOOST_UBLAS_CHECK macro. Check bounds etc
#ifndef BOOST_UBLAS_CHECK_ENABLE
#define BOOST_UBLAS_CHECK_ENABLE 1
#endif
// Type compatibiltity numeric checks
#ifndef BOOST_UBLAS_TYPE_CHECK
#define BOOST_UBLAS_TYPE_CHECK 1
#endif
#endif
/*
* Type compatibility checks
* Control type compatibility numeric runtime checks for non dense matrices.
* Require additional storage and complexity
*/
#if BOOST_UBLAS_TYPE_CHECK
template <class Dummy>
struct disable_type_check
{
static bool value;
};
template <class Dummy>
bool disable_type_check<Dummy>::value = false;
#endif
#ifndef BOOST_UBLAS_TYPE_CHECK_EPSILON
#define BOOST_UBLAS_TYPE_CHECK_EPSILON (type_traits<real_type>::type_sqrt (std::numeric_limits<real_type>::epsilon ()))
#endif
#ifndef BOOST_UBLAS_TYPE_CHECK_MIN
#define BOOST_UBLAS_TYPE_CHECK_MIN (type_traits<real_type>::type_sqrt ( (std::numeric_limits<real_type>::min) ()))
#endif
/*
* General Configuration
*/
// Proxy shortcuts overload the alreadly heavily over used operator ()
//#define BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
// In order to simplify debugging is is possible to simplify expression template
// so they are restricted to a single operation
// #define BOOST_UBLAS_SIMPLE_ET_DEBUG
// Use invariant hoisting.
// #define BOOST_UBLAS_USE_INVARIANT_HOISTING
// Use Duff's device in element access loops
// #define BOOST_UBLAS_USE_DUFF_DEVICE
// Choose evaluation method for dense vectors and matrices
#if !(defined(BOOST_UBLAS_USE_INDEXING) || defined(BOOST_UBLAS_USE_ITERATING))
#define BOOST_UBLAS_USE_INDEXING
#endif
// #define BOOST_UBLAS_ITERATOR_THRESHOLD 0
// Use indexed iterators - unsupported implementation experiment
// #define BOOST_UBLAS_USE_INDEXED_ITERATOR
// Alignment of bounded_array type
#ifndef BOOST_UBLAS_BOUNDED_ARRAY_ALIGN
#define BOOST_UBLAS_BOUNDED_ARRAY_ALIGN
#endif
// Enable different sparse element proxies
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
// Sparse proxies prevent reference invalidation problems in expressions such as:
// a [1] = a [0] = 1 Thanks to Marc Duflot for spotting this.
// #define BOOST_UBLAS_STRICT_MAP_ARRAY
#define BOOST_UBLAS_STRICT_VECTOR_SPARSE
#define BOOST_UBLAS_STRICT_MATRIX_SPARSE
// Hermitian matrices use element proxies to allow assignment to conjugate triangle
#define BOOST_UBLAS_STRICT_HERMITIAN
#endif
// Define to configure special settings for reference returning members
// #define BOOST_UBLAS_REFERENCE_CONST_MEMBER
// #define BOOST_UBLAS_PROXY_CONST_MEMBER
// Include type declerations and functions
#include <boost/numeric/ublas/fwd.hpp>
#include <boost/numeric/ublas/detail/definitions.hpp>
#endif

View File

@@ -0,0 +1,212 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// 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)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_DEFINITIONS_
#define _BOOST_UBLAS_DEFINITIONS_
namespace boost { namespace numeric { namespace ublas {
namespace detail {
/* Borrowed from boost/concept_checks.hpp
"inline" is used for ignore_unused_variable_warning()
to make sure there is no overhead with g++.
*/
template <class T> inline
void ignore_unused_variable_warning(const T&) {}
} // namespace detail
// Borrowed from Dave Abraham's noncopyable.
// I believe this should be part of utility.hpp one day...
namespace nonassignable_ // protection from unintended ADL
{
class nonassignable {
protected:
nonassignable () {}
~nonassignable () {}
private: // emphasize the following members are private
const nonassignable& operator= (const nonassignable &);
}; // nonassignable
}
typedef nonassignable_::nonassignable nonassignable;
// Assignment proxy.
// Provides temporary free assigment when LHS has no alias on RHS
template<class C>
class noalias_proxy:
private nonassignable {
public:
typedef typename C::closure_type closure_type;
BOOST_UBLAS_INLINE
noalias_proxy (C& lval):
nonassignable (), lval_ (lval) {}
BOOST_UBLAS_INLINE
noalias_proxy (const noalias_proxy& p):
nonassignable (), lval_ (p.lval_) {}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator= (const E& e) {
lval_.assign (e);
return lval_;
}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator+= (const E& e) {
lval_.plus_assign (e);
return lval_;
}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator-= (const E& e) {
lval_.minus_assign (e);
return lval_;
}
private:
closure_type lval_;
};
// Improve syntax of efficient assignment where no aliases of LHS appear on the RHS
// noalias(lhs) = rhs_expression
template <class C>
BOOST_UBLAS_INLINE
noalias_proxy<C> noalias (C& lvalue) {
return noalias_proxy<C> (lvalue);
}
template <class C>
BOOST_UBLAS_INLINE
noalias_proxy<const C> noalias (const C& lvalue) {
return noalias_proxy<const C> (lvalue);
}
// Possible future compatible syntax where lvalue possible has an unsafe alias on the RHS
// safe(lhs) = rhs_expression
template <class C>
BOOST_UBLAS_INLINE
C& safe (C& lvalue) {
return lvalue;
}
template <class C>
BOOST_UBLAS_INLINE
const C& safe (const C& lvalue) {
return lvalue;
}
// Dimension accessors
namespace dimension {
// Generic accessors
template<unsigned dimension>
struct dimension_properties {};
template<>
struct dimension_properties<1> {
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const vector_expression<E> &e) {
return e ().size ();
}
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const matrix_expression<E> &e) {
return e ().size1 ();
}
// Note: Index functions cannot deduce dependant template parameter V or M from i
template <class V>
BOOST_UBLAS_INLINE static
typename V::size_type index (const typename V::iterator &i) {
return i.index ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator1 &i) {
return i.index1 ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator2 &i) {
return i.index1 ();
}
};
template<>
struct dimension_properties<2> {
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const vector_expression<E> &) {
return 1;
}
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const matrix_expression<E> &e) {
return e ().size2 ();
}
template <class V>
BOOST_UBLAS_INLINE static
typename V::size_type index (const typename V::iterator &) {
return 1;
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator1 &i) {
return i.index2 ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator2 &i) {
return i.index2 ();
}
};
template<unsigned dimension, class E>
BOOST_UBLAS_INLINE
typename E::size_type size (const E& e) {
return dimension_properties<dimension>::size (e);
}
template<unsigned dimension, class I>
BOOST_UBLAS_INLINE
typename I::container_type::size_type
index (const I& i) {
typedef typename I::container_type container_type;
return dimension_properties<dimension>::template index<container_type> (i);
}
// Named accessors - just syntactic sugar
template<class V>
typename V::size_type num_elements (const V &v) {
return v.size ();
}
template<class M>
typename M::size_type num_rows (const M &m) {
return m.size1 ();
}
template<class M>
typename M::size_type num_columns (const M &m) {
return m.size2 ();
}
template<class MV>
typename MV::size_type num_non_zeros (const MV &mv) {
return mv.non_zeros ();
}
}
}}}
#endif

View File

@@ -0,0 +1,33 @@
//
// Copyright (c) 2000-2004
// Joerg Walter, Mathias Koch
//
// 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)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
// this file should not contain any code, but the documentation
// global to all files
/** \namespace boost::numeric::ublas
\brief contains all important classes and functions of uBLAS
all ublas definitions ...
\todo expand this section
*/
/** \defgroup blas1 Level 1 BLAS
\brief level 1 basic linear algebra subroutines
*/
/** \defgroup blas2 Level 2 BLAS
\brief level 2 basic linear algebra subroutines
*/
/** \defgroup blas3 Level 3 BLAS
\brief level 3 basic linear algebra subroutines
*/

View File

@@ -0,0 +1,56 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// 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)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_DUFF_
#define _BOOST_UBLAS_DUFF_
#define DD_SWITCH(n, d, r, expr) \
{ \
unsigned r = ((n) + (d) - 1) / (d); \
switch ((n) % (d)) { \
case 0: do { expr;
#define DD_CASE_I(i, expr) \
case (i): expr;
#define DD_WHILE(r) \
} while (-- (r) > 0); \
} \
}
#define DD_1T(n, d, r, expr) \
DD_WHILE(r)
#define DD_2T(n, d, r, expr) \
DD_CASE_I(1, expr) \
DD_1T(n, d, r, expr)
#define DD_3T(n, d, r, expr) \
DD_CASE_I(2, expr) \
DD_2T(n, d, r, expr)
#define DD_4T(n, d, r, expr) \
DD_CASE_I(3, expr) \
DD_3T(n, d, r, expr)
#define DD_5T(n, d, r, expr) \
DD_CASE_I(4, expr) \
DD_4T(n, d, r, expr)
#define DD_6T(n, d, r, expr) \
DD_CASE_I(5, expr) \
DD_5T(n, d, r, expr)
#define DD_7T(n, d, r, expr) \
DD_CASE_I(6, expr) \
DD_6T(n, d, r, expr)
#define DD_8T(n, d, r, expr) \
DD_CASE_I(7, expr) \
DD_7T(n, d, r, expr)
#define DD(n, d, r, expr) \
DD_SWITCH(n, d, r, expr) \
DD_##d##T(n, d, r, expr)
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,878 @@
//
// Copyright (c) 2002-2003
// Toon Knapen, Kresimir Fresl, Joerg Walter
//
// 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_UBLAS_RAW_
#define _BOOST_UBLAS_RAW_
namespace boost { namespace numeric { namespace ublas { namespace raw {
// We need data_const() mostly due to MSVC 6.0.
// But how shall we write portable code otherwise?
template < typename V >
BOOST_UBLAS_INLINE
int size( const V &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
int size( const vector_reference<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
int size1( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int size2( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int size1( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int size2( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m, row_major_tag ) ;
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m, column_major_tag ) ;
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const matrix_reference<M> &m ) ;
template < typename V >
BOOST_UBLAS_INLINE
int stride( const V &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
int stride( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
int stride( const vector_slice<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_reference<M> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
int stride1( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
int stride2( const c_matrix<T, M, N> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_slice<M> &m ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer data( const MV &mv ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer data_const( const MV &mv ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::pointer data( MV &mv ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_reference<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_reference<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_reference<V> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer data( const c_vector<T, N> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer data_const( const c_vector<T, N> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::pointer data( c_vector<T, N> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_slice<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_slice<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_slice<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_reference<M> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::array_type::const_pointer data( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::array_type::const_pointer data_const( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::pointer data( c_matrix<T, M, N> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_slice<M> &m ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer base( const MV &mv ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer base_const( const MV &mv ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::pointer base( MV &mv ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base( const vector_reference<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base_const( const vector_reference<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_reference<V> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer base( const c_vector<T, N> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer base_const( const c_vector<T, N> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::pointer base( c_vector<T, N> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base( const vector_slice<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base_const( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base_const( const vector_slice<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_slice<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_reference<M> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::array_type::const_pointer base( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::array_type::const_pointer base_const( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::pointer base( c_matrix<T, M, N> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_slice<M> &m ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::size_type start( const MV &mv ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::size_type start( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::size_type start( const vector_slice<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_slice<M> &m ) ;
template < typename V >
BOOST_UBLAS_INLINE
int size( const V &v ) {
return v.size() ;
}
template < typename V >
BOOST_UBLAS_INLINE
int size( const vector_reference<V> &v ) {
return size( v ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int size1( const M &m ) {
return m.size1() ;
}
template < typename M >
BOOST_UBLAS_INLINE
int size2( const M &m ) {
return m.size2() ;
}
template < typename M >
BOOST_UBLAS_INLINE
int size1( const matrix_reference<M> &m ) {
return size1( m.expression() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int size2( const matrix_reference<M> &m ) {
return size2( m.expression() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m, row_major_tag ) {
return m.size2() ;
}
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m, column_major_tag ) {
return m.size1() ;
}
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m ) {
return leading_dimension( m, typename M::orientation_category() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const matrix_reference<M> &m ) {
return leading_dimension( m.expression() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
int stride( const V &v ) {
return 1 ;
}
template < typename V >
BOOST_UBLAS_INLINE
int stride( const vector_range<V> &v ) {
return stride( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
int stride( const vector_slice<V> &v ) {
return v.stride() * stride( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride( const matrix_row<M> &v ) {
return stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride( const matrix_column<M> &v ) {
return stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const M &m ) {
typedef typename M::functor_type functor_type;
return functor_type::one1( m.size1(), m.size2() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const M &m ) {
typedef typename M::functor_type functor_type;
return functor_type::one2( m.size1(), m.size2() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_reference<M> &m ) {
return stride1( m.expression() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_reference<M> &m ) {
return stride2( m.expression() ) ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
int stride1( const c_matrix<T, M, N> &m ) {
return N ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
int stride2( const c_matrix<T, M, N> &m ) {
return 1 ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_range<M> &m ) {
return stride1( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_slice<M> &m ) {
return m.stride1() * stride1( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_range<M> &m ) {
return stride2( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_slice<M> &m ) {
return m.stride2() * stride2( m.data() ) ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::array_type::const_pointer data( const MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer data_const( const MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::pointer data( MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_reference<V> &v ) {
return data( v.expression () ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_reference<V> &v ) {
return data_const( v.expression () ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_reference<V> &v ) {
return data( v.expression () ) ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer data( const c_vector<T, N> &v ) {
return v.data() ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer data_const( const c_vector<T, N> &v ) {
return v.data() ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::pointer data( c_vector<T, N> &v ) {
return v.data() ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_range<V> &v ) {
return data( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_slice<V> &v ) {
return data( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_range<V> &v ) {
return data_const( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer data_const( const vector_slice<V> &v ) {
return data_const( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_range<V> &v ) {
return data( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_slice<V> &v ) {
return data( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_reference<M> &m ) {
return data( m.expression () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_reference<M> &m ) {
return data_const( m.expression () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_reference<M> &m ) {
return data( m.expression () ) ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::const_pointer data( const c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::const_pointer data_const( const c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::pointer data( c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_row<M> &v ) {
return data( v.data() ) + v.index() * stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_column<M> &v ) {
return data( v.data() ) + v.index() * stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_row<M> &v ) {
return data_const( v.data() ) + v.index() * stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_column<M> &v ) {
return data_const( v.data() ) + v.index() * stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_row<M> &v ) {
return data( v.data() ) + v.index() * stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_column<M> &v ) {
return data( v.data() ) + v.index() * stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_range<M> &m ) {
return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_slice<M> &m ) {
return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_range<M> &m ) {
return data_const( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_slice<M> &m ) {
return data_const( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_range<M> &m ) {
return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_slice<M> &m ) {
return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::const_pointer base( const MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::const_pointer base_const( const MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::pointer base( MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base( const vector_reference<V> &v ) {
return base( v.expression () ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base_const( const vector_reference<V> &v ) {
return base_const( v.expression () ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_reference<V> &v ) {
return base( v.expression () ) ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::const_pointer base( const c_vector<T, N> &v ) {
return v.data() ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::const_pointer base_const( const c_vector<T, N> &v ) {
return v.data() ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::pointer base( c_vector<T, N> &v ) {
return v.data() ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base( const vector_range<V> &v ) {
return base( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base( const vector_slice<V> &v ) {
return base( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base_const( const vector_range<V> &v ) {
return base_const( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base_const( const vector_slice<V> &v ) {
return base_const( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_range<V> &v ) {
return base( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_slice<V> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_reference<M> &m ) {
return base( m.expression () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_reference<M> &m ) {
return base_const( m.expression () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_reference<M> &m ) {
return base( m.expression () ) ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::const_pointer base( const c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::const_pointer base_const( const c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::pointer base( c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_row<M> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_column<M> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_row<M> &v ) {
return base_const( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_column<M> &v ) {
return base_const( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_row<M> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_column<M> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_range<M> &m ) {
return base( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_slice<M> &m ) {
return base( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_range<M> &m ) {
return base_const( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_slice<M> &m ) {
return base_const( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_range<M> &m ) {
return base( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_slice<M> &m ) {
return base( m.data() ) ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::size_type start( const MV &mv ) {
return 0 ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::size_type start( const vector_range<V> &v ) {
return v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::size_type start( const vector_slice<V> &v ) {
return v.start() * stride (v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_row<M> &v ) {
return v.index() * stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_column<M> &v ) {
return v.index() * stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_range<M> &m ) {
return m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_slice<M> &m ) {
return m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
}}}}
#endif

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2001-2003 Joel de Guzman
*
* Use, modification and distribution is subject to 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_UBLAS_NUMERICTYPE_DEDUCTION_
#define _BOOST_UBLAS_NUMERICTYPE_DEDUCTION_
// See original in boost-sandbox/boost/utility/type_deduction.hpp for comments
#include <boost/mpl/vector/vector20.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace numeric { namespace ublas {
struct error_cant_deduce_type {};
namespace type_deduction_detail
{
typedef char(&bool_value_type)[1];
typedef char(&float_value_type)[2];
typedef char(&double_value_type)[3];
typedef char(&long_double_value_type)[4];
typedef char(&char_value_type)[5];
typedef char(&schar_value_type)[6];
typedef char(&uchar_value_type)[7];
typedef char(&short_value_type)[8];
typedef char(&ushort_value_type)[9];
typedef char(&int_value_type)[10];
typedef char(&uint_value_type)[11];
typedef char(&long_value_type)[12];
typedef char(&ulong_value_type)[13];
typedef char(&x_value_type)[14];
typedef char(&y_value_type)[15];
typedef char(&cant_deduce_type)[16];
template <typename T, typename PlainT = typename remove_cv<T>::type>
struct is_basic
: mpl::or_<
typename mpl::or_<
is_same<PlainT, bool>
, is_same<PlainT, float>
, is_same<PlainT, double>
, is_same<PlainT, long double>
> ::type,
typename mpl::or_<
is_same<PlainT, char>
, is_same<PlainT, signed char>
, is_same<PlainT, unsigned char>
, is_same<PlainT, short>
, is_same<PlainT, unsigned short>
> ::type,
typename mpl::or_<
is_same<PlainT, int>
, is_same<PlainT, unsigned int>
, is_same<PlainT, long>
, is_same<PlainT, unsigned long>
> ::type
> {};
struct asymmetric;
template <typename X, typename Y>
cant_deduce_type
test(...); // The black hole !!!
template <typename X, typename Y>
bool_value_type
test(bool const&);
template <typename X, typename Y>
float_value_type
test(float const&);
template <typename X, typename Y>
double_value_type
test(double const&);
template <typename X, typename Y>
long_double_value_type
test(long double const&);
template <typename X, typename Y>
char_value_type
test(char const&);
template <typename X, typename Y>
schar_value_type
test(signed char const&);
template <typename X, typename Y>
uchar_value_type
test(unsigned char const&);
template <typename X, typename Y>
short_value_type
test(short const&);
template <typename X, typename Y>
ushort_value_type
test(unsigned short const&);
template <typename X, typename Y>
int_value_type
test(int const&);
template <typename X, typename Y>
uint_value_type
test(unsigned int const&);
template <typename X, typename Y>
long_value_type
test(long const&);
template <typename X, typename Y>
ulong_value_type
test(unsigned long const&);
template <typename X, typename Y>
typename disable_if<
is_basic<X>, x_value_type
>::type
test(X const&);
template <typename X, typename Y>
typename disable_if<
mpl::or_<
is_basic<Y>
, is_same<Y, asymmetric>
, is_same<const X, const Y>
>
, y_value_type
>::type
test(Y const&);
template <typename X, typename Y>
struct base_result_of
{
typedef typename remove_cv<X>::type x_type;
typedef typename remove_cv<Y>::type y_type;
typedef mpl::vector16<
mpl::identity<bool>
, mpl::identity<float>
, mpl::identity<double>
, mpl::identity<long double>
, mpl::identity<char>
, mpl::identity<signed char>
, mpl::identity<unsigned char>
, mpl::identity<short>
, mpl::identity<unsigned short>
, mpl::identity<int>
, mpl::identity<unsigned int>
, mpl::identity<long>
, mpl::identity<unsigned long>
, mpl::identity<x_type>
, mpl::identity<y_type>
, mpl::identity<error_cant_deduce_type>
>
types;
};
}}} } // namespace boost::numeric::ublas ::type_deduction_detail
#endif

View File

@@ -0,0 +1,33 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// 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)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_TEMPORARY_
#define _BOOST_UBLAS_TEMPORARY_
namespace boost { namespace numeric { namespace ublas {
/// For the creation of temporary vectors in the assignment of proxies
template <class M>
struct vector_temporary_traits {
typedef typename M::vector_temporary_type type ;
};
/// For the creation of temporary vectors in the assignment of proxies
template <class M>
struct matrix_temporary_traits {
typedef typename M::matrix_temporary_type type ;
};
} } }
#endif

View File

@@ -0,0 +1,571 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// 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)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_VECTOR_ASSIGN_
#define _BOOST_UBLAS_VECTOR_ASSIGN_
#include <boost/numeric/ublas/functional.hpp> // scalar_assign
// Required for make_conformant storage
#include <vector>
// Iterators based on ideas of Jeremy Siek
namespace boost { namespace numeric { namespace ublas {
namespace detail {
// Weak equality check - useful to compare equality two arbitary vector expression results.
// Since the actual expressions are unknown, we check for and arbitary error bound
// on the relative error.
// For a linear expression the infinity norm makes sense as we do not know how the elements will be
// combined in the expression. False positive results are inevitable for arbirary expressions!
template<class E1, class E2, class S>
BOOST_UBLAS_INLINE
bool equals (const vector_expression<E1> &e1, const vector_expression<E2> &e2, S epsilon, S min_norm) {
return norm_inf (e1 - e2) < epsilon *
std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
}
template<class E1, class E2>
BOOST_UBLAS_INLINE
bool expression_type_check (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
typedef typename type_traits<typename promote_traits<typename E1::value_type,
typename E2::value_type>::promote_type>::real_type real_type;
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
}
// Make sparse proxies conformant
template<class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void make_conformant (V &v, const vector_expression<E> &e) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef typename V::size_type size_type;
typedef typename V::difference_type difference_type;
typedef typename V::value_type value_type;
// FIXME unbounded_array with push_back maybe better
std::vector<size_type> index;
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::const_iterator ite (e ().begin ());
typename E::const_iterator ite_end (e ().end ());
if (it != it_end && ite != ite_end) {
size_type it_index = it.index (), ite_index = ite.index ();
while (true) {
difference_type compare = it_index - ite_index;
if (compare == 0) {
++ it, ++ ite;
if (it != it_end && ite != ite_end) {
it_index = it.index ();
ite_index = ite.index ();
} else
break;
} else if (compare < 0) {
increment (it, it_end, - compare);
if (it != it_end)
it_index = it.index ();
else
break;
} else if (compare > 0) {
if (*ite != value_type/*zero*/())
index.push_back (ite.index ());
++ ite;
if (ite != ite_end)
ite_index = ite.index ();
else
break;
}
}
}
while (ite != ite_end) {
if (*ite != value_type/*zero*/())
index.push_back (ite.index ());
++ ite;
}
for (size_type k = 0; k < index.size (); ++ k)
v (index [k]) = value_type/*zero*/();
}
}//namespace detail
// Explicitly iterating
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void iterating_vector_assign_scalar (V &v, const T &t) {
typedef F<typename V::iterator::reference, T> functor_type;
typedef typename V::difference_type difference_type;
difference_type size (v.size ());
typename V::iterator it (v.begin ());
BOOST_UBLAS_CHECK (v.end () - it == size, bad_size ());
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
while (-- size >= 0)
functor_type::apply (*it, t), ++ it;
#else
DD (size, 4, r, (functor_type::apply (*it, t), ++ it));
#endif
}
// Explicitly case
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void indexing_vector_assign_scalar (V &v, const T &t) {
typedef F<typename V::reference, T> functor_type;
typedef typename V::size_type size_type;
size_type size (v.size ());
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
for (size_type i = 0; i < size; ++ i)
functor_type::apply (v (i), t);
#else
size_type i (0);
DD (size, 4, r, (functor_type::apply (v (i), t), ++ i));
#endif
}
// Dense (proxy) case
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign_scalar (V &v, const T &t, dense_proxy_tag) {
#ifdef BOOST_UBLAS_USE_INDEXING
indexing_vector_assign_scalar<F> (v, t);
#elif BOOST_UBLAS_USE_ITERATING
iterating_vector_assign_scalar<F> (v, t);
#else
typedef typename V::size_type size_type;
size_type size (v.size ());
if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
iterating_vector_assign_scalar<F> (v, t);
else
indexing_vector_assign_scalar<F> (v, t);
#endif
}
// Packed (proxy) case
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign_scalar (V &v, const T &t, packed_proxy_tag) {
typedef F<typename V::iterator::reference, T> functor_type;
typedef typename V::difference_type difference_type;
typename V::iterator it (v.begin ());
difference_type size (v.end () - it);
while (-- size >= 0)
functor_type::apply (*it, t), ++ it;
}
// Sparse (proxy) case
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign_scalar (V &v, const T &t, sparse_proxy_tag) {
typedef F<typename V::iterator::reference, T> functor_type;
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
while (it != it_end)
functor_type::apply (*it, t), ++ it;
}
// Dispatcher
template<template <class T1, class T2> class F, class V, class T>
BOOST_UBLAS_INLINE
void vector_assign_scalar (V &v, const T &t) {
typedef typename V::storage_category storage_category;
vector_assign_scalar<F> (v, t, storage_category ());
}
template<class SC, bool COMPUTED, class RI>
struct vector_assign_traits {
typedef SC storage_category;
};
template<bool COMPUTED>
struct vector_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag> {
typedef packed_tag storage_category;
};
template<>
struct vector_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag> {
typedef sparse_tag storage_category;
};
template<>
struct vector_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<bool COMPUTED>
struct vector_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag> {
typedef packed_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<dense_proxy_tag, false, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<dense_proxy_tag, true, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag> {
typedef sparse_tag storage_category;
};
template<>
struct vector_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<bool COMPUTED>
struct vector_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<sparse_tag, true, dense_random_access_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<sparse_tag, true, packed_random_access_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
// Explicitly iterating
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void iterating_vector_assign (V &v, const vector_expression<E> &e) {
typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
typedef typename V::difference_type difference_type;
difference_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
typename V::iterator it (v.begin ());
BOOST_UBLAS_CHECK (v.end () - it == size, bad_size ());
typename E::const_iterator ite (e ().begin ());
BOOST_UBLAS_CHECK (e ().end () - ite == size, bad_size ());
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
while (-- size >= 0)
functor_type::apply (*it, *ite), ++ it, ++ ite;
#else
DD (size, 2, r, (functor_type::apply (*it, *ite), ++ it, ++ ite));
#endif
}
// Explicitly indexing
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void indexing_vector_assign (V &v, const vector_expression<E> &e) {
typedef F<typename V::reference, typename E::value_type> functor_type;
typedef typename V::size_type size_type;
size_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
for (size_type i = 0; i < size; ++ i)
functor_type::apply (v (i), e () (i));
#else
size_type i (0);
DD (size, 2, r, (functor_type::apply (v (i), e () (i)), ++ i));
#endif
}
// Dense (proxy) case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign (V &v, const vector_expression<E> &e, dense_proxy_tag) {
#ifdef BOOST_UBLAS_USE_INDEXING
indexing_vector_assign<F> (v, e);
#elif BOOST_UBLAS_USE_ITERATING
iterating_vector_assign<F> (v, e);
#else
typedef typename V::size_type size_type;
size_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
iterating_vector_assign<F> (v, e);
else
indexing_vector_assign<F> (v, e);
#endif
}
// Packed (proxy) case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign (V &v, const vector_expression<E> &e, packed_proxy_tag) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
typedef typename V::difference_type difference_type;
typedef typename V::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v.size ());
indexing_vector_assign<scalar_assign> (cv, v);
indexing_vector_assign<F> (cv, e);
#endif
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::const_iterator ite (e ().begin ());
typename E::const_iterator ite_end (e ().end ());
difference_type it_size (it_end - it);
difference_type ite_size (ite_end - ite);
if (it_size > 0 && ite_size > 0) {
difference_type size ((std::min) (difference_type (it.index () - ite.index ()), ite_size));
if (size > 0) {
ite += size;
ite_size -= size;
}
}
if (it_size > 0 && ite_size > 0) {
difference_type size ((std::min) (difference_type (ite.index () - it.index ()), it_size));
if (size > 0) {
it_size -= size;
if (!functor_type::computed) {
while (-- size >= 0) // zeroing
functor_type::apply (*it, value_type/*zero*/()), ++ it;
} else {
it += size;
}
}
}
difference_type size ((std::min) (it_size, ite_size));
it_size -= size;
ite_size -= size;
while (-- size >= 0)
functor_type::apply (*it, *ite), ++ it, ++ ite;
size = it_size;
if (!functor_type::computed) {
while (-- size >= 0) // zeroing
functor_type::apply (*it, value_type/*zero*/()), ++ it;
} else {
it += size;
}
#if BOOST_UBLAS_TYPE_CHECK
if (! disable_type_check<bool>::value)
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv),
external_logic ("external logic or bad condition of inputs"));
#endif
}
// Sparse case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign (V &v, const vector_expression<E> &e, sparse_tag) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
BOOST_STATIC_ASSERT ((!functor_type::computed));
typedef typename V::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v.size ());
indexing_vector_assign<scalar_assign> (cv, v);
indexing_vector_assign<F> (cv, e);
#endif
v.clear ();
typename E::const_iterator ite (e ().begin ());
typename E::const_iterator ite_end (e ().end ());
while (ite != ite_end) {
value_type t (*ite);
if (t != value_type/*zero*/())
v.insert_element (ite.index (), t);
++ ite;
}
#if BOOST_UBLAS_TYPE_CHECK
if (! disable_type_check<bool>::value)
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv),
external_logic ("external logic or bad condition of inputs"));
#endif
}
// Sparse proxy or functional case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign (V &v, const vector_expression<E> &e, sparse_proxy_tag) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
typedef typename V::size_type size_type;
typedef typename V::difference_type difference_type;
typedef typename V::value_type value_type;
typedef typename V::reference reference;
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v.size ());
indexing_vector_assign<scalar_assign> (cv, v);
indexing_vector_assign<F> (cv, e);
#endif
detail::make_conformant (v, e);
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::const_iterator ite (e ().begin ());
typename E::const_iterator ite_end (e ().end ());
if (it != it_end && ite != ite_end) {
size_type it_index = it.index (), ite_index = ite.index ();
while (true) {
difference_type compare = it_index - ite_index;
if (compare == 0) {
functor_type::apply (*it, *ite);
++ it, ++ ite;
if (it != it_end && ite != ite_end) {
it_index = it.index ();
ite_index = ite.index ();
} else
break;
} else if (compare < 0) {
if (!functor_type::computed) {
functor_type::apply (*it, value_type/*zero*/());
++ it;
} else
increment (it, it_end, - compare);
if (it != it_end)
it_index = it.index ();
else
break;
} else if (compare > 0) {
increment (ite, ite_end, compare);
if (ite != ite_end)
ite_index = ite.index ();
else
break;
}
}
}
if (!functor_type::computed) {
while (it != it_end) { // zeroing
functor_type::apply (*it, value_type/*zero*/());
++ it;
}
} else {
it = it_end;
}
#if BOOST_UBLAS_TYPE_CHECK
if (! disable_type_check<bool>::value)
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv),
external_logic ("external logic or bad condition of inputs"));
#endif
}
// Dispatcher
template<template <class T1, class T2> class F, class V, class E>
BOOST_UBLAS_INLINE
void vector_assign (V &v, const vector_expression<E> &e) {
typedef typename vector_assign_traits<typename V::storage_category,
F<typename V::reference, typename E::value_type>::computed,
typename E::const_iterator::iterator_category>::storage_category storage_category;
vector_assign<F> (v, e, storage_category ());
}
template<class SC, class RI>
struct vector_swap_traits {
typedef SC storage_category;
};
template<>
struct vector_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
// Dense (proxy) case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_swap (V &v, vector_expression<E> &e, dense_proxy_tag) {
typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
typedef typename V::difference_type difference_type;
difference_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
typename V::iterator it (v.begin ());
typename E::iterator ite (e ().begin ());
while (-- size >= 0)
functor_type::apply (*it, *ite), ++ it, ++ ite;
}
// Packed (proxy) case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_swap (V &v, vector_expression<E> &e, packed_proxy_tag) {
typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
typedef typename V::difference_type difference_type;
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::iterator ite (e ().begin ());
typename E::iterator ite_end (e ().end ());
difference_type it_size (it_end - it);
difference_type ite_size (ite_end - ite);
if (it_size > 0 && ite_size > 0) {
difference_type size ((std::min) (difference_type (it.index () - ite.index ()), ite_size));
if (size > 0) {
ite += size;
ite_size -= size;
}
}
if (it_size > 0 && ite_size > 0) {
difference_type size ((std::min) (difference_type (ite.index () - it.index ()), it_size));
if (size > 0)
it_size -= size;
}
difference_type size ((std::min) (it_size, ite_size));
it_size -= size;
ite_size -= size;
while (-- size >= 0)
functor_type::apply (*it, *ite), ++ it, ++ ite;
}
// Sparse proxy case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_swap (V &v, vector_expression<E> &e, sparse_proxy_tag) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
typedef typename V::size_type size_type;
typedef typename V::difference_type difference_type;
typedef typename V::value_type value_type;
detail::make_conformant (v, e);
// FIXME should be a seperate restriction for E
detail::make_conformant (e (), v);
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::iterator ite (e ().begin ());
typename E::iterator ite_end (e ().end ());
if (it != it_end && ite != ite_end) {
size_type it_index = it.index (), ite_index = ite.index ();
while (true) {
difference_type compare = it_index - ite_index;
if (compare == 0) {
functor_type::apply (*it, *ite);
++ it, ++ ite;
if (it != it_end && ite != ite_end) {
it_index = it.index ();
ite_index = ite.index ();
} else
break;
} else if (compare < 0) {
increment (it, it_end, - compare);
if (it != it_end)
it_index = it.index ();
else
break;
} else if (compare > 0) {
increment (ite, ite_end, compare);
if (ite != ite_end)
ite_index = ite.index ();
else
break;
}
}
}
#if BOOST_UBLAS_TYPE_CHECK
increment (ite, ite_end);
increment (it, it_end);
#endif
}
// Dispatcher
template<template <class T1, class T2> class F, class V, class E>
BOOST_UBLAS_INLINE
void vector_swap (V &v, vector_expression<E> &e) {
typedef typename vector_swap_traits<typename V::storage_category,
typename E::const_iterator::iterator_category>::storage_category storage_category;
vector_swap<F> (v, e, storage_category ());
}
}}}
#endif