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  {
194  /* move only if move constructor doesn't throw exceptions */
195  const size_t toMove = std::min(N, size());
196  for (size_t k = 0; k < toMove; k++)
197  newPtr[k] = std::move_if_noexcept(ptr[k]);
198  }
199  catch(...)
200  {
201  delete[] newPtr;
202  throw;
203  }
204  delete[] ptr;
205  ptr = newPtr;
206  ptrEnd = ptr + N;
207  }
208 
210  void clear()
211  {
212  delete[] ptr;
213  ptr = ptrEnd = nullptr;
214  }
215 
217  template<typename It>
218  Array& assign(It b, It e)
219  {
220  const size_t N = e-b;
221  if (N != size())
222  {
223  T* newPtr = nullptr;
224  if (N != 0)
225  newPtr = new T[N];
226  try
227  { std::copy(b, e, newPtr); }
228  catch(...)
229  {
230  delete[] newPtr;
231  throw;
232  }
233  delete[] ptr;
234  ptr = newPtr;
235  ptrEnd = ptr+N;
236  }
237  else // no size changed only copy
238  std::copy(b, e, ptr);
239  return *this;
240  }
241 
243  const T* data() const
244  { return ptr; }
246  T* data()
247  { return ptr; }
248 
250  const T* begin() const
251  { return ptr; }
253  T* begin()
254  { return ptr; }
255 
257  const T* end() const
258  { return ptrEnd; }
260  T* end()
261  { return ptrEnd; }
262 
264  const T& front() const
265  { return *ptr; }
267  T& front()
268  { return *ptr; }
270  const T& back() const
271  { return ptrEnd[-1]; }
273  T& back()
274  { return ptrEnd[-1]; }
275 
277  void swap(Array& array)
278  {
279  std::swap(ptr, array.ptr);
280  std::swap(ptrEnd, array.ptrEnd);
281  }
282 };
283 
285 
291 template<typename Iter>
292 Iter binaryFind(Iter begin, Iter end, const
293  typename std::iterator_traits<Iter>::value_type& v);
294 
296 
303 template<typename Iter, typename Comp =
304  std::less<typename std::iterator_traits<Iter>::value_type> >
305 Iter binaryFind(Iter begin, Iter end, const
306  typename std::iterator_traits<Iter>::value_type& v, Comp comp);
307 
309 
315 template<typename Iter>
316 Iter binaryMapFind(Iter begin, Iter end, const
317  typename std::iterator_traits<Iter>::value_type::first_type& k);
318 
320 
327 template<typename Iter, typename Comp =
328  std::less<typename std::iterator_traits<Iter>::value_type::first_type> >
329 Iter binaryMapFind(Iter begin, Iter end, const
330  typename std::iterator_traits<Iter>::value_type::first_type& k, Comp comp);
331 
333 
337 template<typename Iter>
338 void mapSort(Iter begin, Iter end);
339 
341 
345 template<typename Iter, typename Comp =
346  std::less<typename std::iterator_traits<Iter>::value_type::first_type> >
347 void mapSort(Iter begin, Iter end, Comp comp);
348 
350 
356 template<typename Iter>
357 Iter binaryFind(Iter begin, Iter end,
358  const typename std::iterator_traits<Iter>::value_type& v)
359 {
360  auto it = std::lower_bound(begin, end, v);
361  if (it == end || v < *it)
362  return end;
363  return it;
364 }
365 
367 
374 template<typename Iter, typename Comp>
375 Iter binaryFind(Iter begin, Iter end,
376  const typename std::iterator_traits<Iter>::value_type& v, Comp comp)
377 {
378  auto it = std::lower_bound(begin, end, v, comp);
379  if (it == end || comp(v, *it))
380  return end;
381  return it;
382 }
383 
385 template<typename Iter>
386 Iter binaryMapFind(Iter begin, Iter end, const
387  typename std::iterator_traits<Iter>::value_type::first_type& k)
388 {
389  typedef typename std::iterator_traits<Iter>::value_type::first_type K;
390  typedef typename std::iterator_traits<Iter>::value_type::second_type V;
391  auto it = std::lower_bound(begin, end, std::make_pair(k, V()),
392  [](const std::pair<K,V>& e1, const std::pair<K,V>& e2) {
393  return e1.first < e2.first; });
394  if (it == end || k < it->first)
395  return end;
396  return it;
397 }
398 
400 template<typename Iter, typename Comp>
401 Iter binaryMapFind(Iter begin, Iter end, const
402  typename std::iterator_traits<Iter>::value_type::first_type& k, Comp comp)
403 {
404  typedef typename std::iterator_traits<Iter>::value_type::first_type K;
405  typedef typename std::iterator_traits<Iter>::value_type::second_type V;
406  auto it = std::lower_bound(begin, end, std::make_pair(k, V()),
407  [&comp](const std::pair<K,V>& e1, const std::pair<K,V>& e2) {
408  return comp(e1.first, e2.first); });
409  if (it == end || comp(k, it->first))
410  return end;
411  return it;
412 }
413 
415 
419 template<typename Iter>
420 void mapSort(Iter begin, Iter end)
421 {
422  typedef typename std::iterator_traits<Iter>::value_type::first_type K;
423  typedef typename std::iterator_traits<Iter>::value_type::second_type V;
424  std::sort(begin, end, [](const std::pair<K,V>& e1, const std::pair<K,V>& e2) {
425  return e1.first < e2.first; });
426 }
427 
429 
434 template<typename Iter, typename Comp>
435 void mapSort(Iter begin, Iter end, Comp comp)
436 {
437  typedef typename std::iterator_traits<Iter>::value_type::first_type K;
438  typedef typename std::iterator_traits<Iter>::value_type::second_type V;
439  std::sort(begin, end, [&comp](const std::pair<K,V>& e1, const std::pair<K,V>& e2) {
440  return comp(e1.first, e2.first); });
441 }
442 
443 };
444 
445 namespace std
446 {
447 
449 template<typename T>
451 { a1.swap(a2); }
452 
453 }
454 
455 #endif
const T * begin() const
get iterator to first element
Definition: Containers.h:250
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:386
void swap(Array &array)
swap two arrays
Definition: Containers.h:277
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:264
STL namespace.
an array class
Definition: Containers.h:38
void resize(size_t N)
resize space with keeping old content
Definition: Containers.h:185
Configuration header.
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:273
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:260
Array & operator=(const Array &cp)
copy assignment
Definition: Containers.h:131
T * data()
get data
Definition: Containers.h:246
T & front()
get first element
Definition: Containers.h:267
void mapSort(Iter begin, Iter end)
map range of iterators
Definition: Containers.h:420
main namespace
Definition: AsmDefs.h:38
Array & assign(It b, It e)
assign from range of iterators
Definition: Containers.h:218
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:253
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:357
size_t size() const
returns number of elements
Definition: Containers.h:169
const T * data() const
get data
Definition: Containers.h:243
void clear()
clear array
Definition: Containers.h:210
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:270
const T * end() const
get iterator to after last element
Definition: Containers.h:257