You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
212 lines
6.4 KiB
212 lines
6.4 KiB
// |
|
// 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
|
|
|