openMSX
dynarray.hh
Go to the documentation of this file.
1 #ifndef DYNARRAY_HH
2 #define DYNARRAY_HH
3 
4 // dynarray -- this models a dynamically sized array.
5 // This falls between a std::array and a std::vector.
6 //
7 // - Like vector the size of a dynarray is set at run-time (for std::array it's
8 // set during compile-time).
9 // - Unlike vector the size of a dynarray can no longer change (grow/shrink)
10 // after the initial construction.
11 //
12 // So qua functionality dynarray can do strictly less than a vector and strictly
13 // more than an array.
14 //
15 // The (only?) advantage of dynarray over vector is that the size of the
16 // dynarray itself is slightly smaller than the size of a vector (vector
17 // additionally needs to store the capacity; for dynarray size and capacity are
18 // always the same). (Typically on a 64-bit system: sizeof(vector)=24 and
19 // sizeof(dynarray)=16).
20 //
21 // This class is very similar to the array-version of std::unique_ptr (in fact
22 // the current implementation is based on unique_ptr<T[]>). The only addition is
23 // that dynarray also stores the size(*).
24 // (*) Technically, I think, unique_ptr<T[]> already stores the size internally
25 // (typically at some offset in the allocated block). Though unfortunately
26 // there's no portable way to access this size. So storing the size in the
27 // dynarray class is necessary but strictly speaking redundant.
28 //
29 // The name and the interface of this class is based on the std::dynarray
30 // proposal for c++14. Though that proposal did not make it in c++14 and seems
31 // to be abandoned. Here's some (old) documentation:
32 // https://www.enseignement.polytechnique.fr/informatique/INF478/docs/Cpp/en/cpp/container/dynarray.html
33 // This is not a full implementation of that proposal, just the easy parts
34 // and/or the parts that we currently need. Can easily be extended in the future
35 // (when needed).
36 
37 #include <cassert>
38 #include <memory>
39 
40 template<typename T>
41 class dynarray
42 {
43 public:
44  dynarray() = default;
45 
46  explicit dynarray(size_t n)
47  : m_size(n), m_data(std::make_unique<T[]>(n)) {}
48 
49  dynarray(size_t n, const T& value)
50  : m_size(n), m_data(std::make_unique<T[]>(n, value)) {}
51 
52  dynarray(dynarray&& other)
53  : m_size(other.m_size), m_data(std::move(other.m_data)) {
54  other.m_size = 0;
55  assert(!other.m_data);
56  }
57 
59  if (this == &other) return *this;
60  m_size = other.m_size;
61  m_data = std::move(other.m_data);
62  assert(!other.m_data);
63  return *this;
64  }
65 
66  dynarray(const dynarray&) = delete;
67  dynarray& operator=(const dynarray&) = delete;
68 
69  [[nodiscard]] T& operator[](size_t i) {
70  assert(i < m_size);
71  return m_data[i];
72  }
73  [[nodiscard]] const T& operator[](size_t i) const {
74  assert(i < m_size);
75  return m_data[i];
76  }
77 
78  [[nodiscard]] T& front() {
79  assert(!empty());
80  return m_data[0];
81  }
82  [[nodiscard]] const T& front() const {
83  assert(!empty());
84  return m_data[0];
85  }
86  [[nodiscard]] T& back() {
87  assert(!empty());
88  return m_data[m_size - 1];
89  }
90  [[nodiscard]] const T& back() const {
91  assert(!empty());
92  return m_data[m_size - 1];
93  }
94 
95  [[nodiscard]] T* data() { return m_data.get(); }
96  [[nodiscard]] const T* data() const { return m_data.get(); }
97 
98  [[nodiscard]] T* begin() { return m_data.get(); }
99  [[nodiscard]] const T* begin() const { return m_data.get(); }
100  [[nodiscard]] T* end() { return m_data.get() + m_size; }
101  [[nodiscard]] const T* end() const { return m_data.get() + m_size; }
102 
103  [[nodiscard]] bool empty() const { return m_size == 0; }
104  [[nodiscard]] size_t size() const { return m_size; }
105 
106 private:
107  size_t m_size = 0;
108  std::unique_ptr<T[]> m_data;
109 };
110 
111 #endif
const T * end() const
Definition: dynarray.hh:101
dynarray(dynarray &&other)
Definition: dynarray.hh:52
T & operator[](size_t i)
Definition: dynarray.hh:69
const T & operator[](size_t i) const
Definition: dynarray.hh:73
dynarray(const dynarray &)=delete
T & back()
Definition: dynarray.hh:86
T * end()
Definition: dynarray.hh:100
bool empty() const
Definition: dynarray.hh:103
const T * begin() const
Definition: dynarray.hh:99
dynarray(size_t n)
Definition: dynarray.hh:46
dynarray()=default
T & front()
Definition: dynarray.hh:78
T * data()
Definition: dynarray.hh:95
dynarray(size_t n, const T &value)
Definition: dynarray.hh:49
dynarray & operator=(const dynarray &)=delete
dynarray & operator=(dynarray &&other)
Definition: dynarray.hh:58
size_t size() const
Definition: dynarray.hh:104
const T * data() const
Definition: dynarray.hh:96
const T & back() const
Definition: dynarray.hh:90
const T & front() const
Definition: dynarray.hh:82
T * begin()
Definition: dynarray.hh:98