FastLED 3.10.8
Loading...
Searching...
No Matches
algorithm.h
Go to the documentation of this file.
1#pragma once
2
5#include "fl/stl/move.h"
6#include "fl/math/random.h"
7#include "fl/stl/noexcept.h"
8
9namespace fl {
10
11namespace adl_barrier { // see fl/stl/adl_barrier.h
12
13template <typename Iterator>
14void reverse(Iterator first, Iterator last) FL_NO_EXCEPT {
15 while ((first != last) && (first != --last)) {
16 swap(*first++, *last);
17 }
18}
19
20template <typename Iterator>
21Iterator max_element(Iterator first, Iterator last) FL_NO_EXCEPT {
22 if (first == last) {
23 return last;
24 }
25
26 Iterator max_iter = first;
27 ++first;
28
29 while (first != last) {
30 if (*max_iter < *first) {
31 max_iter = first;
32 }
33 ++first;
34 }
35
36 return max_iter;
37}
38
39template <typename Iterator, typename Compare>
40Iterator max_element(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
41 if (first == last) {
42 return last;
43 }
44
45 Iterator max_iter = first;
46 ++first;
47
48 while (first != last) {
49 if (comp(*max_iter, *first)) {
50 max_iter = first;
51 }
52 ++first;
53 }
54
55 return max_iter;
56}
57
58template <typename Iterator>
59Iterator min_element(Iterator first, Iterator last) FL_NO_EXCEPT {
60 if (first == last) {
61 return last;
62 }
63
64 Iterator min_iter = first;
65 ++first;
66
67 while (first != last) {
68 if (*first < *min_iter) {
69 min_iter = first;
70 }
71 ++first;
72 }
73
74 return min_iter;
75}
76
77template <typename Iterator, typename Compare>
78Iterator min_element(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
79 if (first == last) {
80 return last;
81 }
82
83 Iterator min_iter = first;
84 ++first;
85
86 while (first != last) {
87 if (comp(*first, *min_iter)) {
88 min_iter = first;
89 }
90 ++first;
91 }
92
93 return min_iter;
94}
95
96
97
98template <typename Iterator1, typename Iterator2>
99bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2) FL_NO_EXCEPT {
100 while (first1 != last1) {
101 if (*first1 != *first2) {
102 return false;
103 }
104 ++first1;
105 ++first2;
106 }
107 return true;
108}
109
110template <typename Iterator1, typename Iterator2, typename BinaryPredicate>
111bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate pred) FL_NO_EXCEPT {
112 while (first1 != last1) {
113 if (!pred(*first1, *first2)) {
114 return false;
115 }
116 ++first1;
117 ++first2;
118 }
119 return true;
120}
121
122template <typename Iterator1, typename Iterator2>
123bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) FL_NO_EXCEPT {
124 while (first1 != last1 && first2 != last2) {
125 if (*first1 != *first2) {
126 return false;
127 }
128 ++first1;
129 ++first2;
130 }
131 return first1 == last1 && first2 == last2;
132}
133
134template <typename Iterator1, typename Iterator2, typename BinaryPredicate>
135bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, BinaryPredicate pred) FL_NO_EXCEPT {
136 while (first1 != last1 && first2 != last2) {
137 if (!pred(*first1, *first2)) {
138 return false;
139 }
140 ++first1;
141 ++first2;
142 }
143 return first1 == last1 && first2 == last2;
144}
145
146// Lexicographical comparison - compares two ranges element by element
147// Returns true if the first range is lexicographically less than the second
148template <typename Iterator1, typename Iterator2>
149bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) FL_NO_EXCEPT {
150 while (first1 != last1 && first2 != last2) {
151 if (*first1 < *first2) {
152 return true;
153 }
154 if (*first2 < *first1) {
155 return false;
156 }
157 ++first1;
158 ++first2;
159 }
160 // If we've exhausted first1 but not first2, first1 is less
161 // If we've exhausted both, they're equal (return false)
162 // If we've exhausted first2 but not first1, first2 is less (return false)
163 return (first1 == last1) && (first2 != last2);
164}
165
166// Lexicographical comparison with custom comparator
167template <typename Iterator1, typename Iterator2, typename Compare>
168bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) FL_NO_EXCEPT {
169 while (first1 != last1 && first2 != last2) {
170 if (comp(*first1, *first2)) {
171 return true;
172 }
173 if (comp(*first2, *first1)) {
174 return false;
175 }
176 ++first1;
177 ++first2;
178 }
179 // If we've exhausted first1 but not first2, first1 is less
180 // If we've exhausted both, they're equal (return false)
181 // If we've exhausted first2 but not first1, first2 is less (return false)
182 return (first1 == last1) && (first2 != last2);
183}
184
185template <typename Container1, typename Container2>
186bool equal_container(const Container1& c1, const Container2& c2) FL_NO_EXCEPT {
187 fl::size size1 = c1.size();
188 fl::size size2 = c2.size();
189 if (size1 != size2) {
190 return false;
191 }
192 return equal(c1.begin(), c1.end(), c2.begin(), c2.end());
193}
194
195template <typename Container1, typename Container2, typename BinaryPredicate>
196bool equal_container(const Container1& c1, const Container2& c2, BinaryPredicate pred) FL_NO_EXCEPT {
197 fl::size size1 = c1.size();
198 fl::size size2 = c2.size();
199 if (size1 != size2) {
200 return false;
201 }
202 return equal(c1.begin(), c1.end(), c2.begin(), c2.end(), pred);
203}
204
205
206template <typename Iterator, typename T>
207void fill(Iterator first, Iterator last, const T& value) FL_NO_EXCEPT {
208 while (first != last) {
209 *first = value;
210 ++first;
211 }
212}
213
214template <typename Iterator, typename T>
215Iterator find(Iterator first, Iterator last, const T& value) FL_NO_EXCEPT {
216 while (first != last) {
217 if (*first == value) {
218 return first;
219 }
220 ++first;
221 }
222 return last;
223}
224
225template <typename Iterator, typename UnaryPredicate>
226Iterator find_if(Iterator first, Iterator last, UnaryPredicate pred) FL_NO_EXCEPT {
227 while (first != last) {
228 if (pred(*first)) {
229 return first;
230 }
231 ++first;
232 }
233 return last;
234}
235
236template <typename Iterator, typename UnaryPredicate>
237Iterator find_if_not(Iterator first, Iterator last, UnaryPredicate pred) FL_NO_EXCEPT {
238 while (first != last) {
239 if (!pred(*first)) {
240 return first;
241 }
242 ++first;
243 }
244 return last;
245}
246
247template <typename Iterator, typename T>
248void replace(Iterator first, Iterator last, const T& old_value, const T& new_value) FL_NO_EXCEPT {
249 while (first != last) {
250 if (*first == old_value) {
251 *first = new_value;
252 }
253 ++first;
254 }
255}
256
257template <typename Iterator, typename UnaryPredicate, typename T>
258void replace_if(Iterator first, Iterator last, UnaryPredicate pred, const T& new_value) FL_NO_EXCEPT {
259 while (first != last) {
260 if (pred(*first)) {
261 *first = new_value;
262 }
263 ++first;
264 }
265}
266
267template <typename Iterator, typename T>
268Iterator remove(Iterator first, Iterator last, const T& value) FL_NO_EXCEPT {
269 Iterator result = first;
270 while (first != last) {
271 if (!(*first == value)) {
272 if (result != first) {
273 *result = fl::move(*first);
274 }
275 ++result;
276 }
277 ++first;
278 }
279 return result;
280}
281
282template <typename Iterator, typename UnaryPredicate>
283Iterator remove_if(Iterator first, Iterator last, UnaryPredicate pred) FL_NO_EXCEPT {
284 Iterator result = first;
285 while (first != last) {
286 if (!pred(*first)) {
287 if (result != first) {
288 *result = fl::move(*first);
289 }
290 ++result;
291 }
292 ++first;
293 }
294 return result;
295}
296
297} // namespace adl_barrier
298
299namespace detail {
300
301// Insertion sort implementation for small arrays
302template <typename Iterator, typename Compare>
303void insertion_sort(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
304 if (first == last) return;
305
306 for (Iterator i = first + 1; i != last; ++i) {
307 auto value = fl::move(*i);
308 Iterator j = i;
309
310 while (j != first && comp(value, *(j - 1))) {
311 *j = fl::move(*(j - 1));
312 --j;
313 }
314
315 *j = fl::move(value);
316 }
317}
318
319// Median-of-three pivot selection
320template <typename Iterator, typename Compare>
321Iterator median_of_three(Iterator first, Iterator middle, Iterator last, Compare comp) FL_NO_EXCEPT {
322 if (comp(*middle, *first)) {
323 if (comp(*last, *middle)) {
324 return middle;
325 } else if (comp(*last, *first)) {
326 return last;
327 } else {
328 return first;
329 }
330 } else {
331 if (comp(*last, *first)) {
332 return first;
333 } else if (comp(*last, *middle)) {
334 return last;
335 } else {
336 return middle;
337 }
338 }
339}
340
341// Partition function for quicksort
342template <typename Iterator, typename Compare>
343Iterator partition(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
344 Iterator middle = first + (last - first) / 2;
345 Iterator pivot_iter = median_of_three(first, middle, last - 1, comp);
346
347 // Move pivot to end
348 swap(*pivot_iter, *(last - 1));
349 Iterator pivot = last - 1;
350
351 Iterator i = first;
352 for (Iterator j = first; j != pivot; ++j) {
353 if (comp(*j, *pivot)) {
354 swap(*i, *j);
355 ++i;
356 }
357 }
358
359 swap(*i, *pivot);
360 return i;
361}
362
363// Heapsort implementation (fallback for deep recursion)
364template <typename Iterator, typename Compare>
365void sift_down(Iterator first, Iterator start, Iterator end, Compare comp) FL_NO_EXCEPT {
366 Iterator root = start;
367
368 while (root - first <= (end - first - 2) / 2) {
369 Iterator child = first + 2 * (root - first) + 1;
370 Iterator swap_iter = root;
371
372 if (comp(*swap_iter, *child)) {
373 swap_iter = child;
374 }
375
376 if (child + 1 <= end && comp(*swap_iter, *(child + 1))) {
377 swap_iter = child + 1;
378 }
379
380 if (swap_iter == root) {
381 return;
382 } else {
383 swap(*root, *swap_iter);
384 root = swap_iter;
385 }
386 }
387}
388
389template <typename Iterator, typename Compare>
390void heapify(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
391 Iterator start = first + (last - first - 2) / 2;
392
393 while (true) {
394 sift_down(first, start, last - 1, comp);
395 if (start == first) {
396 break;
397 }
398 --start;
399 }
400}
401
402template <typename Iterator, typename Compare>
403void heap_sort(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
404 heapify(first, last, comp);
405
406 Iterator end = last - 1;
407 while (end > first) {
408 swap(*end, *first);
409 sift_down(first, first, end - 1, comp);
410 --end;
411 }
412}
413
414// Quicksort implementation
415template <typename Iterator, typename Compare>
416void quicksort_impl(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
417 if (last - first <= 16) { // Use insertion sort for small arrays
418 insertion_sort(first, last, comp);
419 return;
420 }
421
422 Iterator pivot = partition(first, last, comp);
423 quicksort_impl(first, pivot, comp);
424 quicksort_impl(pivot + 1, last, comp);
425}
426
427// Rotate elements in range [first, last) so that middle becomes the new first
428template <typename Iterator>
429void rotate_impl(Iterator first, Iterator middle, Iterator last) FL_NO_EXCEPT {
430 if (first == middle || middle == last) {
431 return;
432 }
433
434 Iterator next = middle;
435 while (first != next) {
436 swap(*first++, *next++);
437 if (next == last) {
438 next = middle;
439 } else if (first == middle) {
440 middle = next;
441 }
442 }
443}
444
445// Find the position where value should be inserted in sorted range [first, last)
446template <typename Iterator, typename T, typename Compare>
447Iterator lower_bound_impl(Iterator first, Iterator last, const T& value, Compare comp) FL_NO_EXCEPT {
448 auto count = last - first;
449 while (count > 0) {
450 auto step = count / 2;
451 Iterator it = first + step;
452 if (comp(*it, value)) {
453 first = ++it;
454 count -= step + 1;
455 } else {
456 count = step;
457 }
458 }
459 return first;
460}
461
462// In-place merge operation for merge sort (stable sort)
463template <typename Iterator, typename Compare>
464void merge_inplace(Iterator first, Iterator middle, Iterator last, Compare comp) FL_NO_EXCEPT {
465 // If one of the ranges is empty, nothing to merge
466 if (first == middle || middle == last) {
467 return;
468 }
469
470 // If arrays are small enough, use insertion-based merge
471 auto left_size = middle - first;
472 auto right_size = last - middle;
473 if (left_size + right_size <= 32) {
474 // Simple insertion-based merge for small arrays
475 Iterator left = first;
476 Iterator right = middle;
477
478 while (left < middle && right < last) {
479 if (!comp(*right, *left)) {
480 // left element is in correct position
481 ++left;
482 } else {
483 // right element needs to be inserted into left part
484 auto value = fl::move(*right);
485 Iterator shift_end = right;
486 Iterator shift_start = left;
487
488 // Shift elements to make room
489 while (shift_end > shift_start) {
490 *shift_end = fl::move(*(shift_end - 1));
491 --shift_end;
492 }
493
494 *left = fl::move(value);
495 ++left;
496 ++middle; // middle has shifted right
497 ++right;
498 }
499 }
500 return;
501 }
502
503 // For larger arrays, use rotation-based merge
504 if (left_size == 0 || right_size == 0) {
505 return;
506 }
507
508 if (left_size == 1) {
509 // Find insertion point for the single left element in right array
510 Iterator pos = lower_bound_impl(middle, last, *first, comp);
511 rotate_impl(first, middle, pos);
512 return;
513 }
514
515 if (right_size == 1) {
516 // Find insertion point for the single right element in left array
517 Iterator pos = lower_bound_impl(first, middle, *(last - 1), comp);
518 rotate_impl(pos, middle, last);
519 return;
520 }
521
522 // Divide both arrays and recursively merge
523 Iterator left_mid = first + left_size / 2;
524 Iterator right_mid = lower_bound_impl(middle, last, *left_mid, comp);
525
526 // Rotate to bring the two middle parts together
527 rotate_impl(left_mid, middle, right_mid);
528
529 // Update middle position
530 Iterator new_middle = left_mid + (right_mid - middle);
531
532 // Recursively merge the two parts
533 merge_inplace(first, left_mid, new_middle, comp);
534 merge_inplace(new_middle, right_mid, last, comp);
535}
536
537// Merge sort implementation (stable, in-place)
538template <typename Iterator, typename Compare>
539void mergesort_impl(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
540 auto size = last - first;
541 if (size <= 16) { // Use insertion sort for small arrays (it's stable)
542 insertion_sort(first, last, comp);
543 return;
544 }
545
546 Iterator middle = first + size / 2;
547 mergesort_impl(first, middle, comp);
548 mergesort_impl(middle, last, comp);
549 merge_inplace(first, middle, last, comp);
550}
551
552} // namespace detail
553
554namespace adl_barrier { // see fl/stl/adl_barrier.h
555
556// Lower bound: find first position in sorted [first, last) where value could be inserted.
557template <typename Iterator, typename T, typename Compare>
558Iterator lower_bound(Iterator first, Iterator last, const T& value, Compare comp) FL_NO_EXCEPT {
559 return detail::lower_bound_impl(first, last, value, comp);
560}
561
562template <typename Iterator, typename T>
563Iterator lower_bound(Iterator first, Iterator last, const T& value) FL_NO_EXCEPT {
564 typedef typename fl::remove_reference<decltype(*first)>::type value_type;
565 return detail::lower_bound_impl(first, last, value,
566 [](const value_type& a, const T& b) { return a < b; });
567}
568
569// Sort function with custom comparator (using quicksort)
570template <typename Iterator, typename Compare>
571void sort(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
572 if (first == last || first + 1 == last) {
573 return; // Already sorted or empty
574 }
575
576 detail::quicksort_impl(first, last, comp);
577}
578
579// Sort function with default comparator
580template <typename Iterator>
581void sort(Iterator first, Iterator last) FL_NO_EXCEPT {
582 // Use explicit template parameter to avoid C++14 auto in lambda
583 typedef typename fl::remove_reference<decltype(*first)>::type value_type;
584 sort(first, last, [](const value_type& a, const value_type& b) { return a < b; });
585}
586
587// Stable sort function with custom comparator (using merge sort)
588template <typename Iterator, typename Compare>
589void stable_sort(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
590 if (first == last || first + 1 == last) {
591 return; // Already sorted or empty
592 }
593
594 detail::mergesort_impl(first, last, comp);
595}
596
597// Stable sort function with default comparator
598template <typename Iterator>
599void stable_sort(Iterator first, Iterator last) FL_NO_EXCEPT {
600 // Use explicit template parameter to avoid C++14 auto in lambda
601 typedef typename fl::remove_reference<decltype(*first)>::type value_type;
602 stable_sort(first, last, [](const value_type& a, const value_type& b) { return a < b; });
603}
604
605// Direct call to insertion sort — meant for call sites with statically
606// bounded input (typically <= 16-32 elements). Skips the runtime fall-through
607// inside `quicksort_impl`, so the compiler does NOT instantiate the
608// quicksort + partition + heap_sort body at all. Per-instantiation savings
609// land in the function symbol that anchors the static-init chain
610// (`ClocklessIdf5` on ESP32-S3). See #2886 / #2907.
611//
612// Use `sort_small` when:
613// - the container's max size is bounded by construction (e.g. fl::vector_inlined<T, N>)
614// and N is small (rule of thumb: <= 32);
615// - O(n^2) worst-case is acceptable.
616//
617// Use `fl::sort` (quicksort) when the container is unbounded or large.
618template <typename Iterator, typename Compare>
619void sort_small(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT {
620 if (first == last || first + 1 == last) {
621 return; // Already sorted or empty
622 }
623 detail::insertion_sort(first, last, comp);
624}
625
626template <typename Iterator>
627void sort_small(Iterator first, Iterator last) FL_NO_EXCEPT {
628 typedef typename fl::remove_reference<decltype(*first)>::type value_type;
629 sort_small(first, last,
630 [](const value_type& a, const value_type& b) { return a < b; });
631}
632
633// Shuffle function with custom random generator (Fisher-Yates shuffle)
634template <typename Iterator, typename RandomGenerator>
635void shuffle(Iterator first, Iterator last, RandomGenerator& g) FL_NO_EXCEPT {
636 if (first == last) {
637 return; // Empty range, nothing to shuffle
638 }
639
640 auto n = last - first;
641 for (auto i = n - 1; i > 0; --i) {
642 // Generate random index from 0 to i (inclusive)
643 auto j = g() % (i + 1);
644
645 // Swap elements at positions i and j
646 swap(*(first + i), *(first + j));
647 }
648}
649
650// Shuffle function with fl::math::random instance
651template <typename Iterator>
652void shuffle(Iterator first, Iterator last, math::random& rng) FL_NO_EXCEPT {
653 if (first == last) {
654 return; // Empty range, nothing to shuffle
655 }
656
657 auto n = last - first;
658 for (auto i = n - 1; i > 0; --i) {
659 // Generate random index from 0 to i (inclusive)
660 auto j = rng(static_cast<u32>(i + 1));
661
662 // Swap elements at positions i and j
663 swap(*(first + i), *(first + j));
664 }
665}
666
667// Shuffle function with default random generator
668template <typename Iterator>
669void shuffle(Iterator first, Iterator last) FL_NO_EXCEPT {
670 shuffle(first, last, default_random());
671}
672
673} // namespace adl_barrier
674
675} // namespace fl
uint8_t pos
Definition Blur.ino:11
Keeps fl's generic templates out of argument-dependent lookup (ADL).
A random number generator class that wraps FastLED's random functions.
Definition random.h:25
void replace(Iterator first, Iterator last, const T &old_value, const T &new_value) FL_NO_EXCEPT
Definition algorithm.h:248
constexpr T * end(T(&array)[N]) FL_NO_EXCEPT
Iterator remove_if(Iterator first, Iterator last, UnaryPredicate pred) FL_NO_EXCEPT
Definition algorithm.h:283
Iterator max_element(Iterator first, Iterator last) FL_NO_EXCEPT
Definition algorithm.h:21
Iterator lower_bound(Iterator first, Iterator last, const T &value, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:558
bool equal_container(const Container1 &c1, const Container2 &c2) FL_NO_EXCEPT
Definition algorithm.h:186
Iterator find_if_not(Iterator first, Iterator last, UnaryPredicate pred) FL_NO_EXCEPT
Definition algorithm.h:237
Iterator min_element(Iterator first, Iterator last) FL_NO_EXCEPT
Definition algorithm.h:59
void sort_small(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:619
Iterator find_if(Iterator first, Iterator last, UnaryPredicate pred) FL_NO_EXCEPT
Definition algorithm.h:226
void replace_if(Iterator first, Iterator last, UnaryPredicate pred, const T &new_value) FL_NO_EXCEPT
Definition algorithm.h:258
bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) FL_NO_EXCEPT
Definition algorithm.h:149
void sort(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:571
void fill(Iterator first, Iterator last, const T &value) FL_NO_EXCEPT
Definition algorithm.h:207
void stable_sort(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:589
Iterator remove(Iterator first, Iterator last, const T &value) FL_NO_EXCEPT
Definition algorithm.h:268
bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2) FL_NO_EXCEPT
Definition algorithm.h:99
void reverse(Iterator first, Iterator last) FL_NO_EXCEPT
Definition algorithm.h:14
Iterator find(Iterator first, Iterator last, const T &value) FL_NO_EXCEPT
Definition algorithm.h:215
void shuffle(Iterator first, Iterator last, RandomGenerator &g) FL_NO_EXCEPT
Definition algorithm.h:635
Iterator partition(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:343
void mergesort_impl(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:539
void rotate_impl(Iterator first, Iterator middle, Iterator last) FL_NO_EXCEPT
Definition algorithm.h:429
Iterator lower_bound_impl(Iterator first, Iterator last, const T &value, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:447
void quicksort_impl(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:416
void heapify(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:390
void sift_down(Iterator first, Iterator start, Iterator end, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:365
Iterator median_of_three(Iterator first, Iterator middle, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:321
void heap_sort(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:403
void insertion_sort(Iterator first, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:303
void merge_inplace(Iterator first, Iterator middle, Iterator last, Compare comp) FL_NO_EXCEPT
Definition algorithm.h:464
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition s16x16x4.h:30
void swap(array< T, N > &lhs, array< T, N > &rhs) FL_NO_EXCEPT
Definition array.h:209
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
constexpr int type_rank< T >::value
math::random & default_random() FL_NO_EXCEPT
Global default random number generator instance.
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
constexpr enable_if< is_fixed_point< T >::value, T >::type step(T edge, T x) FL_NO_EXCEPT
InputGamut g
Definition rgbw.h:125
Base definition for an LED controller.