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
18namespace qlibs {
19
23 namespace algorithm {
36 template <typename T>
37 void swap( T& x, T& y ) noexcept
38 {
39 T tmp = x;
40 x = y;
41 y = tmp;
42 }
43
45 namespace impl {
46 struct sort_pair {
47 int first;
48 int second;
49 };
50 template<typename T, size_t N>
51 class sort_stack {
52 private:
53 T dat[ N ];
54 size_t topIndex;
55 public:
56 sort_stack() : topIndex( 0 ) {}
57 bool empty( void ) const noexcept
58 {
59 return 0 == topIndex;
60 }
61 void push( const T& value ) noexcept
62 {
63 if ( topIndex < N ) {
64 dat[ topIndex++ ] = value;
65 }
66 }
67 void pop( void ) noexcept
68 {
69 if ( topIndex > 0 ) {
70 --topIndex;
71 }
72 }
73 T& top( void ) noexcept
74 {
75 return dat[ topIndex - 1 ];
76 }
77 };
78 }
99 template<typename T, size_t n>
100 void sort( T ( &array )[ n ],
101 size_t first = 0U,
102 size_t last = n - 1U,
103 bool (*comp)( const T&, const T&) = nullptr ) noexcept
104 {
105 if ( n > 1U ) {
106 algorithm::impl::sort_stack<impl::sort_pair, n> stack;
107 int start = static_cast<int>( first );
108 int end = static_cast<int>( last );
109
110 stack.push( { start, end } );
111 while ( !stack.empty() ) {
112 impl::sort_pair indices = stack.top();
113 stack.pop();
114 start = indices.first;
115 end = indices.second;
116 int pivotIndex = start;
117 T pivotValue = array[ end ];
118
119 for ( int i = start; i < end; ++i ) {
120 if ( nullptr != comp ) {
121 if ( comp( array[ i ], array[ pivotIndex ] ) ) {
122 algorithm::swap( array[ i ], array[ pivotIndex ] );
123 ++pivotIndex;
124 }
125 }
126 else if ( array[ i ] < pivotValue ) {
127 algorithm::swap( array[ i ], array[ pivotIndex ] );
128 ++pivotIndex;
129 }
130 }
131 algorithm::swap( array[ pivotIndex ], array[ end ] );
132 if ( pivotIndex - 1 > start ) {
133 stack.push( { start, pivotIndex - 1 } );
134 }
135 if ( pivotIndex + 1 < end ) {
136 stack.push( { pivotIndex + 1, end } );
137 }
138 }
139 }
140 }
141
149 template<typename T, size_t n>
150 inline void reverse( T ( &array )[ n ],
151 const size_t first = 0U,
152 const size_t last = n - 1U ) noexcept
153 {
154 if ( last > first ) {
155 size_t s = first, e = last;
156
157 while ( s < e ) {
158 algorithm::swap( array[ s ], array[ e ] );
159 ++s;
160 --e;
161 }
162 }
163 }
164
173 template<typename T, size_t n>
174 void rotate( T ( &array )[ n ],
175 const int k = 1 ) noexcept
176 {
177 if ( 0 != k ) {
178 size_t r;
179 if ( k > 0 ) {
180 r = static_cast<size_t>( k );
181 r %= n;
182 algorithm::reverse( array, n - r, n - 1U );
183 algorithm::reverse( array, 0U, n - r - 1U );
184 algorithm::reverse( array, 0U, n - 1U );
185 }
186 else {
187 /*cstat -MISRAC++2008-5-0-9*/
188 r = static_cast<size_t>( -k );
189 /*cstat +MISRAC++2008-5-0-9*/
190 r %= n;
191 algorithm::reverse( array, 0U, r - 1U );
192 algorithm::reverse( array, r, n - 1U );
193 algorithm::reverse( array, 0U, n - 1U );
194 }
195 }
196 }
197
207 template<typename T, size_t n>
208 inline void fill( T ( &array )[ n ],
209 const T value,
210 const size_t first = 0U,
211 const size_t last = n - 1U ) noexcept
212 {
213 for ( size_t i = first ; i <= last; ++i ) {
214 array[ i ] = value;
215 }
216 }
217
232 template<typename T, size_t n>
233 inline T* find( T ( &array )[ n ],
234 const T key,
235 const size_t first = 0U,
236 const size_t last = n - 1U ) noexcept
237 {
238 T* found = nullptr;
239
240 for ( size_t i = first; i <= last; ++i ) {
241 if ( array[ i ] == key ) {
242 found = &array[ i ];
243 break;
244 }
245 }
246 return found;
247 }
248
262 template<typename T, size_t n>
263 inline bool any_of( T ( &array )[ n ],
264 bool (*pred)( const T ),
265 const size_t first = 0U,
266 const size_t last = n - 1U ) noexcept
267 {
268 bool ret = false;
269
270 for ( size_t i = first; i <= last; ++i ) {
271 if ( pred( array[ i ] ) ) {
272 ret = true;
273 break;
274 }
275 }
276 return ret;
277 }
278
292 template<typename T, size_t n>
293 inline bool all_of( T ( &array )[ n ],
294 bool (*pred)( const T ),
295 const size_t first = 0U,
296 const size_t last = n - 1U ) noexcept
297 {
298 bool ret = true;
299
300 for ( size_t i = first; i <= last; ++i ) {
301 if ( !pred( array[ i ] ) ) {
302 ret = false;
303 break;
304 }
305 }
306 return ret;
307 }
308
320 template<typename T, size_t n>
321 inline void replace( T ( &array )[ n ],
322 const T& old_value,
323 const T& new_value,
324 const size_t first = 0U,
325 const size_t last = n - 1U ) noexcept
326 {
327 for ( size_t i = first; i <= last; ++i ) {
328 if ( old_value == array[ i ] ) {
329 array[ i ] = new_value;
330 break;
331 }
332 }
333 }
334
347 template<typename T, size_t n>
348 inline void replace_if( T ( &array )[ n ],
349 bool (*pred)( const T& ),
350 const T& new_value,
351 const size_t first = 0U,
352 const size_t last = n - 1U ) noexcept
353 {
354 for ( size_t i = first; i <= last; ++i ) {
355 if ( pred( array[ i ] ) ) {
356 array[ i ] = new_value;
357 break;
358 }
359 }
360 }
361
374 template<typename T, size_t n>
375 inline size_t count_if( T ( &array )[ n ],
376 bool (*pred)( const T ),
377 const size_t first = 0U,
378 const size_t last = n - 1U ) noexcept
379 {
380 size_t count = 0U;
381
382 for ( size_t i = first; i <= last; ++i ) {
383 if ( pred( array[ i ] ) ) {
384 ++count;
385 }
386 }
387 return count;
388 }
389
405 template<typename T, size_t n>
406 inline T* find_if( T ( &array )[ n ],
407 bool (*pred)( const T ),
408 const size_t first = 0U,
409 const size_t last = n - 1U ) noexcept
410 {
411 T *found = nullptr;
412
413 for ( size_t i = first; i <= last; ++i ) {
414 if ( pred( array[ i ] ) ) {
415 found = &array[ i ];
416 }
417 }
418 return found;
419 }
420
431 template<typename T, size_t n>
432 inline void for_each( T ( &array )[ n ],
433 void (*fn)( T& ),
434 const size_t first = 0U,
435 const size_t last = n - 1U ) noexcept
436 {
437 for ( size_t i = first; i <= last; ++i ) {
438 (void)fn( array[ i ] );
439 }
440 }
441
459 template<typename T, size_t n>
460 inline T* binary_search( T ( &array )[ n ],
461 const T key,
462 const size_t first = 0U,
463 const size_t last = n - 1U ) noexcept
464 {
465 T* found = nullptr;
466 int left = static_cast<int>( first );
467 int right = static_cast<int>( last );
468
469 while ( left <= right ) {
470 int mid = left + ( right - left )/2;
471
472 if ( array[ mid ] == key ) {
473 found = &array[ mid ];
474 break;
475 }
476 if ( array[ mid ] < key ) {
477 left = mid + 1;
478 }
479 else {
480 right = mid - 1;
481 }
482 }
483 return found;
484 }
485
487 }
488}
489
490
491#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:150
void swap(T &x, T &y) noexcept
Exchanges the values of a and b.
Definition algorithm.hpp:37
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:100
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:321
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:174
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:460
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:263
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:406
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:348
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:208
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:432
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:293
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:233
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:375
The qLibs++ library namespace.
Definition fp16.cpp:4