Copyright 2014->2015
[folly.git] / folly / Bits.h
1 /*
2  * Copyright 2015 Facebook, Inc.
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
17 /**
18  * Various low-level, bit-manipulation routines.
19  *
20  * findFirstSet(x)  [constexpr]
21  *    find first (least significant) bit set in a value of an integral type,
22  *    1-based (like ffs()).  0 = no bits are set (x == 0)
23  *
24  * findLastSet(x)  [constexpr]
25  *    find last (most significant) bit set in a value of an integral type,
26  *    1-based.  0 = no bits are set (x == 0)
27  *    for x != 0, findLastSet(x) == 1 + floor(log2(x))
28  *
29  * nextPowTwo(x)  [constexpr]
30  *    Finds the next power of two >= x.
31  *
32  * isPowTwo(x)  [constexpr]
33  *    return true iff x is a power of two
34  *
35  * popcount(x)
36  *    return the number of 1 bits in x
37  *
38  * Endian
39  *    convert between native, big, and little endian representation
40  *    Endian::big(x)      big <-> native
41  *    Endian::little(x)   little <-> native
42  *    Endian::swap(x)     big <-> little
43  *
44  * BitIterator
45  *    Wrapper around an iterator over an integral type that iterates
46  *    over its underlying bits in MSb to LSb order
47  *
48  * findFirstSet(BitIterator begin, BitIterator end)
49  *    return a BitIterator pointing to the first 1 bit in [begin, end), or
50  *    end if all bits in [begin, end) are 0
51  *
52  * @author Tudor Bosman (tudorb@fb.com)
53  */
54
55 #ifndef FOLLY_BITS_H_
56 #define FOLLY_BITS_H_
57
58 #if !defined(__clang__) && !defined(_MSC_VER)
59 #define FOLLY_INTRINSIC_CONSTEXPR constexpr
60 #else
61 // GCC is the only compiler with intrinsics constexpr.
62 #define FOLLY_INTRINSIC_CONSTEXPR const
63 #endif
64
65 #include <folly/Portability.h>
66
67 #include <folly/detail/BitsDetail.h>
68 #include <folly/detail/BitIteratorDetail.h>
69 #include <folly/Likely.h>
70
71 #if FOLLY_HAVE_BYTESWAP_H
72 # include <byteswap.h>
73 #endif
74
75 #ifdef _MSC_VER
76 # include <intrin.h>
77 # pragma intrinsic(_BitScanForward)
78 # pragma intrinsic(_BitScanForward64)
79 # pragma intrinsic(_BitScanReverse)
80 # pragma intrinsic(_BitScanReverse64)
81 #endif
82
83 #include <cassert>
84 #include <cinttypes>
85 #include <iterator>
86 #include <limits>
87 #include <type_traits>
88 #include <boost/iterator/iterator_adaptor.hpp>
89 #include <stdint.h>
90
91 namespace folly {
92
93 // Generate overloads for findFirstSet as wrappers around
94 // appropriate ffs, ffsl, ffsll gcc builtins
95 template <class T>
96 inline FOLLY_INTRINSIC_CONSTEXPR
97 typename std::enable_if<
98   (std::is_integral<T>::value &&
99    std::is_unsigned<T>::value &&
100    sizeof(T) <= sizeof(unsigned int)),
101   unsigned int>::type
102   findFirstSet(T x) {
103 #ifdef _MSC_VER
104   unsigned long index;
105   return _BitScanForward(&index, x) ? index : 0;
106 #else
107   return __builtin_ffs(x);
108 #endif
109 }
110
111 template <class T>
112 inline FOLLY_INTRINSIC_CONSTEXPR
113 typename std::enable_if<
114   (std::is_integral<T>::value &&
115    std::is_unsigned<T>::value &&
116    sizeof(T) > sizeof(unsigned int) &&
117    sizeof(T) <= sizeof(unsigned long)),
118   unsigned int>::type
119   findFirstSet(T x) {
120 #ifdef _MSC_VER
121   unsigned long index;
122   return _BitScanForward(&index, x) ? index : 0;
123 #else
124   return __builtin_ffsl(x);
125 #endif
126 }
127
128 template <class T>
129 inline FOLLY_INTRINSIC_CONSTEXPR
130 typename std::enable_if<
131   (std::is_integral<T>::value &&
132    std::is_unsigned<T>::value &&
133    sizeof(T) > sizeof(unsigned long) &&
134    sizeof(T) <= sizeof(unsigned long long)),
135   unsigned int>::type
136   findFirstSet(T x) {
137 #ifdef _MSC_VER
138   unsigned long index;
139   return _BitScanForward64(&index, x) ? index : 0;
140 #else
141   return __builtin_ffsll(x);
142 #endif
143 }
144
145 template <class T>
146 inline FOLLY_INTRINSIC_CONSTEXPR
147 typename std::enable_if<
148   (std::is_integral<T>::value && std::is_signed<T>::value),
149   unsigned int>::type
150   findFirstSet(T x) {
151   // Note that conversion from a signed type to the corresponding unsigned
152   // type is technically implementation-defined, but will likely work
153   // on any impementation that uses two's complement.
154   return findFirstSet(static_cast<typename std::make_unsigned<T>::type>(x));
155 }
156
157 // findLastSet: return the 1-based index of the highest bit set
158 // for x > 0, findLastSet(x) == 1 + floor(log2(x))
159 template <class T>
160 inline FOLLY_INTRINSIC_CONSTEXPR
161 typename std::enable_if<
162   (std::is_integral<T>::value &&
163    std::is_unsigned<T>::value &&
164    sizeof(T) <= sizeof(unsigned int)),
165   unsigned int>::type
166   findLastSet(T x) {
167 #ifdef _MSC_VER
168   unsigned long index;
169   int clz;
170   if (_BitScanReverse(&index, x)) {
171     clz = static_cast<int>(31 - index);
172   } else {
173     clz = 32;
174   }
175   return x ? 8 * sizeof(unsigned int) - clz : 0;
176 #else
177   return x ? 8 * sizeof(unsigned int) - __builtin_clz(x) : 0;
178 #endif
179 }
180
181 template <class T>
182 inline FOLLY_INTRINSIC_CONSTEXPR
183 typename std::enable_if<
184   (std::is_integral<T>::value &&
185    std::is_unsigned<T>::value &&
186    sizeof(T) > sizeof(unsigned int) &&
187    sizeof(T) <= sizeof(unsigned long)),
188   unsigned int>::type
189   findLastSet(T x) {
190 #ifdef _MSC_VER
191   unsigned long index;
192   int clz;
193   if (_BitScanReverse(&index, x)) {
194     clz = static_cast<int>(31 - index);
195   } else {
196     clz = 32;
197   }
198   return x ? 8 * sizeof(unsigned int) - clz : 0;
199 #else
200   return x ? 8 * sizeof(unsigned long) - __builtin_clzl(x) : 0;
201 #endif
202 }
203
204 template <class T>
205 inline FOLLY_INTRINSIC_CONSTEXPR
206 typename std::enable_if<
207   (std::is_integral<T>::value &&
208    std::is_unsigned<T>::value &&
209    sizeof(T) > sizeof(unsigned long) &&
210    sizeof(T) <= sizeof(unsigned long long)),
211   unsigned int>::type
212   findLastSet(T x) {
213 #ifdef _MSC_VER
214   unsigned long index;
215   unsigned long long clz;
216   if (_BitScanReverse(&index, x)) {
217     clz = static_cast<unsigned long long>(63 - index);
218   } else {
219     clz = 64;
220   }
221   return x ? 8 * sizeof(unsigned long long) - clz : 0;
222 #else
223   return x ? 8 * sizeof(unsigned long long) - __builtin_clzll(x) : 0;
224 #endif
225 }
226
227 template <class T>
228 inline FOLLY_INTRINSIC_CONSTEXPR
229 typename std::enable_if<
230   (std::is_integral<T>::value &&
231    std::is_signed<T>::value),
232   unsigned int>::type
233   findLastSet(T x) {
234   return findLastSet(static_cast<typename std::make_unsigned<T>::type>(x));
235 }
236
237 template <class T>
238 inline FOLLY_INTRINSIC_CONSTEXPR
239 typename std::enable_if<
240   std::is_integral<T>::value && std::is_unsigned<T>::value,
241   T>::type
242 nextPowTwo(T v) {
243   return v ? (1ul << findLastSet(v - 1)) : 1;
244 }
245
246 template <class T>
247 inline constexpr
248 typename std::enable_if<
249   std::is_integral<T>::value && std::is_unsigned<T>::value,
250   bool>::type
251 isPowTwo(T v) {
252   return (v != 0) && !(v & (v - 1));
253 }
254
255 /**
256  * Population count
257  */
258 template <class T>
259 inline typename std::enable_if<
260   (std::is_integral<T>::value &&
261    std::is_unsigned<T>::value &&
262    sizeof(T) <= sizeof(unsigned int)),
263   size_t>::type
264   popcount(T x) {
265   return detail::popcount(x);
266 }
267
268 template <class T>
269 inline typename std::enable_if<
270   (std::is_integral<T>::value &&
271    std::is_unsigned<T>::value &&
272    sizeof(T) > sizeof(unsigned int) &&
273    sizeof(T) <= sizeof(unsigned long long)),
274   size_t>::type
275   popcount(T x) {
276   return detail::popcountll(x);
277 }
278
279 /**
280  * Endianness detection and manipulation primitives.
281  */
282 namespace detail {
283
284 template <class T>
285 struct EndianIntBase {
286  public:
287   static T swap(T x);
288 };
289
290 #ifndef _MSC_VER
291
292 /**
293  * If we have the bswap_16 macro from byteswap.h, use it; otherwise, provide our
294  * own definition.
295  */
296 #ifdef bswap_16
297 # define our_bswap16 bswap_16
298 #else
299
300 template<class Int16>
301 inline constexpr typename std::enable_if<
302   sizeof(Int16) == 2,
303   Int16>::type
304 our_bswap16(Int16 x) {
305   return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
306 }
307 #endif
308
309 #endif
310
311 #define FB_GEN(t, fn) \
312 template<> inline t EndianIntBase<t>::swap(t x) { return fn(x); }
313
314 // fn(x) expands to (x) if the second argument is empty, which is exactly
315 // what we want for [u]int8_t. Also, gcc 4.7 on Intel doesn't have
316 // __builtin_bswap16 for some reason, so we have to provide our own.
317 FB_GEN( int8_t,)
318 FB_GEN(uint8_t,)
319 #ifdef _MSC_VER
320 FB_GEN( int64_t, _byteswap_uint64)
321 FB_GEN(uint64_t, _byteswap_uint64)
322 FB_GEN( int32_t, _byteswap_ulong)
323 FB_GEN(uint32_t, _byteswap_ulong)
324 FB_GEN( int16_t, _byteswap_ushort)
325 FB_GEN(uint16_t, _byteswap_ushort)
326 #else
327 FB_GEN( int64_t, __builtin_bswap64)
328 FB_GEN(uint64_t, __builtin_bswap64)
329 FB_GEN( int32_t, __builtin_bswap32)
330 FB_GEN(uint32_t, __builtin_bswap32)
331 FB_GEN( int16_t, our_bswap16)
332 FB_GEN(uint16_t, our_bswap16)
333 #endif
334
335 #undef FB_GEN
336
337 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
338
339 template <class T>
340 struct EndianInt : public detail::EndianIntBase<T> {
341  public:
342   static T big(T x) { return EndianInt::swap(x); }
343   static T little(T x) { return x; }
344 };
345
346 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
347
348 template <class T>
349 struct EndianInt : public detail::EndianIntBase<T> {
350  public:
351   static T big(T x) { return x; }
352   static T little(T x) { return EndianInt::swap(x); }
353 };
354
355 #else
356 # error Your machine uses a weird endianness!
357 #endif  /* __BYTE_ORDER__ */
358
359 }  // namespace detail
360
361 // big* convert between native and big-endian representations
362 // little* convert between native and little-endian representations
363 // swap* convert between big-endian and little-endian representations
364 //
365 // ntohs, htons == big16
366 // ntohl, htonl == big32
367 #define FB_GEN1(fn, t, sz) \
368   static t fn##sz(t x) { return fn<t>(x); } \
369
370 #define FB_GEN2(t, sz) \
371   FB_GEN1(swap, t, sz) \
372   FB_GEN1(big, t, sz) \
373   FB_GEN1(little, t, sz)
374
375 #define FB_GEN(sz) \
376   FB_GEN2(uint##sz##_t, sz) \
377   FB_GEN2(int##sz##_t, sz)
378
379 class Endian {
380  public:
381   enum class Order : uint8_t {
382     LITTLE,
383     BIG
384   };
385
386   static constexpr Order order =
387 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
388     Order::LITTLE;
389 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
390     Order::BIG;
391 #else
392 # error Your machine uses a weird endianness!
393 #endif  /* __BYTE_ORDER__ */
394
395   template <class T> static T swap(T x) {
396     return detail::EndianInt<T>::swap(x);
397   }
398   template <class T> static T big(T x) {
399     return detail::EndianInt<T>::big(x);
400   }
401   template <class T> static T little(T x) {
402     return detail::EndianInt<T>::little(x);
403   }
404
405 #if !defined(__ANDROID__)
406   FB_GEN(64)
407   FB_GEN(32)
408   FB_GEN(16)
409   FB_GEN(8)
410 #endif
411 };
412
413 #undef FB_GEN
414 #undef FB_GEN2
415 #undef FB_GEN1
416
417 /**
418  * Fast bit iteration facility.
419  */
420
421
422 template <class BaseIter> class BitIterator;
423 template <class BaseIter>
424 BitIterator<BaseIter> findFirstSet(BitIterator<BaseIter>,
425                                    BitIterator<BaseIter>);
426 /**
427  * Wrapper around an iterator over an integer type that iterates
428  * over its underlying bits in LSb to MSb order.
429  *
430  * BitIterator models the same iterator concepts as the base iterator.
431  */
432 template <class BaseIter>
433 class BitIterator
434   : public bititerator_detail::BitIteratorBase<BaseIter>::type {
435  public:
436   /**
437    * Return the number of bits in an element of the underlying iterator.
438    */
439   static unsigned int bitsPerBlock() {
440     return std::numeric_limits<
441       typename std::make_unsigned<
442         typename std::iterator_traits<BaseIter>::value_type
443       >::type
444     >::digits;
445   }
446
447   /**
448    * Construct a BitIterator that points at a given bit offset (default 0)
449    * in iter.
450    */
451   #pragma GCC diagnostic push // bitOffset shadows a member
452   #pragma GCC diagnostic ignored "-Wshadow"
453   explicit BitIterator(const BaseIter& iter, size_t bitOffset=0)
454     : bititerator_detail::BitIteratorBase<BaseIter>::type(iter),
455       bitOffset_(bitOffset) {
456     assert(bitOffset_ < bitsPerBlock());
457   }
458   #pragma GCC diagnostic pop
459
460   size_t bitOffset() const {
461     return bitOffset_;
462   }
463
464   void advanceToNextBlock() {
465     bitOffset_ = 0;
466     ++this->base_reference();
467   }
468
469   BitIterator& operator=(const BaseIter& other) {
470     this->~BitIterator();
471     new (this) BitIterator(other);
472     return *this;
473   }
474
475  private:
476   friend class boost::iterator_core_access;
477   friend BitIterator findFirstSet<>(BitIterator, BitIterator);
478
479   typedef bititerator_detail::BitReference<
480       typename std::iterator_traits<BaseIter>::reference,
481       typename std::iterator_traits<BaseIter>::value_type
482     > BitRef;
483
484   void advanceInBlock(size_t n) {
485     bitOffset_ += n;
486     assert(bitOffset_ < bitsPerBlock());
487   }
488
489   BitRef dereference() const {
490     return BitRef(*this->base_reference(), bitOffset_);
491   }
492
493   void advance(ssize_t n) {
494     size_t bpb = bitsPerBlock();
495     ssize_t blocks = n / bpb;
496     bitOffset_ += n % bpb;
497     if (bitOffset_ >= bpb) {
498       bitOffset_ -= bpb;
499       ++blocks;
500     }
501     this->base_reference() += blocks;
502   }
503
504   void increment() {
505     if (++bitOffset_ == bitsPerBlock()) {
506       advanceToNextBlock();
507     }
508   }
509
510   void decrement() {
511     if (bitOffset_-- == 0) {
512       bitOffset_ = bitsPerBlock() - 1;
513       --this->base_reference();
514     }
515   }
516
517   bool equal(const BitIterator& other) const {
518     return (bitOffset_ == other.bitOffset_ &&
519             this->base_reference() == other.base_reference());
520   }
521
522   ssize_t distance_to(const BitIterator& other) const {
523     return
524       (other.base_reference() - this->base_reference()) * bitsPerBlock() +
525       other.bitOffset_ - bitOffset_;
526   }
527
528   unsigned int bitOffset_;
529 };
530
531 /**
532  * Helper function, so you can write
533  * auto bi = makeBitIterator(container.begin());
534  */
535 template <class BaseIter>
536 BitIterator<BaseIter> makeBitIterator(const BaseIter& iter) {
537   return BitIterator<BaseIter>(iter);
538 }
539
540
541 /**
542  * Find first bit set in a range of bit iterators.
543  * 4.5x faster than the obvious std::find(begin, end, true);
544  */
545 template <class BaseIter>
546 BitIterator<BaseIter> findFirstSet(BitIterator<BaseIter> begin,
547                                    BitIterator<BaseIter> end) {
548   // shortcut to avoid ugly static_cast<>
549   static const typename BaseIter::value_type one = 1;
550
551   while (begin.base() != end.base()) {
552     typename BaseIter::value_type v = *begin.base();
553     // mask out the bits that don't matter (< begin.bitOffset)
554     v &= ~((one << begin.bitOffset()) - 1);
555     size_t firstSet = findFirstSet(v);
556     if (firstSet) {
557       --firstSet;  // now it's 0-based
558       assert(firstSet >= begin.bitOffset());
559       begin.advanceInBlock(firstSet - begin.bitOffset());
560       return begin;
561     }
562     begin.advanceToNextBlock();
563   }
564
565   // now begin points to the same block as end
566   if (end.bitOffset() != 0) {  // assume end is dereferenceable
567     typename BaseIter::value_type v = *begin.base();
568     // mask out the bits that don't matter (< begin.bitOffset)
569     v &= ~((one << begin.bitOffset()) - 1);
570     // mask out the bits that don't matter (>= end.bitOffset)
571     v &= (one << end.bitOffset()) - 1;
572     size_t firstSet = findFirstSet(v);
573     if (firstSet) {
574       --firstSet;  // now it's 0-based
575       assert(firstSet >= begin.bitOffset());
576       begin.advanceInBlock(firstSet - begin.bitOffset());
577       return begin;
578     }
579   }
580
581   return end;
582 }
583
584
585 template <class T, class Enable=void> struct Unaligned;
586
587 /**
588  * Representation of an unaligned value of a POD type.
589  */
590 FOLLY_PACK_PUSH
591 template <class T>
592 struct Unaligned<
593     T,
594     typename std::enable_if<std::is_pod<T>::value>::type> {
595   Unaligned() = default;  // uninitialized
596   /* implicit */ Unaligned(T v) : value(v) { }
597   T value;
598 } FOLLY_PACK_ATTR;
599 FOLLY_PACK_POP
600
601 /**
602  * Read an unaligned value of type T and return it.
603  */
604 template <class T>
605 inline T loadUnaligned(const void* p) {
606   static_assert(sizeof(Unaligned<T>) == sizeof(T), "Invalid unaligned size");
607   static_assert(alignof(Unaligned<T>) == 1, "Invalid alignment");
608   return static_cast<const Unaligned<T>*>(p)->value;
609 }
610
611 /**
612  * Write an unaligned value of type T.
613  */
614 template <class T>
615 inline void storeUnaligned(void* p, T value) {
616   static_assert(sizeof(Unaligned<T>) == sizeof(T), "Invalid unaligned size");
617   static_assert(alignof(Unaligned<T>) == 1, "Invalid alignment");
618   new (p) Unaligned<T>(value);
619 }
620
621 }  // namespace folly
622
623 #endif /* FOLLY_BITS_H_ */