// // 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 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 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 BOOST_UBLAS_INLINE closure_type &operator= (const E& e) { lval_.assign (e); return lval_; } template BOOST_UBLAS_INLINE closure_type &operator+= (const E& e) { lval_.plus_assign (e); return lval_; } template BOOST_UBLAS_INLINE closure_type &operator-= (const E& e) { lval_.minus_assign (e); return lval_; } private: closure_type lval_; }; // Improve syntax of effcient assignment where no aliases of LHS appear on the RHS // noalias(lhs) = rhs_expression template BOOST_UBLAS_INLINE noalias_proxy noalias (C& lvalue) { return noalias_proxy (lvalue); } template BOOST_UBLAS_INLINE noalias_proxy noalias (const C& lvalue) { return noalias_proxy (lvalue); } // Possible future compatible syntax where lvalue possible has an unsafe alias on the RHS // safe(lhs) = rhs_expression template BOOST_UBLAS_INLINE C& safe (C& lvalue) { return lvalue; } template BOOST_UBLAS_INLINE const C& safe (const C& lvalue) { return lvalue; } // Dimension accessors namespace dimension { // Generic accessors template struct dimension_properties {}; template<> struct dimension_properties<1> { template BOOST_UBLAS_INLINE static typename E::size_type size (const vector_expression &e) { return e ().size (); } template BOOST_UBLAS_INLINE static typename E::size_type size (const matrix_expression &e) { return e ().size1 (); } // Note: Index functions cannot deduce dependant template parameter V or M from i template BOOST_UBLAS_INLINE static typename V::size_type index (const typename V::iterator &i) { return i.index (); } template BOOST_UBLAS_INLINE static typename M::size_type index (const typename M::iterator1 &i) { return i.index1 (); } template BOOST_UBLAS_INLINE static typename M::size_type index (const typename M::iterator2 &i) { return i.index1 (); } }; template<> struct dimension_properties<2> { template BOOST_UBLAS_INLINE static typename E::size_type size (const vector_expression &) { return 1; } template BOOST_UBLAS_INLINE static typename E::size_type size (const matrix_expression &e) { return e ().size2 (); } template BOOST_UBLAS_INLINE static typename V::size_type index (const typename V::iterator &) { return 1; } template BOOST_UBLAS_INLINE static typename M::size_type index (const typename M::iterator1 &i) { return i.index2 (); } template BOOST_UBLAS_INLINE static typename M::size_type index (const typename M::iterator2 &i) { return i.index2 (); } }; template BOOST_UBLAS_INLINE typename E::size_type size (const E& e) { return dimension_properties::size (e); } template BOOST_UBLAS_INLINE typename I::container_type::size_type index (const I& i) { typedef typename I::container_type container_type; return dimension_properties::template index (i); } // Named accessors - just syntactic sugar template typename V::size_type num_elements (const V &v) { return v.size (); } template typename M::size_type num_rows (const M &m) { return m.size1 (); } template typename M::size_type num_columns (const M &m) { return m.size2 (); } template typename MV::size_type num_non_zeros (const MV &mv) { return mv.non_zeros (); } } }}} #endif