Array STL

Arrays STL各种实现代码。 《C++标准程序库》

  1 /* 
  2 2015.4
  3 an STL container (as wrapper) for arrays of constant size.
  4 
  5 */
  6 
  7 #pragma warning(disable : 4996)
  8 #include <iostream>
  9 #include <cstddef>
 10 #include <stdexcept>
 11 #include <algorithm>    //transform()
 12 #include <functional>    //negate<>()
 13 #include <assert.h>
 14 
 15 namespace boost 
 16 {
 17 
 18     template<class T, std::size_t N>
 19     class array
 20     {
 21     private:
 22         T elems[N];    // fixed-size array of elements of type T
 23 
 24     public:
 25         // type definitions
 26         typedef T              value_type;
 27         typedef T*             iterator;
 28         typedef const T*       const_iterator;
 29         typedef T&             reference;
 30         typedef const T&       const_reference;
 31         typedef std::size_t    size_type;
 32         typedef std::ptrdiff_t difference_type;
 33 
 34         // iterator support
 35         iterator        begin()       { return elems; }
 36         const_iterator  begin() const { return elems; }
 37         const_iterator cbegin() const { return elems; }
 38 
 39         iterator        end()       { return elems + N; }
 40         const_iterator  end() const { return elems + N; }
 41         const_iterator cend() const { return elems + N; }
 42 
 43         // reverse iterator support
 44         typedef std::reverse_iterator<iterator> reverse_iterator;
 45         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 46 
 47         reverse_iterator rbegin() { return reverse_iterator(end()); }
 48         const_reverse_iterator rbegin() const
 49         {
 50             return const_reverse_iterator(end());
 51         }
 52         const_reverse_iterator crbegin() const 
 53         {
 54             return const_reverse_iterator(end());
 55         }
 56 
 57         reverse_iterator rend() { return reverse_iterator(begin()); }
 58         const_reverse_iterator rend() const 
 59         {
 60             return const_reverse_iterator(begin());
 61         }
 62         const_reverse_iterator crend() const 
 63         {
 64             return const_reverse_iterator(begin());
 65         }
 66 
 67         // operator[]
 68         reference operator[](size_type i)
 69         {
 70             //assert(i < N);
 71             return elems[i];
 72         }
 73 
 74         const_reference operator[](size_type i) const
 75         {
 76             //assert(i < N);
 77             return elems[i];
 78         }
 79 
 80         // at() with range check
 81         reference at(size_type i) { rangecheck(i); return elems[i]; }
 82         const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
 83 
 84         // front() and back()
 85         reference front()
 86         {
 87             return elems[0];
 88         }
 89 
 90         const_reference front() const
 91         {
 92             return elems[0];
 93         }
 94 
 95         reference back()
 96         {
 97             return elems[N - 1];
 98         }
 99 
100         const_reference back() const
101         {
102             return elems[N - 1];
103         }
104 
105         // size is constant
106         static size_type size() { return N; }
107         
108         static bool empty() { return false; }
109         static size_type max_size() { return N; }
110         enum { static_size = N };
111 
112         // swap (note: linear complexity)
113         void swap(array<T, N>& y)
114         {
115             for (size_type i = 0; i < N; ++i)
116                 boost::swap(elems[i], y.elems[i]);
117         }
118 
119         // direct access to data (read-only)
120         const T* data() const { return elems; }
121         T* data() { return elems; }
122 
123         // use array as C array (direct read/write access to data)
124         T* c_array() { return elems; }
125 
126         // assignment with type conversion
127         template <typename T2>
128         array<T, N>& operator= (const array<T2, N>& rhs)
129         {
130             std::copy(rhs.begin(), rhs.end(), begin());
131             return *this;
132         }
133 
134         // assign one value to all elements
135         void assign(const T& value) { fill(value); }    // A synonym for fill
136         void fill(const T& value)
137         {
138             std::fill_n(begin(), size(), value);
139         }
140 
141         // check range (may be private because it is static)
142         static void rangecheck(size_type i)
143         {
144             if (i >= size()) 
145             {
146                 std::out_of_range e("array<>: index out of range");
147                 boost::throw_exception(e);
148             }
149         }
150 
151     };//class array
152 
153     // comparisons
154     template<class T, std::size_t N>
155     bool operator== (const array<T, N>& x, const array<T, N>& y)
156     {
157         return std::equal(x.begin(), x.end(), y.begin());
158     }
159     template<class T, std::size_t N>
160     bool operator< (const array<T, N>& x, const array<T, N>& y)
161     {
162         return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
163     }
164     template<class T, std::size_t N>
165     bool operator!= (const array<T, N>& x, const array<T, N>& y)
166     {
167         return !(x == y);
168     }
169     template<class T, std::size_t N>
170     bool operator> (const array<T, N>& x, const array<T, N>& y) 
171     {
172         return y<x;
173     }
174     template<class T, std::size_t N>
175     bool operator<= (const array<T, N>& x, const array<T, N>& y)
176     {
177         return !(y<x);
178     }
179     template<class T, std::size_t N>
180     bool operator>= (const array<T, N>& x, const array<T, N>& y) 
181     {
182         return !(x<y);
183     }
184 
185     // global swap()
186     template<class T, std::size_t N>
187     inline void swap(array<T, N>& x, array<T, N>& y) 
188     {
189         x.swap(y);    //use from <algorithm>  
190     }
191 
192 } /* namespace boost */
193 
194 
195 /*
196 Test:
197 */
198 int main()
199 {
200     using namespace boost;
201     using namespace std;
202 
203     array<int, 10> a;
204     for (unsigned int i = 0; i < a.size(); ++i)
205     {
206         a[i] = i+1;
207     }    
208 
209     //1 2 3 4...10
210     for (int* pos = a.begin(); pos != a.end(); ++pos)
211         cout << *pos << ' ';
212     cout << endl;
213 
214     //10 9 8...1
215     reverse(a.begin(), a.end());
216     for (int* pos = a.begin(); pos != a.end(); ++pos)
217         cout << *pos << ' ';
218     cout << endl;
219 
220     //-10 -9 -8...-1
221     transform(a.begin(), a.end(),    //source
222         a.begin(),                    //destination
223         negate<int>());                //operation
224     for (int* pos = a.begin(); pos != a.end(); ++pos)
225         cout << *pos << ' ';
226     cout << endl;
227 
228     return 0;
229 }

 

posted @ 2015-04-12 20:22  ht-beyond  阅读(528)  评论(0编辑  收藏  举报