1 // templated sized array class
2 // Copyright (C) 2009 Tim Blechmann
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef UTILITIES_SIZED_ARRAY_HPP
20 #define UTILITIES_SIZED_ARRAY_HPP
23 #include <memory> /* std::allocator */
24 #include <type_traits>
26 #include <boost/mpl/if.hpp>
30 /** dynamically sized array
32 * array class, inspired by boost.array, where the size is specified
33 * during the time of the construction.
34 * in contrary to std::vector, it is guaranteed to use continuous
35 * memory. the memory is allocated in the constructor an freed in the
36 * destructor, these are the only places, where the allocator
37 * functions are called.
41 class Alloc
= std::allocator
<T
> >
43 private Alloc::template rebind
<T
>::other
45 typedef typename
Alloc::template rebind
<T
>::other Allocator
;
51 typedef const T
* const_iterator
;
52 typedef std::reverse_iterator
<iterator
> reverse_iterator
;
53 typedef std::reverse_iterator
<const_iterator
> const_reverse_iterator
;
55 typedef const T
& const_reference
;
56 typedef std::size_t size_type
;
57 typedef std::ptrdiff_t difference_type
;
59 // construct/copy/destruct
60 explicit sized_array(size_type size
= 0, T
const & def
= T()):
61 data_( size
? Allocator::allocate(size
) : 0), size_(size
)
63 for (size_type i
= 0; i
!= size
; ++i
)
64 Allocator::construct(data_
+ i
, def
);
67 sized_array(sized_array
& arg
) = delete;
68 sized_array
& operator=(sized_array
& arg
) = delete;
71 template <typename int_type
>
72 void init_from_int(int_type size
)
74 data_
= Allocator::allocate(size
);
76 for (size_type i
= 0; i
!= size_
; ++i
)
77 Alloc::construct(data_
+ i
, T());
80 template <typename Container
>
81 void init_from_container(Container
const & container
)
83 data_
= Allocator::allocate(container
.size());
84 size_
= container
.size();
87 typedef typename
Container::const_iterator iterator
;
88 for (iterator it
= container
.begin(); it
!= container
.end(); ++it
)
89 Allocator::construct(data_
+ index
++, *it
);
90 assert(index
== size());
95 template <typename int_type
>
96 static void init(sized_array
& array
, int_type
const & i
)
98 array
.init_from_int
<int_type
>(i
);
102 struct call_container_ctor
104 template <typename Container
>
105 static void init(sized_array
& array
, Container
const & c
)
107 array
.init_from_container
<Container
>(c
);
112 template<typename Constructor_arg
>
113 explicit sized_array(Constructor_arg
const & arg
)
115 typedef typename
boost::mpl::if_
<std::is_integral
<Constructor_arg
>,
117 call_container_ctor
>::type ctor
;
118 ctor::init(*this, arg
);
121 explicit sized_array(sized_array
&& arg
)
129 /** move assignment */
130 sized_array
& operator=(sized_array
&& arg
)
141 for (size_type i
= 0; i
!= size(); ++i
)
142 Allocator::destroy(data_
+ i
);
144 Allocator::deallocate(data_
, size());
153 const_iterator
begin() const
160 return data_
+ size();
163 const_iterator
end() const
165 return data_
+ size();
168 // reverse iterator support
169 reverse_iterator
rbegin()
171 return reverse_iterator(data_
+ size());
174 const_reverse_iterator
rbegin() const
176 return const_reverse_iterator(data_
+ size());
179 reverse_iterator
rend()
181 return reverse_iterator(data_
);
184 const_reverse_iterator
rend() const
186 return const_reverse_iterator(data_
);
190 size_type
size() const
200 size_type
max_size() const
206 reference
operator[](size_type i
)
211 const_reference
operator[](size_type i
) const
216 reference
at(size_type i
)
221 const_reference
at(size_type i
) const
231 const_reference
front() const
238 return data_
[size_
- 1];
241 const_reference
back() const
243 return data_
[size_
- 1];
246 const T
* data() const
257 void assign(const T
& t
)
259 for (size_type i
= 0; i
!= size_
; ++i
)
263 void resize(size_type new_size
, T
const & t
= T())
265 T
* new_data
= Allocator::allocate(new_size
);
267 for (size_type i
= 0; i
!= new_size
; ++i
)
268 Allocator::construct(new_data
+i
, t
);
270 std::copy(data_
, data_
+std::min(new_size
, size_
), new_data
);
272 T
* old_data
= data_
;
274 for (size_type i
= 0; i
!= size_
; ++i
)
275 Allocator::destroy(old_data
+i
);
277 Allocator::deallocate(old_data
, size_
);
286 } /* namespace nova */
288 #endif /* UTILITIES_SIZED_ARRAY_HPP */