|
|
1.1 root 1: /*
2: * Copyright (C) 2026 Tetsuya Isaki
3: *
4: * Permission to use, copy, modify, and/or distribute this software for any
5: * purpose with or without fee is hereby granted.
6: *
7: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14: */
15:
16: #pragma once
17:
18: #include "header.h"
19: #include <vector>
20:
21: // uint64 に 64 ビットを詰め込んだ std::vector<bool> っぽいクラス。
22: // std::vector<bool> 特殊化より制約と抽象度を少し下げたもので、
23: // 内部構造が uint64 であることを見せている。
24: // 現状 capacity の概念はなく、要素数は64個単位で増減する。
25: //
26: // std::vector 互換のメソッドは小文字(というか同名)にする。
27: class VectorBool64
28: {
29: static constexpr std::size_t NBITS = 64;
30:
31: public:
32: // 初期サイズ 0 で作成する。
33: VectorBool64() { }
34: // 初期サイズを指定して作成する。初期値は false。
35: explicit VectorBool64(std::size_t bits) {
36: Resize(bits);
37: }
38: // 初期サイズと初期値を指定して作成する。
39: VectorBool64(std::size_t bits, const bool c) {
40: Resize(bits, c);
41: }
42:
43: // デストラクタ不要。
44:
45: // デフォルト値を設定する。
46: void SetDefault(bool c) {
47: defval = c;
48: }
49:
50: // 要素数(ビット数) を返す。std::vector 互換のはず。
51: std::size_t size() const noexcept { return capacity(); }
52:
53: // メモリを再確保せずに格納できる要素数を返す。std::vector 互換のはず。
54: std::size_t capacity() const noexcept { return value.size() * NBITS; }
55:
56: // 64 ビットバケット数を返す。
57: std::size_t DataSize() const noexcept { return value.size(); }
58:
59: // コンテナが空なら true を返す。std::vector 互換のはず。
60: bool empty() const noexcept { return value.empty(); }
61:
62: // 初期値 b を指定して要素数(ビット数)を sz に変更する。
63: // ただし bits が 64 で割り切れない場合は 64 単位に切り上げる。
64: void Resize(std::size_t sz, const bool b) {
65: auto n = howmany(sz, NBITS);
66: if (n != value.size()) {
67: uint64 initval = b ? -1 : 0;
68: value.resize(n, initval);
69: }
70: }
71: void Resize(std::size_t sz) { Resize(sz, defval); }
72:
73: // 要素数(ビット数)を sz まで増やす。
74: // つまり増える方向だけの Resize(sz, c)。
75: void Expand(std::size_t sz, const bool c) {
76: auto n = howmany(sz, NBITS);
77: if (n > size()) {
78: Resize(sz, c);
79: }
80: }
81: void Expand(std::size_t sz) { Expand(sz, defval); }
82:
83: // n 番目のビットを返す。
84: // n が範囲外なら defval を返す。
85: bool GetBit(std::size_t n) const {
86: if (__predict_false(n >= size())) {
87: return defval;
88: }
89: std::size_t idx = n / NBITS;
90: std::size_t off = n % NBITS;
91: return ((GetData(idx) >> off) & 1) ? true : false;
92: }
93:
94: // n 番目にビットを b に更新する。
95: // n が範囲外なら何もしない?
96: void SetBit(std::size_t n, bool b) {
97: if (__predict_false(n >= size())) {
98: return;
99: }
100: std::size_t idx = n / NBITS;
101: std::size_t off = n % NBITS;
102: uint64 val = GetData(idx);
103: if (b) {
104: val |= 1ULL << off;
105: } else {
106: val &= ~(1ULL << off);
107: }
108: SetData(idx, val);
109: }
110: // n 番目のビットを立てる。オーバーロード…。
111: void SetBit(std::size_t n) { SetBit(n, true); }
112: // n 番目のビットをクリアする。
113: void ClearBit(std::size_t n) { SetBit(n, false); }
114:
115: // idx 番目の 64 ビットバケットを返す。
116: // idx が範囲外なら defval で構成された 64 ビットを返す。
117: uint64 GetData(std::size_t idx) const noexcept {
118: if (idx < value.size()) {
119: return value[idx];
120: } else {
121: return defval ? -1 : 0;
122: }
123: }
124:
125: // data を idx 番目の 64 ビットバケットを代入する。
126: // idx が範囲外なら何もしない?
127: void SetData(std::size_t idx, uint64 data) {
128: if (idx < value.size()) {
129: value[idx] = data;
130: } else {
131: // どうする?
132: }
133: }
134:
135: private:
136: std::vector<uint64> value {};
137:
138: // デフォルト値。
139: // 要素数を拡大した時の初期値と、範囲外を読んだ時の値に使われる。
140: bool defval {};
141: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.