catboost 1.25.1 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPLOYMENT.md +22 -15
- package/README.md +37 -27
- package/binding.gyp +5 -7
- package/build_scripts/bootstrap.js +2 -1
- package/build_scripts/out/build.js +46 -68
- package/build_scripts/out/build_model.js +1 -1
- package/build_scripts/out/{build_ya.js → build_native.js} +1 -1
- package/build_scripts/out/ci.js +5 -5
- package/build_scripts/out/config.js +32 -18
- package/build_scripts/out/install.js +5 -3
- package/build_scripts/out/package_prepublish.js +1 -1
- package/build_scripts/out/packaging.js +1 -19
- package/build_scripts/out/run_tests.js +1 -1
- package/build_scripts/out/test.js +8 -3
- package/config.json +18 -11
- package/inc/catboost/libs/model_interface/c_api.h +349 -3
- package/lib/catboost.d.ts +65 -21
- package/package.json +4 -4
- package/src/api_helpers.cpp +100 -24
- package/src/api_helpers.h +8 -7
- package/src/api_module.cpp +1 -2
- package/src/model.cpp +483 -83
- package/src/model.h +24 -9
- package/inc/contrib/libs/cxxsupp/system_stl/include/stlfwd +0 -14
- package/inc/util/charset/recode_result.h +0 -9
- package/inc/util/charset/unicode_table.h +0 -123
- package/inc/util/charset/unidata.h +0 -421
- package/inc/util/charset/utf8.h +0 -384
- package/inc/util/charset/wide.h +0 -843
- package/inc/util/charset/wide_specific.h +0 -22
- package/inc/util/datetime/base.h +0 -669
- package/inc/util/datetime/constants.h +0 -7
- package/inc/util/datetime/cputimer.h +0 -124
- package/inc/util/datetime/parser.h +0 -292
- package/inc/util/datetime/systime.h +0 -47
- package/inc/util/datetime/uptime.h +0 -8
- package/inc/util/digest/city.h +0 -88
- package/inc/util/digest/fnv.h +0 -73
- package/inc/util/digest/multi.h +0 -14
- package/inc/util/digest/murmur.h +0 -57
- package/inc/util/digest/numeric.h +0 -86
- package/inc/util/digest/sequence.h +0 -48
- package/inc/util/draft/date.h +0 -129
- package/inc/util/draft/datetime.h +0 -184
- package/inc/util/draft/enum.h +0 -136
- package/inc/util/draft/holder_vector.h +0 -102
- package/inc/util/draft/ip.h +0 -131
- package/inc/util/draft/matrix.h +0 -108
- package/inc/util/draft/memory.h +0 -40
- package/inc/util/folder/dirent_win.h +0 -46
- package/inc/util/folder/dirut.h +0 -121
- package/inc/util/folder/filelist.h +0 -81
- package/inc/util/folder/fts.h +0 -108
- package/inc/util/folder/iterator.h +0 -109
- package/inc/util/folder/lstat_win.h +0 -20
- package/inc/util/folder/path.h +0 -225
- package/inc/util/folder/pathsplit.h +0 -113
- package/inc/util/folder/tempdir.h +0 -42
- package/inc/util/generic/adaptor.h +0 -134
- package/inc/util/generic/algorithm.h +0 -765
- package/inc/util/generic/array_ref.h +0 -282
- package/inc/util/generic/array_size.h +0 -24
- package/inc/util/generic/benchmark/vector_count_ctor/f.h +0 -9
- package/inc/util/generic/bitmap.h +0 -1115
- package/inc/util/generic/bitops.h +0 -459
- package/inc/util/generic/bt_exception.h +0 -24
- package/inc/util/generic/buffer.h +0 -232
- package/inc/util/generic/cast.h +0 -176
- package/inc/util/generic/deque.h +0 -24
- package/inc/util/generic/explicit_type.h +0 -42
- package/inc/util/generic/fastqueue.h +0 -55
- package/inc/util/generic/flags.h +0 -244
- package/inc/util/generic/function.h +0 -103
- package/inc/util/generic/fwd.h +0 -171
- package/inc/util/generic/guid.h +0 -61
- package/inc/util/generic/hash.h +0 -2032
- package/inc/util/generic/hash_primes.h +0 -140
- package/inc/util/generic/hash_set.h +0 -490
- package/inc/util/generic/hide_ptr.h +0 -3
- package/inc/util/generic/intrlist.h +0 -876
- package/inc/util/generic/is_in.h +0 -53
- package/inc/util/generic/iterator.h +0 -137
- package/inc/util/generic/iterator_range.h +0 -105
- package/inc/util/generic/lazy_value.h +0 -66
- package/inc/util/generic/list.h +0 -22
- package/inc/util/generic/map.h +0 -44
- package/inc/util/generic/mapfindptr.h +0 -60
- package/inc/util/generic/maybe.h +0 -713
- package/inc/util/generic/maybe_traits.h +0 -164
- package/inc/util/generic/mem_copy.h +0 -55
- package/inc/util/generic/noncopyable.h +0 -38
- package/inc/util/generic/object_counter.h +0 -53
- package/inc/util/generic/ptr.h +0 -1113
- package/inc/util/generic/queue.h +0 -57
- package/inc/util/generic/refcount.h +0 -162
- package/inc/util/generic/reserve.h +0 -11
- package/inc/util/generic/scope.h +0 -65
- package/inc/util/generic/serialized_enum.h +0 -406
- package/inc/util/generic/set.h +0 -42
- package/inc/util/generic/singleton.h +0 -136
- package/inc/util/generic/size_literals.h +0 -65
- package/inc/util/generic/stack.h +0 -18
- package/inc/util/generic/store_policy.h +0 -120
- package/inc/util/generic/strbase.h +0 -612
- package/inc/util/generic/strbuf.h +0 -552
- package/inc/util/generic/strfcpy.h +0 -17
- package/inc/util/generic/string.h +0 -1572
- package/inc/util/generic/string_hash.h +0 -21
- package/inc/util/generic/string_ut.h +0 -1175
- package/inc/util/generic/type_name.h +0 -34
- package/inc/util/generic/typelist.h +0 -114
- package/inc/util/generic/typetraits.h +0 -325
- package/inc/util/generic/utility.h +0 -132
- package/inc/util/generic/va_args.h +0 -400
- package/inc/util/generic/variant.h +0 -631
- package/inc/util/generic/variant_traits.h +0 -171
- package/inc/util/generic/vector.h +0 -119
- package/inc/util/generic/xrange.h +0 -258
- package/inc/util/generic/yexception.h +0 -212
- package/inc/util/generic/yexception_ut.h +0 -14
- package/inc/util/generic/ylimits.h +0 -92
- package/inc/util/generic/ymath.h +0 -206
- package/inc/util/memory/addstorage.h +0 -93
- package/inc/util/memory/alloc.h +0 -27
- package/inc/util/memory/blob.h +0 -296
- package/inc/util/memory/mmapalloc.h +0 -8
- package/inc/util/memory/pool.h +0 -432
- package/inc/util/memory/segmented_string_pool.h +0 -194
- package/inc/util/memory/segpool_alloc.h +0 -118
- package/inc/util/memory/smallobj.h +0 -141
- package/inc/util/memory/tempbuf.h +0 -111
- package/inc/util/network/address.h +0 -136
- package/inc/util/network/endpoint.h +0 -61
- package/inc/util/network/hostip.h +0 -16
- package/inc/util/network/init.h +0 -60
- package/inc/util/network/interface.h +0 -17
- package/inc/util/network/iovec.h +0 -65
- package/inc/util/network/ip.h +0 -116
- package/inc/util/network/nonblock.h +0 -8
- package/inc/util/network/pair.h +0 -9
- package/inc/util/network/poller.h +0 -58
- package/inc/util/network/pollerimpl.h +0 -707
- package/inc/util/network/sock.h +0 -608
- package/inc/util/network/socket.h +0 -421
- package/inc/util/random/common_ops.h +0 -130
- package/inc/util/random/easy.h +0 -47
- package/inc/util/random/entropy.h +0 -21
- package/inc/util/random/fast.h +0 -101
- package/inc/util/random/init_atfork.h +0 -3
- package/inc/util/random/lcg_engine.h +0 -66
- package/inc/util/random/mersenne.h +0 -46
- package/inc/util/random/mersenne32.h +0 -50
- package/inc/util/random/mersenne64.h +0 -50
- package/inc/util/random/normal.h +0 -38
- package/inc/util/random/random.h +0 -30
- package/inc/util/random/shuffle.h +0 -39
- package/inc/util/str_stl.h +0 -266
- package/inc/util/stream/aligned.h +0 -99
- package/inc/util/stream/buffer.h +0 -119
- package/inc/util/stream/buffered.h +0 -225
- package/inc/util/stream/debug.h +0 -53
- package/inc/util/stream/direct_io.h +0 -43
- package/inc/util/stream/file.h +0 -108
- package/inc/util/stream/format.h +0 -444
- package/inc/util/stream/fwd.h +0 -100
- package/inc/util/stream/hex.h +0 -8
- package/inc/util/stream/holder.h +0 -44
- package/inc/util/stream/input.h +0 -273
- package/inc/util/stream/labeled.h +0 -19
- package/inc/util/stream/length.h +0 -100
- package/inc/util/stream/mem.h +0 -255
- package/inc/util/stream/multi.h +0 -32
- package/inc/util/stream/null.h +0 -61
- package/inc/util/stream/output.h +0 -304
- package/inc/util/stream/pipe.h +0 -112
- package/inc/util/stream/printf.h +0 -25
- package/inc/util/stream/str.h +0 -207
- package/inc/util/stream/tee.h +0 -28
- package/inc/util/stream/tempbuf.h +0 -21
- package/inc/util/stream/tokenizer.h +0 -214
- package/inc/util/stream/trace.h +0 -60
- package/inc/util/stream/walk.h +0 -35
- package/inc/util/stream/zerocopy.h +0 -91
- package/inc/util/stream/zerocopy_output.h +0 -57
- package/inc/util/stream/zlib.h +0 -173
- package/inc/util/string/ascii.h +0 -236
- package/inc/util/string/builder.h +0 -39
- package/inc/util/string/cast.h +0 -347
- package/inc/util/string/cstriter.h +0 -14
- package/inc/util/string/escape.h +0 -70
- package/inc/util/string/hex.h +0 -59
- package/inc/util/string/join.h +0 -194
- package/inc/util/string/printf.h +0 -13
- package/inc/util/string/reverse.h +0 -16
- package/inc/util/string/split.h +0 -1080
- package/inc/util/string/strip.h +0 -257
- package/inc/util/string/strspn.h +0 -65
- package/inc/util/string/subst.h +0 -56
- package/inc/util/string/type.h +0 -50
- package/inc/util/string/util.h +0 -195
- package/inc/util/string/vector.h +0 -132
- package/inc/util/system/align.h +0 -50
- package/inc/util/system/atexit.h +0 -22
- package/inc/util/system/atomic.h +0 -51
- package/inc/util/system/atomic_gcc.h +0 -90
- package/inc/util/system/atomic_ops.h +0 -189
- package/inc/util/system/atomic_win.h +0 -114
- package/inc/util/system/backtrace.h +0 -39
- package/inc/util/system/byteorder.h +0 -186
- package/inc/util/system/compat.h +0 -84
- package/inc/util/system/compiler.h +0 -620
- package/inc/util/system/condvar.h +0 -71
- package/inc/util/system/context.h +0 -181
- package/inc/util/system/context_aarch64.h +0 -8
- package/inc/util/system/context_i686.h +0 -9
- package/inc/util/system/context_x86.h +0 -12
- package/inc/util/system/context_x86_64.h +0 -7
- package/inc/util/system/cpu_id.h +0 -159
- package/inc/util/system/daemon.h +0 -28
- package/inc/util/system/datetime.h +0 -98
- package/inc/util/system/defaults.h +0 -149
- package/inc/util/system/demangle.h +0 -5
- package/inc/util/system/demangle_impl.h +0 -23
- package/inc/util/system/direct_io.h +0 -71
- package/inc/util/system/dynlib.h +0 -119
- package/inc/util/system/env.h +0 -32
- package/inc/util/system/error.h +0 -95
- package/inc/util/system/event.h +0 -122
- package/inc/util/system/execpath.h +0 -17
- package/inc/util/system/fasttime.h +0 -6
- package/inc/util/system/fhandle.h +0 -27
- package/inc/util/system/file.h +0 -210
- package/inc/util/system/file_lock.h +0 -34
- package/inc/util/system/filemap.h +0 -383
- package/inc/util/system/flock.h +0 -35
- package/inc/util/system/fs.h +0 -156
- package/inc/util/system/fs_win.h +0 -29
- package/inc/util/system/fstat.h +0 -46
- package/inc/util/system/getpid.h +0 -12
- package/inc/util/system/guard.h +0 -179
- package/inc/util/system/hi_lo.h +0 -139
- package/inc/util/system/hostname.h +0 -10
- package/inc/util/system/hp_timer.h +0 -36
- package/inc/util/system/info.h +0 -12
- package/inc/util/system/interrupt_signals.h +0 -22
- package/inc/util/system/madvise.h +0 -30
- package/inc/util/system/maxlen.h +0 -32
- package/inc/util/system/mem_info.h +0 -18
- package/inc/util/system/mincore.h +0 -38
- package/inc/util/system/mktemp.h +0 -11
- package/inc/util/system/mlock.h +0 -43
- package/inc/util/system/mutex.h +0 -67
- package/inc/util/system/nice.h +0 -3
- package/inc/util/system/pipe.h +0 -90
- package/inc/util/system/platform.h +0 -246
- package/inc/util/system/progname.h +0 -13
- package/inc/util/system/protect.h +0 -25
- package/inc/util/system/rusage.h +0 -26
- package/inc/util/system/rwlock.h +0 -78
- package/inc/util/system/sanitizers.h +0 -122
- package/inc/util/system/sem.h +0 -41
- package/inc/util/system/shellcommand.h +0 -472
- package/inc/util/system/shmat.h +0 -32
- package/inc/util/system/sigset.h +0 -78
- package/inc/util/system/spin_wait.h +0 -10
- package/inc/util/system/spinlock.h +0 -121
- package/inc/util/system/src_location.h +0 -25
- package/inc/util/system/src_root.h +0 -68
- package/inc/util/system/sys_alloc.h +0 -43
- package/inc/util/system/sysstat.h +0 -52
- package/inc/util/system/tempfile.h +0 -34
- package/inc/util/system/thread.h +0 -167
- package/inc/util/system/tls.h +0 -307
- package/inc/util/system/types.h +0 -119
- package/inc/util/system/unaligned_mem.h +0 -67
- package/inc/util/system/user.h +0 -5
- package/inc/util/system/utime.h +0 -6
- package/inc/util/system/valgrind.h +0 -48
- package/inc/util/system/winint.h +0 -43
- package/inc/util/system/yassert.h +0 -121
- package/inc/util/system/yield.h +0 -4
- package/inc/util/thread/factory.h +0 -65
- package/inc/util/thread/fwd.h +0 -30
- package/inc/util/thread/lfqueue.h +0 -406
- package/inc/util/thread/lfstack.h +0 -188
- package/inc/util/thread/pool.h +0 -388
- package/inc/util/thread/singleton.h +0 -42
- package/inc/util/ysafeptr.h +0 -427
- package/inc/util/ysaveload.h +0 -700
|
@@ -1,1115 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include "fwd.h"
|
|
4
|
-
#include "ptr.h"
|
|
5
|
-
#include "bitops.h"
|
|
6
|
-
#include "typetraits.h"
|
|
7
|
-
#include "algorithm.h"
|
|
8
|
-
#include "utility.h"
|
|
9
|
-
|
|
10
|
-
#include <util/system/yassert.h>
|
|
11
|
-
#include <util/system/defaults.h>
|
|
12
|
-
#include <util/str_stl.h>
|
|
13
|
-
#include <util/ysaveload.h>
|
|
14
|
-
|
|
15
|
-
namespace NBitMapPrivate {
|
|
16
|
-
// Returns number of bits set; result is in most significatnt byte
|
|
17
|
-
inline ui64 ByteSums(ui64 x) {
|
|
18
|
-
ui64 byteSums = x - ((x & 0xAAAAAAAAAAAAAAAAULL) >> 1);
|
|
19
|
-
|
|
20
|
-
byteSums = (byteSums & 0x3333333333333333ULL) + ((byteSums >> 2) & 0x3333333333333333ULL);
|
|
21
|
-
byteSums = (byteSums + (byteSums >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
|
|
22
|
-
|
|
23
|
-
return byteSums * 0x0101010101010101ULL;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// better than intrinsics without -mpopcnt
|
|
27
|
-
template <typename T>
|
|
28
|
-
static unsigned CountBitsPrivate(T v) noexcept {
|
|
29
|
-
return static_cast<unsigned>(ByteSums(v) >> 56);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
template <typename TChunkType, size_t ExtraBits>
|
|
33
|
-
struct TSanitizeMask {
|
|
34
|
-
static constexpr TChunkType Value = ~((~TChunkType(0)) << ExtraBits);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
template <typename TChunkType>
|
|
38
|
-
struct TSanitizeMask<TChunkType, 0> {
|
|
39
|
-
static constexpr TChunkType Value = (TChunkType)~TChunkType(0u);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
template <typename TTargetChunk, typename TSourceChunk>
|
|
43
|
-
struct TBigToSmallDataCopier {
|
|
44
|
-
static_assert(sizeof(TTargetChunk) < sizeof(TSourceChunk), "expect sizeof(TTargetChunk) < sizeof(TSourceChunk)");
|
|
45
|
-
static_assert(0 == sizeof(TSourceChunk) % sizeof(TTargetChunk), "expect 0 == sizeof(TSourceChunk) % sizeof(TTargetChunk)");
|
|
46
|
-
|
|
47
|
-
static constexpr size_t BLOCK_SIZE = sizeof(TSourceChunk) / sizeof(TTargetChunk);
|
|
48
|
-
|
|
49
|
-
union TCnv {
|
|
50
|
-
TSourceChunk BigData;
|
|
51
|
-
TTargetChunk SmallData[BLOCK_SIZE];
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
static inline void CopyChunk(TTargetChunk* target, TSourceChunk source) {
|
|
55
|
-
TCnv c;
|
|
56
|
-
c.BigData = source;
|
|
57
|
-
#if defined(_big_endian_)
|
|
58
|
-
::ReverseCopy(c.SmallData, c.SmallData + Y_ARRAY_SIZE(c.SmallData), target);
|
|
59
|
-
#else
|
|
60
|
-
::Copy(c.SmallData, c.SmallData + Y_ARRAY_SIZE(c.SmallData), target);
|
|
61
|
-
#endif
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
static inline void Copy(TTargetChunk* target, size_t targetSize, const TSourceChunk* source, size_t sourceSize) {
|
|
65
|
-
Y_ASSERT(targetSize >= sourceSize * BLOCK_SIZE);
|
|
66
|
-
if (targetSize > sourceSize * BLOCK_SIZE) {
|
|
67
|
-
::Fill(target + sourceSize * BLOCK_SIZE, target + targetSize, 0);
|
|
68
|
-
}
|
|
69
|
-
for (size_t i = 0; i < sourceSize; ++i) {
|
|
70
|
-
CopyChunk(target + i * BLOCK_SIZE, source[i]);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
template <typename TTargetChunk, typename TSourceChunk>
|
|
76
|
-
struct TSmallToBigDataCopier {
|
|
77
|
-
static_assert(sizeof(TTargetChunk) > sizeof(TSourceChunk), "expect sizeof(TTargetChunk) > sizeof(TSourceChunk)");
|
|
78
|
-
static_assert(0 == sizeof(TTargetChunk) % sizeof(TSourceChunk), "expect 0 == sizeof(TTargetChunk) % sizeof(TSourceChunk)");
|
|
79
|
-
|
|
80
|
-
static constexpr size_t BLOCK_SIZE = sizeof(TTargetChunk) / sizeof(TSourceChunk);
|
|
81
|
-
|
|
82
|
-
union TCnv {
|
|
83
|
-
TSourceChunk SmallData[BLOCK_SIZE];
|
|
84
|
-
TTargetChunk BigData;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
static inline TTargetChunk CopyFullChunk(const TSourceChunk* source) {
|
|
88
|
-
TCnv c;
|
|
89
|
-
#if defined(_big_endian_)
|
|
90
|
-
::ReverseCopy(source, source + BLOCK_SIZE, c.SmallData);
|
|
91
|
-
#else
|
|
92
|
-
::Copy(source, source + BLOCK_SIZE, c.SmallData);
|
|
93
|
-
#endif
|
|
94
|
-
return c.BigData;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
static inline TTargetChunk CopyPartChunk(const TSourceChunk* source, size_t count) {
|
|
98
|
-
Y_ASSERT(count <= BLOCK_SIZE);
|
|
99
|
-
TCnv c;
|
|
100
|
-
c.BigData = 0;
|
|
101
|
-
#if defined(_big_endian_)
|
|
102
|
-
::ReverseCopy(source, source + count, c.SmallData);
|
|
103
|
-
#else
|
|
104
|
-
::Copy(source, source + count, c.SmallData);
|
|
105
|
-
#endif
|
|
106
|
-
return c.BigData;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
static inline void Copy(TTargetChunk* target, size_t targetSize, const TSourceChunk* source, size_t sourceSize) {
|
|
110
|
-
Y_ASSERT(targetSize * BLOCK_SIZE >= sourceSize);
|
|
111
|
-
if (targetSize * BLOCK_SIZE > sourceSize) {
|
|
112
|
-
::Fill(target + sourceSize / BLOCK_SIZE, target + targetSize, 0);
|
|
113
|
-
}
|
|
114
|
-
size_t i = 0;
|
|
115
|
-
for (; i < sourceSize / BLOCK_SIZE; ++i) {
|
|
116
|
-
target[i] = CopyFullChunk(source + i * BLOCK_SIZE);
|
|
117
|
-
}
|
|
118
|
-
if (0 != sourceSize % BLOCK_SIZE) {
|
|
119
|
-
target[i] = CopyPartChunk(source + i * BLOCK_SIZE, sourceSize % BLOCK_SIZE);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
template <typename TChunk>
|
|
125
|
-
struct TUniformDataCopier {
|
|
126
|
-
static inline void Copy(TChunk* target, size_t targetSize, const TChunk* source, size_t sourceSize) {
|
|
127
|
-
Y_ASSERT(targetSize >= sourceSize);
|
|
128
|
-
for (size_t i = 0; i < sourceSize; ++i) {
|
|
129
|
-
target[i] = source[i];
|
|
130
|
-
}
|
|
131
|
-
for (size_t i = sourceSize; i < targetSize; ++i) {
|
|
132
|
-
target[i] = 0;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
template <typename TFirst, typename TSecond>
|
|
138
|
-
struct TIsSmaller {
|
|
139
|
-
enum {
|
|
140
|
-
Result = sizeof(TFirst) < sizeof(TSecond)
|
|
141
|
-
};
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
template <typename TTargetChunk, typename TSourceChunk>
|
|
145
|
-
struct TDataCopier: public std::conditional_t<std::is_same<TTargetChunk, TSourceChunk>::value, TUniformDataCopier<TTargetChunk>, std::conditional_t<TIsSmaller<TTargetChunk, TSourceChunk>::Result, TBigToSmallDataCopier<TTargetChunk, TSourceChunk>, TSmallToBigDataCopier<TTargetChunk, TSourceChunk>>> {
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
template <typename TTargetChunk, typename TSourceChunk>
|
|
149
|
-
inline void CopyData(TTargetChunk* target, size_t targetSize, const TSourceChunk* source, size_t sourceSize) {
|
|
150
|
-
TDataCopier<TTargetChunk, TSourceChunk>::Copy(target, targetSize, source, sourceSize);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
template <size_t BitCount, typename TChunkType>
|
|
154
|
-
struct TFixedStorage {
|
|
155
|
-
using TChunk = TChunkType;
|
|
156
|
-
|
|
157
|
-
static constexpr size_t Size = (BitCount + 8 * sizeof(TChunk) - 1) / (8 * sizeof(TChunk));
|
|
158
|
-
|
|
159
|
-
TChunk Data[Size];
|
|
160
|
-
|
|
161
|
-
TFixedStorage() {
|
|
162
|
-
Zero(Data);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
TFixedStorage(const TFixedStorage<BitCount, TChunkType>& st) {
|
|
166
|
-
for (size_t i = 0; i < Size; ++i) {
|
|
167
|
-
Data[i] = st.Data[i];
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
template <typename TOtherChunk>
|
|
172
|
-
TFixedStorage(const TOtherChunk* data, size_t size) {
|
|
173
|
-
Y_VERIFY(Size * sizeof(TChunk) >= size * sizeof(TOtherChunk), "Exceeding bitmap storage capacity");
|
|
174
|
-
CopyData(Data, Size, data, size);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
Y_FORCE_INLINE void Swap(TFixedStorage<BitCount, TChunkType>& st) {
|
|
178
|
-
for (size_t i = 0; i < Size; ++i) {
|
|
179
|
-
DoSwap(Data[i], st.Data[i]);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
Y_FORCE_INLINE static constexpr size_t GetBitCapacity() noexcept {
|
|
184
|
-
return BitCount;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
Y_FORCE_INLINE static constexpr size_t GetChunkCapacity() noexcept {
|
|
188
|
-
return Size;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Returns true if the resulting storage capacity is enough to fit the requested size
|
|
192
|
-
Y_FORCE_INLINE static constexpr bool ExpandBitSize(const size_t bitSize) noexcept {
|
|
193
|
-
return bitSize <= BitCount;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
Y_FORCE_INLINE void Sanitize() {
|
|
197
|
-
Data[Size - 1] &= TSanitizeMask<TChunk, BitCount % (8 * sizeof(TChunk))>::Value;
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
// Dynamically expanded storage.
|
|
202
|
-
// It uses "on stack" realization with no allocation for one chunk spaces
|
|
203
|
-
template <typename TChunkType>
|
|
204
|
-
struct TDynamicStorage {
|
|
205
|
-
using TChunk = TChunkType;
|
|
206
|
-
|
|
207
|
-
size_t Size;
|
|
208
|
-
TChunk StackData;
|
|
209
|
-
TArrayHolder<TChunk> ArrayData;
|
|
210
|
-
TChunk* Data;
|
|
211
|
-
|
|
212
|
-
TDynamicStorage()
|
|
213
|
-
: Size(1)
|
|
214
|
-
, StackData(0)
|
|
215
|
-
, Data(&StackData)
|
|
216
|
-
{
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
TDynamicStorage(const TDynamicStorage<TChunk>& st)
|
|
220
|
-
: Size(1)
|
|
221
|
-
, StackData(0)
|
|
222
|
-
, Data(&StackData)
|
|
223
|
-
{
|
|
224
|
-
ExpandSize(st.Size, false);
|
|
225
|
-
for (size_t i = 0; i < st.Size; ++i) {
|
|
226
|
-
Data[i] = st.Data[i];
|
|
227
|
-
}
|
|
228
|
-
for (size_t i = st.Size; i < Size; ++i) {
|
|
229
|
-
Data[i] = 0;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
template <typename TOtherChunk>
|
|
234
|
-
TDynamicStorage(const TOtherChunk* data, size_t size)
|
|
235
|
-
: Size(1)
|
|
236
|
-
, StackData(0)
|
|
237
|
-
, Data(&StackData)
|
|
238
|
-
{
|
|
239
|
-
ExpandBitSize(size * sizeof(TOtherChunk) * 8, false);
|
|
240
|
-
CopyData(Data, Size, data, size);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
Y_FORCE_INLINE void Swap(TDynamicStorage<TChunkType>& st) {
|
|
244
|
-
DoSwap(Size, st.Size);
|
|
245
|
-
DoSwap(StackData, st.StackData);
|
|
246
|
-
DoSwap(ArrayData, st.ArrayData);
|
|
247
|
-
Data = 1 == Size ? &StackData : ArrayData.Get();
|
|
248
|
-
st.Data = 1 == st.Size ? &st.StackData : st.ArrayData.Get();
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
Y_FORCE_INLINE size_t GetBitCapacity() const {
|
|
252
|
-
return Size * 8 * sizeof(TChunk);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
Y_FORCE_INLINE size_t GetChunkCapacity() const {
|
|
256
|
-
return Size;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Returns true if the resulting storage capacity is enough to fit the requested size
|
|
260
|
-
Y_FORCE_INLINE bool ExpandSize(size_t size, bool keepData = true) {
|
|
261
|
-
if (size > Size) {
|
|
262
|
-
size = Max(size, Size * 2);
|
|
263
|
-
TArrayHolder<TChunk> newData(new TChunk[size]);
|
|
264
|
-
if (keepData) {
|
|
265
|
-
for (size_t i = 0; i < Size; ++i) {
|
|
266
|
-
newData[i] = Data[i];
|
|
267
|
-
}
|
|
268
|
-
for (size_t i = Size; i < size; ++i) {
|
|
269
|
-
newData[i] = 0;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
DoSwap(ArrayData, newData);
|
|
273
|
-
Data = ArrayData.Get();
|
|
274
|
-
Size = size;
|
|
275
|
-
}
|
|
276
|
-
return true;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
Y_FORCE_INLINE bool ExpandBitSize(size_t bitSize, bool keepData = true) {
|
|
280
|
-
return ExpandSize((bitSize + 8 * sizeof(TChunk) - 1) / (8 * sizeof(TChunk)), keepData);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
Y_FORCE_INLINE void Sanitize() {
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
template <size_t num>
|
|
288
|
-
struct TDivCount {
|
|
289
|
-
static constexpr size_t Value = 1 + TDivCount<(num >> 1)>::Value;
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
template <>
|
|
293
|
-
struct TDivCount<0> {
|
|
294
|
-
static constexpr size_t Value = 0;
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
template <size_t BitCount, typename TChunkType>
|
|
300
|
-
struct TFixedBitMapTraits {
|
|
301
|
-
using TChunk = TChunkType;
|
|
302
|
-
using TStorage = NBitMapPrivate::TFixedStorage<BitCount, TChunkType>;
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
template <typename TChunkType>
|
|
306
|
-
struct TDynamicBitMapTraits {
|
|
307
|
-
using TChunk = TChunkType;
|
|
308
|
-
using TStorage = NBitMapPrivate::TDynamicStorage<TChunkType>;
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
template <class TTraits>
|
|
312
|
-
class TBitMapOps {
|
|
313
|
-
public:
|
|
314
|
-
using TChunk = typename TTraits::TChunk;
|
|
315
|
-
using TThis = TBitMapOps<TTraits>;
|
|
316
|
-
|
|
317
|
-
private:
|
|
318
|
-
static_assert(std::is_unsigned<TChunk>::value, "expect std::is_unsigned<TChunk>::value");
|
|
319
|
-
|
|
320
|
-
static constexpr size_t BitsPerChunk = 8 * sizeof(TChunk);
|
|
321
|
-
static constexpr TChunk ModMask = static_cast<TChunk>(BitsPerChunk - 1);
|
|
322
|
-
static constexpr size_t DivCount = NBitMapPrivate::TDivCount<BitsPerChunk>::Value - 1;
|
|
323
|
-
static constexpr TChunk FullChunk = (TChunk)~TChunk(0);
|
|
324
|
-
|
|
325
|
-
template <class>
|
|
326
|
-
friend class TBitMapOps;
|
|
327
|
-
|
|
328
|
-
using TStorage = typename TTraits::TStorage;
|
|
329
|
-
|
|
330
|
-
// The smallest unsigned type, which can be used in bit ops
|
|
331
|
-
using TIntType = std::conditional_t<sizeof(TChunk) < sizeof(unsigned int), unsigned int, TChunk>;
|
|
332
|
-
|
|
333
|
-
TStorage Mask;
|
|
334
|
-
|
|
335
|
-
public:
|
|
336
|
-
class TReference {
|
|
337
|
-
private:
|
|
338
|
-
friend class TBitMapOps<TTraits>;
|
|
339
|
-
|
|
340
|
-
TChunk* Chunk;
|
|
341
|
-
size_t Offset;
|
|
342
|
-
|
|
343
|
-
TReference(TChunk* c, size_t offset)
|
|
344
|
-
: Chunk(c)
|
|
345
|
-
, Offset(offset)
|
|
346
|
-
{
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
public:
|
|
350
|
-
~TReference() = default;
|
|
351
|
-
|
|
352
|
-
Y_FORCE_INLINE TReference& operator=(bool val) {
|
|
353
|
-
if (val)
|
|
354
|
-
*Chunk |= static_cast<TChunk>(1) << Offset;
|
|
355
|
-
else
|
|
356
|
-
*Chunk &= ~(static_cast<TChunk>(1) << Offset);
|
|
357
|
-
|
|
358
|
-
return *this;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
Y_FORCE_INLINE TReference& operator=(const TReference& ref) {
|
|
362
|
-
if (ref)
|
|
363
|
-
*Chunk |= static_cast<TChunk>(1) << Offset;
|
|
364
|
-
else
|
|
365
|
-
*Chunk &= ~(static_cast<TChunk>(1) << Offset);
|
|
366
|
-
|
|
367
|
-
return *this;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
Y_FORCE_INLINE bool operator~() const {
|
|
371
|
-
return 0 == (*Chunk & (static_cast<TChunk>(1) << Offset));
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
Y_FORCE_INLINE operator bool() const {
|
|
375
|
-
return 0 != (*Chunk & (static_cast<TChunk>(1) << Offset));
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
Y_FORCE_INLINE TReference& Flip() {
|
|
379
|
-
*Chunk ^= static_cast<TChunk>(1) << Offset;
|
|
380
|
-
return *this;
|
|
381
|
-
}
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
private:
|
|
385
|
-
struct TSetOp {
|
|
386
|
-
static constexpr TChunk Op(const TChunk src, const TChunk mask) noexcept {
|
|
387
|
-
return src | mask;
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
|
|
391
|
-
struct TResetOp {
|
|
392
|
-
static constexpr TChunk Op(const TChunk src, const TChunk mask) noexcept {
|
|
393
|
-
return src & ~mask;
|
|
394
|
-
}
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
template <class TUpdateOp>
|
|
398
|
-
void UpdateRange(size_t start, size_t end) {
|
|
399
|
-
const size_t startChunk = start >> DivCount;
|
|
400
|
-
const size_t startBitOffset = start & ModMask;
|
|
401
|
-
|
|
402
|
-
const size_t endChunk = end >> DivCount;
|
|
403
|
-
const size_t endBitOffset = end & ModMask;
|
|
404
|
-
|
|
405
|
-
size_t bitOffset = startBitOffset;
|
|
406
|
-
for (size_t chunk = startChunk; chunk <= endChunk; ++chunk) {
|
|
407
|
-
TChunk updateMask = FullChunk << bitOffset;
|
|
408
|
-
if (chunk == endChunk) {
|
|
409
|
-
updateMask ^= FullChunk << endBitOffset;
|
|
410
|
-
if (!updateMask)
|
|
411
|
-
break;
|
|
412
|
-
}
|
|
413
|
-
Mask.Data[chunk] = TUpdateOp::Op(Mask.Data[chunk], updateMask);
|
|
414
|
-
bitOffset = 0;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
public:
|
|
419
|
-
TBitMapOps() = default;
|
|
420
|
-
|
|
421
|
-
TBitMapOps(TChunk val) {
|
|
422
|
-
Mask.Data[0] = val;
|
|
423
|
-
Mask.Sanitize();
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
TBitMapOps(const TThis&) = default;
|
|
427
|
-
|
|
428
|
-
template <class T>
|
|
429
|
-
TBitMapOps(const TBitMapOps<T>& bitmap)
|
|
430
|
-
: Mask(bitmap.Mask.Data, bitmap.Mask.GetChunkCapacity())
|
|
431
|
-
{
|
|
432
|
-
Mask.Sanitize();
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
template <class T>
|
|
436
|
-
Y_FORCE_INLINE bool operator==(const TBitMapOps<T>& bitmap) const {
|
|
437
|
-
return Equal(bitmap);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
Y_FORCE_INLINE TThis& operator=(const TThis& bitmap) {
|
|
441
|
-
if (this != &bitmap) {
|
|
442
|
-
TThis bm(bitmap);
|
|
443
|
-
Swap(bm);
|
|
444
|
-
}
|
|
445
|
-
return *this;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
template <class T>
|
|
449
|
-
Y_FORCE_INLINE TThis& operator=(const TBitMapOps<T>& bitmap) {
|
|
450
|
-
TThis bm(bitmap);
|
|
451
|
-
Swap(bm);
|
|
452
|
-
return *this;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
template <class T>
|
|
456
|
-
Y_FORCE_INLINE TThis& operator&=(const TBitMapOps<T>& bitmap) {
|
|
457
|
-
return And(bitmap);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
Y_FORCE_INLINE TThis& operator&=(const TChunk& val) {
|
|
461
|
-
return And(val);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
template <class T>
|
|
465
|
-
Y_FORCE_INLINE TThis& operator|=(const TBitMapOps<T>& bitmap) {
|
|
466
|
-
return Or(bitmap);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
Y_FORCE_INLINE TThis& operator|=(const TChunk& val) {
|
|
470
|
-
return Or(val);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
template <class T>
|
|
474
|
-
Y_FORCE_INLINE TThis& operator^=(const TBitMapOps<T>& bitmap) {
|
|
475
|
-
return Xor(bitmap);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
Y_FORCE_INLINE TThis& operator^=(const TChunk& val) {
|
|
479
|
-
return Xor(val);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
template <class T>
|
|
483
|
-
Y_FORCE_INLINE TThis& operator-=(const TBitMapOps<T>& bitmap) {
|
|
484
|
-
return SetDifference(bitmap);
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
Y_FORCE_INLINE TThis& operator-=(const TChunk& val) {
|
|
488
|
-
return SetDifference(val);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
Y_FORCE_INLINE TThis& operator<<=(size_t pos) {
|
|
492
|
-
return LShift(pos);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
Y_FORCE_INLINE TThis& operator>>=(size_t pos) {
|
|
496
|
-
return RShift(pos);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
Y_FORCE_INLINE TThis operator<<(size_t pos) const {
|
|
500
|
-
return TThis(*this).LShift(pos);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
Y_FORCE_INLINE TThis operator>>(size_t pos) const {
|
|
504
|
-
return TThis(*this).RShift(pos);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
Y_FORCE_INLINE bool operator[](size_t pos) const {
|
|
508
|
-
return Get(pos);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
Y_FORCE_INLINE TReference operator[](size_t pos) {
|
|
512
|
-
const bool fitStorage = Mask.ExpandBitSize(pos + 1);
|
|
513
|
-
Y_ASSERT(fitStorage);
|
|
514
|
-
return TReference(&Mask.Data[pos >> DivCount], ModMask & pos);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
Y_FORCE_INLINE void Swap(TThis& bitmap) {
|
|
518
|
-
DoSwap(Mask, bitmap.Mask);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
Y_FORCE_INLINE TThis& Set(size_t pos) {
|
|
522
|
-
const bool fitStorage = Mask.ExpandBitSize(pos + 1);
|
|
523
|
-
Y_ASSERT(fitStorage);
|
|
524
|
-
Mask.Data[pos >> DivCount] |= static_cast<TChunk>(1) << (pos & ModMask);
|
|
525
|
-
return *this;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// Fills the specified [start, end) bit range by the 1. Other bits are kept unchanged
|
|
529
|
-
TThis& Set(size_t start, size_t end) {
|
|
530
|
-
Y_ASSERT(start <= end);
|
|
531
|
-
if (start < end) {
|
|
532
|
-
Reserve(end);
|
|
533
|
-
UpdateRange<TSetOp>(start, end);
|
|
534
|
-
}
|
|
535
|
-
return *this;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
Y_FORCE_INLINE TThis& Reset(size_t pos) {
|
|
539
|
-
if ((pos >> DivCount) < Mask.GetChunkCapacity()) {
|
|
540
|
-
Mask.Data[pos >> DivCount] &= ~(static_cast<TChunk>(1) << (pos & ModMask));
|
|
541
|
-
}
|
|
542
|
-
return *this;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
// Clears the specified [start, end) bit range. Other bits are kept unchanged
|
|
546
|
-
TThis& Reset(size_t start, size_t end) {
|
|
547
|
-
Y_ASSERT(start <= end);
|
|
548
|
-
if (start < end && (start >> DivCount) < Mask.GetChunkCapacity()) {
|
|
549
|
-
UpdateRange<TResetOp>(start, Min(end, Mask.GetBitCapacity()));
|
|
550
|
-
}
|
|
551
|
-
return *this;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
Y_FORCE_INLINE TThis& Flip(size_t pos) {
|
|
555
|
-
const bool fitStorage = Mask.ExpandBitSize(pos + 1);
|
|
556
|
-
Y_ASSERT(fitStorage);
|
|
557
|
-
Mask.Data[pos >> DivCount] ^= static_cast<TChunk>(1) << (pos & ModMask);
|
|
558
|
-
return *this;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
Y_FORCE_INLINE bool Get(size_t pos) const {
|
|
562
|
-
if ((pos >> DivCount) < Mask.GetChunkCapacity()) {
|
|
563
|
-
return Mask.Data[pos >> DivCount] & (static_cast<TChunk>(1) << (pos & ModMask));
|
|
564
|
-
}
|
|
565
|
-
return false;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
template <class TTo>
|
|
569
|
-
void Export(size_t pos, TTo& to) const {
|
|
570
|
-
static_assert(std::is_unsigned<TTo>::value, "expect std::is_unsigned<TTo>::value");
|
|
571
|
-
to = 0;
|
|
572
|
-
size_t chunkpos = pos >> DivCount;
|
|
573
|
-
if (chunkpos >= Mask.GetChunkCapacity())
|
|
574
|
-
return;
|
|
575
|
-
if ((pos & ModMask) == 0) {
|
|
576
|
-
if (sizeof(TChunk) >= sizeof(TTo))
|
|
577
|
-
to = (TTo)Mask.Data[chunkpos];
|
|
578
|
-
else //if (sizeof(TChunk) < sizeof(TTo))
|
|
579
|
-
NBitMapPrivate::CopyData(&to, 1, Mask.Data + chunkpos, Min(((sizeof(TTo) * 8) >> DivCount), Mask.GetChunkCapacity() - chunkpos));
|
|
580
|
-
} else if ((pos & (sizeof(TTo) * 8 - 1)) == 0 && sizeof(TChunk) >= 2 * sizeof(TTo))
|
|
581
|
-
to = (TTo)(Mask.Data[chunkpos] >> (pos & ModMask));
|
|
582
|
-
else {
|
|
583
|
-
static constexpr size_t copyToSize = (sizeof(TChunk) >= sizeof(TTo)) ? (sizeof(TChunk) / sizeof(TTo)) + 2 : 3;
|
|
584
|
-
TTo temp[copyToSize] = {0, 0};
|
|
585
|
-
//or use non defined by now TBitmap<copyToSize, TTo>::CopyData,RShift(pos & ModMask),Export(0,to)
|
|
586
|
-
NBitMapPrivate::CopyData(temp, copyToSize, Mask.Data + chunkpos, Min((sizeof(TTo) / sizeof(TChunk)) + 1, Mask.GetChunkCapacity() - chunkpos));
|
|
587
|
-
to = (temp[0] >> (pos & ModMask)) | (temp[1] << (8 * sizeof(TTo) - (pos & ModMask)));
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
Y_FORCE_INLINE bool Test(size_t n) const {
|
|
592
|
-
return Get(n);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
Y_FORCE_INLINE TThis& Push(bool val) {
|
|
596
|
-
LShift(1);
|
|
597
|
-
return val ? Set(0) : *this;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
Y_FORCE_INLINE bool Pop() {
|
|
601
|
-
bool val = Get(0);
|
|
602
|
-
return RShift(1), val;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// Clear entire bitmap. Current capacity is kept unchanged
|
|
606
|
-
Y_FORCE_INLINE TThis& Clear() {
|
|
607
|
-
for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i) {
|
|
608
|
-
Mask.Data[i] = 0;
|
|
609
|
-
}
|
|
610
|
-
return *this;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// Returns bits capacity
|
|
614
|
-
Y_FORCE_INLINE constexpr size_t Size() const noexcept {
|
|
615
|
-
return Mask.GetBitCapacity();
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
Y_FORCE_INLINE void Reserve(size_t bitCount) {
|
|
619
|
-
Y_VERIFY(Mask.ExpandBitSize(bitCount), "Exceeding bitmap storage capacity");
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
Y_FORCE_INLINE size_t ValueBitCount() const {
|
|
623
|
-
size_t nonZeroChunk = Mask.GetChunkCapacity() - 1;
|
|
624
|
-
while (nonZeroChunk != 0 && !Mask.Data[nonZeroChunk])
|
|
625
|
-
--nonZeroChunk;
|
|
626
|
-
return nonZeroChunk || Mask.Data[nonZeroChunk]
|
|
627
|
-
? nonZeroChunk * BitsPerChunk + GetValueBitCount(TIntType(Mask.Data[nonZeroChunk]))
|
|
628
|
-
: 0;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
Y_PURE_FUNCTION Y_FORCE_INLINE
|
|
632
|
-
bool Empty() const {
|
|
633
|
-
for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
|
|
634
|
-
if (Mask.Data[i])
|
|
635
|
-
return false;
|
|
636
|
-
return true;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
bool HasAny(const TThis& bitmap) const {
|
|
640
|
-
for (size_t i = 0; i < Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity()); ++i) {
|
|
641
|
-
if (0 != (Mask.Data[i] & bitmap.Mask.Data[i])) {
|
|
642
|
-
return true;
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
return false;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
template <class T>
|
|
649
|
-
Y_FORCE_INLINE bool HasAny(const TBitMapOps<T>& bitmap) const {
|
|
650
|
-
return HasAny(TThis(bitmap));
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
Y_FORCE_INLINE bool HasAny(const TChunk& val) const {
|
|
654
|
-
return 0 != (Mask.Data[0] & val);
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
bool HasAll(const TThis& bitmap) const {
|
|
658
|
-
for (size_t i = 0; i < Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity()); ++i) {
|
|
659
|
-
if (bitmap.Mask.Data[i] != (Mask.Data[i] & bitmap.Mask.Data[i])) {
|
|
660
|
-
return false;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
for (size_t i = Mask.GetChunkCapacity(); i < bitmap.Mask.GetChunkCapacity(); ++i) {
|
|
664
|
-
if (bitmap.Mask.Data[i] != 0) {
|
|
665
|
-
return false;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
return true;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
template <class T>
|
|
672
|
-
Y_FORCE_INLINE bool HasAll(const TBitMapOps<T>& bitmap) const {
|
|
673
|
-
return HasAll(TThis(bitmap));
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
Y_FORCE_INLINE bool HasAll(const TChunk& val) const {
|
|
677
|
-
return (Mask.Data[0] & val) == val;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
TThis& And(const TThis& bitmap) {
|
|
681
|
-
// Don't expand capacity here, because resulting bits in positions,
|
|
682
|
-
// which are greater then size of one of these bitmaps, will be zero
|
|
683
|
-
for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
|
|
684
|
-
Mask.Data[i] &= bitmap.Mask.Data[i];
|
|
685
|
-
// Clear bits if current bitmap size is greater than AND-ed one
|
|
686
|
-
for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i)
|
|
687
|
-
Mask.Data[i] = 0;
|
|
688
|
-
return *this;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
template <class T>
|
|
692
|
-
Y_FORCE_INLINE TThis& And(const TBitMapOps<T>& bitmap) {
|
|
693
|
-
return And(TThis(bitmap));
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
Y_FORCE_INLINE TThis& And(const TChunk& val) {
|
|
697
|
-
Mask.Data[0] &= val;
|
|
698
|
-
for (size_t i = 1; i < Mask.GetChunkCapacity(); ++i)
|
|
699
|
-
Mask.Data[i] = 0;
|
|
700
|
-
return *this;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
TThis& Or(const TThis& bitmap) {
|
|
704
|
-
const size_t valueBitCount = bitmap.ValueBitCount();
|
|
705
|
-
if (valueBitCount) {
|
|
706
|
-
// Memory optimization: expand size only for non-zero bits
|
|
707
|
-
Reserve(valueBitCount);
|
|
708
|
-
for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
|
|
709
|
-
Mask.Data[i] |= bitmap.Mask.Data[i];
|
|
710
|
-
}
|
|
711
|
-
return *this;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
template <class T>
|
|
715
|
-
Y_FORCE_INLINE TThis& Or(const TBitMapOps<T>& bitmap) {
|
|
716
|
-
return Or(TThis(bitmap));
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
Y_FORCE_INLINE TThis& Or(const TChunk& val) {
|
|
720
|
-
Mask.Data[0] |= val;
|
|
721
|
-
Mask.Sanitize();
|
|
722
|
-
return *this;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
TThis& Xor(const TThis& bitmap) {
|
|
726
|
-
Reserve(bitmap.Size());
|
|
727
|
-
for (size_t i = 0; i < bitmap.Mask.GetChunkCapacity(); ++i)
|
|
728
|
-
Mask.Data[i] ^= bitmap.Mask.Data[i];
|
|
729
|
-
return *this;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
template <class T>
|
|
733
|
-
Y_FORCE_INLINE TThis& Xor(const TBitMapOps<T>& bitmap) {
|
|
734
|
-
return Xor(TThis(bitmap));
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
Y_FORCE_INLINE TThis& Xor(const TChunk& val) {
|
|
738
|
-
Mask.Data[0] ^= val;
|
|
739
|
-
Mask.Sanitize();
|
|
740
|
-
return *this;
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
TThis& SetDifference(const TThis& bitmap) {
|
|
744
|
-
for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
|
|
745
|
-
Mask.Data[i] &= ~bitmap.Mask.Data[i];
|
|
746
|
-
return *this;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
template <class T>
|
|
750
|
-
Y_FORCE_INLINE TThis& SetDifference(const TBitMapOps<T>& bitmap) {
|
|
751
|
-
return SetDifference(TThis(bitmap));
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
Y_FORCE_INLINE TThis& SetDifference(const TChunk& val) {
|
|
755
|
-
Mask.Data[0] &= ~val;
|
|
756
|
-
return *this;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
Y_FORCE_INLINE TThis& Flip() {
|
|
760
|
-
for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
|
|
761
|
-
Mask.Data[i] = ~Mask.Data[i];
|
|
762
|
-
Mask.Sanitize();
|
|
763
|
-
return *this;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
TThis& LShift(size_t shift) {
|
|
767
|
-
if (shift != 0) {
|
|
768
|
-
const size_t valueBitCount = ValueBitCount();
|
|
769
|
-
// Do nothing for empty bitmap
|
|
770
|
-
if (valueBitCount != 0) {
|
|
771
|
-
const size_t eshift = shift / BitsPerChunk;
|
|
772
|
-
const size_t offset = shift % BitsPerChunk;
|
|
773
|
-
const size_t subOffset = BitsPerChunk - offset;
|
|
774
|
-
|
|
775
|
-
// Don't verify expand result, so l-shift of fixed bitmap will work in the same way as for unsigned integer.
|
|
776
|
-
Mask.ExpandBitSize(valueBitCount + shift);
|
|
777
|
-
|
|
778
|
-
if (offset == 0) {
|
|
779
|
-
for (size_t i = Mask.GetChunkCapacity() - 1; i >= eshift; --i) {
|
|
780
|
-
Mask.Data[i] = Mask.Data[i - eshift];
|
|
781
|
-
}
|
|
782
|
-
} else {
|
|
783
|
-
for (size_t i = Mask.GetChunkCapacity() - 1; i > eshift; --i)
|
|
784
|
-
Mask.Data[i] = (Mask.Data[i - eshift] << offset) | (Mask.Data[i - eshift - 1] >> subOffset);
|
|
785
|
-
if (eshift < Mask.GetChunkCapacity())
|
|
786
|
-
Mask.Data[eshift] = Mask.Data[0] << offset;
|
|
787
|
-
}
|
|
788
|
-
for (size_t i = 0; i < Min(eshift, Mask.GetChunkCapacity()); ++i)
|
|
789
|
-
Mask.Data[i] = 0;
|
|
790
|
-
|
|
791
|
-
// Cleanup extra high bits in the storage
|
|
792
|
-
Mask.Sanitize();
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
return *this;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
TThis& RShift(size_t shift) {
|
|
799
|
-
if (shift != 0) {
|
|
800
|
-
const size_t eshift = shift / BitsPerChunk;
|
|
801
|
-
const size_t offset = shift % BitsPerChunk;
|
|
802
|
-
if (eshift >= Mask.GetChunkCapacity()) {
|
|
803
|
-
Clear();
|
|
804
|
-
|
|
805
|
-
} else {
|
|
806
|
-
const size_t limit = Mask.GetChunkCapacity() - eshift - 1;
|
|
807
|
-
|
|
808
|
-
if (offset == 0) {
|
|
809
|
-
for (size_t i = 0; i <= limit; ++i) {
|
|
810
|
-
Mask.Data[i] = Mask.Data[i + eshift];
|
|
811
|
-
}
|
|
812
|
-
} else {
|
|
813
|
-
const size_t subOffset = BitsPerChunk - offset;
|
|
814
|
-
for (size_t i = 0; i < limit; ++i)
|
|
815
|
-
Mask.Data[i] = (Mask.Data[i + eshift] >> offset) | (Mask.Data[i + eshift + 1] << subOffset);
|
|
816
|
-
Mask.Data[limit] = Mask.Data[Mask.GetChunkCapacity() - 1] >> offset;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
for (size_t i = limit + 1; i < Mask.GetChunkCapacity(); ++i)
|
|
820
|
-
Mask.Data[i] = 0;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
return *this;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
// Applies bitmap at the specified offset using OR operator.
|
|
827
|
-
// This method is optimized combination of Or() and LShift(), which allows reducing memory allocation
|
|
828
|
-
// when combining long dynamic bitmaps.
|
|
829
|
-
TThis& Or(const TThis& bitmap, size_t offset) {
|
|
830
|
-
if (0 == offset)
|
|
831
|
-
return Or(bitmap);
|
|
832
|
-
|
|
833
|
-
const size_t otherValueBitCount = bitmap.ValueBitCount();
|
|
834
|
-
// Continue only if OR-ed bitmap have non-zero bits
|
|
835
|
-
if (otherValueBitCount) {
|
|
836
|
-
const size_t chunkShift = offset / BitsPerChunk;
|
|
837
|
-
const size_t subShift = offset % BitsPerChunk;
|
|
838
|
-
const size_t subOffset = BitsPerChunk - subShift;
|
|
839
|
-
|
|
840
|
-
Reserve(otherValueBitCount + offset);
|
|
841
|
-
|
|
842
|
-
if (subShift == 0) {
|
|
843
|
-
for (size_t i = chunkShift; i < Min(bitmap.Mask.GetChunkCapacity() + chunkShift, Mask.GetChunkCapacity()); ++i) {
|
|
844
|
-
Mask.Data[i] |= bitmap.Mask.Data[i - chunkShift];
|
|
845
|
-
}
|
|
846
|
-
} else {
|
|
847
|
-
Mask.Data[chunkShift] |= bitmap.Mask.Data[0] << subShift;
|
|
848
|
-
size_t i = chunkShift + 1;
|
|
849
|
-
for (; i < Min(bitmap.Mask.GetChunkCapacity() + chunkShift, Mask.GetChunkCapacity()); ++i) {
|
|
850
|
-
Mask.Data[i] |= (bitmap.Mask.Data[i - chunkShift] << subShift) | (bitmap.Mask.Data[i - chunkShift - 1] >> subOffset);
|
|
851
|
-
}
|
|
852
|
-
if (i < Mask.GetChunkCapacity())
|
|
853
|
-
Mask.Data[i] |= bitmap.Mask.Data[i - chunkShift - 1] >> subOffset;
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
return *this;
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
bool Equal(const TThis& bitmap) const {
|
|
861
|
-
if (Mask.GetChunkCapacity() > bitmap.Mask.GetChunkCapacity()) {
|
|
862
|
-
for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i) {
|
|
863
|
-
if (0 != Mask.Data[i])
|
|
864
|
-
return false;
|
|
865
|
-
}
|
|
866
|
-
} else if (Mask.GetChunkCapacity() < bitmap.Mask.GetChunkCapacity()) {
|
|
867
|
-
for (size_t i = Mask.GetChunkCapacity(); i < bitmap.Mask.GetChunkCapacity(); ++i) {
|
|
868
|
-
if (0 != bitmap.Mask.Data[i])
|
|
869
|
-
return false;
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
size_t size = Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity());
|
|
873
|
-
for (size_t i = 0; i < size; ++i) {
|
|
874
|
-
if (Mask.Data[i] != bitmap.Mask.Data[i])
|
|
875
|
-
return false;
|
|
876
|
-
}
|
|
877
|
-
return true;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
template <class T>
|
|
881
|
-
Y_FORCE_INLINE bool Equal(const TBitMapOps<T>& bitmap) const {
|
|
882
|
-
return Equal(TThis(bitmap));
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
int Compare(const TThis& bitmap) const {
|
|
886
|
-
size_t size = Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity());
|
|
887
|
-
int res = ::memcmp(Mask.Data, bitmap.Mask.Data, size * sizeof(TChunk));
|
|
888
|
-
if (0 != res || Mask.GetChunkCapacity() == bitmap.Mask.GetChunkCapacity())
|
|
889
|
-
return res;
|
|
890
|
-
|
|
891
|
-
if (Mask.GetChunkCapacity() > bitmap.Mask.GetChunkCapacity()) {
|
|
892
|
-
for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i) {
|
|
893
|
-
if (0 != Mask.Data[i])
|
|
894
|
-
return 1;
|
|
895
|
-
}
|
|
896
|
-
} else {
|
|
897
|
-
for (size_t i = Mask.GetChunkCapacity(); i < bitmap.Mask.GetChunkCapacity(); ++i) {
|
|
898
|
-
if (0 != bitmap.Mask.Data[i])
|
|
899
|
-
return -1;
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
return 0;
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
template <class T>
|
|
906
|
-
Y_FORCE_INLINE int Compare(const TBitMapOps<T>& bitmap) const {
|
|
907
|
-
return Compare(TThis(bitmap));
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
// For backward compatibility
|
|
911
|
-
Y_FORCE_INLINE static int Compare(const TThis& l, const TThis& r) {
|
|
912
|
-
return l.Compare(r);
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
size_t FirstNonZeroBit() const {
|
|
916
|
-
for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i) {
|
|
917
|
-
if (Mask.Data[i]) {
|
|
918
|
-
// CountTrailingZeroBits() expects unsigned types not smaller than unsigned int. So, convert before calling
|
|
919
|
-
return BitsPerChunk * i + CountTrailingZeroBits(TIntType(Mask.Data[i]));
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
return Size();
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
// Returns position of the next non-zero bit, which offset is greater than specified pos
|
|
926
|
-
// Typical loop for iterating bits:
|
|
927
|
-
// for (size_t pos = bits.FirstNonZeroBit(); pos != bits.Size(); pos = bits.NextNonZeroBit(pos)) {
|
|
928
|
-
// ...
|
|
929
|
-
// }
|
|
930
|
-
// See Y_FOR_EACH_BIT macro definition at the bottom
|
|
931
|
-
size_t NextNonZeroBit(size_t pos) const {
|
|
932
|
-
size_t i = (pos + 1) >> DivCount;
|
|
933
|
-
if (i < Mask.GetChunkCapacity()) {
|
|
934
|
-
const size_t offset = (pos + 1) & ModMask;
|
|
935
|
-
// Process the current chunk
|
|
936
|
-
if (offset) {
|
|
937
|
-
// Zero already iterated trailing bits using mask
|
|
938
|
-
const TChunk val = Mask.Data[i] & ((~TChunk(0)) << offset);
|
|
939
|
-
if (val) {
|
|
940
|
-
return BitsPerChunk * i + CountTrailingZeroBits(TIntType(val));
|
|
941
|
-
}
|
|
942
|
-
// Continue with other chunks
|
|
943
|
-
++i;
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
for (; i < Mask.GetChunkCapacity(); ++i) {
|
|
947
|
-
if (Mask.Data[i]) {
|
|
948
|
-
return BitsPerChunk * i + CountTrailingZeroBits(TIntType(Mask.Data[i]));
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
return Size();
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
Y_FORCE_INLINE size_t Count() const {
|
|
956
|
-
size_t count = 0;
|
|
957
|
-
for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
|
|
958
|
-
count += ::NBitMapPrivate::CountBitsPrivate(Mask.Data[i]);
|
|
959
|
-
return count;
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
void Save(IOutputStream* out) const {
|
|
963
|
-
::Save(out, ui8(sizeof(TChunk)));
|
|
964
|
-
::Save(out, ui64(Size()));
|
|
965
|
-
::SavePodArray(out, Mask.Data, Mask.GetChunkCapacity());
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
void Load(IInputStream* inp) {
|
|
969
|
-
ui8 chunkSize = 0;
|
|
970
|
-
::Load(inp, chunkSize);
|
|
971
|
-
Y_VERIFY(size_t(chunkSize) == sizeof(TChunk), "Chunk size is not the same");
|
|
972
|
-
|
|
973
|
-
ui64 bitCount64 = 0;
|
|
974
|
-
::Load(inp, bitCount64);
|
|
975
|
-
size_t bitCount = size_t(bitCount64);
|
|
976
|
-
Reserve(bitCount);
|
|
977
|
-
|
|
978
|
-
size_t chunkCount = 0;
|
|
979
|
-
if (bitCount > 0) {
|
|
980
|
-
chunkCount = ((bitCount - 1) >> DivCount) + 1;
|
|
981
|
-
::LoadPodArray(inp, Mask.Data, chunkCount);
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
if (chunkCount < Mask.GetChunkCapacity()) {
|
|
985
|
-
::memset(Mask.Data + chunkCount, 0, (Mask.GetChunkCapacity() - chunkCount) * sizeof(TChunk));
|
|
986
|
-
}
|
|
987
|
-
Mask.Sanitize();
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
inline size_t Hash() const {
|
|
991
|
-
THash<TChunk> chunkHasher;
|
|
992
|
-
|
|
993
|
-
size_t hash = chunkHasher(0);
|
|
994
|
-
bool tailSkipped = false;
|
|
995
|
-
for (size_t i = Mask.GetChunkCapacity(); i > 0; --i) {
|
|
996
|
-
if (tailSkipped || Mask.Data[i - 1]) {
|
|
997
|
-
hash = ::CombineHashes(hash, chunkHasher(Mask.Data[i - 1]));
|
|
998
|
-
tailSkipped = true;
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
return hash;
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
inline const TChunk* GetChunks() const {
|
|
1006
|
-
return Mask.Data;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
constexpr size_t GetChunkCount() const noexcept {
|
|
1010
|
-
return Mask.GetChunkCapacity();
|
|
1011
|
-
}
|
|
1012
|
-
};
|
|
1013
|
-
|
|
1014
|
-
template <class X, class Y>
|
|
1015
|
-
inline TBitMapOps<X> operator&(const TBitMapOps<X>& x, const TBitMapOps<Y>& y) {
|
|
1016
|
-
return TBitMapOps<X>(x).And(y);
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
template <class X>
|
|
1020
|
-
inline TBitMapOps<X> operator&(const TBitMapOps<X>& x, const typename TBitMapOps<X>::TChunk& y) {
|
|
1021
|
-
return TBitMapOps<X>(x).And(y);
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
template <class X>
|
|
1025
|
-
inline TBitMapOps<X> operator&(const typename TBitMapOps<X>::TChunk& x, const TBitMapOps<X>& y) {
|
|
1026
|
-
return TBitMapOps<X>(x).And(y);
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
template <class X, class Y>
|
|
1030
|
-
inline TBitMapOps<X> operator|(const TBitMapOps<X>& x, const TBitMapOps<Y>& y) {
|
|
1031
|
-
return TBitMapOps<X>(x).Or(y);
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
template <class X>
|
|
1035
|
-
inline TBitMapOps<X> operator|(const TBitMapOps<X>& x, const typename TBitMapOps<X>::TChunk& y) {
|
|
1036
|
-
return TBitMapOps<X>(x).Or(y);
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
template <class X>
|
|
1040
|
-
inline TBitMapOps<X> operator|(const typename TBitMapOps<X>::TChunk& x, const TBitMapOps<X>& y) {
|
|
1041
|
-
return TBitMapOps<X>(x).Or(y);
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
template <class X, class Y>
|
|
1045
|
-
inline TBitMapOps<X> operator^(const TBitMapOps<X>& x, const TBitMapOps<Y>& y) {
|
|
1046
|
-
return TBitMapOps<X>(x).Xor(y);
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
template <class X>
|
|
1050
|
-
inline TBitMapOps<X> operator^(const TBitMapOps<X>& x, const typename TBitMapOps<X>::TChunk& y) {
|
|
1051
|
-
return TBitMapOps<X>(x).Xor(y);
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
template <class X>
|
|
1055
|
-
inline TBitMapOps<X> operator^(const typename TBitMapOps<X>::TChunk& x, const TBitMapOps<X>& y) {
|
|
1056
|
-
return TBitMapOps<X>(x).Xor(y);
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
template <class X, class Y>
|
|
1060
|
-
inline TBitMapOps<X> operator-(const TBitMapOps<X>& x, const TBitMapOps<Y>& y) {
|
|
1061
|
-
return TBitMapOps<X>(x).SetDifference(y);
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
template <class X>
|
|
1065
|
-
inline TBitMapOps<X> operator-(const TBitMapOps<X>& x, const typename TBitMapOps<X>::TChunk& y) {
|
|
1066
|
-
return TBitMapOps<X>(x).SetDifference(y);
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
template <class X>
|
|
1070
|
-
inline TBitMapOps<X> operator-(const typename TBitMapOps<X>::TChunk& x, const TBitMapOps<X>& y) {
|
|
1071
|
-
return TBitMapOps<X>(x).SetDifference(y);
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
template <class X>
|
|
1075
|
-
inline TBitMapOps<X> operator~(const TBitMapOps<X>& x) {
|
|
1076
|
-
return TBitMapOps<X>(x).Flip();
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
/////////////////// Specialization ///////////////////////////
|
|
1080
|
-
|
|
1081
|
-
template <size_t BitCount, typename TChunkType /*= ui64*/>
|
|
1082
|
-
class TBitMap: public TBitMapOps<TFixedBitMapTraits<BitCount, TChunkType>> {
|
|
1083
|
-
private:
|
|
1084
|
-
using TBase = TBitMapOps<TFixedBitMapTraits<BitCount, TChunkType>>;
|
|
1085
|
-
|
|
1086
|
-
public:
|
|
1087
|
-
TBitMap()
|
|
1088
|
-
: TBase()
|
|
1089
|
-
{
|
|
1090
|
-
}
|
|
1091
|
-
|
|
1092
|
-
TBitMap(typename TBase::TChunk val)
|
|
1093
|
-
: TBase(val)
|
|
1094
|
-
{
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
TBitMap(const TBitMap<BitCount, TChunkType>&) = default;
|
|
1098
|
-
|
|
1099
|
-
template <class T>
|
|
1100
|
-
TBitMap(const TBitMapOps<T>& bitmap)
|
|
1101
|
-
: TBase(bitmap)
|
|
1102
|
-
{
|
|
1103
|
-
}
|
|
1104
|
-
};
|
|
1105
|
-
|
|
1106
|
-
using TDynBitMap = TBitMapOps<TDynamicBitMapTraits<ui64>>;
|
|
1107
|
-
|
|
1108
|
-
#define Y_FOR_EACH_BIT(var, bitmap) for (size_t var = (bitmap).FirstNonZeroBit(); var != (bitmap).Size(); var = (bitmap).NextNonZeroBit(var))
|
|
1109
|
-
|
|
1110
|
-
template <typename TTraits>
|
|
1111
|
-
struct THash<TBitMapOps<TTraits>> {
|
|
1112
|
-
size_t operator()(const TBitMapOps<TTraits>& elem) const {
|
|
1113
|
-
return elem.Hash();
|
|
1114
|
-
}
|
|
1115
|
-
};
|