source: NonGTP/Boost/boost/numeric/ublas/detail/definitions.hpp @ 857

Revision 857, 6.9 KB checked in by igarcia, 19 years ago (diff)
Line 
1//
2//  Copyright (c) 2000-2002
3//  Joerg Walter, Mathias Koch
4//
5//  Permission to use, copy, modify, distribute and sell this software
6//  and its documentation for any purpose is hereby granted without fee,
7//  provided that the above copyright notice appear in all copies and
8//  that both that copyright notice and this permission notice appear
9//  in supporting documentation.  The authors make no representations
10//  about the suitability of this software for any purpose.
11//  It is provided "as is" without express or implied warranty.
12//
13//  The authors gratefully acknowledge the support of
14//  GeNeSys mbH & Co. KG in producing this work.
15//
16
17#ifndef _BOOST_UBLAS_DEFINITIONS_
18#define _BOOST_UBLAS_DEFINITIONS_
19
20
21namespace boost { namespace numeric { namespace ublas {
22
23    namespace detail {
24        /* Borrowed from boost/concept_checks.hpp
25           "inline" is used for ignore_unused_variable_warning()
26           to make sure there is no overhead with g++.
27         */
28        template <class T> inline
29        void ignore_unused_variable_warning(const T&) {}
30    } // namespace detail
31
32    // Borrowed from Dave Abraham's noncopyable.
33    // I believe this should be part of utility.hpp one day...
34    namespace nonassignable_  // protection from unintended ADL
35    {
36        class nonassignable {
37        protected:
38            nonassignable () {}
39            ~nonassignable () {}
40        private:  // emphasize the following members are private
41            const nonassignable& operator= (const nonassignable &);
42        }; // nonassignable
43    }
44    typedef nonassignable_::nonassignable nonassignable;
45
46
47    // Assignment proxy.
48    // Provides temporary free assigment when LHS has no alias on RHS
49    template<class C>
50    class noalias_proxy:
51        private nonassignable {
52    public:
53        typedef typename C::closure_type closure_type;
54
55        BOOST_UBLAS_INLINE
56        noalias_proxy (C& lval):
57            nonassignable (), lval_ (lval) {}
58        BOOST_UBLAS_INLINE
59        noalias_proxy (const noalias_proxy& p):
60            nonassignable (), lval_ (p.lval_) {}
61
62        template <class E>
63        BOOST_UBLAS_INLINE
64        closure_type &operator= (const E& e) {
65            lval_.assign (e);
66            return lval_;
67        }
68
69        template <class E>
70        BOOST_UBLAS_INLINE
71        closure_type &operator+= (const E& e) {
72            lval_.plus_assign (e);
73            return lval_;
74        }
75
76        template <class E>
77        BOOST_UBLAS_INLINE
78        closure_type &operator-= (const E& e) {
79            lval_.minus_assign (e);
80            return lval_;
81        }
82
83    private:
84        closure_type lval_;
85    };
86
87    // Improve syntax of effcient assignment where no aliases of LHS appear on the RHS
88    //  noalias(lhs) = rhs_expression
89    template <class C>
90    BOOST_UBLAS_INLINE
91    noalias_proxy<C> noalias (C& lvalue) {
92        return noalias_proxy<C> (lvalue);
93    }
94    template <class C>
95    BOOST_UBLAS_INLINE
96    noalias_proxy<const C> noalias (const C& lvalue) {
97        return noalias_proxy<const C> (lvalue);
98    }
99
100    // Possible future compatible syntax where lvalue possible has an unsafe alias on the RHS
101    //  safe(lhs) = rhs_expression
102    template <class C>
103    BOOST_UBLAS_INLINE
104    C& safe (C& lvalue) {
105        return lvalue;
106    }
107    template <class C>
108    BOOST_UBLAS_INLINE
109    const C& safe (const C& lvalue) {
110        return lvalue;
111    }
112
113
114    // Dimension accessors
115    namespace dimension {
116
117        // Generic accessors
118        template<unsigned dimension>
119        struct dimension_properties {};
120       
121        template<>
122        struct dimension_properties<1> {
123            template <class E>
124            BOOST_UBLAS_INLINE static
125            typename E::size_type size (const vector_expression<E> &e) {
126                return e ().size ();
127            }
128            template <class E>
129            BOOST_UBLAS_INLINE static
130            typename E::size_type size (const matrix_expression<E> &e) {
131                return e ().size1 ();
132            }
133            // Note: Index functions cannot deduce dependant template parameter V or M from i
134            template <class V>
135            BOOST_UBLAS_INLINE static
136            typename V::size_type index (const typename V::iterator &i) {
137                return i.index ();
138            }
139            template <class M>
140            BOOST_UBLAS_INLINE static
141            typename M::size_type index (const typename M::iterator1 &i) {
142                return i.index1 ();
143            }
144            template <class M>
145            BOOST_UBLAS_INLINE static
146            typename M::size_type index (const typename M::iterator2 &i) {
147                return i.index1 ();
148            }
149        };
150        template<>
151        struct dimension_properties<2> {
152            template <class E>
153            BOOST_UBLAS_INLINE static
154            typename E::size_type size (const vector_expression<E> &) {
155                return 1;
156            }
157            template <class E>
158            BOOST_UBLAS_INLINE static
159            typename E::size_type size (const matrix_expression<E> &e) {
160                return e ().size2 ();
161            }
162            template <class V>
163            BOOST_UBLAS_INLINE static
164            typename V::size_type index (const typename V::iterator &) {
165                return 1;
166            }
167            template <class M>
168            BOOST_UBLAS_INLINE static
169            typename M::size_type index (const typename M::iterator1 &i) {
170                return i.index2 ();
171            }
172            template <class M>
173            BOOST_UBLAS_INLINE static
174            typename M::size_type index (const typename M::iterator2 &i) {
175                return i.index2 ();
176            }
177        };
178
179        template<unsigned dimension, class E>
180        BOOST_UBLAS_INLINE
181        typename E::size_type size (const E& e) {
182            return dimension_properties<dimension>::size (e);
183        }
184
185        template<unsigned dimension, class I>
186        BOOST_UBLAS_INLINE
187        typename I::container_type::size_type
188        index (const I& i) {
189            typedef typename I::container_type container_type;
190            return dimension_properties<dimension>::template index<container_type> (i);
191        }
192
193
194        // Named accessors - just syntactic sugar
195        template<class V>
196        typename V::size_type num_elements (const V &v) {
197            return v.size ();
198        }
199        template<class M>
200        typename M::size_type num_rows (const M &m) {
201            return m.size1 ();
202        }
203        template<class M>
204        typename M::size_type num_columns (const M &m) {
205            return m.size2 ();
206        }
207        template<class MV>
208        typename MV::size_type num_non_zeros (const MV &mv) {
209            return mv.non_zeros ();
210        }
211    }
212
213
214}}}
215
216#endif
Note: See TracBrowser for help on using the repository browser.