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