Documentation
Tools for embedded systems
Loading...
Searching...
No Matches
algorithm.hpp
1#ifndef QLIBS_ALGORITHM
2#define QLIBS_ALGORITHM
3
4#include <include/qlibs_types.hpp>
5
13
14
18namespace qlibs {
19
23 namespace algorithm {
29
35 template <typename T>
36 void swap( T& x, T& y ) noexcept
37 {
38 T tmp = x;
39 x = y;
40 y = tmp;
41 }
42
44 namespace impl {
45 struct sort_pair {
46 int first;
47 int second;
48 };
49 template<typename T, size_t N>
50 class sort_stack {
51 private:
52 T dat[ N ];
53 size_t topIndex;
54 public:
55 sort_stack() : topIndex( 0 ) {}
56 bool empty( void ) const noexcept
57 {
58 return 0 == topIndex;
59 }
60 void push( const T& value ) noexcept
61 {
62 if ( topIndex < N ) {
63 dat[ topIndex++ ] = value;
64 }
65 }
66 void pop( void ) noexcept
67 {
68 if ( topIndex > 0 ) {
69 --topIndex;
70 }
71 }
72 T& top( void ) noexcept
73 {
74 return dat[ topIndex - 1 ];
75 }
76 };
77 }
79
97 template<typename T, size_t n>
98 void sort( T ( &array )[ n ],
99 size_t first = 0U,
100 size_t last = n - 1U,
101 bool (*comp)( const T&, const T&) = nullptr ) noexcept
102 {
103 if ( n > 1U ) {
104 algorithm::impl::sort_stack<impl::sort_pair, n> stack;
105 int start = static_cast<int>( first );
106 int end = static_cast<int>( last );
107
108 stack.push( { start, end } );
109 while ( !stack.empty() ) {
110 impl::sort_pair indices = stack.top();
111 stack.pop();
112 start = indices.first;
113 end = indices.second;
114 int pivotIndex = start;
115 T pivotValue = array[ end ];
116
117 for ( int i = start; i < end; ++i ) {
118 if ( nullptr != comp ) {
119 if ( comp( array[ i ], array[ pivotIndex ] ) ) {
120 algorithm::swap( array[ i ], array[ pivotIndex ] );
121 ++pivotIndex;
122 }
123 }
124 else if ( array[ i ] < pivotValue ) {
125 algorithm::swap( array[ i ], array[ pivotIndex ] );
126 ++pivotIndex;
127 }
128 }
129 algorithm::swap( array[ pivotIndex ], array[ end ] );
130 if ( pivotIndex - 1 > start ) {
131 stack.push( { start, pivotIndex - 1 } );
132 }
133 if ( pivotIndex + 1 < end ) {
134 stack.push( { pivotIndex + 1, end } );
135 }
136 }
137 }
138 }
139
146 template<typename T, size_t n>
147 inline void reverse( T ( &array )[ n ],
148 const size_t first = 0U,
149 const size_t last = n - 1U ) noexcept
150 {
151 if ( last > first ) {
152 size_t s = first, e = last;
153
154 while ( s < e ) {
155 algorithm::swap( array[ s ], array[ e ] );
156 ++s;
157 --e;
158 }
159 }
160 }
161
169 template<typename T, size_t n>
170 void rotate( T ( &array )[ n ],
171 const int k = 1 ) noexcept
172 {
173 if ( 0 != k ) {
174 size_t r;
175 if ( k > 0 ) {
176 r = static_cast<size_t>( k );
177 r %= n;
178 algorithm::reverse( array, n - r, n - 1U );
179 algorithm::reverse( array, 0U, n - r - 1U );
180 algorithm::reverse( array, 0U, n - 1U );
181 }
182 else {
183 /*cstat -MISRAC++2008-5-0-9*/
184 r = static_cast<size_t>( -k );
185 /*cstat +MISRAC++2008-5-0-9*/
186 r %= n;
187 algorithm::reverse( array, 0U, r - 1U );
188 algorithm::reverse( array, r, n - 1U );
189 algorithm::reverse( array, 0U, n - 1U );
190 }
191 }
192 }
193
202 template<typename T, size_t n>
203 inline void fill( T ( &array )[ n ],
204 const T value,
205 const size_t first = 0U,
206 const size_t last = n - 1U ) noexcept
207 {
208 for ( size_t i = first ; i <= last; ++i ) {
209 array[ i ] = value;
210 }
211 }
212
227 template<typename T, size_t n>
228 inline T* find( T ( &array )[ n ],
229 const T key,
230 const size_t first = 0U,
231 const size_t last = n - 1U ) noexcept
232 {
233 T* found = nullptr;
234
235 for ( size_t i = first; i <= last; ++i ) {
236 if ( array[ i ] == key ) {
237 found = &array[ i ];
238 break;
239 }
240 }
241 return found;
242 }
243
257 template<typename T, size_t n>
258 inline bool any_of( T ( &array )[ n ],
259 bool (*pred)( const T ),
260 const size_t first = 0U,
261 const size_t last = n - 1U ) noexcept
262 {
263 bool ret = false;
264
265 for ( size_t i = first; i <= last; ++i ) {
266 if ( pred( array[ i ] ) ) {
267 ret = true;
268 break;
269 }
270 }
271 return ret;
272 }
273
287 template<typename T, size_t n>
288 inline bool all_of( T ( &array )[ n ],
289 bool (*pred)( const T ),
290 const size_t first = 0U,
291 const size_t last = n - 1U ) noexcept
292 {
293 bool ret = true;
294
295 for ( size_t i = first; i <= last; ++i ) {
296 if ( !pred( array[ i ] ) ) {
297 ret = false;
298 break;
299 }
300 }
301 return ret;
302 }
303
314 template<typename T, size_t n>
315 inline void replace( T ( &array )[ n ],
316 const T& old_value,
317 const T& new_value,
318 const size_t first = 0U,
319 const size_t last = n - 1U ) noexcept
320 {
321 for ( size_t i = first; i <= last; ++i ) {
322 if ( old_value == array[ i ] ) {
323 array[ i ] = new_value;
324 break;
325 }
326 }
327 }
328
340 template<typename T, size_t n>
341 inline void replace_if( T ( &array )[ n ],
342 bool (*pred)( const T& ),
343 const T& new_value,
344 const size_t first = 0U,
345 const size_t last = n - 1U ) noexcept
346 {
347 for ( size_t i = first; i <= last; ++i ) {
348 if ( pred( array[ i ] ) ) {
349 array[ i ] = new_value;
350 break;
351 }
352 }
353 }
354
367 template<typename T, size_t n>
368 inline size_t count_if( T ( &array )[ n ],
369 bool (*pred)( const T ),
370 const size_t first = 0U,
371 const size_t last = n - 1U ) noexcept
372 {
373 size_t count = 0U;
374
375 for ( size_t i = first; i <= last; ++i ) {
376 if ( pred( array[ i ] ) ) {
377 ++count;
378 }
379 }
380 return count;
381 }
382
398 template<typename T, size_t n>
399 inline T* find_if( T ( &array )[ n ],
400 bool (*pred)( const T ),
401 const size_t first = 0U,
402 const size_t last = n - 1U ) noexcept
403 {
404 T *found = nullptr;
405
406 for ( size_t i = first; i <= last; ++i ) {
407 if ( pred( array[ i ] ) ) {
408 found = &array[ i ];
409 }
410 }
411 return found;
412 }
413
423 template<typename T, size_t n>
424 inline void for_each( T ( &array )[ n ],
425 void (*fn)( T& ),
426 const size_t first = 0U,
427 const size_t last = n - 1U ) noexcept
428 {
429 for ( size_t i = first; i <= last; ++i ) {
430 (void)fn( array[ i ] );
431 }
432 }
433
451 template<typename T, size_t n>
452 inline T* binary_search( T ( &array )[ n ],
453 const T key,
454 const size_t first = 0U,
455 const size_t last = n - 1U ) noexcept
456 {
457 T* found = nullptr;
458 int left = static_cast<int>( first );
459 int right = static_cast<int>( last );
460
461 while ( left <= right ) {
462 int mid = left + ( right - left )/2;
463
464 if ( array[ mid ] == key ) {
465 found = &array[ mid ];
466 break;
467 }
468 if ( array[ mid ] < key ) {
469 left = mid + 1;
470 }
471 else {
472 right = mid - 1;
473 }
474 }
475 return found;
476 }
477
479 }
480}
481
482
483#endif /*QLIBS_ALGORITHM*/
void reverse(T(&array)[n], const size_t first=0U, const size_t last=n - 1U) noexcept
Reverses the order of the elements in the range [first,last).
Definition algorithm.hpp:147
void swap(T &x, T &y) noexcept
Exchanges the values of a and b.
Definition algorithm.hpp:36
void sort(T(&array)[n], size_t first=0U, size_t last=n - 1U, bool(*comp)(const T &, const T &)=nullptr) noexcept
Sorts the given array in the range [first,last) into ascending order.
Definition algorithm.hpp:98
void replace(T(&array)[n], const T &old_value, const T &new_value, const size_t first=0U, const size_t last=n - 1U) noexcept
Replaces all elements satisfying specific criteria with new_value in the range [first,...
Definition algorithm.hpp:315
void rotate(T(&array)[n], const int k=1) noexcept
Rotates k elements of the array. Rotation direction is determined by the sign of k,...
Definition algorithm.hpp:170
T * binary_search(T(&array)[n], const T key, const size_t first=0U, const size_t last=n - 1U) noexcept
Returns a pointer to the first element in the range [first,last) that compares equal to key....
Definition algorithm.hpp:452
bool any_of(T(&array)[n], bool(*pred)(const T), const size_t first=0U, const size_t last=n - 1U) noexcept
Returns true if pred returns true for any of the elements in the range [first,last),...
Definition algorithm.hpp:258
T * find_if(T(&array)[n], bool(*pred)(const T), const size_t first=0U, const size_t last=n - 1U) noexcept
Returns an iterator to the first element in the range [first,last) for which pred returns true....
Definition algorithm.hpp:399
void replace_if(T(&array)[n], bool(*pred)(const T &), const T &new_value, const size_t first=0U, const size_t last=n - 1U) noexcept
Replaces all elements satisfying specific criteria with new_value in the range [first,...
Definition algorithm.hpp:341
void fill(T(&array)[n], const T value, const size_t first=0U, const size_t last=n - 1U) noexcept
Assigns value to all the elements of the array in the range [first,last).
Definition algorithm.hpp:203
void for_each(T(&array)[n], void(*fn)(T &), const size_t first=0U, const size_t last=n - 1U) noexcept
Applies function fn to each of the elements in the range [first,last).
Definition algorithm.hpp:424
bool all_of(T(&array)[n], bool(*pred)(const T), const size_t first=0U, const size_t last=n - 1U) noexcept
Returns true if pred returns true for all the elements in the range [first,last), and false otherwise...
Definition algorithm.hpp:288
T * find(T(&array)[n], const T key, const size_t first=0U, const size_t last=n - 1U) noexcept
Returns a pointer to the first element in the range [first,last) that compares equal to key....
Definition algorithm.hpp:228
size_t count_if(T(&array)[n], bool(*pred)(const T), const size_t first=0U, const size_t last=n - 1U) noexcept
Returns the number of elements in the range [first,last) for which pred is true.
Definition algorithm.hpp:368
The generic namespace.
Definition algorithm.hpp:23
The qLibs++ library namespace.
Definition mat.hpp:18