C++ bit比特位数据编辑类模版CLBitT
目前数据的最小编辑单位大多为Byte(比特),而缺少对bit(比特位)的编辑方式。因此CLBit类就是为了编辑数据比特位构造的包装类。通过比特位级别的数据编辑(增删改查等)功能,可更有效的使用内存空间资源。
#ifndef __CL_BITBASE_H__
#define __CL_BITBASE_H__
#include "../_cl_common/CLCommon.h"
#include <vector>
#include <iostream>
#include <type_traits>
#include <exception>
template<class T>struct is_vector_type : std::false_type {};
template<class T>struct is_vector_type<std::vector<T>> : std::true_type {};
template<class T, int typeId>struct _bitContainerT {
T cont;
using Type = T;
operator const Type& () const noexcept { return cont; }
operator Type& () noexcept { return cont; }
};
template<class T>using _bitVec = _bitContainerT<T, 0>;
template<class T>using _bitVar = _bitContainerT<T, 1>;
template<class T>struct _bitContainerT<T, 2> {
static_assert(is_vector_type<T>::value || std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_pointer_v<T>,
"Bit Container target type is invalid! It must be integral,float,pointer or vector<T>!");
};
template<class T>using _bitOtherVar = _bitContainerT<T, 2>;
template<class T>using _Choose_BitContainer =
typename _Select<is_vector_type<T>::value>::template _Apply<_bitVec<T>,
typename _Select<std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_pointer_v<T>>::template _Apply<_bitVar<T>, _bitOtherVar<T>>>;
//比特位(Bit)读写工具类模版
template<class T>
class CLBitT :_Choose_BitContainer<T> {
typedef _Choose_BitContainer<T> base;
typedef unsigned char Byte;
typedef unsigned long long Var64;
typedef CLBitT obj;
typedef obj& ref;
template<class T> bool _checkBuf(size_t bitCounts, size_t startPos);
template<> bool _checkBuf<_bitVec<T>>(size_t bitCounts, size_t startPos) {
if (bitCounts) {
auto si = (((startPos + bitCounts - 1) >> 3) + 1);
if (base::cont.size() * sizeof(typename base::Type::value_type) < si)
base::cont.resize(si / sizeof(typename base::Type::value_type) + 1, 0);
return true;
}
else return false;
}
template<> bool _checkBuf<_bitVar<T>>(size_t bitCounts, size_t startPos) {
if (bitCounts) {
if (startPos + bitCounts - 1 < sizeof(T) * 8)
return true;
else
return false;
}
else return false;
}
template<class T>const void* _cdata() const;
template<>const void* _cdata<_bitVec<T>>() const { return base::cont.data(); }
template<>const void* _cdata<_bitVar<T>>() const { return (const void*)&this->base::cont; }
template<class T> void* _data();
template<>void* _data<_bitVec<T>>() { return base::cont.data(); }
template<>void* _data<_bitVar<T>>() { return (void*)&this->base::cont; }
template<class T> void _clear();
template<>void _clear<_bitVec<T>>() { base::cont.clear(); }
template<>void _clear<_bitVar<T>>() { base::cont = 0; }
template<class T> size_t _size()const;
template<>size_t _size<_bitVec<T>>() const { return base::cont.size() * sizeof(typename base::Type::value_type) * 8; }
template<>size_t _size<_bitVar<T>>() const { return sizeof(T) * 8; }
static bool _getBit(const void* const src, size_t bitPos) {
return (*(((Byte*)src) + (bitPos >> 3))) & (Byte(0x1) << (bitPos & 0x7));
}
static void _setBit(void* const src, size_t bitPos, bool val) {
if (val)
(*(((Byte*)src) + (bitPos >> 3))) |= (Byte(0x1) << (bitPos & 0x7));//置为1
else
(*(((Byte*)src) + (bitPos >> 3))) &= (~(Byte(0x1) << (bitPos & 0x7)));//置为0
}
//bit比特位位标包装类
struct Bit {
void* const _data;
const size_t _pos;
operator bool() const {
return CLBitT::_getBit(_data, _pos);
}
const Bit& operator=(bool val) const {
CLBitT::_setBit(_data, _pos, val);
return *this;
}
const Bit& operator=(const Bit& val) const {
CLBitT::_setBit(_data, _pos, CLBitT::_getBit(val._data, val._pos));
return *this;
}
const Bit& operator|=(bool val) const {
CLBitT::_setBit(_data, _pos, CLBitT::_getBit(_data, _pos) || val);
return *this;
}
const Bit& operator&=(bool val) const {
CLBitT::_setBit(_data, _pos, CLBitT::_getBit(_data, _pos) && val);
return *this;
}
const Bit& operator^=(bool val) const {
CLBitT::_setBit(_data, _pos, CLBitT::_getBit(_data, _pos) ^ val);
return *this;
}
const Bit& operator~() const {
CLBitT::_setBit(_data, _pos, !CLBitT::_getBit(_data, _pos));
return *this;
}
};
template<class T> size_t _sizeUnit() const;
template<> size_t _sizeUnit<_bitVec<T>>() const { return sizeof(typename T::value_type) * 8; }
template<> size_t _sizeUnit<_bitVar<T>>() const { return sizeof(T) * 8; }
public:
//容器类型
using TypeContain = T;
//容器单元bit长度
size_t sizeUnit() const { return _sizeUnit<base>(); }
//默认构造函数
CLBitT() {}
//用一个数据区src前srcbitCounts个比特位的值设置对象的第insertPos位bit开始的位。
template<class T>
explicit CLBitT(T* src, size_t srcbitCounts, size_t insertPos) {
setValue(src, srcbitCounts, 0, insertPos);
}
//保存(只包含0、1)字符串(例如:"101001100111001010")描述的二进制值到指定位置。字符串只识别0、1字符,若包含其他字符则忽略该字符位。
//其中isbitCharStringBigEnd指明字符串是否是大端顺序记录的,默认下是小端记录。
CLBitT(PCStr charString, size_t pos = 0, bool isbitCharStringBigEnd = false) {
setValueByChar2(charString, pos, isbitCharStringBigEnd);
}
//用一个值src各比特位的值设置对象的第insertPos位bit开始的位。
template<class T>
CLBitT(T src, size_t insertPos = 0) {
static_assert(std::is_integral_v<T> || std::is_floating_point_v<T>,
"template<class T>CLBitT(T src, size_t insertPos): class T must be integral or floating point!");
setValue((const void*)&src, sizeof(T) * 8, insertPos);
}
//用一个Bit比特位的值0或1设置对象的第insertPos位bit。
explicit CLBitT(const Bit& bt, size_t insertPos = 0) {
bool v = bt;
setValue((const void*)&v, 1, insertPos);
}
//范围pos比特位的值0或1。
bool operator[](size_t pos) const {
return _getBit(_cdata<base>(), pos);
}
//返回一个Bit类型,Bit是一个可以设置bit位值的辅助对象。
Bit operator[](size_t pos) {
if (_checkBuf<base>(1, pos))
return Bit{ _data<base>(),pos };
else throw std::out_of_range("Bit index is out of rang!");
}
//清空数据
ref clear() {
_clear<base>();
return *this;
}
//保存的比特位长度
size_t size() const {
return _size<base>();
}
//预分配多少个比特位空间
ref reserve(size_t reserveBitCounts) {
return _checkBuf<base>(reserveBitCounts, 0), * this;
}
//按0/1字符串打印保存数据内容。st=0表示从起始索引,ed=0表示显示到结束索引,eclapse表示多少个0/1字符后输出一个分割占位空格。
void print(size_t st = 0, size_t ed = 0, size_t eclapse = 8) const {
auto _st = min(st, size());
auto _ed = ed <= 0 ? size() :
ed < _st ? _st : ed > size() ? size() : ed;
size_t time = eclapse;
for (size_t i = _st; i < _ed; i++) {
cout << (*this)[i];
if (time)
if (--time == 0) {
cout << " "; time = eclapse;
}
}
}
//目标数据区src从srcBitStartPos开始的前srcBitCount个比特位内容,设置到起始由insertPos指定的比特位。
template<class T>
ref setValue(T* src, size_t srcBitCount, size_t srcBitStartPos, size_t insertPos) {
if (_checkBuf<base>(srcBitCount, insertPos)) {
for (size_t i = 0; i < srcBitCount; i++)
_setBit(_data<base>(), insertPos + i, _getBit(src, srcBitStartPos + i));
}
return *this;
}
//目标数据区src开始的前srcBitCount个比特位内容,设置到起始由insertPos指定的比特位。
template<class T>
ref setValue(T* src, size_t srcBitCount, size_t insertPos) {
return setValue(src, srcBitCount, 0, insertPos);
}
//目标值src开始的前srcBitCount个比特位内容,设置到起始由insertPos指定的比特位。
template<class T>
ref setValue(T src, size_t srcBitCount = 0, size_t insertPos = 0) {
static_assert(std::is_integral_v<T> || std::is_floating_point_v<T>,
"template<class T>setValue(T src, size_t srcBitCount, size_t insertPos): class T must be integral or floating point!");
return setValue((const void*)&src, srcBitCount ? min(sizeof(T) * 8, srcBitCount) : sizeof(T) * 8, insertPos);
}
//目标比特对象bit从srcBitStartPos开始的前srcBitCount个比特位内容,设置到起始由insertPos指定的比特位。
ref setValue(const CLBitT& bit, size_t srcBitCount, size_t srcBitStartPos, size_t insertPos) {
if (_checkBuf<base>(srcBitCount, insertPos)) {
for (size_t i = 0; i < srcBitCount; i++)
_setBit(_data<base>(), insertPos + i, bit[srcBitStartPos + i]);
}
return *this;
}
protected:
template<class CT> auto _getValue(size_t getBitCount, size_t pos) const;
template<>
auto _getValue<_bitVec<T>>(size_t getBitCount, size_t pos) const {
Var64 _var = 0;
getValue(&_var, min(getBitCount, sizeof(Var64) * 8), pos);
return _var;
}
template<>
auto _getValue<_bitVar<T>>(size_t getBitCount, size_t pos) const {
T _var = 0;
getValue(&_var, min(getBitCount, sizeof(T) * 8), pos);
return _var;
}
public:
//取得保存的数据区从pos开始的前getBitCount个比特位内容,返回到一个最大64位的Var64类型中。
//因此,getBitCount不能大于64,当大于64时刻超出部分会被舍弃。若需要取得大于64位的内容,需使用3参数版本。
auto getValue(size_t getBitCount, size_t pos = 0) const {
return _getValue<base>(getBitCount, pos);
}
//取得保存的数据区从pos开始的前getBitCount个比特位内容,返回到一个最大64位的Var64类型中。
//因此,getBitCount不能大于64,当大于64时刻超出部分会被舍弃。若需要取得大于64位的内容,需使用3参数版本。
auto operator()(size_t getBitCount, size_t pos = 0) const {
return _getValue<base>(getBitCount, pos);
}
//取得保存的数据区从pos开始的前getBitCount个比特位内容(当该参数为0则不取值),返回到一个buf指向的空间(按低位字节序保存的任意类型)。
//返回值为buf指向的空间本身。
void* getValue(void* const savebuf, size_t getBitCount, size_t pos = 0) const {
for (size_t i = 0, si = min(pos + getBitCount, size()) - min(pos, size()); i < si; i++)
_setBit(savebuf, i, _getBit(_cdata<base>(), pos + i));
return savebuf;
}
//取得保存的数据区从pos开始的前getBitCount个比特位内容,返回到一个buf指向的空间(按低位字节序保存的任意类型)。
//返回值为buf指向的空间本身。
void* operator()(void* const savebuf, size_t getBitCount, size_t pos = 0) const {
getValue(savebuf, getBitCount, pos);
}
//保存(只包含0、1)字符串(例如:"101001100111001010")描述的二进制值到指定位置。字符串只识别0、1字符,若包含其他字符则忽略该字符位。
//其中isbitCharStringBigEnd指明字符串是否是大端顺序记录的,默认下是小端记录。
ref setValueByChar2(PCStr bitCharString, size_t pos, bool isbitCharStringBigEnd = false) {
if (bitCharString) {
if (isbitCharStringBigEnd) {
PCStr pend = bitCharString;
while (*pend)pend++; pend--;
for (; pend >= bitCharString; pend--)
{
if (*pend == _T('0'))
setValue(0, 1, pos++);
else if (*pend == _T('1'))
setValue(1, 1, pos++);
}
}
else {
for (; *bitCharString; bitCharString++)
{
if (*bitCharString == _T('0'))
setValue(0, 1, pos++);
else if (*bitCharString == _T('1'))
setValue(1, 1, pos++);
}
}
}return *this;
}
//保存(只包含0-3)字符串(例如:"321032103210")描述的四进制值到指定位置。字符串只识别0-3字符,若包含其他字符则忽略该字符位。
//其中isbitCharStringBigEnd指明字符串是否是大端顺序记录的,默认下是小端记录。
ref setValueByChar4(PCStr bitCharString, size_t pos, bool isbitCharStringBigEnd = false) {
if (bitCharString) {
if (isbitCharStringBigEnd) {
PCStr pend = bitCharString;
while (*pend)pend++; pend--;
for (; pend >= bitCharString; pend--)
{
Char ch = *pend;
if (ch >= _T('0') && ch <= _T('3')) {
ch -= 48;
setValue(ch, 2, pos);
pos += 2;
}
}
}
else {
for (; *bitCharString; bitCharString++)
{
Char ch = *bitCharString;
if (ch >= _T('0') && ch <= _T('3')) {
ch -= 48;
setValue(ch, 2, pos);
pos += 2;
}
}
}
}
return *this;
}
//保存(只包含0-7)字符串(例如:"765432107654321076543210")描述的八进制值到指定位置。字符串只识别0-7字符,若包含其他字符则忽略该字符位。
//其中isbitCharStringBigEnd指明字符串是否是大端顺序记录的,默认下是小端记录。
ref setValueByChar8(PCStr bitCharString, size_t pos, bool isbitCharStringBigEnd = false) {
if (bitCharString) {
if (isbitCharStringBigEnd) {
PCStr pend = bitCharString;
while (*pend)pend++; pend--;
for (; pend >= bitCharString; pend--)
{
Char ch = *pend;
if (ch >= _T('0') && ch <= _T('7')) {
ch -= 48;
setValue(ch, 3, pos);
pos += 3;
}
}
}
else {
for (; *bitCharString; bitCharString++)
{
Char ch = *bitCharString;
if (ch >= _T('0') && ch <= _T('7')) {
ch -= 48;
setValue(ch, 3, pos);
pos += 3;
}
}
}
}
return *this;
}
//保存(只包含0-F/f)字符串(例如:"FfDCBA76543210FEDCBA7654321076543210")描述的十六进制值到指定位置。
//字符串只识别0-F/f字符,不区分大小写,若包含其他字符则忽略该字符位。
//其中isbitCharStringBigEnd指明字符串是否是大端顺序记录的,默认下是小端记录。
ref setValueByChar16(PCStr bitCharString, size_t pos, bool isbitCharStringBigEnd = false) {
if (bitCharString) {
if (isbitCharStringBigEnd) {
PCStr pend = bitCharString;
while (*pend)pend++; pend--;
for (; pend >= bitCharString; pend--)
{
Char ch = *pend;
if (ch >= _T('0') && ch <= _T('9')) {
ch -= 48;
setValue(ch, 4, pos);
pos += 4;
}
else if (ch >= _T('a') && ch <= _T('f')) {
ch -= 87;
setValue(ch, 4, pos);
pos += 4;
}
else if (ch >= _T('A') && ch <= _T('F')) {
ch -= 55;
setValue(ch, 4, pos);
pos += 4;
}
}
}
else {
for (; *bitCharString; bitCharString++)
{
Char ch = *bitCharString;
if (ch >= _T('0') && ch <= _T('9')) {
ch -= 48;
setValue(ch, 4, pos);
pos += 4;
}
else if (ch >= _T('a') && ch <= _T('f')) {
ch -= 87;
setValue(ch, 4, pos);
pos += 4;
}
else if (ch >= _T('A') && ch <= _T('F')) {
ch -= 55;
setValue(ch, 4, pos);
pos += 4;
}
}
}
}
return *this;
}
//插入原对象src从srcBitStartPos开始的srcBitCounts个比特位数据到对象insertPos的位置之前。
ref insertBit(const CLBitT& src, size_t srcBitCounts, size_t srcBitStartPos, size_t insertPos) {
if (_checkBuf<base>(srcBitCounts, insertPos)) {
size_t i = size();
for (; i > insertPos;)
{
i--;
if (_getBit(_cdata<base>(), i))
break;
}
for (; i >= insertPos; i--)
_setBit(_data<base>(), i + srcBitCounts, _getBit(_cdata<base>(), i));
for (i = 0; i < srcBitCounts; i++)
_setBit(_data<base>(), insertPos + i, src[srcBitStartPos + i]);
}
return *this;
}
//删除对象从deleteStartPos开始的bitCountsToDelete个比特位数据,后面的数据前移。
ref deleteBit(size_t bitCountsToDelete, size_t deleteStartPos) {
for (size_t i = deleteStartPos; i < size(); i++)
_setBit(_data<base>(), i, i + bitCountsToDelete < size() ? _getBit(_cdata<base>(), i + bitCountsToDelete) : false);
return *this;
}
//擦除对象从eraseStartPos开始的bitCountsToErase个比特位数据,该范围的bit位全部置0
ref erase(size_t bitCountsToErase, size_t eraseStartPos) {
for (size_t i = eraseStartPos, si = min(size(), eraseStartPos + bitCountsToErase); i < si; i++)
_setBit(_data<base>(), i, false);
return *this;
}
//填充对象从fillStartPos开始的bitCountsToFill个比特位数据,该范围的bit位全部置1
ref fill(size_t bitCountsToErase, size_t fillStartPos) {
if (_checkBuf<base>(bitCountsToErase, fillStartPos)) {
for (size_t i = fillStartPos, si = fillStartPos + bitCountsToErase; i < si; i++)
_setBit(_data<base>(), i, true);
}
return *this;
}
//读取一个文件的指定长度的在指定位置的bit比特位数据到对象中的指定位置中。
//file已经打开的可读文件流,loadBitCouunts读取比特数(为0表示读取全部文件bit数据),
//loadStartBitPos文件读取的起始bit位置,insertBitPos读取数据起始插入bit位置,chearBeforeLoad读取前是否先清理对象;
//返回已读取的bit位数;
template<class _iofstream = std::ifstream>
size_t loadFile(_iofstream& file, size_t loadBitCounts = 0, size_t loadStartBitPos = 0,
size_t insertBitPos = 0, bool chearBeforeLoad = true) {
static_assert(std::is_same_v<_iofstream, std::fstream> || std::is_same_v<_iofstream, std::ifstream>,
"template <class _iofstream> loadFile:_iofstream is not std::fstream or std::ifstream!");
if (chearBeforeLoad)
clear();
if (!file.is_open())
return 0;
size_t fileSize = file.seekg(0, file.end).tellg();
auto fileBits = loadBitCounts == 0 ? fileSize * 8 : min(loadBitCounts, fileSize * 8);
auto maxBits = min(fileSize * 8, loadStartBitPos + fileBits) - min(fileSize * 8, loadStartBitPos);
char ch = 0; size_t total = 0;
if (_checkBuf<base>(maxBits, loadStartBitPos)) {
auto startBytePos = min(fileSize, (loadStartBitPos >> 3));
auto endBytePos = min(fileSize, ((loadStartBitPos + maxBits) >> 3) + 1);
file.seekg(ios::beg, startBytePos);
for (size_t i = startBytePos; i < endBytePos; i++)
{
file.read(&ch, 1);
for (size_t j = (loadStartBitPos & 0x7); j < 8; j++, loadStartBitPos++, insertBitPos++)
{
_setBit(_data<base>(), insertBitPos, _getBit(&ch, j));
if (++total >= maxBits)
goto end;
}
}
}
end:
return total;
}
//写入在指定位置的指定长度个bit比特位数据到文件流中。
//file已经打开的可写文件流,写入位置应该已经被设置,srcBitCountsToWrite写入的比特数(为0表示写入全部bit数据),
//srcStartBitPosToWrite要写入文件的原数据的起始bit位置;
//返回已写入的bit位数;
template<class _iofstream = std::ofstream>
size_t writeToFile(_iofstream& file, size_t srcBitCountsToWrite = 0, size_t srcStartBitPosToWrite = 0) {
static_assert(std::is_same_v<_iofstream, std::fstream> || std::is_same_v<_iofstream, std::ofstream>,
"template <class _iofstream> writeToFile:_iofstream is not std::fstream or std::ofstream!");
if (!file.is_open())
return 0;
auto fileBits = srcBitCountsToWrite == 0 ? size() : min(srcBitCountsToWrite, size());
auto maxBits = min(size(), srcStartBitPosToWrite + fileBits) - min(size(), srcStartBitPosToWrite);
char ch = 0; size_t total = 0;
while (1)
{
ch = 0;
for (size_t j = (srcStartBitPosToWrite & 0x7); j < 8; j++, srcStartBitPosToWrite++)
{
_setBit(&ch, j, _getBit(_cdata<base>(), srcStartBitPosToWrite));
if (++total >= maxBits) {
file.write(&ch, 1);
goto end;
}
}
file.write(&ch, 1);
}
end:
return total;
}
};
//8位bit数据类
typedef CLBitT<unsigned char> CLBit8;
//16位bit数据类
typedef CLBitT<unsigned short> CLBit16;
//32位bit数据类
typedef CLBitT<unsigned int> CLBit32;
//64位bit数据类
typedef CLBitT<unsigned long long> CLBit64;
//(无限位)bit数据队列类
typedef CLBitT<std::vector<unsigned char>> CLBitArray;
//(无限位)bit数据队列类
typedef CLBitArray CLBit;
#endif
测试代码
template<class T>
void test_class_CLBit(size_t _len = 0);
void main() {
CLBitT<short> btts = 50;
CLBitT<int> btti = 50;
CLBitT<long long> bttll = 50;
CLBitT<double> bttd = 50;
CLBitT<bool> bttb = 50;
CLBitT<vector<unsigned char>> btvl = 5000;
btvl = "1001010110100101010111001010111001010";
CLBitT<void*> btvvv = 50;
auto c = bttd.getValue(bttd.sizeUnit());
auto cd = btvl.getValue(64);
vector<int> a;
cout << "\n\n\n bool"; test_class_CLBit<bool>();
cout << "\n\n\n char"; test_class_CLBit<char>();
cout << "\n\n\n unsigned char"; test_class_CLBit<unsigned char>();
cout << "\n\n\n short"; test_class_CLBit<short>();
cout << "\n\n\n unsigned short"; test_class_CLBit<unsigned short>();
cout << "\n\n\n int"; test_class_CLBit<int>();
cout << "\n\n\n unsigned int"; test_class_CLBit<unsigned int>();
cout << "\n\n\n long long"; test_class_CLBit<long long>();
cout << "\n\n\n unsigned long long"; test_class_CLBit<unsigned long long>();
cout << "\n\n\n void*"; test_class_CLBit<void*>();
cout << "\n\n\n vector<void*>"; test_class_CLBit<vector<void*>>(64000);
cout << "\n\n\n vector<char>"; test_class_CLBit<vector<char>>(64000);
cout << "\n\n\n vector<unsigned char>"; test_class_CLBit<vector<unsigned char>>(64000);
cout << "\n\n\n vector<char*>"; test_class_CLBit<vector<char*>>(64000);
cout << "\n\n\n vector<long long>"; test_class_CLBit<vector<long long>>(64000);
cout << "\n\n\n vector<unsigned long long>"; test_class_CLBit<vector<unsigned long long>>(64000);
cout << "\n\n\n vector<long long*>"; test_class_CLBit<vector<long long*>>(64000);
}
template<class T>
void test_class_CLBit(size_t _len) {
using CLBit = CLBitT<T>;
cout << "\ntest_class_CLBit:--------------------\nsize = "<< sizeof(CLBit) << "\n\n";
srand(time(0));
const size_t len = _len ? _len : sizeof(T)*8;
CLBit bt;
bt = 1123;
bt[rand()%len] = 1;
bt[rand() % len] = 1;
bt[rand() % len] = 1;
bt[rand() % len] = 1;
bt[rand() % len] = 1;
bt.clear();
((bt[rand() % len] = 1, bt)[rand() % len] = 0, bt)[rand() % len] = 2;
cout << endl;;
for (size_t i = 0; i < len; i++)
{
int v = (rand()%20) > 10 ? 1 : 0;
bt[i] = v;
if(i < 200)
cout << v;;
}
cout << endl;; cout << endl;; cout << endl;;
for (size_t i = 0; i < len; i++)
{
if (i < 200)
cout << bt[i];;
}
cout << endl;; cout << endl;; cout << endl;;
struct _A {
_A(const CLBit& bt,size_t len) {
for (size_t i = 0; i < len; i++)
{
if (i < 200)
cout << bt[i];
}
}
};
auto c = bt.getValue(bt.sizeUnit());
_A a(bt, len);
cout << "\n\n";
bt.print(0,200,8);
cout << "\n\n";
const auto v = bt.getValue(20, 30);
CLBit btv; btv.setValue(&v,64,0); btv.print(0, 200);
cout << "\n\n";
byte d[20] = { 0 };
bt.getValue(d, 20 * 8, 20);
CLBit btd; btd.setValue(d, 48,0); btd.print(0, 200);
char v1 = 34; int v2 = 3456; long long v3 = 2135; double v4 = 65659.362;
CLBit btv1 (v1); cout << "\n\n"; btv1.print(0, 200);
CLBit btv11(v1, 3);
btv11.setValue(v3, 0, 0);
cout << "\n\n"; btv11.print(0, 200);
CLBit btv13(&v1,16,8); cout << "\n\n"; btv13.print(0, 200);
CLBit btv2(v2); cout << "\n\n"; btv2.print(0, 200);
CLBit btv3(v3); cout << "\n\n"; btv3.print(0, 200);
CLBit btv4(v4); cout << "\n\n"; btv4.print(0, 200);
CLBit btv7 = btv4;
cout << "\n\n"; btv7.print(0, 200);
CLBit btv8 ((long long)btv7.getValue(11, 11));
cout << "\n\n"; btv8.print(0, 200);
CLBit btv9((short)btv7(11, 11));
cout << "\n\n"; btv9.print(0, 200);
CLBit btv19(btv7[rand() % len],3);
cout << "\n\n"; btv19.print(0, 200);
btv19[rand() % len] = btv7[rand() % len];
btv19[rand() % len] = 2;
btv19[rand() % len] &= 1;
btv19[rand() % len] ^= 1;
~btv19[rand() % len] ^= 0;
cout << "\n\n"; btv19.print(0, 200);
CLBit btv112; btv112.setValueByChar2("1111111111111111", 5);
cout << "\n\n"; btv112.print(0, 200);
CLBit btv111; btv111.setValueByChar16("A0a0", 8);
cout << "\n\n"; btv111.print(0, 200);
CLBit btv14; btv14.setValueByChar16("FaaCBA7654321000000A765432107654aaff", 8);
cout << "\n\n"; btv14.print(0, 0, 8);
CLBit btv15; btv15.setValueByChar16("aaaa", 8,true);
cout << "\n\n"; btv15.print(0, 0, 8);
btv112.insertBit(CLBit("010010"), 6, 0, 11); cout << "\n\n"; btv112.print(0, 0, 8);
btv112.deleteBit(5,7); cout << "\n\n"; btv112.print(0, 0, 8);
CLBit bt1 = 5625; cout << "\n\n\n"; bt1.print(0, 0, 8);
CLBit bt2 = 5625123.123; cout << "\n\n\n"; bt2.print(0, 0, 8);
CLBit bt3 = "001000101111101111110000111001001101011101010100111110011110111101111111111100111000001111111111111100011111111111110101100"; cout << "\n\n\n"; bt3.print(0, 0, 8);
ofstream f1(CLString().getSpecialFolderPath() << CLSla << "bttem.txt");
bt3.writeToFile(f1);
f1.close();
ifstream f2(CLString().getSpecialFolderPath() << CLSla << "bttem.txt");
CLBit bt4;
bt4.loadFile(f2); cout << "\n\n\n"; bt4.print(0, 0, 8);
f2.close();
}