BitMagicC++Library
bmdef.h
Go to the documentation of this file.
1 /*
2 Copyright(c) 2002-2017 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 
16 For more information please visit: http://bitmagic.io
17 */
18 
19 #include <climits>
20 
21 // Incorporate appropriate tuneups when the NCBI C++ Toolkit's core
22 // headers have been included.
23 //
24 #ifdef NCBI_ASSERT
25 # define BM_ASSERT _ASSERT
26 
27 # ifdef HAVE_RESTRICT_CXX
28 # define BM_HASRESTRICT
29 # define BMRESTRICT NCBI_RESTRICT
30 # endif
31 
32 # if defined(NCBI_FORCEINLINE) && \
33  ( !defined(NCBI_COMPILER_GCC) || NCBI_COMPILER_VERSION >= 400 || \
34  defined(__OPTIMIZE__))
35 # define BM_HASFORCEINLINE
36 # define BMFORCEINLINE NCBI_FORCEINLINE
37 # endif
38 
39 # ifdef NCBI_SSE
40 # if NCBI_SSE >= 20
41 # define BMSSE2OPT 1
42 # endif
43 # if NCBI_SSE >= 40
44 # define BMSSE2OPT 1
45 # endif
46 # if NCBI_SSE >= 42
47 # define BMSSE42OPT 1
48 # endif
49 # endif
50 #endif
51 
52 
53 // macro to define/undefine unaligned memory access (x86, PowerPC)
54 //
55 #if defined(__i386) || defined(__x86_64) || defined(__ppc__) || \
56  defined(__ppc64__) || defined(_M_IX86) || defined(_M_AMD64) || \
57  defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
58  (defined(_M_MPPC) && !defined(BM_FORBID_UNALIGNED_ACCESS))
59 #define BM_UNALIGNED_ACCESS_OK 1
60 #endif
61 
62 #if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
63  defined(__i386) || defined(__x86_64) || defined(_M_AMD64) || \
64  defined(BMSSE2OPT) || defined(BMSSE42OPT)
65 #define BM_x86
66 #endif
67 
68 // cxx11 features
69 //
70 #if defined(BM_NO_CXX11) || (defined(_MSC_VER) && _MSC_VER < 1900)
71 # define BMNOEXEPT
72 #else
73 # ifndef BMNOEXEPT
74 # define BMNOEXEPT noexcept
75 # endif
76 #endif
77 
78 
79 // disable 'register' keyword, which is obsolete in C++11
80 //
81 #ifndef BMREGISTER
82 # define BMREGISTER
83 #endif
84 
85 
86 // Enable MSVC 8.0 (2005) specific optimization options
87 //
88 #if(_MSC_VER >= 1400)
89 
90 # define BM_HASFORCEINLINE
91 # ifndef BMRESTRICT
92 # define BMRESTRICT __restrict
93 # endif
94 #endif
95 
96 #ifdef __GNUG__
97 
98 # ifndef BMRESTRICT
99 # define BMRESTRICT __restrict__
100 # endif
101 
102 # ifdef __OPTIMIZE__
103 # define BM_NOASSERT
104 # endif
105 #endif
106 
107 
108 #ifndef BM_ASSERT
109 
110 # ifndef BM_NOASSERT
111 # include <cassert>
112 # define BM_ASSERT assert
113 # else
114 # ifndef BM_ASSERT
115 # define BM_ASSERT(x)
116 # endif
117 # endif
118 
119 #endif
120 
121 
122 #if defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
123  defined(__LP64__) || defined(_LP64) || ( __WORDSIZE == 64 )
124 #ifndef BM64OPT
125 # define BM64OPT
126 #endif
127 #endif
128 
129 
130 
131 #define FULL_BLOCK_REAL_ADDR bm::all_set<true>::_block._p
132 #define FULL_BLOCK_FAKE_ADDR bm::all_set<true>::_block._p_fullp
133 #define BLOCK_ADDR_SAN(addr) (addr == FULL_BLOCK_FAKE_ADDR) ? FULL_BLOCK_REAL_ADDR : addr
134 #define IS_VALID_ADDR(addr) bm::all_set<true>::is_valid_block_addr(addr)
135 #define IS_FULL_BLOCK(addr) bm::all_set<true>::is_full_block(addr)
136 #define IS_EMPTY_BLOCK(addr) bool(addr == 0)
137 
138 // Macro definitions to manipulate bits in pointers
139 // This trick is based on the fact that pointers allocated by malloc are
140 // aligned and bit 0 is never set. It means we are safe to use it.
141 // BM library keeps GAP flag in pointer.
142 
143 
144 
145 # if ULONG_MAX != 0xffffffff || defined(_WIN64) // 64-bit
146 
147 # define BMPTR_SETBIT0(ptr) ( ((bm::id64_t)ptr) | 1 )
148 # define BMPTR_CLEARBIT0(ptr) ( ((bm::id64_t)ptr) & ~(bm::id64_t)1 )
149 # define BMPTR_TESTBIT0(ptr) ( ((bm::id64_t)ptr) & 1 )
150 
151 # else // 32-bit
152 
153 # define BMPTR_SETBIT0(ptr) ( ((bm::id_t)ptr) | 1 )
154 # define BMPTR_CLEARBIT0(ptr) ( ((bm::id_t)ptr) & ~(bm::id_t)1 )
155 # define BMPTR_TESTBIT0(ptr) ( ((bm::id_t)ptr) & 1 )
156 
157 # endif
158 
159 # define BMGAP_PTR(ptr) ((bm::gap_word_t*)BMPTR_CLEARBIT0(ptr))
160 # define BMSET_PTRGAP(ptr) ptr = (bm::word_t*)BMPTR_SETBIT0(ptr)
161 # define BM_IS_GAP(ptr) bool(BMPTR_TESTBIT0(ptr)!=0)
162 
163 
164 
165 
166 
167 #ifdef BM_HASRESTRICT
168 # ifndef BMRESTRICT
169 # define BMRESTRICT restrict
170 # endif
171 #else
172 # ifndef BMRESTRICT
173 # define BMRESTRICT
174 # endif
175 #endif
176 
177 
178 #ifdef BM_HASFORCEINLINE
179 # ifndef BMFORCEINLINE
180 # define BMFORCEINLINE __forceinline
181 # endif
182 #else
183 # define BMFORCEINLINE inline
184 #endif
185 
186 
187 // --------------------------------
188 // SSE optmization macros
189 //
190 
191 #ifdef BMSSE42OPT
192 # if defined(BM64OPT) || defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
193  defined(__LP64__) || defined(_LP64)
194 # undef BM64OPT
195 # define BM64_SSE4
196 # endif
197 # undef BMSSE2OPT
198 #endif
199 
200 # ifndef BM_SET_MMX_GUARD
201 # define BM_SET_MMX_GUARD
202 # endif
203 
204 
205 #if !(defined(BMSSE2OPT) || defined(BMSSE42OPT) || defined(BMAVX2OPT))
206 
207 
208 #define BM_ALIGN16
209 #define BM_ALIGN16ATTR
210 #define BM_ALIGN32
211 #define BM_ALIGN32ATTR
212 
213 #else
214 
215 # ifndef BM_SET_MMX_GUARD
216 # define BM_SET_MMX_GUARD sse_empty_guard bm_mmx_guard_;
217 # endif
218 
219 #ifdef _MSC_VER
220 
221 #ifndef BM_ALIGN16
222 # define BM_ALIGN16 __declspec(align(16))
223 # define BM_ALIGN16ATTR
224 #endif
225 
226 #ifndef BM_ALIGN32
227 # define BM_ALIGN32 __declspec(align(32))
228 # define BM_ALIGN32ATTR
229 #endif
230 
231 
232 # else // GCC
233 
234 #ifndef BM_ALIGN16
235 # define BM_ALIGN16
236 # define BM_ALIGN16ATTR __attribute__((aligned(16)))
237 #endif
238 
239 #ifndef BM_ALIGN32
240 # define BM_ALIGN32
241 # define BM_ALIGN32ATTR __attribute__((aligned(32)))
242 #endif
243 
244 
245 #endif
246 
247 #endif
248 
249 #if (defined(BMSSE2OPT) || defined(BMSSE42OPT))
250 # define BM_VECT_ALIGN BM_ALIGN16
251 # define BM_VECT_ALIGN_ATTR BM_ALIGN16ATTR
252 #else
253 # if defined(BMAVX2OPT)
254 # define BM_VECT_ALIGN BM_ALIGN32
255 # define BM_VECT_ALIGN_ATTR BM_ALIGN32ATTR
256 # else
257 # define BM_VECT_ALIGN
258 # define BM_VECT_ALIGN_ATTR
259 # endif
260 #endif
261 
262 
263 
264 
265 /*!
266  Define calculates number of 1 bits in 32-bit word.
267  @ingroup bitfunc
268 */
269 #ifndef BM_INCWORD_BITCOUNT
270 
271 #if (defined(BMSSE42OPT) || defined(BMAVX2OPT))
272 
273 # define BM_INCWORD_BITCOUNT(cnt, w) cnt += _mm_popcnt_u32(w);
274 
275 #else
276 
277 # define BM_INCWORD_BITCOUNT(cnt, w) cnt += \
278  bm::bit_count_table<true>::_count[(unsigned char)(w)] + \
279  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 8)] + \
280  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 16)] + \
281  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 24)];
282 
283 
284 #endif
285 
286 // throw redefinintion for compatibility with language wrappers
287 //
288 #ifndef BM_ASSERT_THROW
289 #define BM_ASSERT_THROW(x, xerrcode)
290 #endif
291 
292 #endif
293 
294