2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_BITSET_UTILS_H_
18 #define incl_HPHP_BITSET_UTILS_H_
21 #include "hphp/util/assertions.h"
25 // Return the index of the first set bit in a bitset, or bitset.size() if none.
27 inline size_t bitset_find_first(const std::bitset
<N
>& bitset
) {
28 #if defined(__GNUC__) && !defined(__APPLE__)
29 // GNU provides non-standard (its a hold over from the original SGI
30 // implementation) _Find_first(), which efficiently returns the index of the
32 return bitset
._Find_first();
34 for (size_t i
= 0; i
< bitset
.size(); ++i
) {
35 if (bitset
[i
]) return i
;
41 // Return the index of the first set bit in a bitset after the given index, or
42 // bitset.size() if none.
44 inline size_t bitset_find_next(const std::bitset
<N
>& bitset
, size_t prev
) {
45 assertx(prev
< bitset
.size());
46 #if defined(__GNUC__) && !defined(__APPLE__)
47 // GNU provides non-standard (its a hold over from the original SGI
48 // implementation) _Find_next(), which given an index, efficiently returns
49 // the index of the first set bit after the index.
50 return bitset
._Find_next(prev
);
52 for (size_t i
= prev
+1; i
< bitset
.size(); ++i
) {
53 if (bitset
[i
]) return i
;
59 // Invoke the given callable on the indices of all the set bits in a bitset.
60 template <typename F
, size_t N
>
61 inline void bitset_for_each_set(const std::bitset
<N
>& bitset
, F f
) {
62 for (auto i
= bitset_find_first(bitset
);
64 i
= bitset_find_next(bitset
, i
)) {
70 inline size_t findFirst1(const std::bitset
<N
>& bitset
) {
71 return bitset_find_first(bitset
);
74 // range from [s, e), if not found, return e
76 inline size_t findFirst1(const std::bitset
<N
>& bitset
, size_t s
, size_t e
) {
78 assert(e
<= bitset
.size());
79 for (size_t i
= s
; i
< e
; ++i
) {
80 if (bitset
[i
]) return i
;
86 inline size_t findFirst0(const std::bitset
<N
>& bitset
) {
87 for (size_t i
= 0; i
< bitset
.size(); ++i
) {
88 if (!bitset
[i
]) return i
;
93 // range from [s, e), if not found, return e; if s == e, return e
95 inline size_t findFirst0(const std::bitset
<N
>& bitset
, size_t s
, size_t e
) {
97 assert(e
<= bitset
.size());
98 for (size_t i
= s
; i
< e
; ++i
) {
99 if (!bitset
[i
]) return i
;
105 inline size_t findLast1(const std::bitset
<N
>& bitset
) {
106 for (size_t i
= bitset
.size(); i
-- > 0;) {
107 if (bitset
[i
]) return i
;
109 return bitset
.size();
112 // range from [s, e), if not found, return e; if s == e, return e
114 inline size_t findLast1(const std::bitset
<N
>& bitset
, size_t s
, size_t e
) {
116 assert(e
<= bitset
.size());
117 for (size_t i
= e
; i
-- > s
;) {
118 if (bitset
[i
]) return i
;
124 inline size_t findLast0(const std::bitset
<N
>& bitset
) {
125 for (size_t i
= bitset
.size(); i
-- > 0;) {
126 if (!bitset
[i
]) return i
;
128 return bitset
.size();
131 // range from [s, e), if not found, return e; if s == e, return e
133 inline size_t findLast0(const std::bitset
<N
>& bitset
, size_t s
, size_t e
) {
135 assert(e
<= bitset
.size());
136 for (size_t i
= e
; i
-- > s
;) {
137 if (!bitset
[i
]) return i
;
144 inline std::bitset
<N
>& fill1(std::bitset
<N
>& bitset
) {
150 inline std::bitset
<N
>& fill1(std::bitset
<N
>& bitset
,
151 size_t s
, size_t e
) {
153 assert(e
<= bitset
.size());
154 for(size_t i
= s
; i
< e
; ++i
){
161 inline std::bitset
<N
>& fill0(std::bitset
<N
>& bitset
) {
162 return bitset
.reset();
167 inline std::bitset
<N
>& fill0(std::bitset
<N
>& bitset
,
168 size_t s
, size_t e
) {
170 assert(e
<= bitset
.size());
171 for(size_t i
= s
; i
< e
; ++i
){