FastLED 3.9.15
Loading...
Searching...
No Matches
pair.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/move.h"
5#include "fl/type_traits.h"
6
7namespace fl {
8
9template <typename T1, typename T2> struct pair {
10 // Member typedefs for std::pair compatibility
11 using first_type = T1;
12 using second_type = T2;
13
14 T1 first = T1();
15 T2 second = T2();
16
17 // Default constructor
18 pair() = default;
19
20 // Constructor from values
23 pair(const T1 &k, const T2 &v) : first(k), second(v) {}
25
26 // Perfect forwarding constructor
27 template <typename U1, typename U2>
28 pair(U1&& u1, U2&& u2) : first(fl::forward<U1>(u1)), second(fl::forward<U2>(u2)) {}
29
30 // Copy constructor from different pair types
31 template <typename U1, typename U2>
32 pair(const pair<U1, U2> &other) : first(other.first), second(other.second) {}
33
34 // Move constructor from different pair types
35 template <typename U1, typename U2>
36 pair(pair<U1, U2> &&other) : first(fl::move(other.first)), second(fl::move(other.second)) {}
37
38 // Rule of 5: copy constructor, copy assignment, move constructor, move assignment, destructor
39 pair(const pair &other) = default;
40 pair &operator=(const pair &other) = default;
41 pair(pair &&other) noexcept : first(fl::move(other.first)), second(fl::move(other.second)) {}
42 pair &operator=(pair &&other) = default;
43
44 // Note: Template assignment operators removed to avoid issues with const members
45 // The default copy and move assignment operators will handle same-type assignments
46
47 // Swap member function
48 void swap(pair &other) noexcept {
49 fl::swap(first, other.first);
50 fl::swap(second, other.second);
51 }
52};
53
54// Comparison operators
55template <typename T1, typename T2, typename U1, typename U2>
56bool operator==(const pair<T1, T2> &lhs, const pair<U1, U2> &rhs) {
57 return lhs.first == rhs.first && lhs.second == rhs.second;
58}
59
60template <typename T1, typename T2, typename U1, typename U2>
61bool operator!=(const pair<T1, T2> &lhs, const pair<U1, U2> &rhs) {
62 return !(lhs == rhs);
63}
64
65template <typename T1, typename T2, typename U1, typename U2>
66bool operator<(const pair<T1, T2> &lhs, const pair<U1, U2> &rhs) {
67 return lhs.first < rhs.first || (!(rhs.first < lhs.first) && lhs.second < rhs.second);
68}
69
70template <typename T1, typename T2, typename U1, typename U2>
71bool operator<=(const pair<T1, T2> &lhs, const pair<U1, U2> &rhs) {
72 return !(rhs < lhs);
73}
74
75template <typename T1, typename T2, typename U1, typename U2>
76bool operator>(const pair<T1, T2> &lhs, const pair<U1, U2> &rhs) {
77 return rhs < lhs;
78}
79
80template <typename T1, typename T2, typename U1, typename U2>
81bool operator>=(const pair<T1, T2> &lhs, const pair<U1, U2> &rhs) {
82 return !(lhs < rhs);
83}
84
85// Non-member swap function
86template <typename T1, typename T2>
87void swap(pair<T1, T2> &lhs, pair<T1, T2> &rhs) noexcept {
88 lhs.swap(rhs);
89}
90
91// make_pair function
92template <typename T1, typename T2>
96
97// Helper for get function
98template <fl::size I, typename T1, typename T2>
100
101template <typename T1, typename T2>
102struct pair_element<0, T1, T2> {
103 using type = T1;
104};
105
106template <typename T1, typename T2>
107struct pair_element<1, T1, T2> {
108 using type = T2;
109};
110
111// get function overloads for tuple-like access by index
112template <fl::size I, typename T1, typename T2>
114 static_assert(I < 2, "Index out of bounds for pair");
115 if (I == 0) {
116 return p.first;
117 } else {
118 return p.second;
119 }
120}
121
122template <fl::size I, typename T1, typename T2>
123const typename pair_element<I, T1, T2>::type& get(const pair<T1, T2> &p) noexcept {
124 static_assert(I < 2, "Index out of bounds for pair");
125 if (I == 0) {
126 return p.first;
127 } else {
128 return p.second;
129 }
130}
131
132template <fl::size I, typename T1, typename T2>
134 static_assert(I < 2, "Index out of bounds for pair");
135 if (I == 0) {
136 return fl::move(p.first);
137 } else {
138 return fl::move(p.second);
139 }
140}
141
142// get by type overloads (when T1 and T2 are different types)
143template <typename T, typename T1, typename T2>
144T& get(pair<T1, T2> &p) noexcept {
146 "Type T must be one of the pair's element types");
148 "Type T must be unique in the pair");
150 return p.first;
151 } else {
152 return p.second;
153 }
154}
155
156template <typename T, typename T1, typename T2>
157const T& get(const pair<T1, T2> &p) noexcept {
159 "Type T must be one of the pair's element types");
161 "Type T must be unique in the pair");
163 return p.first;
164 } else {
165 return p.second;
166 }
167}
168
169template <typename T, typename T1, typename T2>
170T&& get(pair<T1, T2> &&p) noexcept {
172 "Type T must be one of the pair's element types");
174 "Type T must be unique in the pair");
176 return fl::move(p.first);
177 } else {
178 return fl::move(p.second);
179 }
180}
181
182// Tuple-like helper classes
183template <typename T>
185
186template <typename T1, typename T2>
187struct tuple_size<pair<T1, T2>> {
188 static constexpr fl::size value = 2;
189};
190
191template <fl::size I, typename T>
193
194template <typename T1, typename T2>
195struct tuple_element<0, pair<T1, T2>> {
196 using type = T1;
197};
198
199template <typename T1, typename T2>
200struct tuple_element<1, pair<T1, T2>> {
201 using type = T2;
202};
203
204template <typename T1, typename T2>
205using Pair = pair<T1, T2>; // Backwards compatibility for 3.10.1
206
207} // namespace fl
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_NULL_DEREFERENCE
#define FL_DISABLE_WARNING_POP
static uint32_t t
Definition Luminova.h:54
constexpr remove_reference< T >::type && move(T &&t) noexcept
Definition move.h:27
void swap(array< T, N > &lhs, array< T, N > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Definition array.h:156
pair< typename fl::decay< T1 >::type, typename fl::decay< T2 >::type > make_pair(T1 &&t, T2 &&u)
Definition pair.h:93
bool operator!=(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:151
pair< T1, T2 > Pair
Definition pair.h:205
bool operator>=(const pair< T1, T2 > &lhs, const pair< U1, U2 > &rhs)
Definition pair.h:81
bool operator<(const pair< T1, T2 > &lhs, const pair< U1, U2 > &rhs)
Definition pair.h:66
bool operator==(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:141
pair_element< I, T1, T2 >::type & get(pair< T1, T2 > &p) noexcept
Definition pair.h:113
bool operator<=(const pair< T1, T2 > &lhs, const pair< U1, U2 > &rhs)
Definition pair.h:71
constexpr T && forward(typename remove_reference< T >::type &t) noexcept
bool operator>(const pair< T1, T2 > &lhs, const pair< U1, U2 > &rhs)
Definition pair.h:76
IMPORTANT!
Definition crgb.h:20
typename conditional< is_array< U >::value, typename remove_extent< U >::type *, typename conditional< is_function< U >::value, typename add_pointer< U >::type, typename remove_cv< U >::type >::type >::type type
static constexpr bool value
Definition type_traits.h:84
pair(pair &&other) noexcept
Definition pair.h:41
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_NULL_DEREFERENCE pair(const T1 &k, const T2 &v)
Definition pair.h:23
void swap(pair &other) noexcept
Definition pair.h:48
const Key first_type
Definition pair.h:11
pair()=default
pair(const pair &other)=default
pair(pair< U1, U2 > &&other)
Definition pair.h:36
pair & operator=(const pair &other)=default
FL_DISABLE_WARNING_POP pair(U1 &&u1, U2 &&u2)
Definition pair.h:28
pair(const pair< U1, U2 > &other)
Definition pair.h:32
pair & operator=(pair &&other)=default
Definition pair.h:9
static constexpr fl::size value
Definition pair.h:188