// // 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