]> git.proxmox.com Git - ceph.git/blob - ceph/src/include/intarith.h
update sources to v12.1.1
[ceph.git] / ceph / src / include / intarith.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_INTARITH_H
16 #define CEPH_INTARITH_H
17
18 #ifndef MIN
19 #define MIN(a,b) ((a) < (b) ? (a):(b))
20 #endif
21
22 #ifndef MAX
23 #define MAX(a,b) ((a) > (b) ? (a):(b))
24 #endif
25
26 #ifndef DIV_ROUND_UP
27 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
28 #endif
29
30 #ifndef ROUND_UP_TO
31 #define ROUND_UP_TO(n, d) ((n)%(d) ? ((n)+(d)-(n)%(d)) : (n))
32 #endif
33
34 #ifndef SHIFT_ROUND_UP
35 #define SHIFT_ROUND_UP(x,y) (((x)+(1<<(y))-1) >> (y))
36 #endif
37
38 /*
39 * Macro to determine if value is a power of 2
40 */
41 #define ISP2(x) (((x) & ((x) - 1)) == 0)
42
43 /*
44 * Macros for various sorts of alignment and rounding. The "align" must
45 * be a power of 2. Often times it is a block, sector, or page.
46 */
47
48 /*
49 * return x rounded down to an align boundary
50 * eg, P2ALIGN(1200, 1024) == 1024 (1*align)
51 * eg, P2ALIGN(1024, 1024) == 1024 (1*align)
52 * eg, P2ALIGN(0x1234, 0x100) == 0x1200 (0x12*align)
53 * eg, P2ALIGN(0x5600, 0x100) == 0x5600 (0x56*align)
54 */
55 #define P2ALIGN(x, align) ((x) & -(align))
56
57 /*
58 * return x % (mod) align
59 * eg, P2PHASE(0x1234, 0x100) == 0x34 (x-0x12*align)
60 * eg, P2PHASE(0x5600, 0x100) == 0x00 (x-0x56*align)
61 */
62 #define P2PHASE(x, align) ((x) & ((align) - 1))
63
64 /*
65 * return how much space is left in this block (but if it's perfectly
66 * aligned, return 0).
67 * eg, P2NPHASE(0x1234, 0x100) == 0xcc (0x13*align-x)
68 * eg, P2NPHASE(0x5600, 0x100) == 0x00 (0x56*align-x)
69 */
70 #define P2NPHASE(x, align) (-(x) & ((align) - 1))
71
72 /*
73 * return x rounded up to an align boundary
74 * eg, P2ROUNDUP(0x1234, 0x100) == 0x1300 (0x13*align)
75 * eg, P2ROUNDUP(0x5600, 0x100) == 0x5600 (0x56*align)
76 */
77 #define P2ROUNDUP(x, align) (-(-(x) & -(align)))
78
79 // count trailing zeros.
80 // NOTE: the builtin is nondeterministic on 0 input
81 template<class T>
82 inline typename std::enable_if<
83 (std::is_integral<T>::value &&
84 sizeof(T) <= sizeof(unsigned)),
85 unsigned>::type ctz(T v) {
86 if (v == 0)
87 return sizeof(v) * 8;
88 return __builtin_ctz(v);
89 }
90
91 template<class T>
92 inline typename std::enable_if<
93 (std::is_integral<T>::value &&
94 sizeof(T) > sizeof(unsigned int) &&
95 sizeof(T) <= sizeof(unsigned long)),
96 unsigned>::type ctz(T v) {
97 if (v == 0)
98 return sizeof(v) * 8;
99 return __builtin_ctzl(v);
100 }
101
102 template<class T>
103 inline typename std::enable_if<
104 (std::is_integral<T>::value &&
105 sizeof(T) > sizeof(unsigned long) &&
106 sizeof(T) <= sizeof(unsigned long long)),
107 unsigned>::type ctz(T v) {
108 if (v == 0)
109 return sizeof(v) * 8;
110 return __builtin_ctzll(v);
111 }
112
113 // count leading zeros
114 // NOTE: the builtin is nondeterministic on 0 input
115 template<class T>
116 inline typename std::enable_if<
117 (std::is_integral<T>::value &&
118 sizeof(T) <= sizeof(unsigned)),
119 unsigned>::type clz(T v) {
120 if (v == 0)
121 return sizeof(v) * 8;
122 return __builtin_clz(v);
123 }
124
125 template<class T>
126 inline typename std::enable_if<
127 (std::is_integral<T>::value &&
128 sizeof(T) > sizeof(unsigned int) &&
129 sizeof(T) <= sizeof(unsigned long)),
130 unsigned>::type clz(T v) {
131 if (v == 0)
132 return sizeof(v) * 8;
133 return __builtin_clzl(v);
134 }
135
136 template<class T>
137 inline typename std::enable_if<
138 (std::is_integral<T>::value &&
139 sizeof(T) > sizeof(unsigned long) &&
140 sizeof(T) <= sizeof(unsigned long long)),
141 unsigned>::type clz(T v) {
142 if (v == 0)
143 return sizeof(v) * 8;
144 return __builtin_clzll(v);
145 }
146
147 // count bits (set + any 0's that follow)
148 template<class T>
149 inline typename std::enable_if<
150 (std::is_integral<T>::value &&
151 sizeof(T) <= sizeof(unsigned)),
152 unsigned>::type cbits(T v) {
153 if (v == 0)
154 return 0;
155 return (sizeof(v) * 8) - __builtin_clz(v);
156 }
157
158 template<class T>
159 inline typename std::enable_if<
160 (std::is_integral<T>::value &&
161 sizeof(T) > sizeof(unsigned int) &&
162 sizeof(T) <= sizeof(unsigned long)),
163 unsigned>::type cbits(T v) {
164 if (v == 0)
165 return 0;
166 return (sizeof(v) * 8) - __builtin_clzl(v);
167 }
168
169 template<class T>
170 inline typename std::enable_if<
171 (std::is_integral<T>::value &&
172 sizeof(T) > sizeof(unsigned long) &&
173 sizeof(T) <= sizeof(unsigned long long)),
174 unsigned>::type cbits(T v) {
175 if (v == 0)
176 return 0;
177 return (sizeof(v) * 8) - __builtin_clzll(v);
178 }
179
180 #endif