FastLED 3.9.15
Loading...
Searching...
No Matches
tuple.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/cstddef.h"
5#include "fl/stl/noexcept.h"
6
7namespace fl {
8
9// Forward declaration
10template<typename... Ts> struct tuple;
11
12// Empty-tuple specialization
13template<>
14struct tuple<> {};
15
16// Recursive tuple: head + tail
17template<typename Head, typename... Tail>
18struct tuple<Head, Tail...> {
19 Head head;
20 tuple<Tail...> tail;
21
22 tuple() = default;
23
24 tuple(const Head& h, const Tail&... t) FL_NOEXCEPT
25 : head(h), tail(t...) {}
26
27 // Only enable rvalue constructor when Head is not a reference
28 // (prevents overload ambiguity when Head = const T&)
29 template<typename H = Head, typename... T,
30 typename = typename enable_if<!is_reference<H>::value>::type>
31 tuple(H&& h, T&&... t) FL_NOEXCEPT
33};
34
35// tuple_size
36template<typename T>
37struct tuple_size;
38
39template<typename... Ts>
40struct tuple_size< tuple<Ts...> > {
41 // Use enum instead of static constexpr to avoid ODR-use issues in C++11
42 enum : size_t { value = sizeof...(Ts) };
45 constexpr operator value_type() const FL_NOEXCEPT { return value; }
46 constexpr value_type operator()() const FL_NOEXCEPT { return value; }
47};
48
49// tuple_element
50template<size_t I, typename Tuple>
51struct tuple_element;
52
53template<typename Head, typename... Tail>
54struct tuple_element<0, tuple<Head, Tail...>> {
55 using type = Head;
56};
57
58template<size_t I, typename Head, typename... Tail>
59struct tuple_element<I, tuple<Head, Tail...>>
60 : tuple_element<I-1, tuple<Tail...>> {};
61
62// get<I>(tuple)
63template<size_t I, typename Head, typename... Tail>
66 return t.head;
67}
68
69template<size_t I, typename Head, typename... Tail>
70typename enable_if<I != 0, typename tuple_element<I, tuple<Head, Tail...>>::type&>::type
72 return get<I-1>(t.tail);
73}
74
75// const overloads
76template<size_t I, typename Head, typename... Tail>
77typename enable_if<I == 0, const Head&>::type
79 return t.head;
80}
81
82template<size_t I, typename Head, typename... Tail>
83typename enable_if<I != 0, const typename tuple_element<I, tuple<Head, Tail...>>::type&>::type
85 return get<I-1>(t.tail);
86}
87
88// rvalue overloads
89template<size_t I, typename Head, typename... Tail>
90typename enable_if<I == 0, Head&&>::type
92 return fl::move(t.head);
93}
94
95template<size_t I, typename Head, typename... Tail>
96typename enable_if<I != 0, typename tuple_element<I, tuple<Head, Tail...>>::type&&>::type
98 return get<I-1>(fl::move(t.tail));
99}
100
101// make_tuple
102template<typename... Ts>
103tuple<typename fl::decay<Ts>::type...>
107
108// C++11 requires out-of-class definitions for static constexpr members that are ODR-used
109// tuple_size<tuple<Ts...>>::value is inherited from integral_constant<size_t, sizeof...(Ts)>
110// which means we need to define integral_constant<T, v>::value
111// This is actually defined in type_traits.h where integral_constant is declared
112
113} // namespace fl
static const int H
Definition PerfDisc.ino:20
constexpr T && forward(typename remove_reference< T >::type &t) FL_NOEXCEPT
Definition s16x16x4.h:234
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition s16x16x4.h:28
fl::size size_t
Definition s16x16x4.h:223
tuple< typename fl::decay< Ts >::type... > make_tuple(Ts &&... args) FL_NOEXCEPT
Definition tuple.h:104
pair_element< I, T1, T2 >::type & get(pair< T1, T2 > &p) FL_NOEXCEPT
Definition pair.h:115
Base definition for an LED controller.
Definition crgb.hpp:179
corkscrew_args args
Definition old.h:149
#define FL_NOEXCEPT
tuple< Tail... > tail
Definition tuple.h:20
tuple(const Head &h, const Tail &... t) FL_NOEXCEPT
Definition tuple.h:24
tuple(H &&h, T &&... t) FL_NOEXCEPT
Definition tuple.h:31
constexpr value_type operator()() const FL_NOEXCEPT
Definition tuple.h:46