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; }
功能还在逐步完善中,小伙伴们记得关注。