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;
}