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
 |