123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- //
- // 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
|