Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
simple_vector.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * tlx/container/simple_vector.hpp
3  *
4  * Copied and modified from STXXL, see http://stxxl.org
5  *
6  * Part of tlx - http://panthema.net/tlx
7  *
8  * Copyright (C) 2002 Roman Dementiev <[email protected]>
9  * Copyright (C) 2008, 2011 Andreas Beckmann <[email protected]>
10  * Copyright (C) 2013-2017 Timo Bingmann <[email protected]>
11  *
12  * All rights reserved. Published under the Boost Software License, Version 1.0
13  ******************************************************************************/
14 
15 #ifndef TLX_CONTAINER_SIMPLE_VECTOR_HEADER
16 #define TLX_CONTAINER_SIMPLE_VECTOR_HEADER
17 
18 #include <algorithm>
19 #include <cstdlib>
20 #include <utility>
21 
22 namespace tlx {
23 
24 //! \addtogroup tlx_container
25 //! \{
26 
27 //! enum class to select SimpleVector object initialization
28 enum class SimpleVectorMode {
29  //! Initialize objects at allocation and destroy on deallocation
30  Normal,
31  //! Do not initialize objects at allocation, but destroy on
32  //! deallocation. Thus, all objects must be constructed from outside.
34  //! Do not initialize objects at allocation and do not destroy them.
36 };
37 
38 /*!
39  * Simpler non-growing vector without initialization.
40  *
41  * SimpleVector can be used a replacement for std::vector when only a
42  * non-growing array of simple types is needed. The advantages of SimpleVector
43  * are that it does not initilize memory for POD types (-> faster), while normal
44  * structs are supported as well if default-contractible. The simple pointer
45  * types allow faster compilation and is less error prone to copying and other
46  * problems.
47  */
48 template <typename ValueType,
51 {
52 public:
53  using value_type = ValueType;
54  using size_type = size_t;
55 
56 protected:
57  //! size of allocated memory
59 
60  //! pointer to allocated memory area
62 
63 public:
64  // *** simple pointer iterators
65 
66  using iterator = value_type *;
67  using const_iterator = const value_type *;
68  using reference = value_type &;
69  using const_reference = const value_type &;
70 
71 public:
72  //! allocate empty simple vector
74  : size_(0), array_(nullptr)
75  { }
76 
77  //! allocate vector's memory
78  explicit SimpleVector(const size_type& sz)
79  : size_(sz), array_(nullptr) {
80  if (size_ > 0)
82  }
83 
84  //! non-copyable: delete copy-constructor
85  SimpleVector(const SimpleVector&) = delete;
86  //! non-copyable: delete assignment operator
87  SimpleVector& operator = (const SimpleVector&) = delete;
88 
89  //! move-constructor
90  SimpleVector(SimpleVector&& v) noexcept
91  : size_(v.size_), array_(v.array_)
92  { v.size_ = 0, v.array_ = nullptr; }
93 
94  //! move-assignment
96  if (&v == this) return *this;
98  size_ = v.size_, array_ = v.array_;
99  v.size_ = 0, v.array_ = nullptr;
100  return *this;
101  }
102 
103  //! swap vector with another one
104  void swap(SimpleVector& obj) noexcept {
105  std::swap(size_, obj.size_);
106  std::swap(array_, obj.array_);
107  }
108 
109  //! delete vector
112  }
113 
114  //! return iterator to beginning of vector
115  iterator data() noexcept {
116  return array_;
117  }
118  //! return iterator to beginning of vector
119  const_iterator data() const noexcept {
120  return array_;
121  }
122  //! return number of items in vector
123  size_type size() const noexcept {
124  return size_;
125  }
126 
127  //! return mutable iterator to first element
128  iterator begin() noexcept {
129  return array_;
130  }
131  //! return constant iterator to first element
132  const_iterator begin() const noexcept {
133  return array_;
134  }
135  //! return constant iterator to first element
136  const_iterator cbegin() const noexcept {
137  return begin();
138  }
139 
140  //! return mutable iterator beyond last element
141  iterator end() noexcept {
142  return array_ + size_;
143  }
144  //! return constant iterator beyond last element
145  const_iterator end() const noexcept {
146  return array_ + size_;
147  }
148  //! return constant iterator beyond last element
149  const_iterator cend() const noexcept {
150  return end();
151  }
152 
153  //! return the i-th position of the vector
155  return *(begin() + i);
156  }
157  //! return constant reference to the i-th position of the vector
159  return *(begin() + i);
160  }
161 
162  //! resize the array to contain exactly new_size items
163  void resize(size_type new_size) {
164  if (array_) {
165  value_type* tmp = array_;
166  array_ = create_array(new_size);
167  std::move(tmp, tmp + std::min(size_, new_size), array_);
168  destroy_array(tmp, size_);
169  size_ = new_size;
170  }
171  else {
172  array_ = create_array(new_size);
173  size_ = new_size;
174  }
175  }
176 
177  //! Zero the whole array content.
178  void fill(const value_type& v = value_type()) noexcept {
179  std::fill(array_, array_ + size_, v);
180  }
181 
182 private:
183  static ValueType * create_array(size_t size) {
184  switch (Mode)
185  {
187  // with normal object construction
188  return new value_type[size];
191  // operator new allocates bytes
192  return static_cast<ValueType*>(
193  operator new (size * sizeof(ValueType)));
194  }
195  abort();
196  }
197 
198  static void destroy_array(ValueType* array, size_t size) {
199  switch (Mode)
200  {
202  // with normal object destruction
203  delete[] array;
204  return;
206  // destroy objects and deallocate memory
207  for (size_t i = 0; i < size; ++i)
208  array[i].~ValueType();
209  operator delete (array);
210  return;
212  // only deallocate memory
213  operator delete (array);
214  return;
215  }
216  abort();
217  }
218 };
219 
220 //! make template alias due to similarity with std::vector
221 template <typename T>
223 
224 //! \}
225 
226 } // namespace tlx
227 
228 #endif // !TLX_CONTAINER_SIMPLE_VECTOR_HEADER
229 
230 /******************************************************************************/
iterator end() noexcept
return mutable iterator beyond last element
Do not initialize objects at allocation and do not destroy them.
void resize(size_type new_size)
resize the array to contain exactly new_size items
SimpleVector(const size_type &sz)
allocate vector's memory
const_iterator begin() const noexcept
return constant iterator to first element
static void destroy_array(ValueType *array, size_t size)
Simpler non-growing vector without initialization.
const_iterator cbegin() const noexcept
return constant iterator to first element
Initialize objects at allocation and destroy on deallocation.
reference operator[](size_type i) noexcept
return the i-th position of the vector
iterator data() noexcept
return iterator to beginning of vector
const_iterator cend() const noexcept
return constant iterator beyond last element
void fill(const value_type &v=value_type()) noexcept
Zero the whole array content.
const_iterator data() const noexcept
return iterator to beginning of vector
void swap(SimpleVector &obj) noexcept
swap vector with another one
iterator begin() noexcept
return mutable iterator to first element
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
static ValueType * create_array(size_t size)
size_type size() const noexcept
return number of items in vector
const_iterator end() const noexcept
return constant iterator beyond last element
SimpleVector(SimpleVector &&v) noexcept
move-constructor
value_type * array_
pointer to allocated memory area
const value_type & const_reference
static uint_pair min()
return an uint_pair instance containing the smallest value possible
Definition: uint_types.hpp:217
~SimpleVector()
delete vector
SimpleVectorMode
enum class to select SimpleVector object initialization
SimpleVector & operator=(const SimpleVector &)=delete
non-copyable: delete assignment operator
size_type size_
size of allocated memory
SimpleVector()
allocate empty simple vector