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