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