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
 | 
