#ifndef BMCONST__H__INCLUDED__
#define BMCONST__H__INCLUDED__
#include <cstdint>
namespace bm
{
#if defined(_WIN32) || defined (_WIN64)
typedef unsigned __int64 id64_t;
#else
typedef unsigned long long int id64_t;
#endif
typedef unsigned int id_t;
typedef unsigned int word_t;
typedef unsigned short short_t;
#ifndef BM_DEFAULT_POOL_SIZE
# define BM_DEFAULT_POOL_SIZE 4096
#endif
#ifdef BM64ADDR
const unsigned long long id_max32 = 0xFFFFFFFFull;
const unsigned long long id_max48 = 0xFFFFFFFFFFFFull;
#else
const unsigned id_max32 = 0xFFFFFFFFu;
#endif
const unsigned set_block_size = 2048u;
const unsigned set_block_shift = 16u;
const unsigned set_block_mask = 0xFFFFu;
const unsigned set_blkblk_mask = 0xFFFFFFu;
const unsigned set_block_alloc_size = bm::set_block_size * unsigned(sizeof(bm::word_t));
const unsigned set_block_plane_size = bm::set_block_size / 32u;
const unsigned set_block_plane_cnt = (unsigned)(sizeof(bm::word_t) * 8u);
const unsigned block_waves = 64;
const unsigned set_block_digest_wave_size = bm::set_block_size / bm::block_waves;
const unsigned set_block_digest_pos_shift = 10;
const unsigned set_word_shift = 5u;
const unsigned set_word_mask = 0x1Fu;
typedef unsigned short gap_word_t;
const unsigned gap_max_buff_len = 1280;
const unsigned gap_max_bits = 65536;
const unsigned gap_equiv_len = (unsigned)
((sizeof(bm::word_t) * bm::set_block_size) / sizeof(bm::gap_word_t));
const unsigned gap_max_bits_cmrz = bm::gap_max_bits / 2;
const unsigned gap_levels = 4;
const unsigned gap_max_level = bm::gap_levels - 1;
const unsigned bie_cut_off = 16384;
const unsigned set_array_size32 = 256u;
const unsigned set_sub_array_size = set_array_size32;
const unsigned set_array_shift = 8u;
const unsigned set_array_mask = 0xFFu;
const unsigned set_total_blocks32 = (bm::set_array_size32 * bm::set_array_size32);
const unsigned set_sub_total_bits = bm::set_sub_array_size * bm::gap_max_bits;
#ifdef BM64ADDR
const unsigned set_total_blocks48 = bm::id_max48 / bm::gap_max_bits;
const unsigned long long id_max = bm::id_max48;
const unsigned long long set_array_size48 = 1 + (bm::id_max48 / set_sub_total_bits);
const unsigned set_top_array_size = bm::set_array_size48;
const id64_t set_total_blocks = id64_t(bm::set_top_array_size) * set_sub_array_size;
#else
const unsigned id_max = bm::id_max32;
const unsigned set_top_array_size = bm::set_array_size32;
const unsigned set_total_blocks = bm::set_total_blocks32;
#endif
const unsigned bits_in_block = bm::set_block_size * unsigned((sizeof(bm::word_t) * 8));
const unsigned bits_in_array = bm::bits_in_block * bm::set_array_size32;
const unsigned rs3_border0 = 21824; const unsigned rs3_border1 = (rs3_border0 * 2); const unsigned rs3_half_span = rs3_border0 / 2;
const unsigned sub_block3_size = bm::gap_max_bits / 4;
#if defined(BM64OPT) || defined(BM64_SSE4)
typedef id64_t wordop_t;
const id64_t all_bits_mask = 0xffffffffffffffffULL;
const unsigned set_block_size_op = bm::set_block_size / 2;
#else
typedef word_t wordop_t;
const word_t all_bits_mask = 0xffffffff;
const unsigned set_block_size_op = bm::set_block_size;
#endif
enum strategy
{
BM_BIT = 0, BM_GAP = 1 };
enum set_operation
{
set_AND = 0,
set_OR = 1,
set_SUB = 2,
set_XOR = 3,
set_ASSIGN = 4,
set_COUNT = 5,
set_COUNT_AND = 6,
set_COUNT_XOR = 7,
set_COUNT_OR = 8,
set_COUNT_SUB_AB= 9,
set_COUNT_SUB_BA= 10,
set_COUNT_A = 11,
set_COUNT_B = 12,
set_END
};
enum operation
{
BM_AND = set_AND,
BM_OR = set_OR,
BM_SUB = set_SUB,
BM_XOR = set_XOR
};
enum sort_order
{
BM_UNSORTED = 0, BM_SORTED = 1, BM_SORTED_UNIFORM = 2, BM_UNKNOWN = 3 };
enum set_representation
{
set_bitset = 0, set_gap = 1, set_array1 = 2, set_array0 = 3 };
enum null_support
{
use_null = 0, no_null = 1 };
template<bool T> struct _copyright
{
static const char _p[]; static const unsigned _v[3]; };
template<bool T> const char _copyright<T>::_p[] =
"BitMagic C++ Library. v.7.7.7 (c) 2002-2021 Anatoliy Kuznetsov.";
template<bool T> const unsigned _copyright<T>::_v[3] = {7, 7, 7};
template<bool T> struct DeBruijn_bit_position
{
static const unsigned _multiply[32];
};
template<bool T>
const unsigned DeBruijn_bit_position<T>::_multiply[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
template<bool T> struct first_bit_table
{
static const signed char _idx[256];
};
template<bool T>
const signed char first_bit_table<T>::_idx[256] = {
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
};
template<bool T> struct bit_count_table
{
static const unsigned char _count[256];
};
template<bool T>
const unsigned char bit_count_table<T>::_count[256] = {
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
};
template<bool T> struct lzcnt_table
{
static unsigned char const _lut[16];
};
template<bool T>
const unsigned char lzcnt_table<T>::_lut[16] =
{
32U, 31U, 30U, 30U, 29U, 29U, 29U, 29U,
28U, 28U, 28U, 28U, 28U, 28U, 28U, 28U
};
template<bool T> struct tzcnt_table
{
static unsigned char const _lut[37];
};
template<bool T>
const unsigned char tzcnt_table<T>::_lut[37] =
{
32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11,
0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0,
21, 14, 9, 5, 20, 8, 19, 18
};
template<bool T> struct block_set_table
{
static const unsigned _left[32];
static const unsigned _right[32];
};
template<bool T>
const unsigned block_set_table<T>::_left[32] = {
0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff,
0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff,
0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff,
0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff
};
template<bool T>
const unsigned block_set_table<T>::_right[32] = {
0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0,
0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00, 0xfffffe00,
0xfffffc00, 0xfffff800, 0xfffff000, 0xffffe000, 0xffffc000,
0xffff8000, 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 0xff000000,
0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000, 0xe0000000,
0xc0000000, 0x80000000
};
template<bool T> struct gap_len_table
{
static const gap_word_t _len[bm::gap_levels];
};
template<bool T>
const gap_word_t gap_len_table<T>::_len[bm::gap_levels] =
{ 128, 256, 512, bm::gap_max_buff_len };
template<bool T> struct gap_len_table_min
{
static const gap_word_t _len[bm::gap_levels];
};
template<bool T>
const gap_word_t gap_len_table_min<T>::_len[bm::gap_levels] =
{ 32, 96, 128, 512 };
template<bool T> struct gap_len_table_nl
{
static const gap_word_t _len[bm::gap_levels];
};
template<bool T>
const gap_word_t gap_len_table_nl<T>::_len[bm::gap_levels] =
{ 32, 128, 512, bm::gap_max_buff_len };
enum simd_codes
{
simd_none = 0, simd_sse2 = 1, simd_sse42 = 2, simd_avx2 = 5, simd_avx512 = 6, simd_wasm128 = 7 };
enum ByteOrder
{
BigEndian = 0,
LittleEndian = 1
};
template<bool T> struct globals
{
struct bo
{
ByteOrder _byte_order;
bo()
{
unsigned x;
unsigned char *s = (unsigned char *)&x;
s[0] = 1; s[1] = 2; s[2] = 3; s[3] = 4;
if(x == 0x04030201)
{
_byte_order = LittleEndian;
return;
}
if(x == 0x01020304)
{
_byte_order = BigEndian;
return;
}
_byte_order = LittleEndian;
}
};
static bo _bo;
static ByteOrder byte_order() { return _bo._byte_order; }
};
template<bool T> typename globals<T>::bo globals<T>::_bo;
}
#endif