source: vendor/nemo/current/NEMOGCM/EXTERNAL/XIOS/extern/boost/include/boost/numeric/ublas/expression_types.hpp @ 44

Last change on this file since 44 was 44, checked in by cholod, 12 years ago

Load NEMO_TMP into vendor/nemo/current.

File size: 18.1 KB
Line 
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_EXPRESSION_TYPE_
13#define _BOOST_UBLAS_EXPRESSION_TYPE_
14
15#include <boost/numeric/ublas/exception.hpp>
16#include <boost/numeric/ublas/traits.hpp>
17#include <boost/numeric/ublas/functional.hpp>
18
19
20// Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish
21// Iterators based on ideas of Jeremy Siek
22
23namespace boost { namespace numeric { namespace ublas {
24
25    /** \brief Base class for uBLAS staticaly derived expressions using the the Barton Nackman trick
26     *
27     * This class provides the numeric properties for linear algebra.
28     * This is a NonAssignable class
29     *
30     * \tparam E an expression type
31     */
32    template<class E>
33    class ublas_expression {
34    public:
35        typedef E expression_type;
36        /* E can be an incomplete type - to define the following we would need more template arguments
37        typedef typename E::type_category type_category;
38        typedef typename E::value_type value_type;
39        */
40       
41        // Directly implement nonassignable - simplifes debugging call trace!
42    protected:
43        ublas_expression () {}
44        ~ublas_expression () {}
45    private:
46        const ublas_expression& operator= (const ublas_expression &);
47    };
48
49
50    /** \brief Base class for Scalar Expression models
51     *
52     * It does not model the Scalar Expression concept but all derived types should.
53     * The class defines a common base type and some common interface for all statically
54     * derived Scalar Expression classes.
55     *
56     * We implement the casts to the statically derived type.
57     *
58     * \tparam E an expression type
59     */
60    template<class E>
61    class scalar_expression:
62        public ublas_expression<E> {
63    public:
64        typedef E expression_type;
65        typedef scalar_tag type_category;
66
67        BOOST_UBLAS_INLINE
68        const expression_type &operator () () const {
69            return *static_cast<const expression_type *> (this);
70        }
71        BOOST_UBLAS_INLINE
72        expression_type &operator () () {
73            return *static_cast<expression_type *> (this);
74        }
75    };
76
77    template<class T>
78    class scalar_reference:
79        public scalar_expression<scalar_reference<T> > {
80
81        typedef scalar_reference<T> self_type;
82    public:
83        typedef T value_type;
84        typedef const value_type &const_reference;
85        typedef typename boost::mpl::if_<boost::is_const<T>,
86                                          const_reference,
87                                          value_type &>::type reference;
88        typedef const self_type const_closure_type;
89        typedef const_closure_type closure_type;
90
91        // Construction and destruction
92        BOOST_UBLAS_INLINE
93        explicit scalar_reference (reference t):
94            t_ (t) {}
95
96        // Conversion
97        BOOST_UBLAS_INLINE
98        operator value_type () const {
99            return t_;
100        }
101
102        // Assignment
103        BOOST_UBLAS_INLINE
104        scalar_reference &operator = (const scalar_reference &s) {
105            t_ = s.t_;
106            return *this;
107        }
108        template<class AE>
109        BOOST_UBLAS_INLINE
110        scalar_reference &operator = (const scalar_expression<AE> &ae) {
111            t_ = ae;
112            return *this;
113        }
114
115        // Closure comparison
116        BOOST_UBLAS_INLINE
117        bool same_closure (const scalar_reference &sr) const {
118            return &t_ == &sr.t_;
119        }
120
121    private:
122        reference t_;
123    };
124
125    template<class T>
126    class scalar_value:
127        public scalar_expression<scalar_value<T> > {
128
129        typedef scalar_value<T> self_type;
130    public:
131        typedef T value_type;
132        typedef const value_type &const_reference;
133        typedef typename boost::mpl::if_<boost::is_const<T>,
134                                          const_reference,
135                                          value_type &>::type reference;
136        typedef const scalar_reference<const self_type> const_closure_type;
137        typedef scalar_reference<self_type> closure_type;
138
139        // Construction and destruction
140        BOOST_UBLAS_INLINE
141        scalar_value ():
142            t_ () {}
143        BOOST_UBLAS_INLINE
144        scalar_value (const value_type &t):
145            t_ (t) {}
146
147        BOOST_UBLAS_INLINE
148        operator value_type () const {
149            return t_;
150        }
151
152        // Assignment
153        BOOST_UBLAS_INLINE
154        scalar_value &operator = (const scalar_value &s) {
155            t_ = s.t_;
156            return *this;
157        }
158        template<class AE>
159        BOOST_UBLAS_INLINE
160        scalar_value &operator = (const scalar_expression<AE> &ae) {
161            t_ = ae;
162            return *this;
163        }
164
165        // Closure comparison
166        BOOST_UBLAS_INLINE
167        bool same_closure (const scalar_value &sv) const {
168            return this == &sv;    // self closing on instances value
169        }
170
171    private:
172        value_type t_;
173    };
174
175
176    /** \brief Base class for Vector Expression models
177     *
178     * it does not model the Vector Expression concept but all derived types should.
179     * The class defines a common base type and some common interface for all
180     * statically derived Vector Expression classes.
181     * We implement the casts to the statically derived type.
182     */
183    template<class E>
184    class vector_expression:
185        public ublas_expression<E> {
186    public:
187        static const unsigned complexity = 0;
188        typedef E expression_type;
189        typedef vector_tag type_category;
190        /* E can be an incomplete type - to define the following we would need more template arguments
191        typedef typename E::size_type size_type;
192        */
193 
194        BOOST_UBLAS_INLINE
195        const expression_type &operator () () const {
196            return *static_cast<const expression_type *> (this);
197        }
198        BOOST_UBLAS_INLINE
199        expression_type &operator () () {
200            return *static_cast<expression_type *> (this);
201        }
202
203#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
204    private:
205        // projection types
206        typedef vector_range<E> vector_range_type;
207        typedef vector_range<const E> const_vector_range_type;
208        typedef vector_slice<E> vector_slice_type;
209        typedef vector_slice<const E> const_vector_slice_type;
210        // vector_indirect_type will depend on the A template parameter
211        typedef basic_range<> default_range;    // required to avoid range/slice name confusion
212        typedef basic_slice<> default_slice;
213   public:
214        BOOST_UBLAS_INLINE
215        const_vector_range_type operator () (const default_range &r) const {
216            return const_vector_range_type (operator () (), r);
217        }
218        BOOST_UBLAS_INLINE
219        vector_range_type operator () (const default_range &r) {
220            return vector_range_type (operator () (), r);
221        }
222        BOOST_UBLAS_INLINE
223        const_vector_slice_type operator () (const default_slice &s) const {
224            return const_vector_slice_type (operator () (), s);
225        }
226        BOOST_UBLAS_INLINE
227        vector_slice_type operator () (const default_slice &s) {
228            return vector_slice_type (operator () (), s);
229        }
230        template<class A>
231        BOOST_UBLAS_INLINE
232        const vector_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia) const {
233            return vector_indirect<const E, indirect_array<A> >  (operator () (), ia);
234        }
235        template<class A>
236        BOOST_UBLAS_INLINE
237        vector_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia) {
238            return vector_indirect<E, indirect_array<A> > (operator () (), ia);
239        }
240
241        BOOST_UBLAS_INLINE
242        const_vector_range_type project (const default_range &r) const {
243            return const_vector_range_type (operator () (), r);
244        }
245        BOOST_UBLAS_INLINE
246        vector_range_type project (const default_range &r) {
247            return vector_range_type (operator () (), r);
248        }
249        BOOST_UBLAS_INLINE
250        const_vector_slice_type project (const default_slice &s) const {
251            return const_vector_slice_type (operator () (), s);
252        }
253        BOOST_UBLAS_INLINE
254        vector_slice_type project (const default_slice &s) {
255            return vector_slice_type (operator () (), s);
256        }
257        template<class A>
258        BOOST_UBLAS_INLINE
259        const vector_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia) const {
260            return vector_indirect<const E, indirect_array<A> > (operator () (), ia);
261        }
262        template<class A>
263        BOOST_UBLAS_INLINE
264        vector_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia) {
265            return vector_indirect<E, indirect_array<A> > (operator () (), ia);
266        }
267#endif
268    };
269
270    /** \brief Base class for Vector container models
271     *
272     * it does not model the Vector concept but all derived types should.
273     * The class defines a common base type and some common interface for all
274     * statically derived Vector classes
275     * We implement the casts to the statically derived type.
276     */
277    template<class C>
278    class vector_container:
279        public vector_expression<C> {
280    public:
281        static const unsigned complexity = 0;
282        typedef C container_type;
283        typedef vector_tag type_category;
284 
285        BOOST_UBLAS_INLINE
286        const container_type &operator () () const {
287            return *static_cast<const container_type *> (this);
288        }
289        BOOST_UBLAS_INLINE
290        container_type &operator () () {
291            return *static_cast<container_type *> (this);
292        }
293
294#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
295        using vector_expression<C>::operator ();
296#endif
297    };
298
299
300    /** \brief Base class for Matrix Expression models
301     *
302     * it does not model the Matrix Expression concept but all derived types should.
303     * The class defines a common base type and some common interface for all
304     * statically derived Matrix Expression classes
305     * We implement the casts to the statically derived type.
306     */
307    template<class E>
308    class matrix_expression:
309        public ublas_expression<E> {
310    private:
311        typedef matrix_expression<E> self_type;
312    public:
313        static const unsigned complexity = 0;
314        typedef E expression_type;
315        typedef matrix_tag type_category;
316        /* E can be an incomplete type - to define the following we would need more template arguments
317        typedef typename E::size_type size_type;
318        */
319
320        BOOST_UBLAS_INLINE
321        const expression_type &operator () () const {
322            return *static_cast<const expression_type *> (this);
323        }
324        BOOST_UBLAS_INLINE
325        expression_type &operator () () {
326            return *static_cast<expression_type *> (this);
327        }
328
329#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
330    private:
331        // projection types
332        typedef vector_range<E> vector_range_type;
333        typedef const vector_range<const E> const_vector_range_type;
334        typedef vector_slice<E> vector_slice_type;
335        typedef const vector_slice<const E> const_vector_slice_type;
336        typedef matrix_row<E> matrix_row_type;
337        typedef const matrix_row<const E> const_matrix_row_type;
338        typedef matrix_column<E> matrix_column_type;
339        typedef const  matrix_column<const E> const_matrix_column_type;
340        typedef matrix_range<E> matrix_range_type;
341        typedef const matrix_range<const E> const_matrix_range_type;
342        typedef matrix_slice<E> matrix_slice_type;
343        typedef const matrix_slice<const E> const_matrix_slice_type;
344        // matrix_indirect_type will depend on the A template parameter
345        typedef basic_range<> default_range;    // required to avoid range/slice name confusion
346        typedef basic_slice<> default_slice;
347
348    public:
349        BOOST_UBLAS_INLINE
350        const_matrix_row_type operator [] (std::size_t i) const {
351            return const_matrix_row_type (operator () (), i);
352        }
353        BOOST_UBLAS_INLINE
354        matrix_row_type operator [] (std::size_t i) {
355            return matrix_row_type (operator () (), i);
356        }
357        BOOST_UBLAS_INLINE
358        const_matrix_row_type row (std::size_t i) const {
359            return const_matrix_row_type (operator () (), i);
360        }
361        BOOST_UBLAS_INLINE
362        matrix_row_type row (std::size_t i) {
363            return matrix_row_type (operator () (), i);
364        }
365        BOOST_UBLAS_INLINE
366        const_matrix_column_type column (std::size_t j) const {
367            return const_matrix_column_type (operator () (), j);
368        }
369        BOOST_UBLAS_INLINE
370        matrix_column_type column (std::size_t j) {
371            return matrix_column_type (operator () (), j);
372        }
373
374        BOOST_UBLAS_INLINE
375        const_matrix_range_type operator () (const default_range &r1, const default_range &r2) const {
376            return const_matrix_range_type (operator () (), r1, r2);
377        }
378        BOOST_UBLAS_INLINE
379        matrix_range_type operator () (const default_range &r1, const default_range &r2) {
380            return matrix_range_type (operator () (), r1, r2);
381        }
382        BOOST_UBLAS_INLINE
383        const_matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) const {
384            return const_matrix_slice_type (operator () (), s1, s2);
385        }
386        BOOST_UBLAS_INLINE
387        matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) {
388            return matrix_slice_type (operator () (), s1, s2);
389        }
390        template<class A>
391        BOOST_UBLAS_INLINE
392        const matrix_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
393            return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
394        }
395        template<class A>
396        BOOST_UBLAS_INLINE
397        matrix_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
398            return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
399        }
400
401        BOOST_UBLAS_INLINE
402        const_matrix_range_type project (const default_range &r1, const default_range &r2) const {
403            return const_matrix_range_type (operator () (), r1, r2);
404        }
405        BOOST_UBLAS_INLINE
406        matrix_range_type project (const default_range &r1, const default_range &r2) {
407            return matrix_range_type (operator () (), r1, r2);
408        }
409        BOOST_UBLAS_INLINE
410        const_matrix_slice_type project (const default_slice &s1, const default_slice &s2) const {
411            return const_matrix_slice_type (operator () (), s1, s2);
412        }
413        BOOST_UBLAS_INLINE
414        matrix_slice_type project (const default_slice &s1, const default_slice &s2) {
415            return matrix_slice_type (operator () (), s1, s2);
416        }
417        template<class A>
418        BOOST_UBLAS_INLINE
419        const matrix_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
420            return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
421        }
422        template<class A>
423        BOOST_UBLAS_INLINE
424        matrix_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
425            return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
426        }
427#endif
428    };
429
430#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
431    struct iterator1_tag {};
432    struct iterator2_tag {};
433
434    template<class I>
435    BOOST_UBLAS_INLINE
436    typename I::dual_iterator_type begin (const I &it, iterator1_tag) {
437        return it ().find2 (1, it.index1 (), 0);
438    }
439    template<class I>
440    BOOST_UBLAS_INLINE
441    typename I::dual_iterator_type end (const I &it, iterator1_tag) {
442        return it ().find2 (1, it.index1 (), it ().size2 ());
443    }
444    template<class I>
445    BOOST_UBLAS_INLINE
446    typename I::dual_reverse_iterator_type rbegin (const I &it, iterator1_tag) {
447        return typename I::dual_reverse_iterator_type (end (it, iterator1_tag ()));
448    }
449    template<class I>
450    BOOST_UBLAS_INLINE
451    typename I::dual_reverse_iterator_type rend (const I &it, iterator1_tag) {
452        return typename I::dual_reverse_iterator_type (begin (it, iterator1_tag ()));
453    }
454
455    template<class I>
456    BOOST_UBLAS_INLINE
457    typename I::dual_iterator_type begin (const I &it, iterator2_tag) {
458        return it ().find1 (1, 0, it.index2 ());
459    }
460    template<class I>
461    BOOST_UBLAS_INLINE
462    typename I::dual_iterator_type end (const I &it, iterator2_tag) {
463        return it ().find1 (1, it ().size1 (), it.index2 ());
464    }
465    template<class I>
466    BOOST_UBLAS_INLINE
467    typename I::dual_reverse_iterator_type rbegin (const I &it, iterator2_tag) {
468        return typename I::dual_reverse_iterator_type (end (it, iterator2_tag ()));
469    }
470    template<class I>
471    BOOST_UBLAS_INLINE
472    typename I::dual_reverse_iterator_type rend (const I &it, iterator2_tag) {
473        return typename I::dual_reverse_iterator_type (begin (it, iterator2_tag ()));
474    }
475#endif
476
477    /** \brief Base class for Matrix container models
478     *
479     * it does not model the Matrix concept but all derived types should.
480     * The class defines a common base type and some common interface for all
481     * statically derived Matrix classes
482     * We implement the casts to the statically derived type.
483     */
484    template<class C>
485    class matrix_container:
486        public matrix_expression<C> {
487    public:
488        static const unsigned complexity = 0;
489        typedef C container_type;
490        typedef matrix_tag type_category;
491
492        BOOST_UBLAS_INLINE
493        const container_type &operator () () const {
494            return *static_cast<const container_type *> (this);
495        }
496        BOOST_UBLAS_INLINE
497        container_type &operator () () {
498            return *static_cast<container_type *> (this);
499        }
500
501#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
502        using matrix_expression<C>::operator ();
503#endif
504    };
505
506}}}
507
508#endif
Note: See TracBrowser for help on using the repository browser.