Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Side by Side Diff: webrtc/base/safe_compare.h

Issue 2808603002: Make safe_cmp::* constexpr (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/base/safe_compare_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 // This file defines six functions: 11 // This file defines six constexpr functions:
12 // 12 //
13 // rtc::safe_cmp::Eq // == 13 // rtc::safe_cmp::Eq // ==
14 // rtc::safe_cmp::Ne // != 14 // rtc::safe_cmp::Ne // !=
15 // rtc::safe_cmp::Lt // < 15 // rtc::safe_cmp::Lt // <
16 // rtc::safe_cmp::Le // <= 16 // rtc::safe_cmp::Le // <=
17 // rtc::safe_cmp::Gt // > 17 // rtc::safe_cmp::Gt // >
18 // rtc::safe_cmp::Ge // >= 18 // rtc::safe_cmp::Ge // >=
19 // 19 //
20 // They each accept two arguments of arbitrary types, and in almost all cases, 20 // They each accept two arguments of arbitrary types, and in almost all cases,
21 // they simply call the appropriate comparison operator. However, if both 21 // they simply call the appropriate comparison operator. However, if both
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 // than T1 (and no larger than the larger of T2 and int*, for performance 63 // than T1 (and no larger than the larger of T2 and int*, for performance
64 // reasons); and if there is such a type, LargerInt<T1, T2>::type is an alias 64 // reasons); and if there is such a type, LargerInt<T1, T2>::type is an alias
65 // for it. 65 // for it.
66 template <typename T1, typename T2> 66 template <typename T1, typename T2>
67 struct LargerInt 67 struct LargerInt
68 : LargerIntImpl<sizeof(T1) < sizeof(T2) || sizeof(T1) < sizeof(int*) 68 : LargerIntImpl<sizeof(T1) < sizeof(T2) || sizeof(T1) < sizeof(int*)
69 ? sizeof(T1) 69 ? sizeof(T1)
70 : 0> {}; 70 : 0> {};
71 71
72 template <typename T> 72 template <typename T>
73 inline typename std::make_unsigned<T>::type MakeUnsigned(T a) { 73 constexpr typename std::make_unsigned<T>::type MakeUnsigned(T a) {
74 return static_cast<typename std::make_unsigned<T>::type>(a); 74 return static_cast<typename std::make_unsigned<T>::type>(a);
75 } 75 }
76 76
77 // Overload for when both T1 and T2 have the same signedness. 77 // Overload for when both T1 and T2 have the same signedness.
78 template <typename Op, 78 template <typename Op,
79 typename T1, 79 typename T1,
80 typename T2, 80 typename T2,
81 typename std::enable_if<std::is_signed<T1>::value == 81 typename std::enable_if<std::is_signed<T1>::value ==
82 std::is_signed<T2>::value>::type* = nullptr> 82 std::is_signed<T2>::value>::type* = nullptr>
83 inline bool Cmp(T1 a, T2 b) { 83 constexpr bool Cmp(T1 a, T2 b) {
84 return Op::Op(a, b); 84 return Op::Op(a, b);
85 } 85 }
86 86
87 // Overload for signed - unsigned comparison that can be promoted to a bigger 87 // Overload for signed - unsigned comparison that can be promoted to a bigger
88 // signed type. 88 // signed type.
89 template <typename Op, 89 template <typename Op,
90 typename T1, 90 typename T1,
91 typename T2, 91 typename T2,
92 typename std::enable_if<std::is_signed<T1>::value && 92 typename std::enable_if<std::is_signed<T1>::value &&
93 std::is_unsigned<T2>::value && 93 std::is_unsigned<T2>::value &&
94 LargerInt<T2, T1>::value>::type* = nullptr> 94 LargerInt<T2, T1>::value>::type* = nullptr>
95 inline bool Cmp(T1 a, T2 b) { 95 constexpr bool Cmp(T1 a, T2 b) {
96 return Op::Op(a, static_cast<typename LargerInt<T2, T1>::type>(b)); 96 return Op::Op(a, static_cast<typename LargerInt<T2, T1>::type>(b));
97 } 97 }
98 98
99 // Overload for unsigned - signed comparison that can be promoted to a bigger 99 // Overload for unsigned - signed comparison that can be promoted to a bigger
100 // signed type. 100 // signed type.
101 template <typename Op, 101 template <typename Op,
102 typename T1, 102 typename T1,
103 typename T2, 103 typename T2,
104 typename std::enable_if<std::is_unsigned<T1>::value && 104 typename std::enable_if<std::is_unsigned<T1>::value &&
105 std::is_signed<T2>::value && 105 std::is_signed<T2>::value &&
106 LargerInt<T1, T2>::value>::type* = nullptr> 106 LargerInt<T1, T2>::value>::type* = nullptr>
107 inline bool Cmp(T1 a, T2 b) { 107 constexpr bool Cmp(T1 a, T2 b) {
108 return Op::Op(static_cast<typename LargerInt<T1, T2>::type>(a), b); 108 return Op::Op(static_cast<typename LargerInt<T1, T2>::type>(a), b);
109 } 109 }
110 110
111 // Overload for signed - unsigned comparison that can't be promoted to a bigger 111 // Overload for signed - unsigned comparison that can't be promoted to a bigger
112 // signed type. 112 // signed type.
113 template <typename Op, 113 template <typename Op,
114 typename T1, 114 typename T1,
115 typename T2, 115 typename T2,
116 typename std::enable_if<std::is_signed<T1>::value && 116 typename std::enable_if<std::is_signed<T1>::value &&
117 std::is_unsigned<T2>::value && 117 std::is_unsigned<T2>::value &&
118 !LargerInt<T2, T1>::value>::type* = nullptr> 118 !LargerInt<T2, T1>::value>::type* = nullptr>
119 inline bool Cmp(T1 a, T2 b) { 119 constexpr bool Cmp(T1 a, T2 b) {
120 return a < 0 ? Op::Op(-1, 0) : Op::Op(safe_cmp_impl::MakeUnsigned(a), b); 120 return a < 0 ? Op::Op(-1, 0) : Op::Op(safe_cmp_impl::MakeUnsigned(a), b);
121 } 121 }
122 122
123 // Overload for unsigned - signed comparison that can't be promoted to a bigger 123 // Overload for unsigned - signed comparison that can't be promoted to a bigger
124 // signed type. 124 // signed type.
125 template <typename Op, 125 template <typename Op,
126 typename T1, 126 typename T1,
127 typename T2, 127 typename T2,
128 typename std::enable_if<std::is_unsigned<T1>::value && 128 typename std::enable_if<std::is_unsigned<T1>::value &&
129 std::is_signed<T2>::value && 129 std::is_signed<T2>::value &&
130 !LargerInt<T1, T2>::value>::type* = nullptr> 130 !LargerInt<T1, T2>::value>::type* = nullptr>
131 inline bool Cmp(T1 a, T2 b) { 131 constexpr bool Cmp(T1 a, T2 b) {
132 return b < 0 ? Op::Op(0, -1) : Op::Op(a, safe_cmp_impl::MakeUnsigned(b)); 132 return b < 0 ? Op::Op(0, -1) : Op::Op(a, safe_cmp_impl::MakeUnsigned(b));
133 } 133 }
134 134
135 #define RTC_SAFECMP_MAKE_OP(name, op) \ 135 #define RTC_SAFECMP_MAKE_OP(name, op) \
136 struct name { \ 136 struct name { \
137 template <typename T1, typename T2> \ 137 template <typename T1, typename T2> \
138 static constexpr bool Op(T1 a, T2 b) { \ 138 static constexpr bool Op(T1 a, T2 b) { \
139 return a op b; \ 139 return a op b; \
140 } \ 140 } \
141 }; 141 };
142 RTC_SAFECMP_MAKE_OP(EqOp, ==) 142 RTC_SAFECMP_MAKE_OP(EqOp, ==)
143 RTC_SAFECMP_MAKE_OP(NeOp, !=) 143 RTC_SAFECMP_MAKE_OP(NeOp, !=)
144 RTC_SAFECMP_MAKE_OP(LtOp, <) 144 RTC_SAFECMP_MAKE_OP(LtOp, <)
145 RTC_SAFECMP_MAKE_OP(LeOp, <=) 145 RTC_SAFECMP_MAKE_OP(LeOp, <=)
146 RTC_SAFECMP_MAKE_OP(GtOp, >) 146 RTC_SAFECMP_MAKE_OP(GtOp, >)
147 RTC_SAFECMP_MAKE_OP(GeOp, >=) 147 RTC_SAFECMP_MAKE_OP(GeOp, >=)
148 #undef RTC_SAFECMP_MAKE_OP 148 #undef RTC_SAFECMP_MAKE_OP
149 149
150 } // namespace safe_cmp_impl 150 } // namespace safe_cmp_impl
151 151
152 #define RTC_SAFECMP_MAKE_FUN(name) \ 152 #define RTC_SAFECMP_MAKE_FUN(name) \
153 template <typename T1, typename T2, \ 153 template <typename T1, typename T2> \
154 typename std::enable_if<IsIntlike<T1>::value && \ 154 constexpr \
155 IsIntlike<T2>::value>::type* = nullptr> \ 155 typename std::enable_if<IsIntlike<T1>::value && IsIntlike<T2>::value, \
156 inline bool name(T1 a, T2 b) { \ 156 bool>::type \
157 /* Unary plus here turns enums into real integral types. */ \ 157 name(T1 a, T2 b) { \
158 return safe_cmp_impl::Cmp<safe_cmp_impl::name##Op>(+a, +b); \ 158 /* Unary plus here turns enums into real integral types. */ \
159 } \ 159 return safe_cmp_impl::Cmp<safe_cmp_impl::name##Op>(+a, +b); \
160 template <typename T1, typename T2, \ 160 } \
161 typename std::enable_if<!IsIntlike<T1>::value || \ 161 template <typename T1, typename T2> \
162 !IsIntlike<T2>::value>::type* = nullptr> \ 162 constexpr \
163 inline bool name(T1&& a, T2&& b) { \ 163 typename std::enable_if<!IsIntlike<T1>::value || !IsIntlike<T2>::value, \
164 return safe_cmp_impl::name##Op::Op(a, b); \ 164 bool>::type \
165 name(const T1& a, const T2& b) { \
166 return safe_cmp_impl::name##Op::Op(a, b); \
165 } 167 }
166 RTC_SAFECMP_MAKE_FUN(Eq) 168 RTC_SAFECMP_MAKE_FUN(Eq)
167 RTC_SAFECMP_MAKE_FUN(Ne) 169 RTC_SAFECMP_MAKE_FUN(Ne)
168 RTC_SAFECMP_MAKE_FUN(Lt) 170 RTC_SAFECMP_MAKE_FUN(Lt)
169 RTC_SAFECMP_MAKE_FUN(Le) 171 RTC_SAFECMP_MAKE_FUN(Le)
170 RTC_SAFECMP_MAKE_FUN(Gt) 172 RTC_SAFECMP_MAKE_FUN(Gt)
171 RTC_SAFECMP_MAKE_FUN(Ge) 173 RTC_SAFECMP_MAKE_FUN(Ge)
172 #undef RTC_SAFECMP_MAKE_FUN 174 #undef RTC_SAFECMP_MAKE_FUN
173 175
174 } // namespace safe_cmp 176 } // namespace safe_cmp
175 } // namespace rtc 177 } // namespace rtc
176 178
177 #endif // WEBRTC_BASE_SAFE_COMPARE_H_ 179 #endif // WEBRTC_BASE_SAFE_COMPARE_H_
OLDNEW
« no previous file with comments | « no previous file | webrtc/base/safe_compare_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698