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