raiigraph
C++ RAII for igraph data structures
Loading...
Searching...
No Matches
Vector.hpp
Go to the documentation of this file.
1#ifndef RAIIGRAPH_VECTOR_HPP
2#define RAIIGRAPH_VECTOR_HPP
3
4#include "igraph.h"
5#include "error.hpp"
6#include <algorithm>
7#include <initializer_list>
8#include <iterator>
9
15namespace raiigraph {
16
25template<class Ns_>
26class Vector {
27private:
28 void setup(igraph_integer_t size) {
29 if (Ns_::init(&my_vector, size)) {
30 throw std::runtime_error("failed to initialize igraph vector of size " + std::to_string(size));
31 }
32 }
33
34public:
38 typedef typename Ns_::igraph_type igraph_type;
39
43 typedef typename Ns_::value_type value_type;
44
49
54
59
64
69
73 typedef const value_type* const_iterator;
74
78 typedef std::reverse_iterator<iterator> reverse_iterator;
79
83 typedef std::reverse_iterator<const_iterator> reverse_const_iterator;
84
85public:
89 Vector() : Vector(0) {}
90
96 setup(size);
97 std::fill_n(begin(), size, val);
98 }
99
103 Vector(igraph_type&& vector) : my_vector(std::move(vector)) {}
104
110 template<typename InputIterator, typename = decltype(*std::declval<InputIterator>())> // use SFINAE to avoid ambiguity with other 2-argument constructors.
114
115public:
121 if (Ns_::copy(&my_vector, &(other.my_vector))) {
122 throw std::runtime_error("failed to copy-construct integer igraph vector");
123 }
124 }
125
131 if (this != &other) {
132 if (Ns_::update(&my_vector, &(other.my_vector))) { // my_vector should already be initialized before the assignment.
133 throw std::runtime_error("failed to copy-assign integer igraph vector");
134 }
135 }
136 return *this;
137 }
138
144 setup(0); // we must leave 'other' in a valid state.
145 std::swap(my_vector, other.my_vector);
146 }
147
153 if (this != &other) {
154 std::swap(my_vector, other.my_vector); // 'my_vector' should already be initialized, so we're leaving 'other' in a valid state.
155 }
156 return *this;
157 }
158
163 Ns_::destroy(&my_vector);
164 }
165
166public:
171 return Ns_::empty(&my_vector);
172 }
173
177 size_type size() const {
178 return Ns_::size(&my_vector);
179 }
180
184 constexpr size_type max_size() const { return IGRAPH_INTEGER_MAX; }
185
190 return my_vector.stor_end - my_vector.stor_begin;
191 }
192
196 void clear() {
197 Ns_::clear(&my_vector);
198 }
199
206 auto old_size = this->size();
207 check_code(Ns_::resize(&my_vector, size));
208 if (old_size < size) {
209 std::fill_n(begin() + old_size, size - old_size, val);
210 }
211 }
212
218 check_code(Ns_::reserve(&my_vector, capacity));
219 }
220
225 Ns_::shrink_to_fit(&my_vector);
226 }
227
233 check_code(Ns_::push_back(&my_vector, val));
234 }
235
240 template<typename ... Args>
241 void emplace_back(Args&& ... args) {
242 // Doesn't really matter for simple types.
243 push_back(value_type(std::forward<Args>(args)...));
244 }
245
249 void pop_back() {
250 Ns_::pop_back(&my_vector);
251 }
252
258 Ns_::remove(&my_vector, pos - begin());
259 return pos;
260 }
261
268 auto start = begin();
269 Ns_::remove_section(&my_vector, first - start, last - start);
270 return first;
271 }
272
280 auto delta = pos - begin();
281 check_code(Ns_::insert(&my_vector, delta, val));
282 return begin() + delta; // recompute it as there might be a reallocation.
283 }
284
291 template<typename ... Args>
293 // Doesn't really matter for simple types.
294 return insert(pos, value_type(std::forward<Args>(args)...));
295 }
296
305 auto delta = pos - begin();
306 auto old_size = size();
307 resize(old_size + n);
308
309 auto new_start = begin() + delta; // recompute it as there might be a reallocation.
310 std::copy(new_start, begin() + old_size, new_start + n);
311 std::fill_n(new_start, n, val);
312 return new_start;
313 }
314
325 auto delta = pos - begin();
326 auto old_size = size();
327 auto n = last - first;
328 resize(old_size + n);
329
330 auto new_start = begin() + delta; // recompute it as there might be a reallocation.
331 std::copy(new_start, begin() + old_size, new_start + n);
332 std::copy(first, last, new_start);
333 return new_start;
334 }
335
336public:
342 return *(begin() + i);
343 }
344
350 return *(begin() + i);
351 }
352
357 return *(end() - 1);
358 }
359
364 return *(end() - 1);
365 }
366
371 return *(begin());
372 }
373
378 return *(begin());
379 }
380
381public:
386 return my_vector.stor_begin;
387 }
388
393 return my_vector.end;
394 }
395
400 return cbegin();
401 }
402
407 return cend();
408 }
409
414 return my_vector.stor_begin;
415 }
416
421 return my_vector.end;
422 }
423
428 return my_vector.stor_begin;
429 }
430
434 const value_type* data() const {
435 return my_vector.stor_begin;
436 }
437
442 return std::reverse_iterator(end());
443 }
444
449 return std::reverse_iterator(begin());
450 }
451
456 return std::reverse_iterator(end());
457 }
458
463 return std::reverse_iterator(begin());
464 }
465
470 return std::reverse_iterator(cend());
471 }
472
477 return std::reverse_iterator(cbegin());
478 }
479
480public:
485 operator igraph_type*() {
486 return &my_vector;
487 }
488
493 operator const igraph_type*() const {
494 return &my_vector;
495 }
496
502 return &my_vector;
503 }
504
509 const igraph_type* get() const {
510 return &my_vector;
511 }
512
513public:
519 // Swapping structures entirely to ensure that iterators and pointers
520 // remain valid; looks like igraph_vector_swap does the same.
521 std::swap(my_vector, other.my_vector);
522 }
523
524private:
525 igraph_type my_vector;
526};
527
531namespace internal {
532
533struct Integer {
534 typedef igraph_integer_t value_type;
535 typedef igraph_vector_int_t igraph_type;
536
537#define RAIIGRAPH_VECTOR_SUFFIX _int
538#include "fragments/vector.hpp"
539#undef RAIIGRAPH_VECTOR_SUFFIX
540};
541
542struct Real {
543 typedef igraph_real_t value_type;
544 typedef igraph_vector_t igraph_type;
545
546#define RAIIGRAPH_VECTOR_SUFFIX
547#include "fragments/vector.hpp"
548#undef RAIIGRAPH_VECTOR_SUFFIX
549};
550
551struct Bool {
552 typedef igraph_bool_t value_type;
553 typedef igraph_vector_bool_t igraph_type;
554
555#define RAIIGRAPH_VECTOR_SUFFIX _bool
556#include "fragments/vector.hpp"
557#undef RAIIGRAPH_VECTOR_SUFFIX
558};
559
560}
569
573// For back-compatibility.
574typedef IntVector IntegerVector;
583
588
589}
590
591
592#endif
Wrapper around igraph_vector_*_t objects with RAII behavior.
Definition Vector.hpp:26
iterator erase(iterator pos)
Definition Vector.hpp:257
iterator insert(iterator pos, value_type val)
Definition Vector.hpp:279
const value_type * data() const
Definition Vector.hpp:434
Vector & operator=(Vector< Ns_ > &&other)
Definition Vector.hpp:152
const_reference operator[](igraph_integer_t i) const
Definition Vector.hpp:349
value_type * data()
Definition Vector.hpp:427
reference operator[](igraph_integer_t i)
Definition Vector.hpp:341
std::reverse_iterator< iterator > reverse_iterator
Definition Vector.hpp:78
iterator erase(iterator first, iterator last)
Definition Vector.hpp:267
iterator emplace(iterator pos, Args &&... args)
Definition Vector.hpp:292
iterator begin()
Definition Vector.hpp:385
reverse_const_iterator rend() const
Definition Vector.hpp:462
void reserve(size_type capacity)
Definition Vector.hpp:217
Vector< Ns_ > & operator=(const Vector< Ns_ > &other)
Definition Vector.hpp:130
Vector(Vector< Ns_ > &&other)
Definition Vector.hpp:143
const value_type & const_reference
Definition Vector.hpp:53
reverse_iterator rend()
Definition Vector.hpp:448
const igraph_type * get() const
Definition Vector.hpp:509
igraph_type * get()
Definition Vector.hpp:501
igraph_integer_t difference_type
Definition Vector.hpp:63
Vector(const Vector< Ns_ > &other)
Definition Vector.hpp:120
reverse_iterator rbegin()
Definition Vector.hpp:441
const_reference back() const
Definition Vector.hpp:363
std::reverse_iterator< const_iterator > reverse_const_iterator
Definition Vector.hpp:83
igraph_bool_t empty() const
Definition Vector.hpp:170
reverse_const_iterator rbegin() const
Definition Vector.hpp:455
const_reference front() const
Definition Vector.hpp:377
igraph_integer_t size_type
Definition Vector.hpp:58
reverse_const_iterator crend() const
Definition Vector.hpp:476
Ns_::value_type value_type
Definition Vector.hpp:43
void clear()
Definition Vector.hpp:196
~Vector()
Definition Vector.hpp:162
Vector()
Definition Vector.hpp:89
const_iterator begin() const
Definition Vector.hpp:399
iterator insert(iterator pos, size_type n, value_type val)
Definition Vector.hpp:304
void emplace_back(Args &&... args)
Definition Vector.hpp:241
iterator insert(iterator pos, InputIterator first, InputIterator last)
Definition Vector.hpp:324
void resize(size_type size, value_type val=value_type())
Definition Vector.hpp:205
const_iterator cbegin() const
Definition Vector.hpp:413
Vector(size_type size, const value_type &val=value_type())
Definition Vector.hpp:95
size_type capacity() const
Definition Vector.hpp:189
Ns_::igraph_type igraph_type
Definition Vector.hpp:38
void swap(Vector< Ns_ > &other)
Definition Vector.hpp:518
void pop_back()
Definition Vector.hpp:249
reference back()
Definition Vector.hpp:356
value_type * iterator
Definition Vector.hpp:68
reference front()
Definition Vector.hpp:370
iterator end()
Definition Vector.hpp:392
reverse_const_iterator crbegin() const
Definition Vector.hpp:469
size_type size() const
Definition Vector.hpp:177
void push_back(value_type val)
Definition Vector.hpp:232
value_type & reference
Definition Vector.hpp:48
Vector(igraph_type &&vector)
Definition Vector.hpp:103
void shrink_to_fit()
Definition Vector.hpp:224
Vector(InputIterator first, InputIterator last)
Definition Vector.hpp:111
const_iterator cend() const
Definition Vector.hpp:420
const value_type * const_iterator
Definition Vector.hpp:73
constexpr size_type max_size() const
Definition Vector.hpp:184
const_iterator end() const
Definition Vector.hpp:406
Error handling for raiigraph.
Utilities for manipulating igraph data structures in C++.
Definition error.hpp:11
Vector< internal::Integer > IntVector
Definition Vector.hpp:568
Vector< internal::Real > RealVector
Definition Vector.hpp:582
void check_code(igraph_error_t code)
Definition error.hpp:34
Vector< internal::Bool > BoolVector
Definition Vector.hpp:587