213 lines
6.6 KiB
C++
213 lines
6.6 KiB
C++
|
//
|
||
|
// 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
|