OSDN Git Service

append dependency to mayu-common.mak
[yamy/yamy.git] / array.h
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 // array.h
3
4
5 #ifndef _ARRAY_H
6 #  define _ARRAY_H
7
8 #  include <memory>
9
10
11 ///
12 template <class T, class Allocator = std::allocator<T> >
13 class Array
14 {
15 public:
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; ///
26 #if 0
27   typedef std::reverse_iterator<iterator>       reverse_iterator; ///
28   typedef std::reverse_iterator<const_iterator> const_reverse_iterator; ///
29 #endif    
30 private:
31   Allocator m_allocator;                        /// 
32   size_type m_size;                             /// 
33   pointer m_buf;                                /// array buffer
34
35 public:
36   /// constructor
37   explicit Array(const Allocator& i_allocator = Allocator())
38     : m_allocator(i_allocator), m_size(0), m_buf(NULL)  { }
39           
40   /// constructor
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))
45   {
46     std::uninitialized_fill_n(m_buf, i_size, i_value);
47   }
48           
49   /// constructor
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))
55   {
56     std::uninitialized_copy(i_begin, i_end, m_buf);
57   }
58           
59   /// copy constructor
60   Array(const Array& i_o) : m_size(0), m_buf(NULL) { operator=(i_o); }
61
62   /// destractor
63   ~Array() { clear(); }
64
65   ///
66   Array& operator=(const Array& i_o)
67   {
68     if (&i_o != this)
69     {
70       clear();
71       m_size = i_o.m_size;
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);
74     }
75     return *this;
76   }
77   ///
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; }
83   ///
84   iterator begin() { return m_buf; }
85   ///
86   const_iterator begin() const { return m_buf; }
87   ///
88   iterator end() { return m_buf + m_size; }
89   ///
90   const_iterator end() const { return m_buf + m_size; }
91 #if 0
92   ///
93   reverse_iterator rbegin() { reverse_iterator(end()); }
94   ///
95   const_reverse_iterator rbegin() const { const_reverse_iterator(end()); }
96   ///
97   reverse_iterator rend() { reverse_iterator(begin()); }
98   ///
99   const_reverse_iterator rend() const { const_reverse_iterator(begin()); }
100 #endif
101   ///
102   size_type size() const { return m_size; }
103   ///
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())
107   {
108     clear();
109     m_size = i_size;
110     m_buf = m_allocator.allocate(m_size, 0);
111     std::uninitialized_fill_n(m_buf, i_size, i_value);
112   }
113   /// resize the array buffer.  
114   template <class InputIterator>
115   void resize(InputIterator i_begin, InputIterator i_end)
116   {
117     clear();
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);
121   }
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())
124   {
125     ASSERT( m_size <= i_size );
126     if (!m_buf)
127       resize(i_size, i_value);
128     else
129     {
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);
133       clear();
134       m_size = i_size;
135       m_buf = buf;
136     }
137   }
138   ///
139   bool empty() const { return !m_buf; }
140   ///
141   reference operator[](size_type i_n) { return *(m_buf + i_n); }
142   ///
143   const_reference operator[](size_type i_n) const
144   { return *(m_buf + i_n); }
145   ///
146   const_reference at(size_type i_n) const
147   { return *(m_buf + i_n); }
148   ///
149   reference at(size_type i_n)
150   { return *(m_buf + i_n); }
151   ///
152   reference front() { return *m_buf; }
153   ///
154   const_reference front() const { return *m_buf; }
155   ///
156   reference back() { return *(m_buf + m_size - 1); }
157   ///
158   const_reference back() const { return *(m_buf + m_size - 1); }
159   ///
160   void swap(Array &i_o)
161   {
162     if (&i_o != this)
163     {
164       pointer buf = m_buf;
165       size_type size = m_size;
166       m_buf = i_o.m_buf;
167       m_size = i_o.m_size;
168       i_o.m_buf = buf;
169       i_o.m_size = size;
170     }
171   }
172   ///
173   void clear()
174   {
175     if (m_buf)
176     {
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);
180       m_buf = 0;
181       m_size = 0;
182     }
183   }
184 };
185
186 #endif // _ARRAY_H