Empirical
vector.h
Go to the documentation of this file.
1 
18 #ifndef EMP_VECTOR_H
19 #define EMP_VECTOR_H
20 
21 #include <initializer_list>
22 #include <iterator>
23 #include <utility>
24 #include <vector>
25 
26 #include "assert.h"
27 
28 #ifdef EMP_NDEBUG
29 
30 // Seemlessly translate emp::vector to std::vector
31 namespace emp {
32  template <typename... Ts> using vector = std::vector<Ts...>;
33 }
34 
35 
36 #else // #EMP_NDEBUG *not* set
37 
38 namespace emp {
39 
41  template <typename T, typename... Ts>
42  class vector : public std::vector<T,Ts...> {
43  private:
44  using this_t = emp::vector<T,Ts...>;
45  using stdv_t = std::vector<T,Ts...>;
46 
48  constexpr static const size_t MAX_SIZE = 2000000001; // 2x10^9 + 1
49 
50  public:
52  int revision;
53 
55  template<typename ITERATOR_T>
56  struct iterator_wrapper : public ITERATOR_T {
58  using wrapped_t = ITERATOR_T;
59  using vec_t = emp::vector<T,Ts...>;
60 
62  const vec_t * v_ptr;
63  int revision;
64 
65  // @CAO: For the moment cannot create an emp iterator from a base since we don't know vector to use.
66  // iterator_wrapper(const ITERATOR_T & _in)
67  // : ITERATOR_T(_in), v_ptr(nullptr), revision(0) { ; }
68  iterator_wrapper(const ITERATOR_T & _in, const vec_t * _v)
69  : ITERATOR_T(_in), v_ptr(_v), revision(_v->revision) { ; }
70  iterator_wrapper(const this_t &) = default;
71  iterator_wrapper(this_t &&) = default;
73 
74  // Debug tools to make sure this iterator is okay.
75  bool OK(bool begin_ok=true, bool end_ok=true) const {
76  if (v_ptr == nullptr) return false; // Invalid vector
77  if (v_ptr->revision == 0) return false; // Vector has been deleted!
78  if (revision != v_ptr->revision) return false; // Vector has changed memory!
79  size_t pos = (size_t) (*this - v_ptr->begin());
80  if (pos > v_ptr->size()) return false; // Iterator out of range.
81  if (!begin_ok && pos == 0) return false; // Iterator not allowed at beginning.
82  if (!end_ok && pos == v_ptr->size()) return false; // Iterator not allowed at end.
83  return true;
84  }
85 
86  this_t & operator=(const this_t &) = default;
87  this_t & operator=(this_t &&) = default;
88 
89  operator ITERATOR_T() { return *this; }
90  operator const ITERATOR_T() const { return *this; }
91 
92  auto & operator*() {
93  emp_assert(OK(true, false)); // Ensure vector hasn't changed since making iterator.
94  return wrapped_t::operator*();
95  }
96  const auto & operator*() const {
97  emp_assert(OK(true, false)); // Ensure vector hasn't changed since making iterator.
98  return wrapped_t::operator*();
99  }
100 
101  auto operator->() {
102  emp_assert(OK(true, false)); // Ensure vector hasn't changed since making iterator.
103  return wrapped_t::operator->();
104  }
105  const auto operator->() const {
106  emp_assert(OK(true, false)); // Ensure vector hasn't changed since making iterator.
107  return wrapped_t::operator->();
108  }
109 
110  this_t & operator++() { emp_assert(OK(true,false)); wrapped_t::operator++(); return *this; }
111  this_t operator++(int x) { emp_assert(OK(true,false)); return this_t(wrapped_t::operator++(x), v_ptr); }
112  this_t & operator--() { emp_assert(OK(false,true)); wrapped_t::operator--(); return *this; }
113  this_t operator--(int x) { emp_assert(OK(false,true)); return this_t(wrapped_t::operator--(x), v_ptr); }
114 
115  auto operator+(int in) { emp_assert(OK()); return this_t(wrapped_t::operator+(in), v_ptr); }
116  auto operator-(int in) { emp_assert(OK()); return this_t(wrapped_t::operator-(in), v_ptr); }
117  auto operator-(const this_t & in) { emp_assert(OK()); return ((wrapped_t) *this) - (wrapped_t) in; }
118 
119  this_t & operator+=(int in) { emp_assert(OK()); wrapped_t::operator+=(in); return *this; }
120  this_t & operator-=(int in) { emp_assert(OK()); wrapped_t::operator-=(in); return *this; }
121  auto & operator[](int offset) { emp_assert(OK()); return wrapped_t::operator[](offset); }
122 
123  //bool operator==(const wrapped_t & in) const { emp_assert(OK()); return wrapped_t::operator==(in); }
124  //bool operator!=(const wrapped_t & in) const { emp_assert(OK()); return wrapped_t::operator!=(in); }
125 
126  //bool operator< (const wrapped_t & in) const { emp_assert(OK()); return wrapped_t::operator< (in); }
127  //bool operator<=(const wrapped_t & in) const { emp_assert(OK()); return wrapped_t::operator<=(in); }
128  //bool operator> (const wrapped_t & in) const { emp_assert(OK()); return wrapped_t::operator> (in); }
129  //bool operator>=(const wrapped_t & in) const { emp_assert(OK()); return wrapped_t::operator>=(in); }
130  };
131 
132  using iterator = iterator_wrapper< typename stdv_t::iterator >;
133  using const_iterator = iterator_wrapper< typename stdv_t::const_iterator >;
134  using reverse_iterator = iterator_wrapper< typename stdv_t::reverse_iterator >;
135  using const_reverse_iterator = iterator_wrapper< typename stdv_t::const_reverse_iterator >;
136  using value_type = T;
137  using size_type = typename stdv_t::size_type;
138  using reference = typename stdv_t::reference;
139  using const_reference = typename stdv_t::const_reference;
140 
141  vector() : stdv_t(), revision(1) {};
142  vector(const this_t & _in) : stdv_t(_in), revision(1) {};
143  vector(size_t size) : stdv_t(size), revision(1) { emp_assert(size < MAX_SIZE, size); }
144  vector(size_t size, const T & val) : stdv_t(size, val), revision(1) { emp_assert(size < MAX_SIZE, size); }
145  vector(std::initializer_list<T> in_list) : stdv_t(in_list), revision(1) { ; }
146  vector(const stdv_t & in) : stdv_t(in), revision(1) { ; } // Emergency fallback conversion.
147  template <typename InputIt>
148  vector(InputIt first, InputIt last) : stdv_t(first, last), revision(1) { ; }
149  ~vector() { revision = 0; } // Clear out revision when vector is deleted.
150 
151  size_t size() const { return stdv_t::size(); }
152 
153  iterator begin() noexcept { return iterator(stdv_t::begin(), this); }
154  const_iterator begin() const noexcept { return const_iterator(stdv_t::begin(), this); }
155  iterator end() noexcept { return iterator(stdv_t::end(), this); }
156  const_iterator end() const noexcept { return const_iterator(stdv_t::end(), this); }
157 
158  // operator stdv_t &() { return v; }
159  // operator const stdv_t &() const { return v; }
160 
161  void resize(size_t new_size) {
162  emp_assert(new_size < MAX_SIZE, new_size);
163  stdv_t::resize(new_size);
164  revision++;
165  }
166  void resize(size_t new_size, const T & val) {
167  emp_assert(new_size < MAX_SIZE, new_size);
168  stdv_t::resize(new_size, val);
169  revision++;
170  }
171  this_t & operator=(const this_t &) = default;
172 
173  T & operator[](size_t pos) {
174  emp_assert(pos < stdv_t::size(), pos, stdv_t::size());
175  return stdv_t::operator[](pos);
176  }
177 
178  const T & operator[](size_t pos) const {
179  emp_assert(pos < stdv_t::size(), pos, stdv_t::size());
180  return stdv_t::operator[](pos);
181  }
182 
183  T & back() { emp_assert(stdv_t::size() > 0); return stdv_t::back(); }
184  const T & back() const { emp_assert(stdv_t::size() > 0); return stdv_t::back(); }
185  T & front() { emp_assert(stdv_t::size() > 0); return stdv_t::front(); }
186  const T & front() const { emp_assert(stdv_t::size() > 0); return stdv_t::front(); }
187 
188  template <typename... PB_Ts>
189  void push_back(PB_Ts &&... args) {
190  stdv_t::push_back(std::forward<PB_Ts>(args)...);
191  revision++;
192  }
193 
194  void pop_back() {
195  emp_assert(stdv_t::size() > 0, stdv_t::size());
196  stdv_t::pop_back();
197  revision++; // Technically reducing size can cause memory reallocation, but less likely.
198  }
199 
200  template <typename... ARGS>
201  iterator insert(ARGS &&... args) {
202  ++revision;
203  return iterator( stdv_t::insert(std::forward<ARGS>(args)...), this );
204  }
205 
206  template <typename... ARGS>
207  iterator erase(ARGS &&... args) {
208  ++revision;
209  return iterator( stdv_t::erase(std::forward<ARGS>(args)...), this );
210  }
211 
212  template <typename... ARGS>
213  iterator emplace(ARGS &&... args) {
214  ++revision;
215  return iterator( stdv_t::emplace(std::forward<ARGS>(args)...), this );
216  }
217 
218  template <typename... ARGS>
219  void emplace_back(ARGS &&... args) {
220  stdv_t::emplace_back(std::forward<ARGS>(args)...);
221  revision++;
222  }
223  };
224 
226  template <typename... Ts>
227  class vector<bool, Ts...> : public std::vector<bool,Ts...> {
228  private:
229  using this_t = emp::vector<bool,Ts...>;
230  using stdv_t = std::vector<bool,Ts...>;
231 
233  constexpr static const size_t MAX_SIZE = 2000000001;
234 
235  public:
236  using iterator = typename stdv_t::iterator;
237  using const_iterator = typename stdv_t::const_iterator;
238  using value_type = bool;
239  using size_type = typename stdv_t::size_type;
240  using reference = typename stdv_t::reference;
241  using const_reference = typename stdv_t::const_reference;
242 
243  vector() : stdv_t() {};
244  vector(const this_t & _in) : stdv_t(_in) {};
245  vector(size_t size) : stdv_t(size) { emp_assert(size < MAX_SIZE, size); }
246  vector(size_t size, bool val) : stdv_t(size, val) { emp_assert(size < MAX_SIZE, size); }
247  vector(std::initializer_list<bool> in_list) : stdv_t(in_list) { ; }
248  vector(const stdv_t & in) : stdv_t(in) { ; } // Emergency fallback conversion.
249  template <typename InputIt>
250  vector(InputIt first, InputIt last) : stdv_t(first, last){;}
251 
252 
253  // operator stdv_t &() { return v; }
254  // operator const stdv_t &() const { return v; }
255 
256  void resize(size_t new_size) { emp_assert(new_size < MAX_SIZE, new_size); stdv_t::resize(new_size); }
257  void resize(size_t new_size, bool val) {
258  emp_assert(new_size < MAX_SIZE, new_size);
259  stdv_t::resize(new_size, val);
260  }
261  this_t & operator=(const this_t &) = default;
262 
263  auto operator[](size_t pos) -> decltype(stdv_t::operator[](pos)) {
264  emp_assert(pos < stdv_t::size(), pos, stdv_t::size());
265  return stdv_t::operator[](pos);
266  }
267 
268  bool operator[](size_t pos) const {
269  emp_assert(pos < stdv_t::size(), pos, stdv_t::size());
270  return stdv_t::operator[](pos);
271  }
272 
273  auto & back() { emp_assert(stdv_t::size() > 0); return stdv_t::back(); }
274  bool back() const { emp_assert(stdv_t::size() > 0); return stdv_t::back(); }
275  auto & front() { emp_assert(stdv_t::size() > 0); return stdv_t::front(); }
276  bool front() const { emp_assert(stdv_t::size() > 0); return stdv_t::front(); }
277 
278  void pop_back() {
279  emp_assert(stdv_t::size() > 0, stdv_t::size());
280  stdv_t::pop_back();
281  }
282  };
283 
284 }
285 
286 // A crude, generic printing function for vectors.
287 template <typename T, typename... Ts>
288 std::ostream & operator<<(std::ostream & out, const emp::vector<T,Ts...> & v) {
289  for (const T & x : v) out << x << " ";
290  return out;
291 }
292 
293 template <typename T, typename... Ts>
294 std::istream & operator>>(std::istream & is, emp::vector<T,Ts...> & v) {
295  for (T & x : v) is >> x;
296  return is;
297 }
298 
299 #endif
300 
301 // namespace emp {
302 // template<typename T, typename... Ts> struct TypeID< emp::vector<T,Ts...> > {
303 // static std::string GetName() {
304 // using simple_vt = emp::vector<T>;
305 // using full_vt = emp::vector<T,Ts...>;
306 // if (std::is_same<simple_vt,full_vt>::value) {
307 // return "emp::vector<" + TypeID<T>::GetName() + ">";
308 // }
309 // return "emp::vector<" + TypeID<TypePack<T,Ts...>>::GetTypes() + ">";
310 // }
311 // };
312 // }
313 
314 #endif
Build a specialized debug wrapper for emp::vector<bool>
Definition: vector.h:227
vector()
Definition: vector.h:243
iterator insert(ARGS &&...args)
Definition: vector.h:201
ITERATOR_T wrapped_t
Definition: vector.h:58
vector(std::initializer_list< bool > in_list)
Definition: vector.h:247
int revision
Definition: vector.h:63
auto operator-(const this_t &in)
Definition: vector.h:117
State value_type
Definition: vector.h:136
void resize(size_t new_size, bool val)
Definition: vector.h:257
const_iterator end() const noexcept
Definition: vector.h:156
iterator end() noexcept
Definition: vector.h:155
typename stdv_t::reference reference
Definition: vector.h:138
vector(InputIt first, InputIt last)
Definition: vector.h:250
bool front() const
Definition: vector.h:276
void resize(size_t new_size)
Definition: vector.h:256
iterator_wrapper(const ITERATOR_T &_in, const vec_t *_v)
Definition: vector.h:68
vector(size_t size, bool val)
Definition: vector.h:246
vector()
Definition: vector.h:141
auto & operator*()
Definition: vector.h:92
auto & back()
Definition: vector.h:273
~vector()
Definition: vector.h:149
~iterator_wrapper()
Definition: vector.h:72
std::istream & operator>>(std::istream &is, emp::Ptr< T > &ptr)
Definition: Ptr.h:808
bool operator[](size_t pos) const
Definition: vector.h:268
typename stdv_t::iterator iterator
Definition: vector.h:236
iterator emplace(ARGS &&...args)
Definition: vector.h:213
vector(size_t size)
Definition: vector.h:245
void push_back(PB_Ts &&...args)
Definition: vector.h:189
const T & back() const
Definition: vector.h:184
vector(const stdv_t &in)
Definition: vector.h:146
iterator_wrapper< ITERATOR_T > this_t
Definition: vector.h:57
const auto & operator*() const
Definition: vector.h:96
void resize(size_t new_size, const T &val)
Definition: vector.h:166
size_t size() const
Definition: vector.h:151
void emplace_back(ARGS &&...args)
Definition: vector.h:219
A more dynamic replacement for standard library asserts.
const vec_t * v_ptr
What vector and revision was this iterator created from?
Definition: vector.h:62
const T & operator[](size_t pos) const
Definition: vector.h:178
const_iterator begin() const noexcept
Definition: vector.h:154
bool OK(bool begin_ok=true, bool end_ok=true) const
Definition: vector.h:75
this_t & operator++()
Definition: vector.h:110
std::ostream & operator<<(std::ostream &out, const emp::Ptr< T > &ptr)
Definition: Ptr.h:800
auto operator+(int in)
Definition: vector.h:115
void pop_back()
Definition: vector.h:278
const T & front() const
Definition: vector.h:186
auto operator->()
Definition: vector.h:101
auto & front()
Definition: vector.h:275
void pop_back()
Definition: vector.h:194
auto operator[](size_t pos) -> decltype(stdv_t::operator[](pos))
Definition: vector.h:263
typename stdv_t::const_reference const_reference
Definition: vector.h:139
this_t & operator-=(int in)
Definition: vector.h:120
iterator_wrapper< typename stdv_t::iterator > iterator
Definition: vector.h:132
typename stdv_t::size_type size_type
Definition: vector.h:239
iterator_wrapper< typename stdv_t::const_reverse_iterator > const_reverse_iterator
Definition: vector.h:135
typename stdv_t::size_type size_type
Definition: vector.h:137
void insert(std::set< T > &s1, const std::set< T > &s2)
Insert the full contents of s2 into s1.
Definition: set_utils.h:24
Setup an iterator wrapper to make sure that they&#39;re not used again after a vector changes...
Definition: vector.h:56
void resize(size_t new_size)
Definition: vector.h:161
vector(size_t size, const T &val)
Definition: vector.h:144
iterator begin() noexcept
Definition: vector.h:153
vector(const this_t &_in)
Definition: vector.h:142
vector(std::initializer_list< T > in_list)
Definition: vector.h:145
this_t & operator--()
Definition: vector.h:112
If we are in emscripten, make sure to include the header.
Definition: array.h:37
typename stdv_t::reference reference
Definition: vector.h:240
bool value_type
Definition: vector.h:238
Build a debug wrapper emp::vector around std::vector.
Definition: vector.h:42
vector(InputIt first, InputIt last)
Definition: vector.h:148
int revision
Setup a revision number - iterators must match the revision of their vector.
Definition: vector.h:52
#define emp_assert(...)
Definition: assert.h:199
this_t & operator+=(int in)
Definition: vector.h:119
T & back()
Definition: vector.h:183
iterator_wrapper< typename stdv_t::const_iterator > const_iterator
Definition: vector.h:133
T & front()
Definition: vector.h:185
auto operator-(int in)
Definition: vector.h:116
typename stdv_t::const_reference const_reference
Definition: vector.h:241
T & operator[](size_t pos)
Definition: vector.h:173
iterator erase(ARGS &&...args)
Definition: vector.h:207
this_t operator--(int x)
Definition: vector.h:113
bool back() const
Definition: vector.h:274
vector(const this_t &_in)
Definition: vector.h:244
const auto operator->() const
Definition: vector.h:105
iterator_wrapper< typename stdv_t::reverse_iterator > reverse_iterator
Definition: vector.h:134
typename stdv_t::const_iterator const_iterator
Definition: vector.h:237
vector(size_t size)
Definition: vector.h:143
this_t operator++(int x)
Definition: vector.h:111
this_t & operator=(const this_t &)=default
vector(const stdv_t &in)
Definition: vector.h:248
auto & operator[](int offset)
Definition: vector.h:121