【原创】C++ bit比特位数据编辑类模版CLBitT

9 篇文章 0 订阅
5 篇文章 0 订阅

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();
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值