mn_algorithm.hpp
Go to the documentation of this file.
1 
21 #ifndef _MINLIB_STL_ALGORITHM_H_
22 #define _MINLIB_STL_ALGORITHM_H_
23 
24 #include "mn_config.hpp"
25 
26 #include "utils/mn_alignment.hpp"
27 #include "utils/mn_inttokey.hpp"
28 #include "utils/mn_utils.hpp"
29 #include "mn_typetraits.hpp"
30 #include "mn_iterator.hpp"
31 #include "mn_functional.hpp"
32 
33 #include "mn_initializer_list.hpp"
34 
35 
36 namespace mn {
37 
38  inline size_t popcount (uint32_t v) {
39  return __builtin_popcount (v);
40  }
41 
42 
43 
44  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
45  inline void copy_construct(T* mem, const T& orig) {
47  }
48 
49  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
50  inline void copy_construct(T* mem, const T&& orig) {
52  }
53 
54  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
55  inline void construct(T* mem) {
57  }
58 
59 
60  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
61  inline void destruct(T* mem) {
63  }
64 
73  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
74  void copy_n(const T* src, size_t n, T* dest) {
76  }
77 
78  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
79  void copy(const T* src, const T* last, T* dest) {
81  }
82 
83  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
84  void copy_construct_n(T* src, size_t n, T* dest) {
86  }
87 
88  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
89  void move_n(const T* from, size_t n, T* dest) {
90  assert(from != dest || n == 0);
91 
92  if (dest + n >= from && dest < from + n) {
94  } else {
96  }
97  }
98 
99  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
100  inline void move(const T* src, const T* last, T* dest) {
101  assert(src != dest || src == last);
102  const size_t n = reinterpret_cast<uintptr_t>(last) - reinterpret_cast<uintptr_t>(src);
103  const unsigned char* destEnd = reinterpret_cast<const unsigned char*>(dest) + n;
104 
105  if (destEnd >= reinterpret_cast<const unsigned char*>(src) && dest < last) {
107  } else {
109  }
110  }
111 
112  template <typename T>
113  inline T* copy_backward (const T* first, const T* last, T* result) noexcept {
114  const size_t nBytes (mn::distance (first, last));
115  memmove (advance_ptr(result,-nBytes), first, nBytes);
116  }
117 
118  MN_TEMPLATE_FULL_DECL_TWO(class, TIter, class, TFn)
119  TFn foreach(TIter src, TIter last, TFn fn) {
120  while (src!=last) {
121  fn (*src); ++src;
122  }
123  return (fn);
124  }
125 
126  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
127  void construct_n(T* src, size_t n) {
129  }
130  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
131  void destruct_n(T* src, size_t n) {
133  }
134  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
135  inline void fill(T* src, T* last, const T& val) {
136  while (src != last) {
137  *src = val; src = src + 1;
138  }
139  }
140 
141  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
142  inline void fill_n(T* src, size_t n, const T& val) {
143  T* last = src + n;
144  while (src != last) {
145  switch (n & 0x7) {
146  case 0: *src = val; ++src;
147  case 7: *src = val; ++src;
148  case 6: *src = val; ++src;
149  case 5: *src = val; ++src;
150  case 4: *src = val; ++src;
151  case 3: *src = val; ++src;
152  case 2: *src = val; ++src;
153  case 1: *src = val; ++src;
154  }
155  }
156  }
157 
158 
159  MN_TEMPLATE_FULL_DECL_TWO(class, TIter, class, TPred = mn::less<TIter> )
160  constexpr TIter lower_bound (TIter first, TIter last, const TPred& value) {
161  TIter mid;
162  while (first != last) {
163 
164  mid = first + size_t(mn::distance (first,last))/2;
165  if (value < *mid) first = mid + 1;
166  else last = mid;
167  }
168  return last;
169  }
170 
171  MN_TEMPLATE_FULL_DECL_THREE(class, TIter, typename, T, class, TPred = mn::less<TIter> )
172  constexpr TIter lower_bound(TIter src, TIter last, const T& val, const TPred& pred) {
173  internal::test_ordering(src, last, pred);
174  int dist(0);
175  dist = distance(src, last);
176 
177  while (dist > 0) {
178  const int halfDist = dist >> 1;
179  TIter mid = src;
180  advance(mid, halfDist);
181  if (internal::debug_pred(pred, *mid, val))
182  src = ++mid, dist -= halfDist + 1;
183  else
184  dist = halfDist;
185  }
186  return src;
187  }
188 
189 
190  MN_TEMPLATE_FULL_DECL_TWO(class, TIter, class, TPred = mn::less<TIter> )
191  constexpr TIter upper_bound (TIter first, TIter last, const TPred& value) {
192  TIter mid;
193  while (first != last) {
194 
195  mid = first + size_t(mn::distance (first,last))/2;
196  if (value < *mid) last = mid;
197  else first = mid + 1;
198  }
199  return last;
200  }
201 
202  MN_TEMPLATE_FULL_DECL_THREE(class, TIter, typename, T, class, TPred = mn::less<TIter>)
203  constexpr TIter upper_bound(TIter src, TIter last, const T& val, const TPred& pred) {
204  internal::test_ordering(src, last, pred);
205  int dist(0);
206  dist = distance(src, last);
207 
208  while (dist > 0) {
209  const int halfDist = dist >> 1;
210  TIter mid = src;
211  advance(mid, halfDist);
212  if (!internal::debug_pred(pred, val, *mid))
213  src = ++mid, dist -= halfDist + 1;
214  else
215  dist = halfDist;
216  }
217  return src;
218  }
219 
220  template <typename TIter, typename TComp>
221  inline constexpr bool binary_search (TIter first, TIter last, const TComp& value) {
222  TIter found = mn::lower_bound (first, last, value);
223  return found != last && !(value < *found);
224  }
225 
226 
227 
228 
229  MN_TEMPLATE_FULL_DECL_TWO(class, TIter, typename, T)
230  TIter find(TIter src, TIter last, const T& val) {
231  while (src != last) {
232  if ((*src) == val) return src;
233  ++src;
234  }
235  return last;
236  }
237 
238  MN_TEMPLATE_FULL_DECL_THREE(class ,TIter, typename, T, class, TPred = mn::less<TIter>)
239  TIter find_if(TIter src, TIter last, const T& val, const TPred& pred) {
240  while (src != last) {
241  if (pred(*src, val))
242  return src;
243  ++src;
244  }
245  return last;
246  }
247 
248  MN_TEMPLATE_FULL_DECL_TWO(class, TIter, typename, T)
249  void accumulate(TIter src, TIter last, T& dest) {
250  while (src != last) {
251  dest += *src; ++src;
252  }
253  }
254 
255  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
256  T abs(const T& t) {
257  return t >= T(0) ? t : -t;
258  }
259  template<int>
260  inline int abs(const int& x) {
261  const int y = x >> 31;
262  return (x ^ y) - y;
263  }
264  template<short>
265  inline short abs(const short& x) {
266  const short y = x >> 15;
267  return (x ^ y) - y;
268  }
269 
270  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
271  inline bool is_range(const T ch, const T min, const T max) { return (ch >= min && ch <= max); }
272 
273  inline bool islower(char ch) { return is_range<char>(ch, 0x61, 0x7A); }
274 
275  inline bool isupper(char ch) { return is_range<char>(ch, 0x41, 0x5A); }
276 
277  inline bool isalpha(char ch) { return (isupper(ch) || islower(ch) ); }
278 
279  inline bool isdigit(char ch) { return is_range<char>(ch, 0x30, 0x39); }
280 
281  inline bool iscntrl(char ch) { return is_range<char>(ch, 0x00, 0x1F) || ch == 0x7F; }
282 
283  inline bool isspace(char ch) { return is_range<char>(ch, 0x09, 0x0D) || ch == 0x20; }
284 
285  inline bool isblank(char ch) { return ch == 0x09 || ch == 0x20; }
286 
287  inline bool isgraph(char ch) { return is_range<char>(ch, 0x21, 0x7E); }
288 
289  inline bool isprint(char ch) { return (isgraph(ch) || ch == 0x20 ); }
290 
291  inline bool isxdigit(char ch){ return isdigit(ch) || is_range<char>(ch, 0x41, 0x46) || is_range<char>(ch, 0x61, 0x66); }
292 
293  inline bool isalnum(char ch) { return isdigit(ch) || isalpha(ch); }
294 
295  inline char hex2char(char ch) {
296  return ( isdigit(ch) ) ? ch - 48 : ( islower(ch) ) ? ch - 87 :
297  ( isupper(ch) ) ? ch - 55 : 0;
298  }
299 
300 
301  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
302  inline T max(const T x, const T y) {
303  return x > y ? x : y;
304  }
305 
306  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
307  inline T min(const T x, const T y) {
308  return x < y ? x : y;
309  }
310 
311  MN_TEMPLATE_FULL_DECL_ONE(typename, TAssignable)
312  void swap(TAssignable& a, TAssignable& b) {
313  TAssignable tmp = mn::move(a);
314 
315  a = mn::move(b);
316  b = mn::move(tmp);
317  }
318 
319  MN_TEMPLATE_FULL_DECL_TWO(typename, TAssignable, size_t, N)
320  inline void swap(TAssignable (&x)[N], TAssignable (&y)[N]) {
321  for (size_t i = 0; i < N; i++)
322  mn::swap(x[i], y[i]);
323  }
324 
325  MN_TEMPLATE_FULL_DECL_TWO(typename, fIt1, typename, fIt2 )
326  inline void iter_swap(fIt1 a, fIt2 b) {
327  mn::swap(*a, *b);
328  }
329 
330  MN_TEMPLATE_FULL_DECL_TWO(typename, fIt1, typename, fIt2 )
331  fIt2 swap_ranges(fIt1 a, fIt1 b, fIt2 c) {
332  for (; a != b; ++a, ++c)
333  mn::iter_swap(*a, *c);
334  return c;
335  }
336 
337  template <typename TRandomAccessIterator, typename TRandFunc>
338  void random_shuffle (TRandomAccessIterator first, TRandomAccessIterator last, const TRandFunc& func) {
339  for (; first != last; ++ first)
340  mn::iter_swap (first, first + (func() % distance (first, last)));
341  }
342 
343  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
344  struct value2size {
345  enum { size = sizeof(T) * 8 };
346  };
347  MN_TEMPLATE_FULL_DECL_ONE(typename, T)
348  struct value2size_raw {
349  enum { size = sizeof(T) };
350  };
351 }
352 
353 #endif
#define MN_TEMPLATE_FULL_DECL_THREE(d1, t1, d2, t2, d3, t3)
Definition: mn_defines.hpp:27
#define MN_TEMPLATE_FULL_DECL_ONE(d1, t1)
Definition: mn_defines.hpp:25
#define MN_TEMPLATE_FULL_DECL_TWO(d1, t1, d2, t2)
Definition: mn_defines.hpp:26
This file is part of the Mini Thread Library (https://github.com/RoseLeBlood/MiniThread ).
void construct_n(T *to, mn::size_t count, int_to_type< false >)
Definition: mn_utils.hpp:147
void destruct_n(T *first, mn::size_t n, int_to_type< false >)
Definition: mn_utils.hpp:104
void move_n(const T *from, mn::size_t n, T *result, int_to_type< false >)
Definition: mn_utils.hpp:68
bool debug_pred(const TPred &pred, const T1 &a, const T2 &b)
Definition: mn_utils.hpp:164
void copy_construct(T *mem, const T &orig, int_to_type< false >)
Definition: mn_utils.hpp:137
void copy_n(const T *first, mn::size_t n, T *result, int_to_type< false >)
Definition: mn_utils.hpp:36
void construct(T *mem, int_to_type< false >)
Definition: mn_utils.hpp:127
void move(const T *first, const T *last, T *result, int_to_type< false >)
Definition: mn_utils.hpp:79
void copy(const T *first, const T *last, T *result, int_to_type< false >)
Definition: mn_utils.hpp:56
void copy_construct_n(const T *first, mn::size_t n, T *result, int_to_type< false >)
Definition: mn_utils.hpp:92
void test_ordering(TIter first, TIter last, const TPred &pred)
Definition: mn_utils.hpp:159
void destruct(T *mem, int_to_type< false >)
Definition: mn_utils.hpp:116
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
Definition: mn_allocator_typetraits.hpp:25
char hex2char(char ch)
Definition: mn_algorithm.hpp:295
bool islower(char ch)
Definition: mn_algorithm.hpp:273
void fill_n(T *src, size_t n, const T &val)
Definition: mn_algorithm.hpp:142
void construct_n(T *src, size_t n)
Definition: mn_algorithm.hpp:127
bool isdigit(char ch)
Definition: mn_algorithm.hpp:279
bool isspace(char ch)
Definition: mn_algorithm.hpp:283
void iter_swap(fIt1 a, fIt2 b)
Definition: mn_algorithm.hpp:326
void destruct(T *mem)
Definition: mn_algorithm.hpp:61
void move_n(const T *from, size_t n, T *dest)
Definition: mn_algorithm.hpp:89
constexpr bool binary_search(TIter first, TIter last, const TComp &value)
Definition: mn_algorithm.hpp:221
T * copy_backward(const T *first, const T *last, T *result) noexcept
Definition: mn_algorithm.hpp:113
void destruct_n(T *src, size_t n)
Definition: mn_algorithm.hpp:131
T max(const T x, const T y)
Definition: mn_algorithm.hpp:302
size_t popcount(uint32_t v)
Definition: mn_algorithm.hpp:38
TIter find(TIter src, TIter last, const T &val)
Definition: mn_algorithm.hpp:230
constexpr iterator_traits< TIter >::difference_type distance(TIter first, TIter last)
Definition: mn_iterator.hpp:100
T min(const T x, const T y)
Definition: mn_algorithm.hpp:307
bool isgraph(char ch)
Definition: mn_algorithm.hpp:287
bool is_range(const T ch, const T min, const T max)
Definition: mn_algorithm.hpp:271
bool isalnum(char ch)
Definition: mn_algorithm.hpp:293
bool isxdigit(char ch)
Definition: mn_algorithm.hpp:291
void accumulate(TIter src, TIter last, T &dest)
Definition: mn_algorithm.hpp:249
bool isalpha(char ch)
Definition: mn_algorithm.hpp:277
TIter find_if(TIter src, TIter last, const T &val, const TPred &pred)
Definition: mn_algorithm.hpp:239
bool isprint(char ch)
Definition: mn_algorithm.hpp:289
void swap(TAssignable &a, TAssignable &b)
Definition: mn_algorithm.hpp:312
bool isblank(char ch)
Definition: mn_algorithm.hpp:285
void copy_construct(T *mem, const T &orig)
Definition: mn_algorithm.hpp:45
fIt2 swap_ranges(fIt1 a, fIt1 b, fIt2 c)
Definition: mn_algorithm.hpp:331
void random_shuffle(TRandomAccessIterator first, TRandomAccessIterator last, const TRandFunc &func)
Definition: mn_algorithm.hpp:338
constexpr TIter upper_bound(TIter first, TIter last, const TPred &value)
Definition: mn_algorithm.hpp:191
TFn foreach(TIter src, TIter last, TFn fn)
Definition: mn_algorithm.hpp:119
void copy_construct_n(T *src, size_t n, T *dest)
Definition: mn_algorithm.hpp:84
void copy(const T *src, const T *last, T *dest)
Definition: mn_algorithm.hpp:79
T abs(const T &t)
Definition: mn_algorithm.hpp:256
void fill(T *src, T *last, const T &val)
Definition: mn_algorithm.hpp:135
constexpr void advance(TIter &iter, TDistance d)
Definition: mn_iterator.hpp:105
void construct(T *mem)
Definition: mn_algorithm.hpp:55
constexpr TIter lower_bound(TIter first, TIter last, const TPred &value)
Definition: mn_algorithm.hpp:160
void move(const T *src, const T *last, T *dest)
Definition: mn_algorithm.hpp:100
bool isupper(char ch)
Definition: mn_algorithm.hpp:275
void copy_n(const T *src, size_t n, T *dest)
Copy N elements from src to dest.
Definition: mn_algorithm.hpp:74
MN_THREAD_CONFIG_SIZE_TYPE size_t
Definition: mn_def.hpp:48
bool iscntrl(char ch)
Definition: mn_algorithm.hpp:281
Definition: mn_typetraits.hpp:361
Definition: mn_typetraits.hpp:365
Definition: mn_typetraits.hpp:373
Definition: mn_inttokey.hpp:25
Definition: mn_utils.hpp:175
Definition: mn_algorithm.hpp:348
Definition: mn_algorithm.hpp:344