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

Revision 857, 53.7 KB checked in by igarcia, 18 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_VECTOR_
18#define _BOOST_UBLAS_VECTOR_
19
20#include <boost/numeric/ublas/storage.hpp>
21#include <boost/numeric/ublas/vector_expression.hpp>
22#include <boost/numeric/ublas/detail/vector_assign.hpp>
23
24// Iterators based on ideas of Jeremy Siek
25
26namespace boost { namespace numeric { namespace ublas {
27
28    // Array based vector class
29    template<class T, class A>
30    class vector:
31        public vector_container<vector<T, A> > {
32
33        typedef vector<T, A> self_type;
34    public:
35        typedef T *pointer;
36        typedef const T *const_pointer;
37#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
38        using vector_container<self_type>::operator ();
39#endif
40        typedef typename A::size_type size_type;
41        typedef typename A::difference_type difference_type;
42        typedef T value_type;
43        typedef typename type_traits<T>::const_reference const_reference;
44        typedef T &reference;
45        typedef A array_type;
46        typedef const vector_reference<const self_type> const_closure_type;
47        typedef vector_reference<self_type> closure_type;
48        typedef self_type vector_temporary_type;
49        typedef dense_tag storage_category;
50
51        // Construction and destruction
52        BOOST_UBLAS_INLINE
53        vector ():
54            vector_container<self_type> (),
55            data_ () {}
56        explicit BOOST_UBLAS_INLINE
57        vector (size_type size):
58            vector_container<self_type> (),
59            data_ (size) {
60        }
61        BOOST_UBLAS_INLINE
62        vector (size_type size, const array_type &data):
63            vector_container<self_type> (),
64            data_ (data) {}
65        BOOST_UBLAS_INLINE
66        vector (const vector &v):
67            vector_container<self_type> (),
68            data_ (v.data_) {}
69        template<class AE>
70        BOOST_UBLAS_INLINE
71        vector (const vector_expression<AE> &ae):
72            vector_container<self_type> (),
73            data_ (ae ().size ()) {
74            vector_assign<scalar_assign> (*this, ae);
75        }
76
77        // Accessors
78        BOOST_UBLAS_INLINE
79        size_type size () const {
80            return data_.size ();
81        }
82
83        // Storage accessors
84        BOOST_UBLAS_INLINE
85        const array_type &data () const {
86            return data_;
87        }
88        BOOST_UBLAS_INLINE
89        array_type &data () {
90            return data_;
91        }
92
93        // Resizing
94        BOOST_UBLAS_INLINE
95        void resize (size_type size, bool preserve = true) {
96            if (preserve)
97                data ().resize (size, typename A::value_type ());
98            else
99                data ().resize (size);
100        }
101
102        // Element support
103        BOOST_UBLAS_INLINE
104        pointer find_element (size_type i) {
105            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
106        }
107        BOOST_UBLAS_INLINE
108        const_pointer find_element (size_type i) const {
109            return & (data () [i]);
110        }
111
112        // Element access
113        BOOST_UBLAS_INLINE
114        const_reference operator () (size_type i) const {
115            return data () [i];
116        }
117        BOOST_UBLAS_INLINE
118        reference operator () (size_type i) {
119            return data () [i];
120        }
121
122        BOOST_UBLAS_INLINE
123        const_reference operator [] (size_type i) const {
124            return (*this) (i);
125        }
126        BOOST_UBLAS_INLINE
127        reference operator [] (size_type i) {
128            return (*this) (i);
129        }
130
131        // Element assignment
132        BOOST_UBLAS_INLINE
133        reference insert_element (size_type i, const_reference t) {
134            return (data () [i] = t);
135        }
136        BOOST_UBLAS_INLINE
137        void erase_element (size_type i) {
138            data () [i] = value_type/*zero*/();
139        }
140       
141        // Zeroing
142        BOOST_UBLAS_INLINE
143        void clear () {
144            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
145        }
146
147        // Assignment
148        BOOST_UBLAS_INLINE
149        vector &operator = (const vector &v) {
150            data () = v.data ();
151            return *this;
152        }
153        template<class C>          // Container assignment without temporary
154        BOOST_UBLAS_INLINE
155        vector &operator = (const vector_container<C> &v) {
156            resize (v ().size (), false);
157            assign (v);
158            return *this;
159        }
160        BOOST_UBLAS_INLINE
161        vector &assign_temporary (vector &v) {
162            swap (v);
163            return *this;
164        }
165        template<class AE>
166        BOOST_UBLAS_INLINE
167        vector &operator = (const vector_expression<AE> &ae) {
168            self_type temporary (ae);
169            return assign_temporary (temporary);
170        }
171        template<class AE>
172        BOOST_UBLAS_INLINE
173        vector &assign (const vector_expression<AE> &ae) {
174            vector_assign<scalar_assign> (*this, ae);
175            return *this;
176        }
177
178        // Computed assignment
179        template<class AE>
180        BOOST_UBLAS_INLINE
181        vector &operator += (const vector_expression<AE> &ae) {
182            self_type temporary (*this + ae);
183            return assign_temporary (temporary);
184        }
185        template<class C>          // Container assignment without temporary
186        BOOST_UBLAS_INLINE
187        vector &operator += (const vector_container<C> &v) {
188            plus_assign (v);
189            return *this;
190        }
191        template<class AE>
192        BOOST_UBLAS_INLINE
193        vector &plus_assign (const vector_expression<AE> &ae) {
194            vector_assign<scalar_plus_assign> (*this, ae);
195            return *this;
196        }
197        template<class AE>
198        BOOST_UBLAS_INLINE
199        vector &operator -= (const vector_expression<AE> &ae) {
200            self_type temporary (*this - ae);
201            return assign_temporary (temporary);
202        }
203        template<class C>          // Container assignment without temporary
204        BOOST_UBLAS_INLINE
205        vector &operator -= (const vector_container<C> &v) {
206            minus_assign (v);
207            return *this;
208        }
209        template<class AE>
210        BOOST_UBLAS_INLINE
211        vector &minus_assign (const vector_expression<AE> &ae) {
212            vector_assign<scalar_minus_assign> (*this, ae);
213            return *this;
214        }
215        template<class AT>
216        BOOST_UBLAS_INLINE
217        vector &operator *= (const AT &at) {
218            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
219            return *this;
220        }
221        template<class AT>
222        BOOST_UBLAS_INLINE
223        vector &operator /= (const AT &at) {
224            vector_assign_scalar<scalar_divides_assign> (*this, at);
225            return *this;
226        }
227
228        // Swapping
229        BOOST_UBLAS_INLINE
230        void swap (vector &v) {
231            if (this != &v) {
232                data ().swap (v.data ());
233            }
234        }
235        BOOST_UBLAS_INLINE
236        friend void swap (vector &v1, vector &v2) {
237            v1.swap (v2);
238        }
239
240        // Iterator types
241    private:
242        // Use the storage array iterator
243        typedef typename A::const_iterator const_subiterator_type;
244        typedef typename A::iterator subiterator_type;
245
246    public:
247#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
248        typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
249        typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
250#else
251        class const_iterator;
252        class iterator;
253#endif
254
255        // Element lookup
256        BOOST_UBLAS_INLINE
257        const_iterator find (size_type i) const {
258#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
259            return const_iterator (*this, data ().begin () + i);
260#else
261            return const_iterator (*this, i);
262#endif
263        }
264        BOOST_UBLAS_INLINE
265        iterator find (size_type i) {
266#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
267            return iterator (*this, data ().begin () + i);
268#else
269            return iterator (*this, i);
270#endif
271        }
272
273#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
274        class const_iterator:
275            public container_const_reference<vector>,
276            public random_access_iterator_base<dense_random_access_iterator_tag,
277                                               const_iterator, value_type, difference_type> {
278        public:
279            typedef typename vector::difference_type difference_type;
280            typedef typename vector::value_type value_type;
281            typedef typename vector::const_reference reference;
282            typedef const typename vector::pointer pointer;
283
284            // Construction and destruction
285            BOOST_UBLAS_INLINE
286            const_iterator ():
287                container_const_reference<self_type> (), it_ () {}
288            BOOST_UBLAS_INLINE
289            const_iterator (const self_type &v, const const_subiterator_type &it):
290                container_const_reference<self_type> (v), it_ (it) {}
291            BOOST_UBLAS_INLINE
292            const_iterator (const iterator &it):
293                container_const_reference<self_type> (it ()), it_ (it.it_) {}
294
295            // Arithmetic
296            BOOST_UBLAS_INLINE
297            const_iterator &operator ++ () {
298                ++ it_;
299                return *this;
300            }
301            BOOST_UBLAS_INLINE
302            const_iterator &operator -- () {
303                -- it_;
304                return *this;
305            }
306            BOOST_UBLAS_INLINE
307            const_iterator &operator += (difference_type n) {
308                it_ += n;
309                return *this;
310            }
311            BOOST_UBLAS_INLINE
312            const_iterator &operator -= (difference_type n) {
313                it_ -= n;
314                return *this;
315            }
316            BOOST_UBLAS_INLINE
317            difference_type operator - (const const_iterator &it) const {
318                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
319                return it_ - it.it_;
320            }
321
322            // Dereference
323            BOOST_UBLAS_INLINE
324            const_reference operator * () const {
325                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
326                return *it_;
327            }
328
329            // Index
330            BOOST_UBLAS_INLINE
331            size_type index () const {
332                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
333                return it_ - (*this) ().begin ().it_;
334            }
335
336            // Assignment
337            BOOST_UBLAS_INLINE
338            const_iterator &operator = (const const_iterator &it) {
339                container_const_reference<self_type>::assign (&it ());
340                it_ = it.it_;
341                return *this;
342            }
343
344            // Comparison
345            BOOST_UBLAS_INLINE
346            bool operator == (const const_iterator &it) const {
347                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
348                return it_ == it.it_;
349            }
350            BOOST_UBLAS_INLINE
351            bool operator < (const const_iterator &it) const {
352                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
353                return it_ < it.it_;
354            }
355
356        private:
357            const_subiterator_type it_;
358
359            friend class iterator;
360        };
361#endif
362
363        BOOST_UBLAS_INLINE
364        const_iterator begin () const {
365            return find (0);
366        }
367        BOOST_UBLAS_INLINE
368        const_iterator end () const {
369            return find (data_.size ());
370        }
371
372#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
373        class iterator:
374            public container_reference<vector>,
375            public random_access_iterator_base<dense_random_access_iterator_tag,
376                                               iterator, value_type, difference_type> {
377        public:
378            typedef typename vector::difference_type difference_type;
379            typedef typename vector::value_type value_type;
380            typedef typename vector::reference reference;
381            typedef typename vector::pointer pointer;
382
383
384            // Construction and destruction
385            BOOST_UBLAS_INLINE
386            iterator ():
387                container_reference<self_type> (), it_ () {}
388            BOOST_UBLAS_INLINE
389            iterator (self_type &v, const subiterator_type &it):
390                container_reference<self_type> (v), it_ (it) {}
391
392            // Arithmetic
393            BOOST_UBLAS_INLINE
394            iterator &operator ++ () {
395                ++ it_;
396                return *this;
397            }
398            BOOST_UBLAS_INLINE
399            iterator &operator -- () {
400                -- it_;
401                return *this;
402            }
403            BOOST_UBLAS_INLINE
404            iterator &operator += (difference_type n) {
405                it_ += n;
406                return *this;
407            }
408            BOOST_UBLAS_INLINE
409            iterator &operator -= (difference_type n) {
410                it_ -= n;
411                return *this;
412            }
413            BOOST_UBLAS_INLINE
414            difference_type operator - (const iterator &it) const {
415                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
416                return it_ - it.it_;
417            }
418
419            // Dereference
420            BOOST_UBLAS_INLINE
421            reference operator * () const {
422                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
423                return *it_;
424            }
425
426            // Index
427            BOOST_UBLAS_INLINE
428            size_type index () const {
429                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
430                return it_ - (*this) ().begin ().it_;
431            }
432
433            // Assignment
434            BOOST_UBLAS_INLINE
435            iterator &operator = (const iterator &it) {
436                container_reference<self_type>::assign (&it ());
437                it_ = it.it_;
438                return *this;
439            }
440
441            // Comparison
442            BOOST_UBLAS_INLINE
443            bool operator == (const iterator &it) const {
444                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
445                return it_ == it.it_;
446            }
447            BOOST_UBLAS_INLINE
448            bool operator < (const iterator &it) const {
449                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
450                return it_ < it.it_;
451            }
452
453        private:
454            subiterator_type it_;
455
456            friend class const_iterator;
457        };
458#endif
459
460        BOOST_UBLAS_INLINE
461        iterator begin () {
462            return find (0);
463        }
464        BOOST_UBLAS_INLINE
465        iterator end () {
466            return find (data_.size ());
467        }
468
469        // Reverse iterator
470        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
471        typedef reverse_iterator_base<iterator> reverse_iterator;
472
473        BOOST_UBLAS_INLINE
474        const_reverse_iterator rbegin () const {
475            return const_reverse_iterator (end ());
476        }
477        BOOST_UBLAS_INLINE
478        const_reverse_iterator rend () const {
479            return const_reverse_iterator (begin ());
480        }
481        BOOST_UBLAS_INLINE
482        reverse_iterator rbegin () {
483            return reverse_iterator (end ());
484        }
485        BOOST_UBLAS_INLINE
486        reverse_iterator rend () {
487            return reverse_iterator (begin ());
488        }
489
490    private:
491        array_type data_;
492    };
493
494
495    // Bounded vector class
496    template<class T, std::size_t N>
497    class bounded_vector:
498        public vector<T, bounded_array<T, N> > {
499
500        typedef vector<T, bounded_array<T, N> > vector_type;
501    public:
502        typedef typename vector_type::size_type size_type;
503        static const size_type max_size = N;
504
505        // Construction and destruction
506        BOOST_UBLAS_INLINE
507        bounded_vector ():
508            vector_type (N) {}
509        BOOST_UBLAS_INLINE
510        bounded_vector (size_type size):
511            vector_type (size) {}
512        BOOST_UBLAS_INLINE
513        bounded_vector (const bounded_vector &v):
514            vector_type (v) {}
515        template<class A2>              // Allow vector<T,bounded_array<N> construction
516        BOOST_UBLAS_INLINE
517        bounded_vector (const vector<T, A2> &v):
518            vector_type (v) {}
519        template<class AE>
520        BOOST_UBLAS_INLINE
521        bounded_vector (const vector_expression<AE> &ae):
522            vector_type (ae) {}
523        BOOST_UBLAS_INLINE
524        ~bounded_vector () {}
525
526        // Assignment
527        BOOST_UBLAS_INLINE
528        bounded_vector &operator = (const bounded_vector &v) {
529            vector_type::operator = (v);
530            return *this;
531        }
532        template<class A2>         // Generic vector assignment
533        BOOST_UBLAS_INLINE
534        bounded_vector &operator = (const vector<T, A2> &v) {
535            vector_type::operator = (v);
536            return *this;
537        }
538        template<class C>          // Container assignment without temporary
539        BOOST_UBLAS_INLINE
540        bounded_vector &operator = (const vector_container<C> &v) {
541            vector_type::operator = (v);
542            return *this;
543        }
544        template<class AE>
545        BOOST_UBLAS_INLINE
546        bounded_vector &operator = (const vector_expression<AE> &ae) {
547            vector_type::operator = (ae);
548            return *this;
549        }
550    };
551
552
553    // Zero vector class
554    template<class T>
555    class zero_vector:
556        public vector_container<zero_vector<T> > {
557
558        typedef const T *const_pointer;
559        typedef zero_vector<T> self_type;
560    public:
561#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
562        using vector_container<self_type>::operator ();
563#endif
564        typedef std::size_t size_type;
565        typedef std::ptrdiff_t difference_type;
566        typedef T value_type;
567        typedef const T &const_reference;
568        typedef T &reference;
569        typedef const vector_reference<const self_type> const_closure_type;
570        typedef vector_reference<self_type> closure_type;
571        typedef sparse_tag storage_category;
572
573        // Construction and destruction
574        BOOST_UBLAS_INLINE
575        zero_vector ():
576            vector_container<self_type> (),
577            size_ (0) {}
578        explicit BOOST_UBLAS_INLINE
579        zero_vector (size_type size):
580            vector_container<self_type> (),
581            size_ (size) {}
582        BOOST_UBLAS_INLINE
583        zero_vector (const zero_vector &v):
584            vector_container<self_type> (),
585            size_ (v.size_) {}
586
587        // Accessors
588        BOOST_UBLAS_INLINE
589        size_type size () const {
590            return size_;
591        }
592
593        // Resizing
594        BOOST_UBLAS_INLINE
595        void resize (size_type size, bool /*preserve*/ = true) {
596            size_ = size;
597        }
598
599        // Element support
600        BOOST_UBLAS_INLINE
601        const_pointer find_element (size_type i) const {
602            return & zero_;
603        }
604
605        // Element access
606        BOOST_UBLAS_INLINE
607        const_reference operator () (size_type /* i */) const {
608            return zero_;
609        }
610
611        BOOST_UBLAS_INLINE
612        const_reference operator [] (size_type i) const {
613            return (*this) (i);
614        }
615
616        // Assignment
617        BOOST_UBLAS_INLINE
618        zero_vector &operator = (const zero_vector &v) {
619            size_ = v.size_;
620            return *this;
621        }
622        BOOST_UBLAS_INLINE
623        zero_vector &assign_temporary (zero_vector &v) {
624            swap (v);
625            return *this;
626        }
627
628        // Swapping
629        BOOST_UBLAS_INLINE
630        void swap (zero_vector &v) {
631            if (this != &v) {
632                std::swap (size_, v.size_);
633            }
634        }
635        BOOST_UBLAS_INLINE
636        friend void swap (zero_vector &v1, zero_vector &v2) {
637            v1.swap (v2);
638        }
639
640        // Iterator types
641    public:
642        class const_iterator;
643
644        // Element lookup
645        BOOST_UBLAS_INLINE
646        const_iterator find (size_type /*i*/) const {
647            return const_iterator (*this);
648        }
649
650        class const_iterator:
651            public container_const_reference<zero_vector>,
652            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
653                                               const_iterator, value_type> {
654        public:
655            typedef typename zero_vector::difference_type difference_type;
656            typedef typename zero_vector::value_type value_type;
657            typedef typename zero_vector::const_reference reference;
658            typedef typename zero_vector::const_pointer pointer;
659
660            // Construction and destruction
661            BOOST_UBLAS_INLINE
662            const_iterator ():
663                container_const_reference<self_type> () {}
664            BOOST_UBLAS_INLINE
665            const_iterator (const self_type &v):
666                container_const_reference<self_type> (v) {}
667
668            // Arithmetic
669            BOOST_UBLAS_INLINE
670            const_iterator &operator ++ () {
671                BOOST_UBLAS_CHECK (false, bad_index ());
672                return *this;
673            }
674            BOOST_UBLAS_INLINE
675            const_iterator &operator -- () {
676                BOOST_UBLAS_CHECK (false, bad_index ());
677                return *this;
678            }
679
680            // Dereference
681            BOOST_UBLAS_INLINE
682            const_reference operator * () const {
683                BOOST_UBLAS_CHECK (false, bad_index ());
684                return zero_;   // arbitary return value
685            }
686
687            // Index
688            BOOST_UBLAS_INLINE
689            size_type index () const {
690                BOOST_UBLAS_CHECK (false, bad_index ());
691                return 0;   // arbitary return value
692            }
693
694            // Assignment
695            BOOST_UBLAS_INLINE
696            const_iterator &operator = (const const_iterator &it) {
697                container_const_reference<self_type>::assign (&it ());
698                return *this;
699            }
700
701            // Comparison
702            BOOST_UBLAS_INLINE
703            bool operator == (const const_iterator &it) const {
704                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
705                detail::ignore_unused_variable_warning(it);
706                return true;
707            }
708        };
709
710        typedef const_iterator iterator;
711
712        BOOST_UBLAS_INLINE
713        const_iterator begin () const {
714            return const_iterator (*this);
715        }
716        BOOST_UBLAS_INLINE
717        const_iterator end () const {
718            return const_iterator (*this);
719        }
720
721        // Reverse iterator
722        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
723
724        BOOST_UBLAS_INLINE
725        const_reverse_iterator rbegin () const {
726            return const_reverse_iterator (end ());
727        }
728        BOOST_UBLAS_INLINE
729        const_reverse_iterator rend () const {
730            return const_reverse_iterator (begin ());
731        }
732
733    private:
734        size_type size_;
735        typedef const value_type const_value_type;
736        static const_value_type zero_;
737    };
738
739    template<class T>
740    typename zero_vector<T>::const_value_type zero_vector<T>::zero_ (0);
741
742
743    // Unit vector class
744    template<class T>
745    class unit_vector:
746        public vector_container<unit_vector<T> > {
747
748        typedef const T *const_pointer;
749        typedef unit_vector<T> self_type;
750    public:
751#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
752        using vector_container<self_type>::operator ();
753#endif
754        typedef std::size_t size_type;
755        typedef std::ptrdiff_t difference_type;
756        typedef T value_type;
757        typedef const T &const_reference;
758        typedef T &reference;
759        typedef const vector_reference<const self_type> const_closure_type;
760        typedef vector_reference<self_type> closure_type;
761        typedef sparse_tag storage_category;
762
763        // Construction and destruction
764        BOOST_UBLAS_INLINE
765        unit_vector ():
766            vector_container<self_type> (),
767            size_ (0), index_ (0) {}
768        BOOST_UBLAS_INLINE
769        explicit unit_vector (size_type size, size_type index = 0):
770            vector_container<self_type> (),
771            size_ (size), index_ (index) {}
772        BOOST_UBLAS_INLINE
773        unit_vector (const unit_vector &v):
774            vector_container<self_type> (),
775            size_ (v.size_), index_ (v.index_) {}
776
777        // Accessors
778        BOOST_UBLAS_INLINE
779        size_type size () const {
780            return size_;
781        }
782        BOOST_UBLAS_INLINE
783        size_type index () const {
784            return index_;
785        }
786
787        // Resizing
788        BOOST_UBLAS_INLINE
789        void resize (size_type size, bool /*preserve*/ = true) {
790            size_ = size;
791        }
792
793        // Element support
794        BOOST_UBLAS_INLINE
795        const_pointer find_element (size_type i) const {
796            if (i == index_)
797                return & one_;
798            else
799                return & zero_;
800        }
801
802        // Element access
803        BOOST_UBLAS_INLINE
804        const_reference operator () (size_type i) const {
805            if (i == index_)
806                return one_;
807            else
808                return zero_;
809        }
810
811        BOOST_UBLAS_INLINE
812        const_reference operator [] (size_type i) const {
813            return (*this) (i);
814        }
815
816        // Assignment
817        BOOST_UBLAS_INLINE
818        unit_vector &operator = (const unit_vector &v) {
819            size_ = v.size_;
820            index_ = v.index_;
821            return *this;
822        }
823        BOOST_UBLAS_INLINE
824        unit_vector &assign_temporary (unit_vector &v) {
825            swap (v);
826            return *this;
827        }
828
829        // Swapping
830        BOOST_UBLAS_INLINE
831        void swap (unit_vector &v) {
832            if (this != &v) {
833                std::swap (size_, v.size_);
834                std::swap (index_, v.index_);
835            }
836        }
837        BOOST_UBLAS_INLINE
838        friend void swap (unit_vector &v1, unit_vector &v2) {
839            v1.swap (v2);
840        }
841
842        // Iterator types
843    private:
844        // Use bool to indicate begin (one_ as value)
845        typedef bool const_subiterator_type;
846    public:
847        class const_iterator;
848
849        // Element lookup
850        BOOST_UBLAS_INLINE
851        const_iterator find (size_type i) const {
852            return const_iterator (*this, i == index_);
853        }
854
855        class const_iterator:
856            public container_const_reference<unit_vector>,
857            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
858                                               const_iterator, value_type> {
859        public:
860            typedef typename unit_vector::difference_type difference_type;
861            typedef typename unit_vector::value_type value_type;
862            typedef typename unit_vector::const_reference reference;
863            typedef typename unit_vector::const_pointer pointer;
864
865            // Construction and destruction
866            BOOST_UBLAS_INLINE
867            const_iterator ():
868                container_const_reference<unit_vector> (), it_ () {}
869            BOOST_UBLAS_INLINE
870            const_iterator (const unit_vector &v, const const_subiterator_type &it):
871                container_const_reference<unit_vector> (v), it_ (it) {}
872
873            // Arithmetic
874            BOOST_UBLAS_INLINE
875            const_iterator &operator ++ () {
876                BOOST_UBLAS_CHECK (it_, bad_index ());
877                it_ = !it_;
878                return *this;
879            }
880            BOOST_UBLAS_INLINE
881            const_iterator &operator -- () {
882                BOOST_UBLAS_CHECK (!it_, bad_index ());
883                it_ = !it_;
884                return *this;
885            }
886
887            // Dereference
888            BOOST_UBLAS_INLINE
889            const_reference operator * () const {
890                BOOST_UBLAS_CHECK (it_, bad_index ());
891                return one_;
892            }
893
894            // Index
895            BOOST_UBLAS_INLINE
896            size_type index () const {
897                BOOST_UBLAS_CHECK (it_, bad_index ());
898                return (*this) ().index_;
899            }
900
901            // Assignment
902            BOOST_UBLAS_INLINE
903            const_iterator &operator = (const const_iterator &it) {
904                container_const_reference<unit_vector>::assign (&it ());
905                it_ = it.it_;
906                return *this;
907            }
908
909            // Comparison
910            BOOST_UBLAS_INLINE
911            bool operator == (const const_iterator &it) const {
912                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
913                return it_ == it.it_;
914            }
915
916        private:
917            const_subiterator_type it_;
918        };
919
920        typedef const_iterator iterator;
921
922        BOOST_UBLAS_INLINE
923        const_iterator begin () const {
924            return const_iterator (*this, true);
925        }
926        BOOST_UBLAS_INLINE
927        const_iterator end () const {
928            return const_iterator (*this, false);
929        }
930
931        // Reverse iterator
932        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
933
934        BOOST_UBLAS_INLINE
935        const_reverse_iterator rbegin () const {
936            return const_reverse_iterator (end ());
937        }
938        BOOST_UBLAS_INLINE
939        const_reverse_iterator rend () const {
940            return const_reverse_iterator (begin ());
941        }
942
943    private:
944        size_type size_;
945        size_type index_;
946        typedef const value_type const_value_type;
947        static const_value_type zero_;
948        static const_value_type one_;
949    };
950
951    template<class T>
952    typename unit_vector<T>::const_value_type unit_vector<T>::zero_ (0);
953    template<class T>
954    typename unit_vector<T>::const_value_type unit_vector<T>::one_ (1);
955
956
957    // Scalar vector class
958    template<class T>
959    class scalar_vector:
960        public vector_container<scalar_vector<T> > {
961
962        typedef const T *const_pointer;
963        typedef scalar_vector<T> self_type;
964    public:
965#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
966        using vector_container<self_type>::operator ();
967#endif
968        typedef std::size_t size_type;
969        typedef std::ptrdiff_t difference_type;
970        typedef T value_type;
971        typedef const T &const_reference;
972        typedef T &reference;
973        typedef const vector_reference<const self_type> const_closure_type;
974        typedef dense_tag storage_category;
975
976        // Construction and destruction
977        BOOST_UBLAS_INLINE
978        scalar_vector ():
979            vector_container<self_type> (),
980            size_ (0), value_ () {}
981        BOOST_UBLAS_INLINE
982        explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
983            vector_container<self_type> (),
984            size_ (size), value_ (value) {}
985        BOOST_UBLAS_INLINE
986        scalar_vector (const scalar_vector &v):
987            vector_container<self_type> (),
988            size_ (v.size_), value_ (v.value_) {}
989
990        // Accessors
991        BOOST_UBLAS_INLINE
992        size_type size () const {
993            return size_;
994        }
995
996        // Resizing
997        BOOST_UBLAS_INLINE
998        void resize (size_type size, bool /*preserve*/ = true) {
999            size_ = size;
1000        }
1001
1002        // Element support
1003        BOOST_UBLAS_INLINE
1004        const_pointer find_element (size_type /*i*/) const {
1005            return & value_;
1006        }
1007
1008        // Element access
1009        BOOST_UBLAS_INLINE
1010        const_reference operator () (size_type /*i*/) const {
1011            return value_;
1012        }
1013
1014        BOOST_UBLAS_INLINE
1015        const_reference operator [] (size_type /*i*/) const {
1016            return value_;
1017        }
1018
1019        // Assignment
1020        BOOST_UBLAS_INLINE
1021        scalar_vector &operator = (const scalar_vector &v) {
1022            size_ = v.size_;
1023            value_ = v.value_;
1024            return *this;
1025        }
1026        BOOST_UBLAS_INLINE
1027        scalar_vector &assign_temporary (scalar_vector &v) {
1028            swap (v);
1029            return *this;
1030        }
1031
1032        // Swapping
1033        BOOST_UBLAS_INLINE
1034        void swap (scalar_vector &v) {
1035            if (this != &v) {
1036                std::swap (size_, v.size_);
1037                std::swap (value_, v.value_);
1038            }
1039        }
1040        BOOST_UBLAS_INLINE
1041        friend void swap (scalar_vector &v1, scalar_vector &v2) {
1042            v1.swap (v2);
1043        }
1044
1045        // Iterator types
1046    private:
1047        // Use an index
1048        typedef size_type const_subiterator_type;
1049
1050    public:
1051#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1052        typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
1053        typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
1054#else
1055        class const_iterator;
1056#endif
1057
1058        // Element lookup
1059        BOOST_UBLAS_INLINE
1060        const_iterator find (size_type i) const {
1061            return const_iterator (*this, i);
1062        }
1063
1064#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1065        class const_iterator:
1066            public container_const_reference<scalar_vector>,
1067            public random_access_iterator_base<dense_random_access_iterator_tag,
1068                                               const_iterator, value_type> {
1069        public:
1070            typedef typename scalar_vector::difference_type difference_type;
1071            typedef typename scalar_vector::value_type value_type;
1072            typedef typename scalar_vector::const_reference reference;
1073            typedef typename scalar_vector::const_pointer pointer;
1074
1075            // Construction and destruction
1076            BOOST_UBLAS_INLINE
1077            const_iterator ():
1078                container_const_reference<scalar_vector> (), it_ () {}
1079            BOOST_UBLAS_INLINE
1080            const_iterator (const scalar_vector &v, const const_subiterator_type &it):
1081                container_const_reference<scalar_vector> (v), it_ (it) {}
1082
1083            // Arithmetic
1084            BOOST_UBLAS_INLINE
1085            const_iterator &operator ++ () {
1086                ++ it_;
1087                return *this;
1088            }
1089            BOOST_UBLAS_INLINE
1090            const_iterator &operator -- () {
1091                -- it_;
1092                return *this;
1093            }
1094            BOOST_UBLAS_INLINE
1095            const_iterator &operator += (difference_type n) {
1096                it_ += n;
1097                return *this;
1098            }
1099            BOOST_UBLAS_INLINE
1100            const_iterator &operator -= (difference_type n) {
1101                it_ -= n;
1102                return *this;
1103            }
1104            BOOST_UBLAS_INLINE
1105            difference_type operator - (const const_iterator &it) const {
1106                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1107                return it_ - it.it_;
1108            }
1109
1110            // Dereference
1111            BOOST_UBLAS_INLINE
1112            const_reference operator * () const {
1113                BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
1114                return (*this) () (index ());
1115            }
1116
1117            // Index
1118            BOOST_UBLAS_INLINE
1119            size_type index () const {
1120                BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
1121                return it_;
1122            }
1123
1124            // Assignment
1125            BOOST_UBLAS_INLINE
1126            const_iterator &operator = (const const_iterator &it) {
1127                container_const_reference<scalar_vector>::assign (&it ());
1128                it_ = it.it_;
1129                return *this;
1130            }
1131
1132            // Comparison
1133            BOOST_UBLAS_INLINE
1134            bool operator == (const const_iterator &it) const {
1135                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1136                return it_ == it.it_;
1137            }
1138            BOOST_UBLAS_INLINE
1139            bool operator < (const const_iterator &it) const {
1140                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1141                return it_ < it.it_;
1142            }
1143
1144        private:
1145            const_subiterator_type it_;
1146        };
1147
1148        typedef const_iterator iterator;
1149#endif
1150
1151        BOOST_UBLAS_INLINE
1152        const_iterator begin () const {
1153            return find (0);
1154        }
1155        BOOST_UBLAS_INLINE
1156        const_iterator end () const {
1157            return find (size_);
1158        }
1159
1160        // Reverse iterator
1161        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1162
1163        BOOST_UBLAS_INLINE
1164        const_reverse_iterator rbegin () const {
1165            return const_reverse_iterator (end ());
1166        }
1167        BOOST_UBLAS_INLINE
1168        const_reverse_iterator rend () const {
1169            return const_reverse_iterator (begin ());
1170        }
1171
1172    private:
1173        size_type size_;
1174        value_type value_;
1175    };
1176
1177
1178    // Array based vector class
1179    template<class T, std::size_t N>
1180    class c_vector:
1181        public vector_container<c_vector<T, N> > {
1182
1183        typedef c_vector<T, N> self_type;
1184    public:
1185#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1186        using vector_container<self_type>::operator ();
1187#endif
1188        typedef std::size_t size_type;
1189        typedef std::ptrdiff_t difference_type;
1190        typedef T value_type;
1191        typedef const T &const_reference;
1192        typedef T &reference;
1193        typedef value_type array_type[N];
1194        typedef T *pointer;
1195        typedef const T *const_pointer;
1196        typedef const vector_reference<const self_type> const_closure_type;
1197        typedef vector_reference<self_type> closure_type;
1198        typedef self_type vector_temporary_type;
1199        typedef dense_tag storage_category;
1200
1201        // Construction and destruction
1202        BOOST_UBLAS_INLINE
1203        c_vector ():
1204            size_ (N) /* , data_ () */ {}
1205        explicit BOOST_UBLAS_INLINE
1206        c_vector (size_type size):
1207            size_ (size) /* , data_ () */ {
1208            if (size_ > N)
1209                bad_size ().raise ();
1210        }
1211        BOOST_UBLAS_INLINE
1212        c_vector (const c_vector &v):
1213            size_ (v.size_) /* , data_ () */ {
1214            if (size_ > N)
1215                bad_size ().raise ();
1216            *this = v;
1217        }
1218        template<class AE>
1219        BOOST_UBLAS_INLINE
1220        c_vector (const vector_expression<AE> &ae):
1221            size_ (ae ().size ()) /* , data_ () */ {
1222            if (size_ > N)
1223                bad_size ().raise ();
1224            vector_assign<scalar_assign> (*this, ae);
1225        }
1226
1227        // Accessors
1228        BOOST_UBLAS_INLINE
1229        size_type size () const {
1230            return size_;
1231        }
1232        BOOST_UBLAS_INLINE
1233        const_pointer data () const {
1234            return data_;
1235        }
1236        BOOST_UBLAS_INLINE
1237        pointer data () {
1238            return data_;
1239        }
1240
1241        // Resizing
1242        BOOST_UBLAS_INLINE
1243        void resize (size_type size, bool preserve = true) {
1244            if (size > N)
1245                bad_size ().raise ();
1246            size_ = size;
1247        }
1248
1249        // Element support
1250        BOOST_UBLAS_INLINE
1251        pointer find_element (size_type i) {
1252            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
1253        }
1254        BOOST_UBLAS_INLINE
1255        const_pointer find_element (size_type i) const {
1256            return & data_ [i];
1257        }
1258
1259        // Element access
1260        BOOST_UBLAS_INLINE
1261        const_reference operator () (size_type i) const {
1262            BOOST_UBLAS_CHECK (i < size_,  bad_index ());
1263            return data_ [i];
1264        }
1265        BOOST_UBLAS_INLINE
1266        reference operator () (size_type i) {
1267            BOOST_UBLAS_CHECK (i < size_, bad_index ());
1268            return data_ [i];
1269        }
1270
1271        BOOST_UBLAS_INLINE
1272        const_reference operator [] (size_type i) const {
1273            return (*this) (i);
1274        }
1275        BOOST_UBLAS_INLINE
1276        reference operator [] (size_type i) {
1277            return (*this) (i);
1278        }
1279
1280        // Element assignment
1281        BOOST_UBLAS_INLINE
1282        reference insert_element (size_type i, const_reference t) {
1283            BOOST_UBLAS_CHECK (i < size_, bad_index ());
1284            return (data_ [i] = t);
1285        }
1286        BOOST_UBLAS_INLINE
1287        void erase_element (size_type i) {
1288            BOOST_UBLAS_CHECK (i < size_, bad_index ());
1289            data_ [i] = value_type/*zero*/();
1290        }
1291       
1292        // Zeroing
1293        BOOST_UBLAS_INLINE
1294        void clear () {
1295            std::fill (data_, data_ + size_, value_type/*zero*/());
1296        }
1297
1298        // Assignment
1299        BOOST_UBLAS_INLINE
1300        c_vector &operator = (const c_vector &v) {
1301            size_ = v.size_;
1302            std::copy (v.data_, v.data_ + v.size_, data_);
1303            return *this;
1304        }
1305        template<class C>          // Container assignment without temporary
1306        BOOST_UBLAS_INLINE
1307        c_vector &operator = (const vector_container<C> &v) {
1308            resize (v ().size (), false);
1309            assign (v);
1310            return *this;
1311        }
1312        BOOST_UBLAS_INLINE
1313        c_vector &assign_temporary (c_vector &v) {
1314            swap (v);
1315            return *this;
1316        }
1317        template<class AE>
1318        BOOST_UBLAS_INLINE
1319        c_vector &operator = (const vector_expression<AE> &ae) {
1320            self_type temporary (ae);
1321            return assign_temporary (temporary);
1322        }
1323        template<class AE>
1324        BOOST_UBLAS_INLINE
1325        c_vector &assign (const vector_expression<AE> &ae) {
1326            vector_assign<scalar_assign> (*this, ae);
1327            return *this;
1328        }
1329
1330        // Computed assignment
1331        template<class AE>
1332        BOOST_UBLAS_INLINE
1333        c_vector &operator += (const vector_expression<AE> &ae) {
1334            self_type temporary (*this + ae);
1335            return assign_temporary (temporary);
1336        }
1337        template<class C>          // Container assignment without temporary
1338        BOOST_UBLAS_INLINE
1339        c_vector &operator += (const vector_container<C> &v) {
1340            plus_assign (v);
1341            return *this;
1342        }
1343        template<class AE>
1344        BOOST_UBLAS_INLINE
1345        c_vector &plus_assign (const vector_expression<AE> &ae) {
1346            vector_assign<scalar_plus_assign> ( *this, ae);
1347            return *this;
1348        }
1349        template<class AE>
1350        BOOST_UBLAS_INLINE
1351        c_vector &operator -= (const vector_expression<AE> &ae) {
1352            self_type temporary (*this - ae);
1353            return assign_temporary (temporary);
1354        }
1355        template<class C>          // Container assignment without temporary
1356        BOOST_UBLAS_INLINE
1357        c_vector &operator -= (const vector_container<C> &v) {
1358            minus_assign (v);
1359            return *this;
1360        }
1361        template<class AE>
1362        BOOST_UBLAS_INLINE
1363        c_vector &minus_assign (const vector_expression<AE> &ae) {
1364            vector_assign<scalar_minus_assign> (*this, ae);
1365            return *this;
1366        }
1367        template<class AT>
1368        BOOST_UBLAS_INLINE
1369        c_vector &operator *= (const AT &at) {
1370            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
1371            return *this;
1372        }
1373        template<class AT>
1374        BOOST_UBLAS_INLINE
1375        c_vector &operator /= (const AT &at) {
1376            vector_assign_scalar<scalar_divides_assign> (*this, at);
1377            return *this;
1378        }
1379
1380        // Swapping
1381        BOOST_UBLAS_INLINE
1382        void swap (c_vector &v) {
1383            if (this != &v) {
1384                BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
1385                std::swap (size_, v.size_);
1386                std::swap_ranges (data_, data_ + size_, v.data_);
1387            }
1388        }
1389        BOOST_UBLAS_INLINE
1390        friend void swap (c_vector &v1, c_vector &v2) {
1391            v1.swap (v2);
1392        }
1393
1394        // Iterator types
1395    private:
1396        // Use pointers for iterator
1397        typedef const_pointer const_subiterator_type;
1398        typedef pointer subiterator_type;
1399
1400    public:
1401#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1402        typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
1403        typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
1404#else
1405        class const_iterator;
1406        class iterator;
1407#endif
1408
1409        // Element lookup
1410        BOOST_UBLAS_INLINE
1411        const_iterator find (size_type i) const {
1412#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1413            return const_iterator (*this, &data_ [i]);
1414#else
1415            return const_iterator (*this, i);
1416#endif
1417        }
1418        BOOST_UBLAS_INLINE
1419        iterator find (size_type i) {
1420#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1421            return iterator (*this, &data_ [i]);
1422#else
1423            return iterator (*this, i);
1424#endif
1425        }
1426
1427#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1428        class const_iterator:
1429            public container_const_reference<c_vector>,
1430            public random_access_iterator_base<dense_random_access_iterator_tag,
1431                                               const_iterator, value_type> {
1432        public:
1433            typedef typename c_vector::difference_type difference_type;
1434            typedef typename c_vector::value_type value_type;
1435            typedef typename c_vector::const_reference reference;
1436            typedef typename c_vector::const_pointer pointer;
1437
1438            // Construction and destruction
1439            BOOST_UBLAS_INLINE
1440            const_iterator ():
1441                container_const_reference<self_type> (), it_ () {}
1442            BOOST_UBLAS_INLINE
1443            const_iterator (const self_type &v, const const_subiterator_type &it):
1444                container_const_reference<self_type> (v), it_ (it) {}
1445            BOOST_UBLAS_INLINE
1446            const_iterator (const iterator &it):
1447                container_const_reference<self_type> (it ()), it_ (it.it_) {}
1448
1449            // Arithmetic
1450            BOOST_UBLAS_INLINE
1451            const_iterator &operator ++ () {
1452                ++ it_;
1453                return *this;
1454            }
1455            BOOST_UBLAS_INLINE
1456            const_iterator &operator -- () {
1457                -- it_;
1458                return *this;
1459            }
1460            BOOST_UBLAS_INLINE
1461            const_iterator &operator += (difference_type n) {
1462                it_ += n;
1463                return *this;
1464            }
1465            BOOST_UBLAS_INLINE
1466            const_iterator &operator -= (difference_type n) {
1467                it_ -= n;
1468                return *this;
1469            }
1470            BOOST_UBLAS_INLINE
1471            difference_type operator - (const const_iterator &it) const {
1472                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1473                return it_ - it.it_;
1474            }
1475
1476            // Dereference
1477            BOOST_UBLAS_INLINE
1478            const_reference operator * () const {
1479                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1480                return *it_;
1481            }
1482
1483            // Index
1484            BOOST_UBLAS_INLINE
1485            size_type index () const {
1486                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1487                const self_type &v = (*this) ();
1488                return it_ - v.begin ().it_;
1489            }
1490
1491            // Assignment
1492            BOOST_UBLAS_INLINE
1493            const_iterator &operator = (const const_iterator &it) {
1494                container_const_reference<self_type>::assign (&it ());
1495                it_ = it.it_;
1496                return *this;
1497            }
1498
1499            // Comparison
1500            BOOST_UBLAS_INLINE
1501            bool operator == (const const_iterator &it) const {
1502                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1503                return it_ == it.it_;
1504            }
1505            BOOST_UBLAS_INLINE
1506            bool operator < (const const_iterator &it) const {
1507                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1508                return it_ < it.it_;
1509            }
1510
1511        private:
1512            const_subiterator_type it_;
1513
1514            friend class iterator;
1515        };
1516#endif
1517
1518        BOOST_UBLAS_INLINE
1519        const_iterator begin () const {
1520            return find (0);
1521        }
1522        BOOST_UBLAS_INLINE
1523        const_iterator end () const {
1524            return find (size_);
1525        }
1526
1527#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1528        class iterator:
1529            public container_reference<c_vector>,
1530            public random_access_iterator_base<dense_random_access_iterator_tag,
1531                                               iterator, value_type> {
1532        public:
1533            typedef typename c_vector::difference_type difference_type;
1534            typedef typename c_vector::value_type value_type;
1535            typedef typename c_vector::reference reference;
1536            typedef typename c_vector::pointer pointer;
1537
1538            // Construction and destruction
1539            BOOST_UBLAS_INLINE
1540            iterator ():
1541                container_reference<self_type> (), it_ () {}
1542            BOOST_UBLAS_INLINE
1543            iterator (self_type &v, const subiterator_type &it):
1544                container_reference<self_type> (v), it_ (it) {}
1545
1546            // Arithmetic
1547            BOOST_UBLAS_INLINE
1548            iterator &operator ++ () {
1549                ++ it_;
1550                return *this;
1551            }
1552            BOOST_UBLAS_INLINE
1553            iterator &operator -- () {
1554                -- it_;
1555                return *this;
1556            }
1557            BOOST_UBLAS_INLINE
1558            iterator &operator += (difference_type n) {
1559                it_ += n;
1560                return *this;
1561            }
1562            BOOST_UBLAS_INLINE
1563            iterator &operator -= (difference_type n) {
1564                it_ -= n;
1565                return *this;
1566            }
1567            BOOST_UBLAS_INLINE
1568            difference_type operator - (const iterator &it) const {
1569                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1570                return it_ - it.it_;
1571            }
1572
1573            // Dereference
1574            BOOST_UBLAS_INLINE
1575            reference operator * () const {
1576                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1577                return *it_;
1578            }
1579
1580            // Index
1581            BOOST_UBLAS_INLINE
1582            size_type index () const {
1583                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
1584                // EDG won't allow const self_type it doesn't allow friend access to it_
1585                self_type &v = (*this) ();
1586                return it_ - v.begin ().it_;
1587            }
1588
1589            // Assignment
1590            BOOST_UBLAS_INLINE
1591            iterator &operator = (const iterator &it) {
1592                container_reference<self_type>::assign (&it ());
1593                it_ = it.it_;
1594                return *this;
1595            }
1596
1597            // Comparison
1598            BOOST_UBLAS_INLINE
1599            bool operator == (const iterator &it) const {
1600                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1601                return it_ == it.it_;
1602            }
1603            BOOST_UBLAS_INLINE
1604            bool operator < (const iterator &it) const {
1605                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
1606                return it_ < it.it_;
1607            }
1608
1609        private:
1610            subiterator_type it_;
1611
1612            friend class const_iterator;
1613        };
1614#endif
1615
1616        BOOST_UBLAS_INLINE
1617        iterator begin () {
1618            return find (0);
1619        }
1620        BOOST_UBLAS_INLINE
1621        iterator end () {
1622            return find (size_);
1623        }
1624
1625        // Reverse iterator
1626        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1627        typedef reverse_iterator_base<iterator> reverse_iterator;
1628
1629        BOOST_UBLAS_INLINE
1630        const_reverse_iterator rbegin () const {
1631            return const_reverse_iterator (end ());
1632        }
1633        BOOST_UBLAS_INLINE
1634        const_reverse_iterator rend () const {
1635            return const_reverse_iterator (begin ());
1636        }
1637        BOOST_UBLAS_INLINE
1638        reverse_iterator rbegin () {
1639            return reverse_iterator (end ());
1640        }
1641        BOOST_UBLAS_INLINE
1642        reverse_iterator rend () {
1643            return reverse_iterator (begin ());
1644        }
1645
1646    private:
1647        size_type size_;
1648        array_type data_;
1649    };
1650
1651}}}
1652
1653#endif
Note: See TracBrowser for help on using the repository browser.