CLRX  1
An unofficial OpenCL extensions designed for Radeon GPUs
Containers.h
Go to the documentation of this file.
1 /*
2  * CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3  * Copyright (C) 2014-2017 Mateusz Szpakowski
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
23 #ifndef __CLRX_CONTAINERS_H__
24 #define __CLRX_CONTAINERS_H__
25 
26 #include <CLRX/Config.h>
27 #include <cstddef>
28 #include <iterator>
29 #include <algorithm>
30 #include <initializer_list>
31 
33 namespace CLRX
34 {
35 
37 template<typename T>
38 class Array
39 {
40 public:
41  typedef T* iterator;
42  typedef const T* const_iterator;
43  typedef T element_type;
44 private:
45  T* ptr, *ptrEnd;
46 public:
48  Array(): ptr(nullptr), ptrEnd(nullptr)
49  { }
50 
52  explicit Array(size_t N)
53  {
54  ptr = nullptr;
55  if (N != 0)
56  ptr = new T[N];
57  ptrEnd = ptr+N;
58  }
59 
61  template<typename It>
62  Array(It b, It e)
63  {
64  try
65  {
66  ptr = nullptr;
67  const size_t N = e-b;
68  if (N != 0)
69  ptr = new T[N];
70  ptrEnd = ptr+N;
71  std::copy(b, e, ptr);
72  }
73  catch(...)
74  {
75  delete[] ptr;
76  throw;
77  }
78  }
79 
81  Array(const Array& cp)
82  {
83  try
84  {
85  ptr = ptrEnd = nullptr;
86  const size_t N = cp.size();
87  if (N != 0)
88  ptr = new T[N];
89  ptrEnd = ptr+N;
90  std::copy(cp.ptr, cp.ptrEnd, ptr);
91  }
92  catch(...)
93  {
94  delete[] ptr;
95  throw;
96  }
97  }
98 
100  Array(Array&& cp) noexcept
101  {
102  ptr = cp.ptr;
103  ptrEnd = cp.ptrEnd;
104  cp.ptr = cp.ptrEnd = nullptr;
105  }
106 
108  Array(std::initializer_list<T> list)
109  {
110  try
111  {
112  ptr = nullptr;
113  const size_t N = list.size();
114  if (N != 0)
115  ptr = new T[N];
116  ptrEnd = ptr+N;
117  std::copy(list.begin(), list.end(), ptr);
118  }
119  catch(...)
120  {
121  delete[] ptr;
122  throw;
123  }
124  }
125 
128  { delete[] ptr; }
129 
131  Array& operator=(const Array& cp)
132  {
133  if (this == &cp)
134  return *this;
135  assign(cp.begin(), cp.end());
136  return *this;
137  }
139  Array& operator=(Array&& cp) noexcept
140  {
141  if (this == &cp)
142  return *this;
143  delete[] ptr;
144  ptr = cp.ptr;
145  ptrEnd = cp.ptrEnd;
146  cp.ptr = cp.ptrEnd = nullptr;
147  return *this;
148  }
149 
151  Array& operator=(std::initializer_list<T> list)
152  {
153  assign(list.begin(), list.end());
154  return *this;
155  }
156 
158  const T& operator[] (size_t i) const
159  { return ptr[i]; }
161  T& operator[] (size_t i)
162  { return ptr[i]; }
163 
165  bool empty() const
166  { return ptrEnd==ptr; }
167 
169  size_t size() const
170  { return ptrEnd-ptr; }
171 
173  void allocate(size_t N)
174  {
175  if (N == size())
176  return;
177  delete[] ptr;
178  ptr = nullptr;
179  if (N != 0)
180  ptr = new T[N];
181  ptrEnd = ptr + N;
182  }
183 
185  void resize(size_t N)
186  {
187  if (N == size())
188  return;
189  T* newPtr = nullptr;
190  if (N != 0)
191  newPtr = new T[N];
192  try
193  { /* move only if move constructor doesn't throw exceptions */
194  const size_t toMove = std::min(N, size());
195  for (size_t k = 0; k < toMove; k++)
196  newPtr[k] = std::move_if_noexcept(ptr[k]);
197  }
198  catch(...)
199  {
200  delete[] newPtr;
201  throw;
202  }
203  delete[] ptr;
204  ptr = newPtr;
205  ptrEnd = ptr + N;
206  }
207 
209  void clear()
210  {
211  delete[] ptr;
212  ptr = ptrEnd = nullptr;
213  }
214 
216  template<typename It>
217  Array& assign(It b, It e)
218  {
219  const size_t N = e-b;
220  if (N != size())
221  {
222  T* newPtr = nullptr;
223  if (N != 0)
224  newPtr = new T[N];
225  try
226  { std::copy(b, e, newPtr); }
227  catch(...)
228  {
229  delete[] newPtr;
230  throw;
231  }
232  delete[] ptr;
233  ptr = newPtr;
234  ptrEnd = ptr+N;
235  }
236  else // no size changed only copy
237  std::copy(b, e, ptr);
238  return *this;
239  }
240 
242  const T* data() const
243  { return ptr; }
245  T* data()
246  { return ptr; }
247 
249  const T* begin() const
250  { return ptr; }
252  T* begin()
253  { return ptr; }
254 
256  const T* end() const
257  { return ptrEnd; }
259  T* end()
260  { return ptrEnd; }
261 
263  const T& front() const
264  { return *ptr; }
266  T& front()
267  { return *ptr; }
269  const T& back() const
270  { return ptrEnd[-1]; }
272  T& back()
273  { return ptrEnd[-1]; }
274 
276  void swap(Array& array)
277  {
278  std::swap(ptr, array.ptr);
279  std::swap(ptrEnd, array.ptrEnd);
280  }
281 };
282 
284 
290 template<typename Iter>
291 Iter binaryFind(Iter begin, Iter end, const
292  typename std::iterator_traits<Iter>::value_type& v);
293 
295 
302 template<typename Iter, typename Comp =
303  std::less<typename std::iterator_traits<Iter>::value_type> >
304 Iter binaryFind(Iter begin, Iter end, const
305  typename std::iterator_traits<Iter>::value_type& v, Comp comp);
306 
308 
314 template<typename Iter>
315 Iter binaryMapFind(Iter begin, Iter end, const
316  typename std::iterator_traits<Iter>::value_type::first_type& k);
317 
319 
326 template<typename Iter, typename Comp =
327  std::less<typename std::iterator_traits<Iter>::value_type::first_type> >
328 Iter binaryMapFind(Iter begin, Iter end, const
329  typename std::iterator_traits<Iter>::value_type::first_type& k, Comp comp);
330 
332 
336 template<typename Iter>
337 void mapSort(Iter begin, Iter end);
338 
340 
344 template<typename Iter, typename Comp =
345  std::less<typename std::iterator_traits<Iter>::value_type::first_type> >
346 void mapSort(Iter begin, Iter end, Comp comp);
347 
349 
355 template<typename Iter>
356 Iter binaryFind(Iter begin, Iter end,
357  const typename std::iterator_traits<Iter>::value_type& v)
358 {
359  auto it = std::lower_bound(begin, end, v);
360  if (it == end || v < *it)
361  return end;
362  return it;
363 }
364 
366 
373 template<typename Iter, typename Comp>
374 Iter binaryFind(Iter begin, Iter end,
375  const typename std::iterator_traits<Iter>::value_type& v, Comp comp)
376 {
377  auto it = std::lower_bound(begin, end, v, comp);
378  if (it == end || comp(v, *it))
379  return end;
380  return it;
381 }
382 
384 template<typename Iter>
385 Iter binaryMapFind(Iter begin, Iter end, const
386  typename std::iterator_traits<Iter>::value_type::first_type& k)
387 {
388  typedef typename std::iterator_traits<Iter>::value_type::first_type K;
389  typedef typename std::iterator_traits<Iter>::value_type::second_type V;
390  auto it = std::lower_bound(begin, end, std::make_pair(k, V()),
391  [](const std::pair<K,V>& e1, const std::pair<K,V>& e2) {
392  return e1.first < e2.first; });
393  if (it == end || k < it->first)
394  return end;
395  return it;
396 }
397 
399 template<typename Iter, typename Comp>
400 Iter binaryMapFind(Iter begin, Iter end, const
401  typename std::iterator_traits<Iter>::value_type::first_type& k, Comp comp)
402 {
403  typedef typename std::iterator_traits<Iter>::value_type::first_type K;
404  typedef typename std::iterator_traits<Iter>::value_type::second_type V;
405  auto it = std::lower_bound(begin, end, std::make_pair(k, V()),
406  [&comp](const std::pair<K,V>& e1, const std::pair<K,V>& e2) {
407  return comp(e1.first, e2.first); });
408  if (it == end || comp(k, it->first))
409  return end;
410  return it;
411 }
412 
414 
418 template<typename Iter>
419 void mapSort(Iter begin, Iter end)
420 {
421  typedef typename std::iterator_traits<Iter>::value_type::first_type K;
422  typedef typename std::iterator_traits<Iter>::value_type::second_type V;
423  std::sort(begin, end, [](const std::pair<K,V>& e1, const std::pair<K,V>& e2) {
424  return e1.first < e2.first; });
425 }
426 
428 
433 template<typename Iter, typename Comp>
434 void mapSort(Iter begin, Iter end, Comp comp)
435 {
436  typedef typename std::iterator_traits<Iter>::value_type::first_type K;
437  typedef typename std::iterator_traits<Iter>::value_type::second_type V;
438  std::sort(begin, end, [&comp](const std::pair<K,V>& e1, const std::pair<K,V>& e2) {
439  return comp(e1.first, e2.first); });
440 }
441 
442 };
443 
444 namespace std
445 {
446 
448 template<typename T>
450 { a1.swap(a2); }
451 
452 }
453 
454 #endif
const T * begin() const
get iterator to first element
Definition: Containers.h:249
T element_type
element type
Definition: Containers.h:43
Iter binaryMapFind(Iter begin, Iter end, const typename std::iterator_traits< Iter >::value_type::first_type &k)
binary find helper for array-map
Definition: Containers.h:385
void swap(Array &array)
swap two arrays
Definition: Containers.h:276
void allocate(size_t N)
only allocating space without keeping previous content
Definition: Containers.h:173
const T & operator[](size_t i) const
operator of indexing
Definition: Containers.h:158
const T & front() const
get first element
Definition: Containers.h:263
STL namespace.
an array class
Definition: Containers.h:38
void resize(size_t N)
resize space with keeping old content
Definition: Containers.h:185
const T * const_iterator
type of constant iterator
Definition: Containers.h:42
Array()
empty constructor
Definition: Containers.h:48
Array(size_t N)
construct array of N elements
Definition: Containers.h:52
Array & operator=(Array &&cp) noexcept
move assignment
Definition: Containers.h:139
T & back()
get last element
Definition: Containers.h:272
Array & operator=(std::initializer_list< T > list)
assignment from initializer list
Definition: Containers.h:151
Array(std::initializer_list< T > list)
constructor with initializer list
Definition: Containers.h:108
T * end()
get iterator to after last element
Definition: Containers.h:259
Array & operator=(const Array &cp)
copy assignment
Definition: Containers.h:131
T * data()
get data
Definition: Containers.h:245
T & front()
get first element
Definition: Containers.h:266
void mapSort(Iter begin, Iter end)
map range of iterators
Definition: Containers.h:419
main namespace
Definition: AsmDefs.h:38
Array & assign(It b, It e)
assign from range of iterators
Definition: Containers.h:217
T * iterator
type of iterator
Definition: Containers.h:41
~Array()
destructor
Definition: Containers.h:127
Array(It b, It e)
construct array of elements in begin and end
Definition: Containers.h:62
T * begin()
get iterator to first element
Definition: Containers.h:252
Array(const Array &cp)
copy constructor
Definition: Containers.h:81
Iter binaryFind(Iter begin, Iter end, const typename std::iterator_traits< Iter >::value_type &v)
binary find helper
Definition: Containers.h:356
size_t size() const
returns number of elements
Definition: Containers.h:169
const T * data() const
get data
Definition: Containers.h:242
void clear()
clear array
Definition: Containers.h:209
bool empty() const
returns true if empty
Definition: Containers.h:165
Array(Array &&cp) noexcept
move constructor
Definition: Containers.h:100
const T & back() const
get last element
Definition: Containers.h:269
const T * end() const
get iterator to after last element
Definition: Containers.h:256