1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
12 template <class T, class Allocator = std::allocator<T> >
\r
16 typedef typename Allocator::reference reference; ///
\r
17 typedef typename Allocator::const_reference const_reference; ///
\r
18 typedef typename Allocator::pointer iterator; ///
\r
19 typedef typename Allocator::const_pointer const_iterator; ///
\r
20 typedef typename Allocator::size_type size_type; ///
\r
21 typedef typename Allocator::difference_type difference_type; ///
\r
22 typedef T value_type; ///
\r
23 typedef Allocator allocator_type; ///
\r
24 typedef typename Allocator::pointer pointer; ///
\r
25 typedef typename Allocator::const_pointer const_pointer; ///
\r
27 typedef std::reverse_iterator<iterator> reverse_iterator; ///
\r
28 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; ///
\r
31 Allocator m_allocator; ///
\r
32 size_type m_size; ///
\r
33 pointer m_buf; /// array buffer
\r
37 explicit Array(const Allocator& i_allocator = Allocator())
\r
38 : m_allocator(i_allocator), m_size(0), m_buf(NULL) { }
\r
41 explicit Array(size_type i_size, const T& i_value = T(),
\r
42 const Allocator& i_allocator = Allocator())
\r
43 : m_allocator(i_allocator), m_size(i_size),
\r
44 m_buf(m_allocator.allocate(m_size, 0))
\r
46 std::uninitialized_fill_n(m_buf, i_size, i_value);
\r
50 template <class InputIterator>
\r
51 Array(InputIterator i_begin, InputIterator i_end,
\r
52 const Allocator& i_allocator = Allocator())
\r
53 : m_allocator(i_allocator), m_size(distance(i_begin, i_end)),
\r
54 m_buf(Allocator::allocate(m_size, 0))
\r
56 std::uninitialized_copy(i_begin, i_end, m_buf);
\r
59 /// copy constructor
\r
60 Array(const Array& i_o) : m_size(0), m_buf(NULL) { operator=(i_o); }
\r
63 ~Array() { clear(); }
\r
66 Array& operator=(const Array& i_o)
\r
71 m_size = i_o.m_size;
\r
72 m_buf = m_allocator.allocate(m_size, 0);
\r
73 std::uninitialized_copy(i_o.m_buf, i_o.m_buf + m_size, m_buf);
\r
78 allocator_type get_allocator() const { return Allocator(); }
\r
79 /// return pointer to the array buffer
\r
80 typename allocator_type::pointer get() { return m_buf; }
\r
81 /// return pointer to the array buffer
\r
82 typename allocator_type::const_pointer get() const { return m_buf; }
\r
84 iterator begin() { return m_buf; }
\r
86 const_iterator begin() const { return m_buf; }
\r
88 iterator end() { return m_buf + m_size; }
\r
90 const_iterator end() const { return m_buf + m_size; }
\r
93 reverse_iterator rbegin() { reverse_iterator(end()); }
\r
95 const_reverse_iterator rbegin() const { const_reverse_iterator(end()); }
\r
97 reverse_iterator rend() { reverse_iterator(begin()); }
\r
99 const_reverse_iterator rend() const { const_reverse_iterator(begin()); }
\r
102 size_type size() const { return m_size; }
\r
104 size_type max_size() const { return -1; }
\r
105 /// resize the array buffer. NOTE: the original contents are cleared.
\r
106 void resize(size_type i_size, const T& i_value = T())
\r
110 m_buf = m_allocator.allocate(m_size, 0);
\r
111 std::uninitialized_fill_n(m_buf, i_size, i_value);
\r
113 /// resize the array buffer.
\r
114 template <class InputIterator>
\r
115 void resize(InputIterator i_begin, InputIterator i_end)
\r
118 m_size = distance(i_begin, i_end);
\r
119 m_buf = m_allocator.allocate(m_size, 0);
\r
120 std::uninitialized_copy(i_begin, i_end, m_buf);
\r
122 /// expand the array buffer. the contents of it are copied to the new one
\r
123 void expand(size_type i_size, const T& i_value = T())
\r
125 ASSERT( m_size <= i_size );
\r
127 resize(i_size, i_value);
\r
130 pointer buf = m_allocator.allocate(i_size, 0);
\r
131 std::uninitialized_copy(m_buf, m_buf + m_size, buf);
\r
132 std::uninitialized_fill_n(buf + m_size, i_size - m_size, i_value);
\r
139 bool empty() const { return !m_buf; }
\r
141 reference operator[](size_type i_n) { return *(m_buf + i_n); }
\r
143 const_reference operator[](size_type i_n) const
\r
144 { return *(m_buf + i_n); }
\r
146 const_reference at(size_type i_n) const
\r
147 { return *(m_buf + i_n); }
\r
149 reference at(size_type i_n)
\r
150 { return *(m_buf + i_n); }
\r
152 reference front() { return *m_buf; }
\r
154 const_reference front() const { return *m_buf; }
\r
156 reference back() { return *(m_buf + m_size - 1); }
\r
158 const_reference back() const { return *(m_buf + m_size - 1); }
\r
160 void swap(Array &i_o)
\r
164 pointer buf = m_buf;
\r
165 size_type size = m_size;
\r
167 m_size = i_o.m_size;
\r
177 for (size_type i = 0; i < m_size; i ++)
\r
178 m_allocator.destroy(&m_buf[i]);
\r
179 m_allocator.deallocate(m_buf, m_size);
\r