Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/numeric/ublas/vector.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

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