C实现与 uint64_t 相同功能的类
实现与uint64_t相同的类,如果平台不支持uint64_t的话,可以代替之。
目前只完成部分功能,其他功能敬请期待。
uint64.hpp
#include<endian.h>
#include<cstdint>
#include<type_traits>
#include<array>
#defineMC_BEGIN_NAMESPACEnamespacemc{
#defineMC_END_NAMESPACE}
MC_BEGIN_NAMESPACE
#if__BYTE_ORDER==__BIG_ENDIAN
structmaybe_big_endian:std::true_type{};
#elif__BYTE_ORDER==__LITTLE_ENDIAN
structmaybe_big_endian:std::false_type{};
#else
#error"Endiannessnotdefined!"
#endif
template<typenameArray,bool>
structuint64_data:publicArray
{
protected:
uint32_t&first(){return(*this)[0];}
uint32_t&second(){return(*this)[1];}
uint32_tfirst()const{return(*this)[0];}
uint32_tsecond()const{return(*this)[1];}
};
template<typenameArray>
structuint64_data<Array,true>:publicArray
{
protected:
uint32_t&first(){return(*this)[1];}
uint32_t&second(){return(*this)[0];}
uint32_tfirst()const{return(*this)[1];}
uint32_tsecond()const{return(*this)[0];}
};
classuint64:publicuint64_data
<std::array<uint32_t,2>,maybe_big_endian::value>
{
public:
uint64()=default;
//explicit
uint64(uint32_tv);
uint64(constuint64&o);
~uint64()=default;
uint64&operator+=(constuint64&v)noexcept;
uint64&operator<<=(unsignedintn)noexcept;
uint64&operator>>=(unsignedintn)noexcept;
operatoruint32_t(){returnfirst();}
friendvoidswap(uint64&l,uint64&r);
};
inlineuint64operator+(constuint64&l,constuint64&r)
{autotmp=l;returntmp+=r;}
inlineuint64operator>>(constuint64&l,unsignedintn)
{autotmp=l;returntmp>>=n;}
inlineuint64operator<<(constuint64&l,unsignedintn)
{autotmp=l;returntmp<<=n;}
MC_END_NAMESPACE
uint64.cpp
#include"uint64.hpp"
MC_BEGIN_NAMESPACE
uint64::uint64(uint32_tv)
{
first()=v;
second()=0u;
}
uint64::uint64(constuint64&o)
{
*this=o;
}
uint64&uint64::operator+=(constuint64&o)noexcept
{
second()+=o.second();//先计算second,预防(this==&o)的情况
uint32_told=first();
if((first()+=o.first())<old){
++second();
}
return*this;
}
uint64&uint64::operator<<=(unsignedintn)noexcept
{
if(n<32){
second()=(second()<<n)|(first()>>(32-n));
first()<<=n;
}elseif(n<64){
second()=first()<<(n-32);
first()=0u;
}else/*if(n>=64)*/{
second()=first()=0u;
}
return*this;
}
uint64&uint64::operator>>=(unsignedintn)noexcept
{
if(n<32){
first()=(first()>>n)|(second()<<(32-n));
second()>>=n;
}elseif(n<64){
first()=second()>>(n-32);
second()=0u;
}else/*if(n>=64)*/{
second()=first()=0u;
}
return*this;
}
voidswap(uint64&l,uint64&r)
{
if(&l!=&r){
autotmp=l.first();
l.first()=r.first();
r.first()=tmp;
tmp=l.second();
l.second()=r.second();
r.second()=tmp;
}
}
MC_END_NAMESPACE
test.cpp
#include<cstdint>
#include<cstdio>
#include"uint64.hpp"
#if1
typedefmc::uint64U64;
inlinevoidptype(){std::printf("使用mc::uint64\n");}
#else
typedefstd::uint64_tU64;
inlinevoidptype(){std::printf("使用std::uint64_t\n");}
#endif
voidfrm(constchar*str){
std::printf("%20s",str);
}
voiddata_hex(constU64&v){
constuint8_t*p=(constuint8_t*)&v;
for(inti=0;i<8;++i){
if(i==4)std::printf("");
std::printf("%02x",p[i]);
}
std::printf("\n");
}
voidtest(){
uint32_tv=0xffffffff;
U64a=v;
frm("(a=0xffffffff)=>");
data_hex(a);
frm("(a>>=1)=>");
data_hex(a>>=1);
a=v;
frm("(a<<=1)=>");
data_hex(a<<=1);
a=v;
frm("(a+=a)=>");
data_hex(a+=a);
}
intmain(){
ptype();
if(mc::maybe_big_endian::value){
std::printf("主机字节序是big-endian\n");
}else{
std::printf("主机字节序是little-endian\n");
}
for(inti=0;i<20;++i)
std::printf("");
if(mc::maybe_big_endian::value)
std::printf("H<<<<LH<<<<L\n");
else
std::printf("L>>>>HL>>>>H\n");
test();
return0;
}
功能还在逐步完善中,小伙伴们记得关注。