New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
vector.hpp in vendors/XIOS/current/extern/boost/include/boost/numeric/ublas – NEMO

source: vendors/XIOS/current/extern/boost/include/boost/numeric/ublas/vector.hpp @ 3428

Last change on this file since 3428 was 3428, checked in by rblod, 12 years ago

importing initial XIOS vendor drop

File size: 72.6 KB
Line 
1//
2//  Copyright (c) 2000-2010
3//  Joerg Walter, Mathias Koch, David Bellot
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//  And we acknowledge the support from all contributors.
13
14/// \file vector.hpp Definition for the class vector and its derivative
15
16#ifndef _BOOST_UBLAS_VECTOR_
17#define _BOOST_UBLAS_VECTOR_
18
19#include <boost/numeric/ublas/storage.hpp>
20#include <boost/numeric/ublas/vector_expression.hpp>
21#include <boost/numeric/ublas/detail/vector_assign.hpp>
22#include <boost/serialization/collection_size_type.hpp>
23#include <boost/serialization/nvp.hpp>
24
25
26// Iterators based on ideas of Jeremy Siek
27
28namespace boost { namespace numeric { namespace ublas {
29
30    /** \brief A dense vector of values of type \c T.
31     *
32     * For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped
33     * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array.
34     * Elements are constructed by \c A, which need not initialise their value.
35     *
36     * \tparam T type of the objects stored in the vector (like int, double, complex,...)
37     * \tparam A The type of the storage array of the vector. Default is \c unbounded_array<T>. \c <bounded_array<T> and \c std::vector<T> can also be used
38     */
39    template<class T, class A>
40    class vector:
41        public vector_container<vector<T, A> > {
42
43        typedef vector<T, A> self_type;
44    public:
45#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
46        using vector_container<self_type>::operator ();
47#endif
48
49   typedef typename A::size_type size_type;
50        typedef typename A::difference_type difference_type;
51        typedef T value_type;
52        typedef typename type_traits<T>::const_reference const_reference;
53        typedef T &reference;
54        typedef T *pointer;
55        typedef const T *const_pointer;
56        typedef A array_type;
57        typedef const vector_reference<const self_type> const_closure_type;
58        typedef vector_reference<self_type> closure_type;
59        typedef self_type vector_temporary_type;
60        typedef dense_tag storage_category;
61
62        // Construction and destruction
63   
64   /// \brief Constructor of a vector
65   /// By default it is empty, i.e. \c size()==0.
66        BOOST_UBLAS_INLINE
67        vector ():
68            vector_container<self_type> (),
69            data_ () {}
70
71   /// \brief Constructor of a vector with a predefined size
72   /// By default, its elements are initialized to 0.
73   /// \param size initial size of the vector
74        explicit BOOST_UBLAS_INLINE
75        vector (size_type size):
76            vector_container<self_type> (),
77            data_ (size) {
78        }
79
80   /// \brief Constructor of a vector by copying from another container
81   /// This type has the generic name \c array_typ within the vector definition.
82   /// \param size initial size of the vector \bug this value is not used
83   /// \param data container of type \c A
84   /// \todo remove this definition because \c size is not used
85        BOOST_UBLAS_INLINE
86        vector (size_type size, const array_type &data):
87            vector_container<self_type> (),
88            data_ (data) {}
89
90   /// \brief Constructor of a vector by copying from another container
91   /// This type has the generic name \c array_typ within the vector definition.
92   /// \param data container of type \c A
93        BOOST_UBLAS_INLINE
94        vector (const array_type &data):
95            vector_container<self_type> (),
96            data_ (data) {}
97
98   /// \brief Constructor of a vector with a predefined size and a unique initial value
99   /// \param size of the vector
100   /// \param init value to assign to each element of the vector
101        BOOST_UBLAS_INLINE
102        vector (size_type size, const value_type &init):
103            vector_container<self_type> (),
104            data_ (size, init) {}
105
106   /// \brief Copy-constructor of a vector
107   /// \param v is the vector to be duplicated
108        BOOST_UBLAS_INLINE
109        vector (const vector &v):
110            vector_container<self_type> (),
111            data_ (v.data_) {}
112
113   /// \brief Copy-constructor of a vector from a vector_expression
114   /// Depending on the vector_expression, this constructor can have the cost of the computations
115   /// of the expression (trivial to say it, but it is to take into account in your complexity calculations).
116   /// \param ae the vector_expression which values will be duplicated into the vector
117        template<class AE>
118        BOOST_UBLAS_INLINE
119        vector (const vector_expression<AE> &ae):
120            vector_container<self_type> (),
121            data_ (ae ().size ()) {
122            vector_assign<scalar_assign> (*this, ae);
123        }
124
125   // -----------------------
126        // Random Access Container
127   // -----------------------
128   
129   /// \brief Return the maximum size of the data container.
130   /// Return the upper bound (maximum size) on the data container. Depending on the container, it can be bigger than the current size of the vector.
131        BOOST_UBLAS_INLINE
132        size_type max_size () const {
133            return data_.max_size ();
134        }
135       
136   /// \brief Return true if the vector is empty (\c size==0)
137   /// \return \c true if empty, \c false otherwise
138        BOOST_UBLAS_INLINE
139        bool empty () const {
140            return data_.size () == 0;
141        }
142
143   // ---------
144        // Accessors
145   // ---------
146   
147   /// \brief Return the size of the vector
148        BOOST_UBLAS_INLINE
149        size_type size () const {
150            return data_.size ();
151        }
152
153   // -----------------
154        // Storage accessors
155   // -----------------
156   
157   /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
158        BOOST_UBLAS_INLINE
159        const array_type &data () const {
160            return data_;
161        }
162
163   /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
164        BOOST_UBLAS_INLINE
165        array_type &data () {
166            return data_;
167        }
168
169   // --------
170        // Resizing
171   // --------
172   
173   /// \brief Resize the vector
174   /// Resize the vector to a new size. If \c preserve is true, data are copied otherwise data are lost. If the new size is bigger, the remaining values are filled in with the initial value (0 by default) in the case of \c unbounded_array, which is the container by default. If the new size is smaller, last values are lost. This behaviour can be different if you explicitely specify another type of container.
175   /// \param size new size of the vector
176   /// \param preserve if true, keep values
177        BOOST_UBLAS_INLINE
178        void resize (size_type size, bool preserve = true) {
179            if (preserve)
180                data ().resize (size, typename A::value_type ());
181            else
182                data ().resize (size);
183        }
184
185   // ---------------
186        // Element support
187   // ---------------
188   
189   /// \brief Return a pointer to the element \f$i\f$
190   /// \param i index of the element
191   // XXX this semantic is not the one expected by the name of this method
192        BOOST_UBLAS_INLINE
193        pointer find_element (size_type i) {
194            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
195        }
196
197   /// \brief Return a const pointer to the element \f$i\f$
198   /// \param i index of the element
199   // XXX  this semantic is not the one expected by the name of this method
200        BOOST_UBLAS_INLINE
201        const_pointer find_element (size_type i) const {
202            return & (data () [i]);
203        }
204
205   // --------------
206        // Element access
207   // --------------
208
209   /// \brief Return a const reference to the element \f$i\f$
210   /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
211   /// \param i index of the element
212        BOOST_UBLAS_INLINE
213        const_reference operator () (size_type i) const {
214            return data () [i];
215        }
216   
217   /// \brief Return a reference to the element \f$i\f$
218   /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
219   /// \param i index of the element
220        BOOST_UBLAS_INLINE
221        reference operator () (size_type i) {
222            return data () [i];
223        }
224
225   /// \brief Return a const reference to the element \f$i\f$
226   /// \param i index of the element
227        BOOST_UBLAS_INLINE
228        const_reference operator [] (size_type i) const {
229            return (*this) (i);
230        }
231   
232   /// \brief Return a reference to the element \f$i\f$
233   /// \param i index of the element
234        BOOST_UBLAS_INLINE
235        reference operator [] (size_type i) {
236            return (*this) (i);
237        }
238
239   // ------------------
240        // Element assignment
241   // ------------------
242   
243   /// \brief Set element \f$i\f$ to the value \c t
244   /// \param i index of the element
245   /// \param t reference to the value to be set
246   // XXX semantic of this is to insert a new element and therefore size=size+1 ?
247        BOOST_UBLAS_INLINE
248        reference insert_element (size_type i, const_reference t) {
249            return (data () [i] = t);
250        }
251
252   /// \brief Set element \f$i\f$ to the \e zero value
253   /// \param i index of the element
254        BOOST_UBLAS_INLINE
255        void erase_element (size_type i) {
256            data () [i] = value_type/*zero*/();
257        }
258       
259   // -------
260        // Zeroing
261   // -------
262   
263   /// \brief Clear the vector, i.e. set all values to the \c zero value.
264        BOOST_UBLAS_INLINE
265        void clear () {
266            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
267        }
268
269        // Assignment
270#ifdef BOOST_UBLAS_MOVE_SEMANTICS
271
272   /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
273   /// \param v is the source vector
274   /// \return a reference to a vector (i.e. the destination vector)
275        /*! @note "pass by value" the key idea to enable move semantics */
276        BOOST_UBLAS_INLINE
277        vector &operator = (vector v) {
278            assign_temporary(v);
279            return *this;
280        }
281#else
282   /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
283   /// \param v is the source vector
284   /// \return a reference to a vector (i.e. the destination vector)
285        BOOST_UBLAS_INLINE
286        vector &operator = (const vector &v) {
287            data () = v.data ();
288            return *this;
289        }
290#endif
291
292   /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
293   /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary.
294   /// \param v is the source vector container
295   /// \return a reference to a vector (i.e. the destination vector)
296        template<class C>          // Container assignment without temporary
297        BOOST_UBLAS_INLINE
298        vector &operator = (const vector_container<C> &v) {
299            resize (v ().size (), false);
300            assign (v);
301            return *this;
302        }
303
304   /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
305   /// \param v is the source vector
306   /// \return a reference to a vector (i.e. the destination vector)
307        BOOST_UBLAS_INLINE
308        vector &assign_temporary (vector &v) {
309            swap (v);
310            return *this;
311        }
312
313   /// \brief Assign the result of a vector_expression to the vector
314   /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
315   /// \tparam AE is the type of the vector_expression
316   /// \param ae is a const reference to the vector_expression
317   /// \return a reference to the resulting vector
318        template<class AE>
319        BOOST_UBLAS_INLINE
320        vector &operator = (const vector_expression<AE> &ae) {
321            self_type temporary (ae);
322            return assign_temporary (temporary);
323        }
324
325   /// \brief Assign the result of a vector_expression to the vector
326   /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
327   /// \tparam AE is the type of the vector_expression
328   /// \param ae is a const reference to the vector_expression
329   /// \return a reference to the resulting vector
330        template<class AE>
331        BOOST_UBLAS_INLINE
332        vector &assign (const vector_expression<AE> &ae) {
333            vector_assign<scalar_assign> (*this, ae);
334            return *this;
335        }
336
337   // -------------------
338        // Computed assignment
339   // -------------------
340   
341   /// \brief Assign the sum of the vector and a vector_expression to the vector
342   /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
343   /// A temporary is created for the computations.
344   /// \tparam AE is the type of the vector_expression
345   /// \param ae is a const reference to the vector_expression
346   /// \return a reference to the resulting vector
347        template<class AE>
348        BOOST_UBLAS_INLINE
349        vector &operator += (const vector_expression<AE> &ae) {
350            self_type temporary (*this + ae);
351            return assign_temporary (temporary);
352        }
353
354   /// \brief Assign the sum of the vector and a vector_expression to the vector
355   /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
356   /// No temporary is created. Computations are done and stored directly into the resulting vector.
357   /// \tparam AE is the type of the vector_expression
358   /// \param ae is a const reference to the vector_expression
359   /// \return a reference to the resulting vector
360        template<class C>          // Container assignment without temporary
361        BOOST_UBLAS_INLINE
362        vector &operator += (const vector_container<C> &v) {
363            plus_assign (v);
364            return *this;
365        }
366
367   /// \brief Assign the sum of the vector and a vector_expression to the vector
368   /// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
369   /// No temporary is created. Computations are done and stored directly into the resulting vector.
370   /// \tparam AE is the type of the vector_expression
371   /// \param ae is a const reference to the vector_expression
372   /// \return a reference to the resulting vector
373        template<class AE>
374        BOOST_UBLAS_INLINE
375        vector &plus_assign (const vector_expression<AE> &ae) {
376            vector_assign<scalar_plus_assign> (*this, ae);
377            return *this;
378        }
379   
380   /// \brief Assign the difference of the vector and a vector_expression to the vector
381   /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
382   /// A temporary is created for the computations.
383   /// \tparam AE is the type of the vector_expression
384   /// \param ae is a const reference to the vector_expression
385        template<class AE>
386        BOOST_UBLAS_INLINE
387        vector &operator -= (const vector_expression<AE> &ae) {
388            self_type temporary (*this - ae);
389            return assign_temporary (temporary);
390        }
391
392   /// \brief Assign the difference of the vector and a vector_expression to the vector
393   /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
394   /// No temporary is created. Computations are done and stored directly into the resulting vector.
395   /// \tparam AE is the type of the vector_expression
396   /// \param ae is a const reference to the vector_expression
397   /// \return a reference to the resulting vector
398        template<class C>          // Container assignment without temporary
399        BOOST_UBLAS_INLINE
400        vector &operator -= (const vector_container<C> &v) {
401            minus_assign (v);
402            return *this;
403        }
404
405   /// \brief Assign the difference of the vector and a vector_expression to the vector
406   /// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
407   /// No temporary is created. Computations are done and stored directly into the resulting vector.
408   /// \tparam AE is the type of the vector_expression
409   /// \param ae is a const reference to the vector_expression
410   /// \return a reference to the resulting vector
411        template<class AE>
412        BOOST_UBLAS_INLINE
413        vector &minus_assign (const vector_expression<AE> &ae) {
414            vector_assign<scalar_minus_assign> (*this, ae);
415            return *this;
416        }
417
418   /// \brief Assign the product of the vector and a scalar to the vector
419   /// Assign the product of the vector and a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
420   /// No temporary is created. Computations are done and stored directly into the resulting vector.
421   /// \tparam AE is the type of the vector_expression
422   /// \param at is a const reference to the scalar
423   /// \return a reference to the resulting vector
424        template<class AT>
425        BOOST_UBLAS_INLINE
426        vector &operator *= (const AT &at) {
427            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
428            return *this;
429        }
430
431   /// \brief Assign the division of the vector by a scalar to the vector
432   /// Assign the division of the vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
433   /// No temporary is created. Computations are done and stored directly into the resulting vector.
434   /// \tparam AE is the type of the vector_expression
435   /// \param at is a const reference to the scalar
436   /// \return a reference to the resulting vector
437        template<class AT>
438        BOOST_UBLAS_INLINE
439        vector &operator /= (const AT &at) {
440            vector_assign_scalar<scalar_divides_assign> (*this, at);
441            return *this;
442        }
443
444   // --------
445        // Swapping
446   // --------
447
448   /// \brief Swap the content of the vector with another vector
449   /// \param v is the vector to be swapped with
450        BOOST_UBLAS_INLINE
451        void swap (vector &v) {
452            if (this != &v) {
453                data ().swap (v.data ());
454            }
455        }
456
457   /// \brief Swap the content of two vectors
458   /// \param v1 is the first vector. It takes values from v2
459   /// \param v2 is the second vector It takes values from v1
460        BOOST_UBLAS_INLINE
461        friend void swap (vector &v1, vector &v2) {
462            v1.swap (v2);
463        }
464
465        // Iterator types
466    private:
467        // Use the storage array iterator
468        typedef typename A::const_iterator const_subiterator_type;
469        typedef typename A::iterator subiterator_type;
470
471    public:
472#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
473        typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
474        typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
475#else
476        class const_iterator;
477        class iterator;
478#endif
479
480   // --------------
481        // Element lookup
482   // --------------
483   
484   /// \brief Return a const iterator to the element \e i
485   /// \param i index of the element
486        BOOST_UBLAS_INLINE
487        const_iterator find (size_type i) const {
488#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
489            return const_iterator (*this, data ().begin () + i);
490#else
491            return const_iterator (*this, i);
492#endif
493        }
494
495   /// \brief Return an iterator to the element \e i
496   /// \param i index of the element
497        BOOST_UBLAS_INLINE
498        iterator find (size_type i) {
499#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
500            return iterator (*this, data ().begin () + i);
501#else
502            return iterator (*this, i);
503#endif
504        }
505
506#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
507        class const_iterator:
508            public container_const_reference<vector>,
509            public random_access_iterator_base<dense_random_access_iterator_tag,
510                                               const_iterator, value_type, difference_type> {
511        public:
512            typedef typename vector::difference_type difference_type;
513            typedef typename vector::value_type value_type;
514            typedef typename vector::const_reference reference;
515            typedef const typename vector::pointer pointer;
516
517       // ----------------------------
518            // Construction and destruction
519       // ----------------------------
520
521
522            BOOST_UBLAS_INLINE
523            const_iterator ():
524                container_const_reference<self_type> (), it_ () {}
525            BOOST_UBLAS_INLINE
526            const_iterator (const self_type &v, const const_subiterator_type &it):
527                container_const_reference<self_type> (v), it_ (it) {}
528            BOOST_UBLAS_INLINE
529            const_iterator (const typename self_type::iterator &it):  // ISSUE vector:: stops VC8 using std::iterator here
530                container_const_reference<self_type> (it ()), it_ (it.it_) {}
531
532       // ----------
533            // Arithmetic
534       // ----------
535
536       /// \brief Increment by 1 the position of the iterator
537       /// \return a reference to the const iterator
538            BOOST_UBLAS_INLINE
539            const_iterator &operator ++ () {
540                ++ it_;
541                return *this;
542            }
543
544       /// \brief Decrement by 1 the position of the iterator
545       /// \return a reference to the const iterator
546            BOOST_UBLAS_INLINE
547            const_iterator &operator -- () {
548                -- it_;
549                return *this;
550            }
551     
552       /// \brief Increment by \e n the position of the iterator
553       /// \return a reference to the const iterator
554            BOOST_UBLAS_INLINE
555            const_iterator &operator += (difference_type n) {
556                it_ += n;
557                return *this;
558            }
559
560       /// \brief Decrement by \e n the position of the iterator
561       /// \return a reference to the const iterator
562            BOOST_UBLAS_INLINE
563            const_iterator &operator -= (difference_type n) {
564                it_ -= n;
565                return *this;
566            }
567
568       /// \brief Return the different in number of positions between 2 iterators
569            BOOST_UBLAS_INLINE
570            difference_type operator - (const const_iterator &it) const {
571                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
572                return it_ - it.it_;
573            }
574
575            /// \brief Dereference an iterator
576            /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
577       /// \return a const reference to the value pointed by the iterator
578            BOOST_UBLAS_INLINE
579            const_reference operator * () const {
580                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
581                return *it_;
582            }
583
584       /// \brief Dereference an iterator at the n-th forward value
585       /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
586            /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
587       /// \return a const reference
588            BOOST_UBLAS_INLINE
589            const_reference operator [] (difference_type n) const {
590                return *(it_ + n);
591            }
592
593            // Index
594       /// \brief return the index of the element referenced by the iterator
595            BOOST_UBLAS_INLINE
596            size_type index () const {
597                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
598                return it_ - (*this) ().begin ().it_;
599            }
600
601            // Assignment
602            BOOST_UBLAS_INLINE
603       /// \brief assign the value of an iterator to the iterator   
604            const_iterator &operator = (const const_iterator &it) {
605                container_const_reference<self_type>::assign (&it ());
606                it_ = it.it_;
607                return *this;
608            }
609
610            // Comparison
611       /// \brief compare the value of two itetarors
612       /// \return true if they reference the same element
613            BOOST_UBLAS_INLINE
614            bool operator == (const const_iterator &it) const {
615                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
616                return it_ == it.it_;
617            }
618
619   
620       /// \brief compare the value of two iterators
621       /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
622            BOOST_UBLAS_INLINE
623            bool operator < (const const_iterator &it) const {
624                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
625                return it_ < it.it_;
626            }
627
628        private:
629            const_subiterator_type it_;
630
631            friend class iterator;
632        };
633#endif
634
635   /// \brief return an iterator on the first element of the vector
636        BOOST_UBLAS_INLINE
637        const_iterator begin () const {
638            return find (0);
639        }
640
641   /// \brief return an iterator after the last element of the vector
642        BOOST_UBLAS_INLINE
643        const_iterator end () const {
644            return find (data_.size ());
645        }
646
647#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
648        class iterator:
649            public container_reference<vector>,
650            public random_access_iterator_base<dense_random_access_iterator_tag,
651                                               iterator, value_type, difference_type> {
652        public:
653            typedef typename vector::difference_type difference_type;
654            typedef typename vector::value_type value_type;
655            typedef typename vector::reference reference;
656            typedef typename vector::pointer pointer;
657
658
659            // Construction and destruction
660            BOOST_UBLAS_INLINE
661            iterator ():
662                container_reference<self_type> (), it_ () {}
663            BOOST_UBLAS_INLINE
664            iterator (self_type &v, const subiterator_type &it):
665                container_reference<self_type> (v), it_ (it) {}
666
667            // Arithmetic
668            BOOST_UBLAS_INLINE
669            iterator &operator ++ () {
670                ++ it_;
671                return *this;
672            }
673            BOOST_UBLAS_INLINE
674            iterator &operator -- () {
675                -- it_;
676                return *this;
677            }
678            BOOST_UBLAS_INLINE
679            iterator &operator += (difference_type n) {
680                it_ += n;
681                return *this;
682            }
683            BOOST_UBLAS_INLINE
684            iterator &operator -= (difference_type n) {
685                it_ -= n;
686                return *this;
687            }
688            BOOST_UBLAS_INLINE
689            difference_type operator - (const iterator &it) const {
690                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
691                return it_ - it.it_;
692            }
693
694            // Dereference
695            BOOST_UBLAS_INLINE
696            reference operator * () const {
697                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
698                return *it_;
699            }
700            BOOST_UBLAS_INLINE
701            reference operator [] (difference_type n) const {
702                return *(it_ + n);
703            }
704
705            // Index
706            BOOST_UBLAS_INLINE
707            size_type index () const {
708                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
709                return it_ - (*this) ().begin ().it_;
710            }
711
712            // Assignment
713            BOOST_UBLAS_INLINE
714            iterator &operator = (const iterator &it) {
715                container_reference<self_type>::assign (&it ());
716                it_ = it.it_;
717                return *this;
718            }
719
720            // Comparison
721            BOOST_UBLAS_INLINE
722            bool operator == (const iterator &it) const {
723                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
724                return it_ == it.it_;
725            }
726            BOOST_UBLAS_INLINE
727            bool operator < (const iterator &it) const {
728                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
729                return it_ < it.it_;
730            }
731
732        private:
733            subiterator_type it_;
734
735            friend class const_iterator;
736        };
737#endif
738
739   /// \brief Return an iterator on the first element of the vector
740        BOOST_UBLAS_INLINE
741        iterator begin () {
742            return find (0);
743        }
744
745   /// \brief Return an iterator at the end of the vector
746        BOOST_UBLAS_INLINE
747        iterator end () {
748            return find (data_.size ());
749        }
750
751        // Reverse iterator
752        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
753        typedef reverse_iterator_base<iterator> reverse_iterator;
754
755   /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
756        BOOST_UBLAS_INLINE
757        const_reverse_iterator rbegin () const {
758            return const_reverse_iterator (end ());
759        }
760
761   /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
762        BOOST_UBLAS_INLINE
763        const_reverse_iterator rend () const {
764            return const_reverse_iterator (begin ());
765        }
766
767   /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
768        BOOST_UBLAS_INLINE
769        reverse_iterator rbegin () {
770            return reverse_iterator (end ());
771        }
772
773   /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
774        BOOST_UBLAS_INLINE
775        reverse_iterator rend () {
776            return reverse_iterator (begin ());
777        }
778
779   // -------------
780        // Serialization
781   // -------------
782   
783   /// Serialize a vector into and archive as defined in Boost
784   /// \param ar Archive object. Can be a flat file, an XML file or any other stream
785   /// \param file_version Optional file version (not yet used)
786        template<class Archive>
787        void serialize(Archive & ar, const unsigned int /* file_version */){
788            ar & serialization::make_nvp("data",data_);
789        }
790
791    private:
792        array_type data_;
793    };
794
795
796    // --------------------
797    // Bounded vector class
798    // --------------------
799
800    /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$.
801    /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$.  The default constructor
802    /// creates the vector with size \f$N\f$. Elements are constructed by the storage type \c bounded_array, which \b need \b not \b initialise their value.
803    template<class T, std::size_t N>
804    class bounded_vector:
805        public vector<T, bounded_array<T, N> > {
806
807        typedef vector<T, bounded_array<T, N> > vector_type;
808    public:
809        typedef typename vector_type::size_type size_type;
810        static const size_type max_size = N;
811
812        // Construction and destruction
813        BOOST_UBLAS_INLINE
814        bounded_vector ():
815            vector_type (N) {}
816        BOOST_UBLAS_INLINE
817        bounded_vector (size_type size):
818            vector_type (size) {}
819        BOOST_UBLAS_INLINE
820        bounded_vector (const bounded_vector &v):
821            vector_type (v) {}
822        template<class A2>              // Allow vector<T,bounded_array<N> construction
823        BOOST_UBLAS_INLINE
824        bounded_vector (const vector<T, A2> &v):
825            vector_type (v) {}
826        template<class AE>
827        BOOST_UBLAS_INLINE
828        bounded_vector (const vector_expression<AE> &ae):
829            vector_type (ae) {}
830        BOOST_UBLAS_INLINE
831        ~bounded_vector () {}
832
833        // Assignment
834#ifdef BOOST_UBLAS_MOVE_SEMANTICS
835
836        /*! @note "pass by value" the key idea to enable move semantics */
837        BOOST_UBLAS_INLINE
838        bounded_vector &operator = (bounded_vector v) {
839            vector_type::operator = (v);
840            return *this;
841        }
842#else
843        BOOST_UBLAS_INLINE
844        bounded_vector &operator = (const bounded_vector &v) {
845            vector_type::operator = (v);
846            return *this;
847        }
848#endif
849        template<class A2>         // Generic vector assignment
850        BOOST_UBLAS_INLINE
851        bounded_vector &operator = (const vector<T, A2> &v) {
852            vector_type::operator = (v);
853            return *this;
854        }
855        template<class C>          // Container assignment without temporary
856        BOOST_UBLAS_INLINE
857        bounded_vector &operator = (const vector_container<C> &v) {
858            vector_type::operator = (v);
859            return *this;
860        }
861        template<class AE>
862        BOOST_UBLAS_INLINE
863        bounded_vector &operator = (const vector_expression<AE> &ae) {
864            vector_type::operator = (ae);
865            return *this;
866        }
867    };
868
869
870    // -----------------
871    // Zero vector class
872    // -----------------
873   
874    /// \brief A zero vector of type \c T and a given \c size
875    /// A zero vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated
876    /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero
877    /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
878    template<class T, class ALLOC>
879    class zero_vector:
880        public vector_container<zero_vector<T, ALLOC> > {
881
882        typedef const T *const_pointer;
883        typedef zero_vector<T, ALLOC> self_type;
884    public:
885#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
886        using vector_container<self_type>::operator ();
887#endif
888        typedef typename ALLOC::size_type size_type;
889        typedef typename ALLOC::difference_type difference_type;
890        typedef T value_type;
891        typedef const T &const_reference;
892        typedef T &reference;
893        typedef const vector_reference<const self_type> const_closure_type;
894        typedef vector_reference<self_type> closure_type;
895        typedef sparse_tag storage_category;
896
897        // Construction and destruction
898        BOOST_UBLAS_INLINE
899        zero_vector ():
900            vector_container<self_type> (),
901            size_ (0) {}
902        explicit BOOST_UBLAS_INLINE
903        zero_vector (size_type size):
904            vector_container<self_type> (),
905            size_ (size) {}
906        BOOST_UBLAS_INLINE
907        zero_vector (const zero_vector &v):
908            vector_container<self_type> (),
909            size_ (v.size_) {}
910
911        // Accessors
912        BOOST_UBLAS_INLINE
913        size_type size () const {
914            return size_;
915        }
916
917        // Resizing
918        BOOST_UBLAS_INLINE
919        void resize (size_type size, bool /*preserve*/ = true) {
920            size_ = size;
921        }
922
923        // Element support
924        BOOST_UBLAS_INLINE
925        const_pointer find_element (size_type i) const {
926            return & zero_;
927        }
928
929        // Element access
930        BOOST_UBLAS_INLINE
931        const_reference operator () (size_type /* i */) const {
932            return zero_;
933        }
934
935        BOOST_UBLAS_INLINE
936        const_reference operator [] (size_type i) const {
937            return (*this) (i);
938        }
939
940        // Assignment
941        BOOST_UBLAS_INLINE
942        zero_vector &operator = (const zero_vector &v) {
943            size_ = v.size_;
944            return *this;
945        }
946        BOOST_UBLAS_INLINE
947        zero_vector &assign_temporary (zero_vector &v) {
948            swap (v);
949            return *this;
950        }
951
952        // Swapping
953        BOOST_UBLAS_INLINE
954        void swap (zero_vector &v) {
955            if (this != &v) {
956                std::swap (size_, v.size_);
957            }
958        }
959        BOOST_UBLAS_INLINE
960        friend void swap (zero_vector &v1, zero_vector &v2) {
961            v1.swap (v2);
962        }
963
964        // Iterator types
965    public:
966        class const_iterator;
967
968        // Element lookup
969        BOOST_UBLAS_INLINE
970        const_iterator find (size_type /*i*/) const {
971            return const_iterator (*this);
972        }
973
974        class const_iterator:
975            public container_const_reference<zero_vector>,
976            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
977                                               const_iterator, value_type> {
978        public:
979            typedef typename zero_vector::difference_type difference_type;
980            typedef typename zero_vector::value_type value_type;
981            typedef typename zero_vector::const_reference reference;
982            typedef typename zero_vector::const_pointer pointer;
983
984            // Construction and destruction
985            BOOST_UBLAS_INLINE
986            const_iterator ():
987                container_const_reference<self_type> () {}
988            BOOST_UBLAS_INLINE
989            const_iterator (const self_type &v):
990                container_const_reference<self_type> (v) {}
991
992            // Arithmetic
993            BOOST_UBLAS_INLINE
994            const_iterator &operator ++ () {
995                BOOST_UBLAS_CHECK_FALSE (bad_index ());
996                return *this;
997            }
998            BOOST_UBLAS_INLINE
999            const_iterator &operator -- () {
1000                BOOST_UBLAS_CHECK_FALSE (bad_index ());
1001                return *this;
1002            }
1003
1004            // Dereference
1005            BOOST_UBLAS_INLINE
1006            const_reference operator * () const {
1007                BOOST_UBLAS_CHECK_FALSE (bad_index ());
1008                return zero_;   // arbitary return value
1009            }
1010
1011            // Index
1012            BOOST_UBLAS_INLINE
1013            size_type index () const {
1014                BOOST_UBLAS_CHECK_FALSE (bad_index ());
1015                return 0;   // arbitary return value
1016            }
1017
1018            // Assignment
1019            BOOST_UBLAS_INLINE
1020            const_iterator &operator = (const const_iterator &it) {
1021                container_const_reference<self_type>::assign (&it ());
1022                return *this;
1023            }
1024
1025            // Comparison
1026            BOOST_UBLAS_INLINE
1027            bool operator == (const const_iterator &it) const {
1028                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1029                detail::ignore_unused_variable_warning(it);
1030                return true;
1031            }
1032        };
1033
1034        typedef const_iterator iterator;
1035
1036        BOOST_UBLAS_INLINE
1037        const_iterator begin () const {
1038            return const_iterator (*this);
1039        }
1040        BOOST_UBLAS_INLINE
1041        const_iterator end () const {
1042            return const_iterator (*this);
1043        }
1044
1045        // Reverse iterator
1046        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1047
1048        BOOST_UBLAS_INLINE
1049        const_reverse_iterator rbegin () const {
1050            return const_reverse_iterator (end ());
1051        }
1052        BOOST_UBLAS_INLINE
1053        const_reverse_iterator rend () const {
1054            return const_reverse_iterator (begin ());
1055        }
1056
1057         // Serialization
1058        template<class Archive>
1059        void serialize(Archive & ar, const unsigned int /* file_version */){
1060            serialization::collection_size_type s (size_);
1061            ar & serialization::make_nvp("size",s);
1062            if (Archive::is_loading::value) {
1063                size_ = s;
1064            }
1065        }
1066
1067    private:
1068        size_type size_;
1069        typedef const value_type const_value_type;
1070        static const_value_type zero_;
1071    };
1072
1073    template<class T, class ALLOC>
1074    typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/);
1075
1076
1077    // Unit vector class
1078    /// \brief unit_vector represents a canonical unit vector
1079    /// unit_vector represents a canonical unit vector. The \e k-th unit vector of dimension \f$n\f$ holds 0 for every value \f$u_i\f$ s.t. \f$i \neq k\f$ and 1 when \f$i=k\f$.
1080    /// At construction, the value \e k is given after the dimension of the vector.
1081    /// \tparam T is the type of elements in the vector. They must be 0 and 1 assignable in order for the vector to have its unit-vector semantic.
1082    /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited.
1083    template<class T, class ALLOC>
1084    class unit_vector:
1085        public vector_container<unit_vector<T, ALLOC> > {
1086
1087        typedef const T *const_pointer;
1088        typedef unit_vector<T, ALLOC> self_type;
1089    public:
1090#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1091        using vector_container<self_type>::operator ();
1092#endif
1093        typedef typename ALLOC::size_type size_type;
1094        typedef typename ALLOC::difference_type difference_type;
1095        typedef T value_type;
1096        typedef const T &const_reference;
1097        typedef T &reference;
1098        typedef const vector_reference<const self_type> const_closure_type;
1099        typedef vector_reference<self_type> closure_type;
1100        typedef sparse_tag storage_category;
1101
1102        // Construction and destruction
1103   /// \brief Simple constructor with dimension and index 0
1104        BOOST_UBLAS_INLINE
1105        unit_vector ():
1106            vector_container<self_type> (),
1107            size_ (0), index_ (0) {}
1108
1109   /// \brief Constructor of unit_vector
1110   /// \param size is the dimension of the vector
1111   /// \param index is the order of the vector
1112        BOOST_UBLAS_INLINE
1113        explicit unit_vector (size_type size, size_type index = 0):
1114            vector_container<self_type> (),
1115            size_ (size), index_ (index) {}
1116
1117   /// \brief Copy-constructor
1118        BOOST_UBLAS_INLINE
1119        unit_vector (const unit_vector &v):
1120            vector_container<self_type> (),
1121            size_ (v.size_), index_ (v.index_) {}
1122
1123        // Accessors
1124   //----------
1125   
1126   /// \brief Return the size (dimension) of the vector
1127        BOOST_UBLAS_INLINE
1128        size_type size () const {
1129            return size_;
1130        }
1131
1132   /// \brief Return the order of the unit vector
1133        BOOST_UBLAS_INLINE
1134        size_type index () const {
1135            return index_;
1136        }
1137
1138        // Resizing
1139   // --------
1140   
1141   /// \brief Resize the vector. The values are preserved by default (i.e. the index does not change)
1142   /// \param size is the new size of the vector
1143        BOOST_UBLAS_INLINE
1144        void resize (size_type size, bool /*preserve*/ = true) {
1145            size_ = size;
1146        }
1147
1148        // Element support
1149   // ---------------
1150   
1151   /// \brief Return a const pointer to the element of index i
1152        BOOST_UBLAS_INLINE
1153        const_pointer find_element (size_type i) const {
1154            if (i == index_)
1155                return & one_;
1156            else
1157                return & zero_;
1158        }
1159
1160        // Element access
1161        BOOST_UBLAS_INLINE
1162        const_reference operator () (size_type i) const {
1163            if (i == index_)
1164                return one_;
1165            else
1166                return zero_;
1167        }
1168
1169        BOOST_UBLAS_INLINE
1170        const_reference operator [] (size_type i) const {
1171            return (*this) (i);
1172        }
1173
1174        // Assignment
1175        BOOST_UBLAS_INLINE
1176        unit_vector &operator = (const unit_vector &v) {
1177            size_ = v.size_;
1178            index_ = v.index_;
1179            return *this;
1180        }
1181        BOOST_UBLAS_INLINE
1182        unit_vector &assign_temporary (unit_vector &v) {
1183            swap (v);
1184            return *this;
1185        }
1186
1187        // Swapping
1188        BOOST_UBLAS_INLINE
1189        void swap (unit_vector &v) {
1190            if (this != &v) {
1191                std::swap (size_, v.size_);
1192                std::swap (index_, v.index_);
1193            }
1194        }
1195        BOOST_UBLAS_INLINE
1196        friend void swap (unit_vector &v1, unit_vector &v2) {
1197            v1.swap (v2);
1198        }
1199
1200        // Iterator types
1201    private:
1202        // Use bool to indicate begin (one_ as value)
1203        typedef bool const_subiterator_type;
1204    public:
1205        class const_iterator;
1206
1207        // Element lookup
1208        BOOST_UBLAS_INLINE
1209        const_iterator find (size_type i) const {
1210            return const_iterator (*this, i <= index_);
1211        }
1212
1213        class const_iterator:
1214            public container_const_reference<unit_vector>,
1215            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
1216                                               const_iterator, value_type> {
1217        public:
1218            typedef typename unit_vector::difference_type difference_type;
1219            typedef typename unit_vector::value_type value_type;
1220            typedef typename unit_vector::const_reference reference;
1221            typedef typename unit_vector::const_pointer pointer;
1222
1223            // Construction and destruction
1224            BOOST_UBLAS_INLINE
1225            const_iterator ():
1226                container_const_reference<unit_vector> (), it_ () {}
1227            BOOST_UBLAS_INLINE
1228            const_iterator (const unit_vector &v, const const_subiterator_type &it):
1229                container_const_reference<unit_vector> (v), it_ (it) {}
1230
1231            // Arithmetic
1232            BOOST_UBLAS_INLINE
1233            const_iterator &operator ++ () {
1234                BOOST_UBLAS_CHECK (it_, bad_index ());
1235                it_ = !it_;
1236                return *this;
1237            }
1238            BOOST_UBLAS_INLINE
1239            const_iterator &operator -- () {
1240                BOOST_UBLAS_CHECK (!it_, bad_index ());
1241                it_ = !it_;
1242                return *this;
1243            }
1244
1245            // Dereference
1246            BOOST_UBLAS_INLINE
1247            const_reference operator * () const {
1248                BOOST_UBLAS_CHECK (it_, bad_index ());
1249                return one_;
1250            }
1251
1252            // Index
1253            BOOST_UBLAS_INLINE
1254            size_type index () const {
1255                BOOST_UBLAS_CHECK (it_, bad_index ());
1256                return (*this) ().index_;
1257            }
1258
1259            // Assignment
1260            BOOST_UBLAS_INLINE
1261            const_iterator &operator = (const const_iterator &it) {
1262                container_const_reference<unit_vector>::assign (&it ());
1263                it_ = it.it_;
1264                return *this;
1265            }
1266
1267            // Comparison
1268            BOOST_UBLAS_INLINE
1269            bool operator == (const const_iterator &it) const {
1270                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1271                return it_ == it.it_;
1272            }
1273
1274        private:
1275            const_subiterator_type it_;
1276        };
1277
1278        typedef const_iterator iterator;
1279
1280        BOOST_UBLAS_INLINE
1281        const_iterator begin () const {
1282            return const_iterator (*this, true);
1283        }
1284        BOOST_UBLAS_INLINE
1285        const_iterator end () const {
1286            return const_iterator (*this, false);
1287        }
1288
1289        // Reverse iterator
1290        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1291
1292        BOOST_UBLAS_INLINE
1293        const_reverse_iterator rbegin () const {
1294            return const_reverse_iterator (end ());
1295        }
1296        BOOST_UBLAS_INLINE
1297        const_reverse_iterator rend () const {
1298            return const_reverse_iterator (begin ());
1299        }
1300
1301         // Serialization
1302        template<class Archive>
1303        void serialize(Archive & ar, const unsigned int /* file_version */){
1304            serialization::collection_size_type s (size_);
1305            ar & serialization::make_nvp("size",s);
1306            if (Archive::is_loading::value) {
1307                size_ = s;
1308            }
1309            ar & serialization::make_nvp("index", index_);
1310        }
1311
1312    private:
1313        size_type size_;
1314        size_type index_;
1315        typedef const value_type const_value_type;
1316        static const_value_type zero_;
1317        static const_value_type one_;
1318    };
1319
1320    template<class T, class ALLOC>
1321    typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/);
1322    template<class T, class ALLOC>
1323    typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1);  // ISSUE: need 'one'-traits here
1324
1325    /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size
1326    /// A scalar (i.e. unique value) vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated
1327    /// for storing the unique value more than once: it still acts like any other vector. However assigning a new value will change all the value at once.
1328    /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
1329    /// \tparam T type of the objects stored in the vector: it can be anything even if most of the time, scalar types will be used like \c double or \c int. Complex types can be used, or even classes like boost::interval.
1330    template<class T, class ALLOC>
1331    class scalar_vector:
1332        public vector_container<scalar_vector<T, ALLOC> > {
1333
1334        typedef const T *const_pointer;
1335        typedef scalar_vector<T, ALLOC> self_type;
1336    public:
1337#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1338        using vector_container<self_type>::operator ();
1339#endif
1340        typedef typename ALLOC::size_type size_type;
1341        typedef typename ALLOC::difference_type difference_type;
1342        typedef T value_type;
1343        typedef const T &const_reference;
1344        typedef T &reference;
1345        typedef const vector_reference<const self_type> const_closure_type;
1346        typedef vector_reference<self_type> closure_type;
1347        typedef dense_tag storage_category;
1348
1349        // Construction and destruction
1350        BOOST_UBLAS_INLINE
1351        scalar_vector ():
1352            vector_container<self_type> (),
1353            size_ (0), value_ () {}
1354        BOOST_UBLAS_INLINE
1355        explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
1356            vector_container<self_type> (),
1357            size_ (size), value_ (value) {}
1358        BOOST_UBLAS_INLINE
1359        scalar_vector (const scalar_vector &v):
1360            vector_container<self_type> (),
1361            size_ (v.size_), value_ (v.value_) {}
1362
1363        // Accessors
1364        BOOST_UBLAS_INLINE
1365        size_type size () const {
1366            return size_;
1367        }
1368
1369        // Resizing
1370        BOOST_UBLAS_INLINE
1371        void resize (size_type size, bool /*preserve*/ = true) {
1372            size_ = size;
1373        }
1374
1375        // Element support
1376        BOOST_UBLAS_INLINE
1377        const_pointer find_element (size_type /*i*/) const {
1378            return & value_;
1379        }
1380
1381        // Element access
1382        BOOST_UBLAS_INLINE
1383        const_reference operator () (size_type /*i*/) const {
1384            return value_;
1385        }
1386
1387        BOOST_UBLAS_INLINE
1388        const_reference operator [] (size_type /*i*/) const {
1389            return value_;
1390        }
1391
1392        // Assignment
1393        BOOST_UBLAS_INLINE
1394        scalar_vector &operator = (const scalar_vector &v) {
1395            size_ = v.size_;
1396            value_ = v.value_;
1397            return *this;
1398        }
1399        BOOST_UBLAS_INLINE
1400        scalar_vector &assign_temporary (scalar_vector &v) {
1401            swap (v);
1402            return *this;
1403        }
1404
1405        // Swapping
1406        BOOST_UBLAS_INLINE
1407        void swap (scalar_vector &v) {
1408            if (this != &v) {
1409                std::swap (size_, v.size_);
1410                std::swap (value_, v.value_);
1411            }
1412        }
1413        BOOST_UBLAS_INLINE
1414        friend void swap (scalar_vector &v1, scalar_vector &v2) {
1415            v1.swap (v2);
1416        }
1417
1418        // Iterator types
1419    private:
1420        // Use an index
1421        typedef size_type const_subiterator_type;
1422
1423    public:
1424#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1425        typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
1426        typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
1427#else
1428        class const_iterator;
1429#endif
1430
1431        // Element lookup
1432        BOOST_UBLAS_INLINE
1433        const_iterator find (size_type i) const {
1434            return const_iterator (*this, i);
1435        }
1436
1437#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1438        class const_iterator:
1439            public container_const_reference<scalar_vector>,
1440            public random_access_iterator_base<dense_random_access_iterator_tag,
1441                                               const_iterator, value_type> {
1442        public:
1443            typedef typename scalar_vector::difference_type difference_type;
1444            typedef typename scalar_vector::value_type value_type;
1445            typedef typename scalar_vector::const_reference reference;
1446            typedef typename scalar_vector::const_pointer pointer;
1447
1448            // Construction and destruction
1449            BOOST_UBLAS_INLINE
1450            const_iterator ():
1451                container_const_reference<scalar_vector> (), it_ () {}
1452            BOOST_UBLAS_INLINE
1453            const_iterator (const scalar_vector &v, const const_subiterator_type &it):
1454                container_const_reference<scalar_vector> (v), it_ (it) {}
1455
1456            // Arithmetic
1457            BOOST_UBLAS_INLINE
1458            const_iterator &operator ++ () {
1459                ++ it_;
1460                return *this;
1461            }
1462            BOOST_UBLAS_INLINE
1463            const_iterator &operator -- () {
1464                -- it_;
1465                return *this;
1466            }
1467            BOOST_UBLAS_INLINE
1468            const_iterator &operator += (difference_type n) {
1469                it_ += n;
1470                return *this;
1471            }
1472            BOOST_UBLAS_INLINE
1473            const_iterator &operator -= (difference_type n) {
1474                it_ -= n;
1475                return *this;
1476            }
1477            BOOST_UBLAS_INLINE
1478            difference_type operator - (const const_iterator &it) const {
1479                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1480                return it_ - it.it_;
1481            }
1482
1483            // Dereference
1484            BOOST_UBLAS_INLINE
1485            const_reference operator * () const {
1486                BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
1487                return (*this) () (index ());
1488            }
1489            BOOST_UBLAS_INLINE
1490            const_reference operator [] (difference_type n) const {
1491                return *(*this + n);
1492            }
1493
1494            // Index
1495            BOOST_UBLAS_INLINE
1496            size_type index () const {
1497                BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
1498                return it_;
1499            }
1500
1501            // Assignment
1502            BOOST_UBLAS_INLINE
1503            const_iterator &operator = (const const_iterator &it) {
1504                container_const_reference<scalar_vector>::assign (&it ());
1505                it_ = it.it_;
1506                return *this;
1507            }
1508
1509            // Comparison
1510            BOOST_UBLAS_INLINE
1511            bool operator == (const const_iterator &it) const {
1512                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1513                return it_ == it.it_;
1514            }
1515            BOOST_UBLAS_INLINE
1516            bool operator < (const const_iterator &it) const {
1517                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1518                return it_ < it.it_;
1519            }
1520
1521        private:
1522            const_subiterator_type it_;
1523        };
1524
1525        typedef const_iterator iterator;
1526#endif
1527
1528        BOOST_UBLAS_INLINE
1529        const_iterator begin () const {
1530            return find (0);
1531        }
1532        BOOST_UBLAS_INLINE
1533        const_iterator end () const {
1534            return find (size_);
1535        }
1536
1537        // Reverse iterator
1538        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1539
1540        BOOST_UBLAS_INLINE
1541        const_reverse_iterator rbegin () const {
1542            return const_reverse_iterator (end ());
1543        }
1544        BOOST_UBLAS_INLINE
1545        const_reverse_iterator rend () const {
1546            return const_reverse_iterator (begin ());
1547        }
1548
1549         // Serialization
1550        template<class Archive>
1551        void serialize(Archive & ar, const unsigned int /* file_version */){
1552            serialization::collection_size_type s (size_);
1553            ar & serialization::make_nvp("size",s);
1554            if (Archive::is_loading::value) {
1555                size_ = s;
1556            }
1557            ar & serialization::make_nvp("value", value_);
1558        }
1559
1560    private:
1561        size_type size_;
1562        value_type value_;
1563    };
1564
1565    // ------------------------
1566    // Array based vector class
1567    // ------------------------
1568
1569    /// \brief A dense vector of values of type \c T with the given \c size. The data is stored as an ordinary C++ array \c T \c data_[M]
1570    template<class T, std::size_t N>
1571    class c_vector:
1572        public vector_container<c_vector<T, N> > {
1573
1574        typedef c_vector<T, N> self_type;
1575    public:
1576#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1577        using vector_container<self_type>::operator ();
1578#endif
1579        typedef std::size_t size_type;
1580        typedef std::ptrdiff_t difference_type;
1581        typedef T value_type;
1582        typedef const T &const_reference;
1583        typedef T &reference;
1584        typedef value_type array_type[N];
1585        typedef T *pointer;
1586        typedef const T *const_pointer;
1587        typedef const vector_reference<const self_type> const_closure_type;
1588        typedef vector_reference<self_type> closure_type;
1589        typedef self_type vector_temporary_type;
1590        typedef dense_tag storage_category;
1591
1592        // Construction and destruction
1593        BOOST_UBLAS_INLINE
1594        c_vector ():
1595            size_ (N) /* , data_ () */ {}
1596        explicit BOOST_UBLAS_INLINE
1597        c_vector (size_type size):
1598            size_ (size) /* , data_ () */ {
1599            if (size_ > N)
1600                bad_size ().raise ();
1601        }
1602        BOOST_UBLAS_INLINE
1603        c_vector (const c_vector &v):
1604            size_ (v.size_) /* , data_ () */ {
1605            if (size_ > N)
1606                bad_size ().raise ();
1607            assign(v);
1608        }
1609        template<class AE>
1610        BOOST_UBLAS_INLINE
1611        c_vector (const vector_expression<AE> &ae):
1612            size_ (ae ().size ()) /* , data_ () */ {
1613            if (size_ > N)
1614                bad_size ().raise ();
1615            vector_assign<scalar_assign> (*this, ae);
1616        }
1617
1618        // Accessors
1619        BOOST_UBLAS_INLINE
1620        size_type size () const {
1621            return size_;
1622        }
1623        BOOST_UBLAS_INLINE
1624        const_pointer data () const {
1625            return data_;
1626        }
1627        BOOST_UBLAS_INLINE
1628        pointer data () {
1629            return data_;
1630        }
1631
1632        // Resizing
1633        BOOST_UBLAS_INLINE
1634        void resize (size_type size, bool preserve = true) {
1635            if (size > N)
1636                bad_size ().raise ();
1637            size_ = size;
1638        }
1639
1640        // Element support
1641        BOOST_UBLAS_INLINE
1642        pointer find_element (size_type i) {
1643            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
1644        }
1645        BOOST_UBLAS_INLINE
1646        const_pointer find_element (size_type i) const {
1647            return & data_ [i];
1648        }
1649
1650        // Element access
1651        BOOST_UBLAS_INLINE
1652        const_reference operator () (size_type i) const {
1653            BOOST_UBLAS_CHECK (i < size_,  bad_index ());
1654            return data_ [i];
1655        }
1656        BOOST_UBLAS_INLINE
1657        reference operator () (size_type i) {
1658            BOOST_UBLAS_CHECK (i < size_, bad_index ());
1659            return data_ [i];
1660        }
1661
1662        BOOST_UBLAS_INLINE
1663        const_reference operator [] (size_type i) const {
1664            return (*this) (i);
1665        }
1666        BOOST_UBLAS_INLINE
1667        reference operator [] (size_type i) {
1668            return (*this) (i);
1669        }
1670
1671        // Element assignment
1672        BOOST_UBLAS_INLINE
1673        reference insert_element (size_type i, const_reference t) {
1674            BOOST_UBLAS_CHECK (i < size_, bad_index ());
1675            return (data_ [i] = t);
1676        }
1677        BOOST_UBLAS_INLINE
1678        void erase_element (size_type i) {
1679            BOOST_UBLAS_CHECK (i < size_, bad_index ());
1680            data_ [i] = value_type/*zero*/();
1681        }
1682       
1683        // Zeroing
1684        BOOST_UBLAS_INLINE
1685        void clear () {
1686            std::fill (data_, data_ + size_, value_type/*zero*/());
1687        }
1688
1689        // Assignment
1690#ifdef BOOST_UBLAS_MOVE_SEMANTICS
1691
1692        /*! @note "pass by value" the key idea to enable move semantics */
1693        BOOST_UBLAS_INLINE
1694        c_vector &operator = (c_vector v) {
1695            assign_temporary(v);
1696            return *this;
1697        }
1698#else
1699        BOOST_UBLAS_INLINE
1700        c_vector &operator = (const c_vector &v) {
1701            size_ = v.size_;
1702            std::copy (v.data_, v.data_ + v.size_, data_);
1703            return *this;
1704        }
1705#endif
1706        template<class C>          // Container assignment without temporary
1707        BOOST_UBLAS_INLINE
1708        c_vector &operator = (const vector_container<C> &v) {
1709            resize (v ().size (), false);
1710            assign (v);
1711            return *this;
1712        }
1713        BOOST_UBLAS_INLINE
1714        c_vector &assign_temporary (c_vector &v) {
1715            swap (v);
1716            return *this;
1717        }
1718        template<class AE>
1719        BOOST_UBLAS_INLINE
1720        c_vector &operator = (const vector_expression<AE> &ae) {
1721            self_type temporary (ae);
1722            return assign_temporary (temporary);
1723        }
1724        template<class AE>
1725        BOOST_UBLAS_INLINE
1726        c_vector &assign (const vector_expression<AE> &ae) {
1727            vector_assign<scalar_assign> (*this, ae);
1728            return *this;
1729        }
1730
1731        // Computed assignment
1732        template<class AE>
1733        BOOST_UBLAS_INLINE
1734        c_vector &operator += (const vector_expression<AE> &ae) {
1735            self_type temporary (*this + ae);
1736            return assign_temporary (temporary);
1737        }
1738        template<class C>          // Container assignment without temporary
1739        BOOST_UBLAS_INLINE
1740        c_vector &operator += (const vector_container<C> &v) {
1741            plus_assign (v);
1742            return *this;
1743        }
1744        template<class AE>
1745        BOOST_UBLAS_INLINE
1746        c_vector &plus_assign (const vector_expression<AE> &ae) {
1747            vector_assign<scalar_plus_assign> ( *this, ae);
1748            return *this;
1749        }
1750        template<class AE>
1751        BOOST_UBLAS_INLINE
1752        c_vector &operator -= (const vector_expression<AE> &ae) {
1753            self_type temporary (*this - ae);
1754            return assign_temporary (temporary);
1755        }
1756        template<class C>          // Container assignment without temporary
1757        BOOST_UBLAS_INLINE
1758        c_vector &operator -= (const vector_container<C> &v) {
1759            minus_assign (v);
1760            return *this;
1761        }
1762        template<class AE>
1763        BOOST_UBLAS_INLINE
1764        c_vector &minus_assign (const vector_expression<AE> &ae) {
1765            vector_assign<scalar_minus_assign> (*this, ae);
1766            return *this;
1767        }
1768        template<class AT>
1769        BOOST_UBLAS_INLINE
1770        c_vector &operator *= (const AT &at) {
1771            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
1772            return *this;
1773        }
1774        template<class AT>
1775        BOOST_UBLAS_INLINE
1776        c_vector &operator /= (const AT &at) {
1777            vector_assign_scalar<scalar_divides_assign> (*this, at);
1778            return *this;
1779        }
1780
1781        // Swapping
1782        BOOST_UBLAS_INLINE
1783        void swap (c_vector &v) {
1784            if (this != &v) {
1785                BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
1786                std::swap (size_, v.size_);
1787                std::swap_ranges (data_, data_ + size_, v.data_);
1788            }
1789        }
1790        BOOST_UBLAS_INLINE
1791        friend void swap (c_vector &v1, c_vector &v2) {
1792            v1.swap (v2);
1793        }
1794
1795        // Iterator types
1796    private:
1797        // Use pointers for iterator
1798        typedef const_pointer const_subiterator_type;
1799        typedef pointer subiterator_type;
1800
1801    public:
1802#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1803        typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
1804        typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
1805#else
1806        class const_iterator;
1807        class iterator;
1808#endif
1809
1810        // Element lookup
1811        BOOST_UBLAS_INLINE
1812        const_iterator find (size_type i) const {
1813#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1814            return const_iterator (*this, &data_ [i]);
1815#else
1816            return const_iterator (*this, i);
1817#endif
1818        }
1819        BOOST_UBLAS_INLINE
1820        iterator find (size_type i) {
1821#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1822            return iterator (*this, &data_ [i]);
1823#else
1824            return iterator (*this, i);
1825#endif
1826        }
1827
1828#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1829        class const_iterator:
1830            public container_const_reference<c_vector>,
1831            public random_access_iterator_base<dense_random_access_iterator_tag,
1832                                               const_iterator, value_type> {
1833        public:
1834            typedef typename c_vector::difference_type difference_type;
1835            typedef typename c_vector::value_type value_type;
1836            typedef typename c_vector::const_reference reference;
1837            typedef typename c_vector::const_pointer pointer;
1838
1839            // Construction and destruction
1840            BOOST_UBLAS_INLINE
1841            const_iterator ():
1842                container_const_reference<self_type> (), it_ () {}
1843            BOOST_UBLAS_INLINE
1844            const_iterator (const self_type &v, const const_subiterator_type &it):
1845                container_const_reference<self_type> (v), it_ (it) {}
1846            BOOST_UBLAS_INLINE
1847            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
1848                container_const_reference<self_type> (it ()), it_ (it.it_) {}
1849
1850            // Arithmetic
1851            BOOST_UBLAS_INLINE
1852            const_iterator &operator ++ () {
1853                ++ it_;
1854                return *this;
1855            }
1856            BOOST_UBLAS_INLINE
1857            const_iterator &operator -- () {
1858                -- it_;
1859                return *this;
1860            }
1861            BOOST_UBLAS_INLINE
1862            const_iterator &operator += (difference_type n) {
1863                it_ += n;
1864                return *this;
1865            }
1866            BOOST_UBLAS_INLINE
1867            const_iterator &operator -= (difference_type n) {
1868                it_ -= n;
1869                return *this;
1870            }
1871            BOOST_UBLAS_INLINE
1872            difference_type operator - (const const_iterator &it) const {
1873                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1874                return it_ - it.it_;
1875            }
1876
1877            // Dereference
1878            BOOST_UBLAS_INLINE
1879            const_reference operator * () const {
1880                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1881                return *it_;
1882            }
1883            BOOST_UBLAS_INLINE
1884            const_reference operator [] (difference_type n) const {
1885                return *(it_ + n);
1886            }
1887
1888            // Index
1889            BOOST_UBLAS_INLINE
1890            size_type index () const {
1891                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1892                const self_type &v = (*this) ();
1893                return it_ - v.begin ().it_;
1894            }
1895
1896            // Assignment
1897            BOOST_UBLAS_INLINE
1898            const_iterator &operator = (const const_iterator &it) {
1899                container_const_reference<self_type>::assign (&it ());
1900                it_ = it.it_;
1901                return *this;
1902            }
1903
1904            // Comparison
1905            BOOST_UBLAS_INLINE
1906            bool operator == (const const_iterator &it) const {
1907                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1908                return it_ == it.it_;
1909            }
1910            BOOST_UBLAS_INLINE
1911            bool operator < (const const_iterator &it) const {
1912                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1913                return it_ < it.it_;
1914            }
1915
1916        private:
1917            const_subiterator_type it_;
1918
1919            friend class iterator;
1920        };
1921#endif
1922
1923        BOOST_UBLAS_INLINE
1924        const_iterator begin () const {
1925            return find (0);
1926        }
1927        BOOST_UBLAS_INLINE
1928        const_iterator end () const {
1929            return find (size_);
1930        }
1931
1932#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1933        class iterator:
1934            public container_reference<c_vector>,
1935            public random_access_iterator_base<dense_random_access_iterator_tag,
1936                                               iterator, value_type> {
1937        public:
1938            typedef typename c_vector::difference_type difference_type;
1939            typedef typename c_vector::value_type value_type;
1940            typedef typename c_vector::reference reference;
1941            typedef typename c_vector::pointer pointer;
1942
1943            // Construction and destruction
1944            BOOST_UBLAS_INLINE
1945            iterator ():
1946                container_reference<self_type> (), it_ () {}
1947            BOOST_UBLAS_INLINE
1948            iterator (self_type &v, const subiterator_type &it):
1949                container_reference<self_type> (v), it_ (it) {}
1950
1951            // Arithmetic
1952            BOOST_UBLAS_INLINE
1953            iterator &operator ++ () {
1954                ++ it_;
1955                return *this;
1956            }
1957            BOOST_UBLAS_INLINE
1958            iterator &operator -- () {
1959                -- it_;
1960                return *this;
1961            }
1962            BOOST_UBLAS_INLINE
1963            iterator &operator += (difference_type n) {
1964                it_ += n;
1965                return *this;
1966            }
1967            BOOST_UBLAS_INLINE
1968            iterator &operator -= (difference_type n) {
1969                it_ -= n;
1970                return *this;
1971            }
1972            BOOST_UBLAS_INLINE
1973            difference_type operator - (const iterator &it) const {
1974                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1975                return it_ - it.it_;
1976            }
1977
1978            // Dereference
1979            BOOST_UBLAS_INLINE
1980            reference operator * () const {
1981                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1982                return *it_;
1983            }
1984            BOOST_UBLAS_INLINE
1985            reference operator [] (difference_type n) const {
1986                return *(it_ + n);
1987            }
1988
1989            // Index
1990            BOOST_UBLAS_INLINE
1991            size_type index () const {
1992                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1993                // EDG won't allow const self_type it doesn't allow friend access to it_
1994                self_type &v = (*this) ();
1995                return it_ - v.begin ().it_;
1996            }
1997
1998            // Assignment
1999            BOOST_UBLAS_INLINE
2000            iterator &operator = (const iterator &it) {
2001                container_reference<self_type>::assign (&it ());
2002                it_ = it.it_;
2003                return *this;
2004            }
2005
2006            // Comparison
2007            BOOST_UBLAS_INLINE
2008            bool operator == (const iterator &it) const {
2009                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2010                return it_ == it.it_;
2011            }
2012            BOOST_UBLAS_INLINE
2013            bool operator < (const iterator &it) const {
2014                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
2015                return it_ < it.it_;
2016            }
2017
2018        private:
2019            subiterator_type it_;
2020
2021            friend class const_iterator;
2022        };
2023#endif
2024
2025        BOOST_UBLAS_INLINE
2026        iterator begin () {
2027            return find (0);
2028        }
2029        BOOST_UBLAS_INLINE
2030        iterator end () {
2031            return find (size_);
2032        }
2033
2034        // Reverse iterator
2035        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
2036        typedef reverse_iterator_base<iterator> reverse_iterator;
2037
2038        BOOST_UBLAS_INLINE
2039        const_reverse_iterator rbegin () const {
2040            return const_reverse_iterator (end ());
2041        }
2042        BOOST_UBLAS_INLINE
2043        const_reverse_iterator rend () const {
2044            return const_reverse_iterator (begin ());
2045        }
2046        BOOST_UBLAS_INLINE
2047        reverse_iterator rbegin () {
2048            return reverse_iterator (end ());
2049        }
2050        BOOST_UBLAS_INLINE
2051        reverse_iterator rend () {
2052            return reverse_iterator (begin ());
2053        }
2054
2055        // Serialization
2056        template<class Archive>
2057        void serialize(Archive & ar, const unsigned int /* file_version */){
2058            serialization::collection_size_type s (size_);
2059            ar & serialization::make_nvp("size",s);
2060           
2061            // copy the value back if loading
2062            if (Archive::is_loading::value) {
2063              if (s > N) bad_size("too large size in bounded_vector::load()\n").raise();
2064              size_ = s;
2065            }
2066            // ISSUE: this writes the full array
2067            ar & serialization::make_nvp("data",data_);
2068        }
2069
2070    private:
2071        size_type size_;
2072        array_type data_;
2073    };
2074
2075}}}
2076
2077#endif
Note: See TracBrowser for help on using the repository browser.