Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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