definitions.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. //
  2. // Copyright (c) 2000-2002
  3. // Joerg Walter, Mathias Koch
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // The authors gratefully acknowledge the support of
  10. // GeNeSys mbH & Co. KG in producing this work.
  11. //
  12. #ifndef _BOOST_UBLAS_DEFINITIONS_
  13. #define _BOOST_UBLAS_DEFINITIONS_
  14. namespace boost { namespace numeric { namespace ublas {
  15. namespace detail {
  16. /* Borrowed from boost/concept_checks.hpp
  17. "inline" is used for ignore_unused_variable_warning()
  18. to make sure there is no overhead with g++.
  19. */
  20. template <class T> inline
  21. void ignore_unused_variable_warning(const T&) {}
  22. } // namespace detail
  23. // Borrowed from Dave Abraham's noncopyable.
  24. // I believe this should be part of utility.hpp one day...
  25. namespace nonassignable_ // protection from unintended ADL
  26. {
  27. class nonassignable {
  28. protected:
  29. nonassignable () {}
  30. ~nonassignable () {}
  31. private: // emphasize the following members are private
  32. const nonassignable& operator= (const nonassignable &);
  33. }; // nonassignable
  34. }
  35. typedef nonassignable_::nonassignable nonassignable;
  36. // Assignment proxy.
  37. // Provides temporary free assigment when LHS has no alias on RHS
  38. template<class C>
  39. class noalias_proxy:
  40. private nonassignable {
  41. public:
  42. typedef typename C::closure_type closure_type;
  43. BOOST_UBLAS_INLINE
  44. noalias_proxy (C& lval):
  45. nonassignable (), lval_ (lval) {}
  46. BOOST_UBLAS_INLINE
  47. noalias_proxy (const noalias_proxy& p):
  48. nonassignable (), lval_ (p.lval_) {}
  49. template <class E>
  50. BOOST_UBLAS_INLINE
  51. closure_type &operator= (const E& e) {
  52. lval_.assign (e);
  53. return lval_;
  54. }
  55. template <class E>
  56. BOOST_UBLAS_INLINE
  57. closure_type &operator+= (const E& e) {
  58. lval_.plus_assign (e);
  59. return lval_;
  60. }
  61. template <class E>
  62. BOOST_UBLAS_INLINE
  63. closure_type &operator-= (const E& e) {
  64. lval_.minus_assign (e);
  65. return lval_;
  66. }
  67. private:
  68. closure_type lval_;
  69. };
  70. // Improve syntax of efficient assignment where no aliases of LHS appear on the RHS
  71. // noalias(lhs) = rhs_expression
  72. template <class C>
  73. BOOST_UBLAS_INLINE
  74. noalias_proxy<C> noalias (C& lvalue) {
  75. return noalias_proxy<C> (lvalue);
  76. }
  77. template <class C>
  78. BOOST_UBLAS_INLINE
  79. noalias_proxy<const C> noalias (const C& lvalue) {
  80. return noalias_proxy<const C> (lvalue);
  81. }
  82. // Possible future compatible syntax where lvalue possible has an unsafe alias on the RHS
  83. // safe(lhs) = rhs_expression
  84. template <class C>
  85. BOOST_UBLAS_INLINE
  86. C& safe (C& lvalue) {
  87. return lvalue;
  88. }
  89. template <class C>
  90. BOOST_UBLAS_INLINE
  91. const C& safe (const C& lvalue) {
  92. return lvalue;
  93. }
  94. // Dimension accessors
  95. namespace dimension {
  96. // Generic accessors
  97. template<unsigned dimension>
  98. struct dimension_properties {};
  99. template<>
  100. struct dimension_properties<1> {
  101. template <class E>
  102. BOOST_UBLAS_INLINE static
  103. typename E::size_type size (const vector_expression<E> &e) {
  104. return e ().size ();
  105. }
  106. template <class E>
  107. BOOST_UBLAS_INLINE static
  108. typename E::size_type size (const matrix_expression<E> &e) {
  109. return e ().size1 ();
  110. }
  111. // Note: Index functions cannot deduce dependant template parameter V or M from i
  112. template <class V>
  113. BOOST_UBLAS_INLINE static
  114. typename V::size_type index (const typename V::iterator &i) {
  115. return i.index ();
  116. }
  117. template <class M>
  118. BOOST_UBLAS_INLINE static
  119. typename M::size_type index (const typename M::iterator1 &i) {
  120. return i.index1 ();
  121. }
  122. template <class M>
  123. BOOST_UBLAS_INLINE static
  124. typename M::size_type index (const typename M::iterator2 &i) {
  125. return i.index1 ();
  126. }
  127. };
  128. template<>
  129. struct dimension_properties<2> {
  130. template <class E>
  131. BOOST_UBLAS_INLINE static
  132. typename E::size_type size (const vector_expression<E> &) {
  133. return 1;
  134. }
  135. template <class E>
  136. BOOST_UBLAS_INLINE static
  137. typename E::size_type size (const matrix_expression<E> &e) {
  138. return e ().size2 ();
  139. }
  140. template <class V>
  141. BOOST_UBLAS_INLINE static
  142. typename V::size_type index (const typename V::iterator &) {
  143. return 1;
  144. }
  145. template <class M>
  146. BOOST_UBLAS_INLINE static
  147. typename M::size_type index (const typename M::iterator1 &i) {
  148. return i.index2 ();
  149. }
  150. template <class M>
  151. BOOST_UBLAS_INLINE static
  152. typename M::size_type index (const typename M::iterator2 &i) {
  153. return i.index2 ();
  154. }
  155. };
  156. template<unsigned dimension, class E>
  157. BOOST_UBLAS_INLINE
  158. typename E::size_type size (const E& e) {
  159. return dimension_properties<dimension>::size (e);
  160. }
  161. template<unsigned dimension, class I>
  162. BOOST_UBLAS_INLINE
  163. typename I::container_type::size_type
  164. index (const I& i) {
  165. typedef typename I::container_type container_type;
  166. return dimension_properties<dimension>::template index<container_type> (i);
  167. }
  168. // Named accessors - just syntactic sugar
  169. template<class V>
  170. typename V::size_type num_elements (const V &v) {
  171. return v.size ();
  172. }
  173. template<class M>
  174. typename M::size_type num_rows (const M &m) {
  175. return m.size1 ();
  176. }
  177. template<class M>
  178. typename M::size_type num_columns (const M &m) {
  179. return m.size2 ();
  180. }
  181. template<class MV>
  182. typename MV::size_type num_non_zeros (const MV &mv) {
  183. return mv.non_zeros ();
  184. }
  185. }
  186. }}}
  187. #endif