Skip to content

Commit 8fe100b

Browse files
committed
Basic: Re-implement Bitset.
1 parent 3251ba1 commit 8fe100b

File tree

3 files changed

+89
-87
lines changed

3 files changed

+89
-87
lines changed

include/basic/bitset.h

+54-85
Original file line numberDiff line numberDiff line change
@@ -23,62 +23,75 @@
2323

2424
#pragma once
2525

26-
#include <bits/ranges_algo.h>
2726
#include <algorithm>
28-
#include <bitset>
2927
#include "basic/exception.h"
3028
#include "basic/mem.h"
31-
#include "basic/vec.h"
3229

3330
namespace lps::basic {
34-
template <size_t N, typename T = void>
31+
template <size_t N>
3532
class Bitset {
3633
public:
34+
using ele_type = bool;
35+
using bitset = std::array<ele_type, N>;
3736
constexpr static mem::TraceTag::tag_type kTag = "Bitset";
3837
template <std::size_t R, std::size_t L>
39-
static std::bitset<N> range(std::bitset<N> b) {
38+
static std::array<ele_type, L - R> range(const bitset& b) {
4039
static_assert(R <= L && L <= N, "Not valid.");
41-
b >>= R;
42-
b <<= (N - L + R);
43-
b >>= (N - L);
44-
return b;
40+
std::array<ele_type, L - R> new_b;
41+
size_t idx = 0;
42+
for (int i = R; i < L; i++) {
43+
new_b[idx++] = b[i];
44+
}
45+
return new_b;
4546
}
4647

47-
static std::bitset<N> range(std::bitset<N> b, std::size_t R, std::size_t L) {
48+
static bitset range(const bitset& b, std::size_t R, std::size_t L) {
4849
lps_assert(kTag, R <= L && L <= N);
49-
b >>= R;
50-
b <<= (N - L + R);
51-
b >>= (N - L);
52-
return b;
50+
bitset new_b;
51+
size_t idx = 0;
52+
for (int i = R; i < L; i++) {
53+
new_b[idx++] = b[i];
54+
}
55+
return new_b;
5356
}
5457

5558
static constexpr size_t kN = N;
56-
Bitset() : len_(N) { value_.reset(); }
59+
60+
explicit Bitset() { reset(); }
61+
5762
template <size_t N1>
58-
explicit Bitset(const std::array<bool, N1>& other, size_t start_idx = 0)
63+
explicit Bitset(const std::array<ele_type, N1>& other, size_t start_idx = 0)
5964
: start_idx_(start_idx) {
60-
size_t m = std::min(N, N1);
61-
for (size_t i = start_idx; i < m; i++) {
62-
value_[i] = other[i];
63-
}
64-
len_ = m;
65+
set(other, start_idx);
6566
}
6667

6768
template <size_t N1>
68-
explicit Bitset(const std::bitset<N1>& other, size_t start_idx = 0)
69-
: start_idx_(start_idx) {
69+
void set(const std::array<ele_type, N1>& other, size_t start_idx = 0) {
70+
start_idx_ = start_idx;
7071
size_t m = std::min(N, N1);
7172
if (start_idx > 0) {
7273
lps_assert(kTag, N1 < N);
7374
value_ = value_.to_ullong() || (other.to_ullong() << start_idx);
7475
} else {
75-
value_ = other.to_ullong();
76+
77+
for (int i = 0; i < m; i++) {
78+
value_[i] = other[i];
79+
}
7680
}
7781
len_ = m;
82+
lps_assert(kTag, len_ + start_idx_ <= N);
7883
}
7984

80-
void reset() { value_ = value(start_idx_).reset().to_ullong(); }
81-
void set() { value_ = value(start_idx_).set().to_ullong(); }
85+
void reset() {
86+
for (int i = start_idx_; i < start_idx_ + len_; i++) {
87+
value_[i] = false;
88+
}
89+
}
90+
void set() {
91+
for (int i = start_idx_; i < start_idx_ + len_; i++) {
92+
value_[i] = true;
93+
}
94+
}
8295
void set(size_t pos) {
8396
lps_assert(kTag, (pos + start_idx_) < len_);
8497
value_[pos + start_idx_] = true;
@@ -87,73 +100,29 @@ class Bitset {
87100
lps_assert(kTag, (pos + start_idx_) < len_);
88101
return value_[pos + start_idx_];
89102
}
90-
std::bitset<N> value(size_t start_idx = 0) {
91-
return std::bitset<N>(
92-
range(value_, start_idx, start_idx + len_).to_ullong());
93-
}
94-
95-
template <size_t N1>
96-
std::bitset<N1> value(size_t start_idx = 0) {
97-
return std::bitset<N1>(
98-
range(value_, start_idx, start_idx + len_).to_ullong());
103+
bitset value(size_t start_idx = 0) {
104+
if (start_idx == 0) {
105+
return range(value_, 0, len_);
106+
}
107+
auto a = range(value_, start_idx, len_);
108+
return a;
99109
}
100110

101111
bool all() {
102-
return range(value_, start_idx_, start_idx_ + len_).count() == len_;
112+
size_t cnt = 0;
113+
for (int i = start_idx_; i < start_idx_ + len_; i++) {
114+
if (value_[i]) {
115+
cnt++;
116+
}
117+
}
118+
return cnt == len_;
103119
}
104120
[[nodiscard]] size_t start_idx() const { return start_idx_; }
105121

106122
private:
107-
std::bitset<N> value_;
108-
size_t len_{0};
123+
bitset value_;
124+
size_t len_{N};
109125
size_t start_idx_{0};
110126
};
111127

112-
template <size_t N>
113-
class Bitset<N, typename std::enable_if<(N > (8 * sizeof(unsigned long long))),
114-
bool>::type> {
115-
public:
116-
constexpr static mem::TraceTag::tag_type kTag = "Bitset";
117-
static constexpr size_t kN = N;
118-
Bitset() : len_(N) { LPS_ERROR(kTag, "Unsupport yet."); }
119-
template <size_t N1>
120-
explicit Bitset(const std::array<bool, N1>& other, size_t start_idx = 0) {
121-
constexpr size_t kM = std::min(N, N1);
122-
for (size_t i = start_idx; i < kM; i++) {
123-
value_[i] = other[i];
124-
}
125-
len_ = kM;
126-
}
127-
template <size_t N1>
128-
explicit Bitset(const std::bitset<N1>& other, size_t start_idx = 0) {
129-
static_assert(N1 < N, "not valid size");
130-
for (size_t i = start_idx; i < N1; i++) {
131-
value_[i] = other[i];
132-
}
133-
len_ = N1;
134-
}
135-
void reset() { value_.fill(false); }
136-
void set() { value_.fill(true); }
137-
void set(size_t pos) {
138-
lps_assert(kTag, pos < len_);
139-
value_[pos] = true;
140-
}
141-
bool at(size_t pos) {
142-
lps_assert(kTag, pos < len_);
143-
return value_[pos];
144-
}
145-
std::array<bool, N> value(size_t start_idx = 0) {
146-
lps_assert(kTag, start_idx == 0);
147-
return value_;
148-
}
149-
bool all() {
150-
lps_assert(kTag, len_ <= N);
151-
return std::ranges::all_of(value_.begin(), value_.begin() + len_,
152-
[](bool a) { return a; });
153-
}
154-
155-
private:
156-
basic::Vector<N, bool> value_;
157-
size_t len_{0};
158-
};
159128
} // namespace lps::basic

tests/basic/CMakeLists.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
add_executable(test_vec test_vec.cc)
2-
target_link_libraries(test_vec)
32

43
add_executable(test_str test_str.cc)
5-
target_link_libraries(test_str)
4+
5+
add_executable(test_bitset test_bitset.cc)
66

77
enable_testing()
88

99
add_test(NAME test_vec COMMAND test_vec)
1010
add_test(NAME test_str COMMAND test_str)
11+
add_test(NAME test_bitset COMMAND test_bitset)

tests/basic/test_bitset.cc

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* MIT License
3+
* Copyright (c) 2023 mxlol233 ([email protected])
4+
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
12+
* The above copyright notice and this permission notice shall be included in all
13+
* copies or substantial portions of the Software.
14+
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
* SOFTWARE.
22+
*/
23+
24+
#include "basic/bitset.h"
25+
26+
int main(int argc, char** argv) {
27+
lps::basic::Bitset<2> a;
28+
a.set();
29+
30+
lps::basic::Bitset<1> b(a.value(1));
31+
return 0;
32+
}

0 commit comments

Comments
 (0)