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
40template<typename T>
42{
43public:
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
53 template<typename SizedRange>
55 : m_size(std::size(range)), m_data(std::make_unique<T[]>(m_size)) {
56 size_t i = 0;
57 for (const auto& e : range) {
58 m_data[i] = e;
59 ++i;
60 }
61 }
62
63 dynarray(dynarray&& other) noexcept
64 : m_size(other.m_size), m_data(std::move(other.m_data)) {
65 other.m_size = 0;
66 assert(!other.m_data);
67 }
68
69 dynarray& operator=(dynarray&& other) noexcept {
70 if (this == &other) return *this;
71 m_size = other.m_size;
72 m_data = std::move(other.m_data);
73 assert(!other.m_data);
74 return *this;
75 }
76
77 dynarray(const dynarray&) = delete;
78 dynarray& operator=(const dynarray&) = delete;
79
80 [[nodiscard]] T& operator[](size_t i) {
81 assert(i < m_size);
82 return m_data[i];
83 }
84 [[nodiscard]] const T& operator[](size_t i) const {
85 assert(i < m_size);
86 return m_data[i];
87 }
88
89 [[nodiscard]] T& front() {
90 assert(!empty());
91 return m_data[0];
92 }
93 [[nodiscard]] const T& front() const {
94 assert(!empty());
95 return m_data[0];
96 }
97 [[nodiscard]] T& back() {
98 assert(!empty());
99 return m_data[m_size - 1];
100 }
101 [[nodiscard]] const T& back() const {
102 assert(!empty());
103 return m_data[m_size - 1];
104 }
105
106 [[nodiscard]] T* data() { return m_data.get(); }
107 [[nodiscard]] const T* data() const { return m_data.get(); }
108
109 [[nodiscard]] T* begin() { return m_data.get(); }
110 [[nodiscard]] const T* begin() const { return m_data.get(); }
111 [[nodiscard]] T* end() { return m_data.get() + m_size; }
112 [[nodiscard]] const T* end() const { return m_data.get() + m_size; }
113
114 [[nodiscard]] bool empty() const { return m_size == 0; }
115 [[nodiscard]] size_t size() const { return m_size; }
116
117private:
118 size_t m_size = 0;
119 std::unique_ptr<T[]> m_data;
120};
121
122#endif
dynarray & operator=(const dynarray &)=delete
T & front()
Definition: dynarray.hh:89
T * data()
Definition: dynarray.hh:106
dynarray(construct_from_range_tag, SizedRange &&range)
Definition: dynarray.hh:54
dynarray(const dynarray &)=delete
const T & back() const
Definition: dynarray.hh:101
const T * begin() const
Definition: dynarray.hh:110
bool empty() const
Definition: dynarray.hh:114
dynarray(size_t n)
Definition: dynarray.hh:46
T * begin()
Definition: dynarray.hh:109
dynarray()=default
const T * end() const
Definition: dynarray.hh:112
T * end()
Definition: dynarray.hh:111
dynarray(size_t n, const T &value)
Definition: dynarray.hh:49
dynarray(dynarray &&other) noexcept
Definition: dynarray.hh:63
size_t size() const
Definition: dynarray.hh:115
dynarray & operator=(dynarray &&other) noexcept
Definition: dynarray.hh:69
const T & operator[](size_t i) const
Definition: dynarray.hh:84
const T * data() const
Definition: dynarray.hh:107
const T & front() const
Definition: dynarray.hh:93
T & operator[](size_t i)
Definition: dynarray.hh:80
T & back()
Definition: dynarray.hh:97
constexpr double e
Definition: Math.hh:20
STL namespace.