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 }