xref: /DragonStub/inc/dragonstub/minmax.h (revision f412fd2a1a248b546b7085648dece8d908077fab)
1*f412fd2aSLoGin /* SPDX-License-Identifier: GPL-2.0 */
2*f412fd2aSLoGin #ifndef _LINUX_MINMAX_H
3*f412fd2aSLoGin #define _LINUX_MINMAX_H
4*f412fd2aSLoGin 
5*f412fd2aSLoGin #include "linux/const.h"
6*f412fd2aSLoGin #include "linux/compiler.h"
7*f412fd2aSLoGin #include "types.h"
8*f412fd2aSLoGin 
9*f412fd2aSLoGin /*
10*f412fd2aSLoGin  * min()/max()/clamp() macros must accomplish three things:
11*f412fd2aSLoGin  *
12*f412fd2aSLoGin  * - avoid multiple evaluations of the arguments (so side-effects like
13*f412fd2aSLoGin  *   "x++" happen only once) when non-constant.
14*f412fd2aSLoGin  * - perform strict type-checking (to generate warnings instead of
15*f412fd2aSLoGin  *   nasty runtime surprises). See the "unnecessary" pointer comparison
16*f412fd2aSLoGin  *   in __typecheck().
17*f412fd2aSLoGin  * - retain result as a constant expressions when called with only
18*f412fd2aSLoGin  *   constant expressions (to avoid tripping VLA warnings in stack
19*f412fd2aSLoGin  *   allocation usage).
20*f412fd2aSLoGin  */
21*f412fd2aSLoGin #define __typecheck(x, y) (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
22*f412fd2aSLoGin 
23*f412fd2aSLoGin #define __no_side_effects(x, y) (__is_constexpr(x) && __is_constexpr(y))
24*f412fd2aSLoGin 
25*f412fd2aSLoGin #define __safe_cmp(x, y) (__typecheck(x, y) && __no_side_effects(x, y))
26*f412fd2aSLoGin 
27*f412fd2aSLoGin #define __cmp(x, y, op) ((x)op(y) ? (x) : (y))
28*f412fd2aSLoGin 
29*f412fd2aSLoGin #define __cmp_once(x, y, unique_x, unique_y, op) \
30*f412fd2aSLoGin 	({                                       \
31*f412fd2aSLoGin 		typeof(x) unique_x = (x);        \
32*f412fd2aSLoGin 		typeof(y) unique_y = (y);        \
33*f412fd2aSLoGin 		__cmp(unique_x, unique_y, op);   \
34*f412fd2aSLoGin 	})
35*f412fd2aSLoGin 
36*f412fd2aSLoGin #define __careful_cmp(x, y, op)                                  \
37*f412fd2aSLoGin 	__builtin_choose_expr(__safe_cmp(x, y), __cmp(x, y, op), \
38*f412fd2aSLoGin 			      __cmp_once(x, y, __UNIQUE_ID(__x), \
39*f412fd2aSLoGin 					 __UNIQUE_ID(__y), op))
40*f412fd2aSLoGin 
41*f412fd2aSLoGin #define __clamp(val, lo, hi) \
42*f412fd2aSLoGin 	((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
43*f412fd2aSLoGin 
44*f412fd2aSLoGin #define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) \
45*f412fd2aSLoGin 	({                                                          \
46*f412fd2aSLoGin 		typeof(val) unique_val = (val);                     \
47*f412fd2aSLoGin 		typeof(lo) unique_lo = (lo);                        \
48*f412fd2aSLoGin 		typeof(hi) unique_hi = (hi);                        \
49*f412fd2aSLoGin 		__clamp(unique_val, unique_lo, unique_hi);          \
50*f412fd2aSLoGin 	})
51*f412fd2aSLoGin 
52*f412fd2aSLoGin #define __clamp_input_check(lo, hi)                                           \
53*f412fd2aSLoGin 	(BUILD_BUG_ON_ZERO(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \
54*f412fd2aSLoGin 						 (lo) > (hi), false)))
55*f412fd2aSLoGin 
56*f412fd2aSLoGin #define __careful_clamp(val, lo, hi)                                          \
57*f412fd2aSLoGin 	({                                                                    \
58*f412fd2aSLoGin 		__clamp_input_check(lo, hi) +                                 \
59*f412fd2aSLoGin 			__builtin_choose_expr(                                \
60*f412fd2aSLoGin 				__typecheck(val, lo) &&                       \
61*f412fd2aSLoGin 					__typecheck(val, hi) &&               \
62*f412fd2aSLoGin 					__typecheck(hi, lo) &&                \
63*f412fd2aSLoGin 					__is_constexpr(val) &&                \
64*f412fd2aSLoGin 					__is_constexpr(lo) &&                 \
65*f412fd2aSLoGin 					__is_constexpr(hi),                   \
66*f412fd2aSLoGin 				__clamp(val, lo, hi),                         \
67*f412fd2aSLoGin 				__clamp_once(val, lo, hi, __UNIQUE_ID(__val), \
68*f412fd2aSLoGin 					     __UNIQUE_ID(__lo),               \
69*f412fd2aSLoGin 					     __UNIQUE_ID(__hi)));             \
70*f412fd2aSLoGin 	})
71*f412fd2aSLoGin 
72*f412fd2aSLoGin /**
73*f412fd2aSLoGin  * min - return minimum of two values of the same or compatible types
74*f412fd2aSLoGin  * @x: first value
75*f412fd2aSLoGin  * @y: second value
76*f412fd2aSLoGin  */
77*f412fd2aSLoGin #define min(x, y) __careful_cmp(x, y, <)
78*f412fd2aSLoGin 
79*f412fd2aSLoGin /**
80*f412fd2aSLoGin  * max - return maximum of two values of the same or compatible types
81*f412fd2aSLoGin  * @x: first value
82*f412fd2aSLoGin  * @y: second value
83*f412fd2aSLoGin  */
84*f412fd2aSLoGin #define max(x, y) __careful_cmp(x, y, >)
85*f412fd2aSLoGin 
86*f412fd2aSLoGin /**
87*f412fd2aSLoGin  * min3 - return minimum of three values
88*f412fd2aSLoGin  * @x: first value
89*f412fd2aSLoGin  * @y: second value
90*f412fd2aSLoGin  * @z: third value
91*f412fd2aSLoGin  */
92*f412fd2aSLoGin #define min3(x, y, z) min((typeof(x))min(x, y), z)
93*f412fd2aSLoGin 
94*f412fd2aSLoGin /**
95*f412fd2aSLoGin  * max3 - return maximum of three values
96*f412fd2aSLoGin  * @x: first value
97*f412fd2aSLoGin  * @y: second value
98*f412fd2aSLoGin  * @z: third value
99*f412fd2aSLoGin  */
100*f412fd2aSLoGin #define max3(x, y, z) max((typeof(x))max(x, y), z)
101*f412fd2aSLoGin 
102*f412fd2aSLoGin /**
103*f412fd2aSLoGin  * min_not_zero - return the minimum that is _not_ zero, unless both are zero
104*f412fd2aSLoGin  * @x: value1
105*f412fd2aSLoGin  * @y: value2
106*f412fd2aSLoGin  */
107*f412fd2aSLoGin #define min_not_zero(x, y)                                           \
108*f412fd2aSLoGin 	({                                                           \
109*f412fd2aSLoGin 		typeof(x) __x = (x);                                 \
110*f412fd2aSLoGin 		typeof(y) __y = (y);                                 \
111*f412fd2aSLoGin 		__x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); \
112*f412fd2aSLoGin 	})
113*f412fd2aSLoGin 
114*f412fd2aSLoGin /**
115*f412fd2aSLoGin  * clamp - return a value clamped to a given range with strict typechecking
116*f412fd2aSLoGin  * @val: current value
117*f412fd2aSLoGin  * @lo: lowest allowable value
118*f412fd2aSLoGin  * @hi: highest allowable value
119*f412fd2aSLoGin  *
120*f412fd2aSLoGin  * This macro does strict typechecking of @lo/@hi to make sure they are of the
121*f412fd2aSLoGin  * same type as @val.  See the unnecessary pointer comparisons.
122*f412fd2aSLoGin  */
123*f412fd2aSLoGin #define clamp(val, lo, hi) __careful_clamp(val, lo, hi)
124*f412fd2aSLoGin 
125*f412fd2aSLoGin /*
126*f412fd2aSLoGin  * ..and if you can't take the strict
127*f412fd2aSLoGin  * types, you can specify one yourself.
128*f412fd2aSLoGin  *
129*f412fd2aSLoGin  * Or not use min/max/clamp at all, of course.
130*f412fd2aSLoGin  */
131*f412fd2aSLoGin 
132*f412fd2aSLoGin /**
133*f412fd2aSLoGin  * min_t - return minimum of two values, using the specified type
134*f412fd2aSLoGin  * @type: data type to use
135*f412fd2aSLoGin  * @x: first value
136*f412fd2aSLoGin  * @y: second value
137*f412fd2aSLoGin  */
138*f412fd2aSLoGin #define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <)
139*f412fd2aSLoGin 
140*f412fd2aSLoGin /**
141*f412fd2aSLoGin  * max_t - return maximum of two values, using the specified type
142*f412fd2aSLoGin  * @type: data type to use
143*f412fd2aSLoGin  * @x: first value
144*f412fd2aSLoGin  * @y: second value
145*f412fd2aSLoGin  */
146*f412fd2aSLoGin #define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >)
147*f412fd2aSLoGin 
148*f412fd2aSLoGin /*
149*f412fd2aSLoGin  * Remove a const qualifier from integer types
150*f412fd2aSLoGin  * _Generic(foo, type-name: association, ..., default: association) performs a
151*f412fd2aSLoGin  * comparison against the foo type (not the qualified type).
152*f412fd2aSLoGin  * Do not use the const keyword in the type-name as it will not match the
153*f412fd2aSLoGin  * unqualified type of foo.
154*f412fd2aSLoGin  */
155*f412fd2aSLoGin #define __unconst_integer_type_cases(type) \
156*f412fd2aSLoGin 	unsigned type : (unsigned type)0, signed type : (signed type)0
157*f412fd2aSLoGin 
158*f412fd2aSLoGin #define __unconst_integer_typeof(x)                                        \
159*f412fd2aSLoGin 	typeof(_Generic((x), char                                          \
160*f412fd2aSLoGin 			: (char)0, __unconst_integer_type_cases(char),     \
161*f412fd2aSLoGin 			  __unconst_integer_type_cases(short),             \
162*f412fd2aSLoGin 			  __unconst_integer_type_cases(int),               \
163*f412fd2aSLoGin 			  __unconst_integer_type_cases(long),              \
164*f412fd2aSLoGin 			  __unconst_integer_type_cases(long long), default \
165*f412fd2aSLoGin 			: (x)))
166*f412fd2aSLoGin 
167*f412fd2aSLoGin /*
168*f412fd2aSLoGin  * Do not check the array parameter using __must_be_array().
169*f412fd2aSLoGin  * In the following legit use-case where the "array" passed is a simple pointer,
170*f412fd2aSLoGin  * __must_be_array() will return a failure.
171*f412fd2aSLoGin  * --- 8< ---
172*f412fd2aSLoGin  * int *buff
173*f412fd2aSLoGin  * ...
174*f412fd2aSLoGin  * min = min_array(buff, nb_items);
175*f412fd2aSLoGin  * --- 8< ---
176*f412fd2aSLoGin  *
177*f412fd2aSLoGin  * The first typeof(&(array)[0]) is needed in order to support arrays of both
178*f412fd2aSLoGin  * 'int *buff' and 'int buff[N]' types.
179*f412fd2aSLoGin  *
180*f412fd2aSLoGin  * The array can be an array of const items.
181*f412fd2aSLoGin  * typeof() keeps the const qualifier. Use __unconst_integer_typeof() in order
182*f412fd2aSLoGin  * to discard the const qualifier for the __element variable.
183*f412fd2aSLoGin  */
184*f412fd2aSLoGin #define __minmax_array(op, array, len)                             \
185*f412fd2aSLoGin 	({                                                         \
186*f412fd2aSLoGin 		typeof(&(array)[0]) __array = (array);             \
187*f412fd2aSLoGin 		typeof(len) __len = (len);                         \
188*f412fd2aSLoGin 		__unconst_integer_typeof(__array[0])               \
189*f412fd2aSLoGin 			__element = __array[--__len];              \
190*f412fd2aSLoGin 		while (__len--)                                    \
191*f412fd2aSLoGin 			__element = op(__element, __array[__len]); \
192*f412fd2aSLoGin 		__element;                                         \
193*f412fd2aSLoGin 	})
194*f412fd2aSLoGin 
195*f412fd2aSLoGin /**
196*f412fd2aSLoGin  * min_array - return minimum of values present in an array
197*f412fd2aSLoGin  * @array: array
198*f412fd2aSLoGin  * @len: array length
199*f412fd2aSLoGin  *
200*f412fd2aSLoGin  * Note that @len must not be zero (empty array).
201*f412fd2aSLoGin  */
202*f412fd2aSLoGin #define min_array(array, len) __minmax_array(min, array, len)
203*f412fd2aSLoGin 
204*f412fd2aSLoGin /**
205*f412fd2aSLoGin  * max_array - return maximum of values present in an array
206*f412fd2aSLoGin  * @array: array
207*f412fd2aSLoGin  * @len: array length
208*f412fd2aSLoGin  *
209*f412fd2aSLoGin  * Note that @len must not be zero (empty array).
210*f412fd2aSLoGin  */
211*f412fd2aSLoGin #define max_array(array, len) __minmax_array(max, array, len)
212*f412fd2aSLoGin 
213*f412fd2aSLoGin /**
214*f412fd2aSLoGin  * clamp_t - return a value clamped to a given range using a given type
215*f412fd2aSLoGin  * @type: the type of variable to use
216*f412fd2aSLoGin  * @val: current value
217*f412fd2aSLoGin  * @lo: minimum allowable value
218*f412fd2aSLoGin  * @hi: maximum allowable value
219*f412fd2aSLoGin  *
220*f412fd2aSLoGin  * This macro does no typechecking and uses temporary variables of type
221*f412fd2aSLoGin  * @type to make all the comparisons.
222*f412fd2aSLoGin  */
223*f412fd2aSLoGin #define clamp_t(type, val, lo, hi) \
224*f412fd2aSLoGin 	__careful_clamp((type)(val), (type)(lo), (type)(hi))
225*f412fd2aSLoGin 
226*f412fd2aSLoGin /**
227*f412fd2aSLoGin  * clamp_val - return a value clamped to a given range using val's type
228*f412fd2aSLoGin  * @val: current value
229*f412fd2aSLoGin  * @lo: minimum allowable value
230*f412fd2aSLoGin  * @hi: maximum allowable value
231*f412fd2aSLoGin  *
232*f412fd2aSLoGin  * This macro does no typechecking and uses temporary variables of whatever
233*f412fd2aSLoGin  * type the input argument @val is.  This is useful when @val is an unsigned
234*f412fd2aSLoGin  * type and @lo and @hi are literals that will otherwise be assigned a signed
235*f412fd2aSLoGin  * integer type.
236*f412fd2aSLoGin  */
237*f412fd2aSLoGin #define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
238*f412fd2aSLoGin 
in_range64(u64 val,u64 start,u64 len)239*f412fd2aSLoGin static inline bool in_range64(u64 val, u64 start, u64 len)
240*f412fd2aSLoGin {
241*f412fd2aSLoGin 	return (val - start) < len;
242*f412fd2aSLoGin }
243*f412fd2aSLoGin 
in_range32(u32 val,u32 start,u32 len)244*f412fd2aSLoGin static inline bool in_range32(u32 val, u32 start, u32 len)
245*f412fd2aSLoGin {
246*f412fd2aSLoGin 	return (val - start) < len;
247*f412fd2aSLoGin }
248*f412fd2aSLoGin 
249*f412fd2aSLoGin /**
250*f412fd2aSLoGin  * in_range - Determine if a value lies within a range.
251*f412fd2aSLoGin  * @val: Value to test.
252*f412fd2aSLoGin  * @start: First value in range.
253*f412fd2aSLoGin  * @len: Number of values in range.
254*f412fd2aSLoGin  *
255*f412fd2aSLoGin  * This is more efficient than "if (start <= val && val < (start + len))".
256*f412fd2aSLoGin  * It also gives a different answer if @start + @len overflows the size of
257*f412fd2aSLoGin  * the type by a sufficient amount to encompass @val.  Decide for yourself
258*f412fd2aSLoGin  * which behaviour you want, or prove that start + len never overflow.
259*f412fd2aSLoGin  * Do not blindly replace one form with the other.
260*f412fd2aSLoGin  */
261*f412fd2aSLoGin #define in_range(val, start, len)                                     \
262*f412fd2aSLoGin 	((sizeof(start) | sizeof(len) | sizeof(val)) <= sizeof(u32) ? \
263*f412fd2aSLoGin 		 in_range32(val, start, len) :                        \
264*f412fd2aSLoGin 		 in_range64(val, start, len))
265*f412fd2aSLoGin 
266*f412fd2aSLoGin /**
267*f412fd2aSLoGin  * swap - swap values of @a and @b
268*f412fd2aSLoGin  * @a: first value
269*f412fd2aSLoGin  * @b: second value
270*f412fd2aSLoGin  */
271*f412fd2aSLoGin #define swap(a, b)                     \
272*f412fd2aSLoGin 	do {                           \
273*f412fd2aSLoGin 		typeof(a) __tmp = (a); \
274*f412fd2aSLoGin 		(a) = (b);             \
275*f412fd2aSLoGin 		(b) = __tmp;           \
276*f412fd2aSLoGin 	} while (0)
277*f412fd2aSLoGin 
278*f412fd2aSLoGin #endif /* _LINUX_MINMAX_H */
279