openMSX
MemBuffer.hh
Go to the documentation of this file.
1 #ifndef MEMBUFFER_HH
2 #define MEMBUFFER_HH
3 
4 #include "noncopyable.hh"
5 #include <algorithm>
6 #include <new> // for bad_alloc
7 #include <cstdlib>
8 #include <cassert>
9 
10 namespace openmsx {
11 
27 template<typename T> class MemBuffer //: private noncopyable
28 {
29 public:
33  : dat(nullptr)
34  , sz(0)
35  {
36  }
37 
40  explicit MemBuffer(size_t size)
41  : dat(static_cast<T*>(malloc(size * sizeof(T))))
42  , sz(size)
43  {
44  if (size && !dat) {
45  throw std::bad_alloc();
46  }
47  }
48 
53  MemBuffer(T* data, size_t size)
54  : dat(data)
55  , sz(size)
56  {
57  }
58 
61  : dat(other.dat)
62  , sz(other.sz)
63  {
64  other.dat = nullptr;
65  }
66 
69  {
70  std::swap(dat, other.dat);
71  std::swap(sz , other.sz);
72  return *this;
73  }
74 
78  {
79  free(dat);
80  }
81 
85  const T* data() const { return dat; }
86  T* data() { return dat; }
87 
90  const T& operator[](size_t i) const
91  {
92  assert(i < sz);
93  return dat[i];
94  }
95  T& operator[](size_t i)
96  {
97  assert(i < sz);
98  return dat[i];
99  }
100 
104  size_t size() const { return sz; }
105 
108  bool empty() const { return sz == 0; }
109 
116  void resize(size_t size)
117  {
118  if (size) {
119  auto newDat = static_cast<T*>(realloc(dat, size * sizeof(T)));
120  if (!newDat) {
121  throw std::bad_alloc();
122  }
123  dat = newDat;
124  sz = size;
125  } else {
126  // realloc() can handle zero-size allocactions,
127  // but then we anyway still need to check for
128  // 'size == 0' for the error handling.
129  clear();
130  }
131  }
132 
135  void clear()
136  {
137  free(dat);
138  dat = nullptr;
139  sz = 0;
140  }
141 
144  const T* begin() const { return dat; }
145  T* begin() { return dat; }
146  const T* end() const { return dat + sz; }
147  T* end() { return dat + sz; }
148 
151  void swap(MemBuffer& other)
152  {
153  std::swap(dat, other.dat);
154  std::swap(sz , other.sz );
155  }
156 
157 private:
158  T* dat;
159  size_t sz;
160 };
161 
162 } // namespace openmsx
163 
164 namespace std {
165  template<typename T>
167  {
168  l.swap(r);
169  }
170 }
171 
172 #endif