Implement the same class as uint64_t, if the platform does not support uint64_t, you can replace it.
Currently only part of the function, other features please look forward to.
Uint64.hpp
#include <endian.h> #include <cstdint> #include <type_traits> #include <array> #define Mc_begin _namespace NAMESPACE MC {#define MC_END_NAMESPACE} mc_begin_namespace #if __byte_order = __big_endian struct MAYBE_
Big_endian:std::true_type {};
#elif __byte_order = = __little_endian struct Maybe_big_endian:std::false_type {}; #else #error "Endianness not defined!" #endif template<typename array, bool> struct uint64_data:public array {p
rotected:uint32_t& A () {return (*this) [0];}
uint32_t& second () {return (*this) [1];}
uint32_t-I () const {return (*this) [0];}
uint32_t second () const {return (*this) [1];}; Template<typename array> struct Uint64_data<array, true>: public Array {protected:uint32_t& A () { return (*this) [1];
} uint32_t& second () {return (*this) [0];}
uint32_t-I () const {return (*this) [1];}
uint32_t second () const {return (*this) [0];}; Class Uint64:public UInT64_data <std::array<uint32_t, 2>, maybe_big_endian::value> {public:uint64 () = default;
Explicit UInt64 (uint32_t v);
UInt64 (const uint64& o);
~uint64 () = default;
uint64& operator+= (const uint64& v) noexcept;
uint64& operator<<= (unsigned int n) noexcept;
uint64& operator>>= (unsigned int n) noexcept;
Operator uint32_t () {return a ();}
friend void Swap (uint64& L, uint64& R);
};
Inline UInt64 operator+ (const uint64& L, const uint64& r) {Auto TMP = L; return tmp + = r;}
Inline UInt64 operator>> (const uint64& l, unsigned int n) {auto tmp = l; return tmp >>= N;}
Inline UInt64 operator<< (const uint64& l, unsigned int n) {auto tmp = l; return tmp <<= N;} Mc_end_namespace
Uint64.cpp
#include "uint64.hpp" Mc_begin_namespace Uint64::uint64 (uint32_t v) {A () = V;
Second () = 0u;
} uint64::uint64 (const uint64& o) {*this = O;} uint64& uint64::operator+= (const uint64& o) noexcept {second () + = O.second ();//calculate second first, prevent (this = = &o)
The case uint32_t old = a ();
if ((I () + + O.first ()) < old) {++second ();
return *this; uint64& uint64::operator<<= (unsigned int n) noexcept {if (n < a) {second () = (second () << N) |
(A () >> (32-n));
A () <<= N;
else if (n <) {second () = A-I () << (n-32);
A () = 0u;
else/*if (n >=)/{second () = i = 0u;
return *this; uint64& uint64::operator>>= (unsigned int n) noexcept {if (n < a) {I () = (a) (a) |
(Second () << (32-n));
Second () >>= N;
else if (n <) {A () = second () >> (n-32);
Second () = 0u; else/*if (n >= /{second () = a () = 0u;
return *this;
} void Swap (uint64& L, uint64& R) {if (&l!= &r) {Auto TMP = 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" #if 1 typedef mc::uint64 U64;
inline void PType () {std::p rintf ("Using mc::uint64\n");} #else typedef std::uint64_t U64;
inline void PType () {std::p rintf ("Using std::uint64_t\n");} #endif void frm (const char* str) {std::p rintf ("%20s", str);}
void Data_hex (const u64& v) {const uint8_t* p = (const uint8_t*) &v;
for (int i = 0; i < 8; ++i) {if (i = = 4) std::p rintf ("");
std::p rintf ("%02x", P[i]);
std::p rintf ("\ n");
void Test () {uint32_t v = 0xffffffff;
U64 a = 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);
int main () {ptype ();
if (mc::maybe_big_endian::value) {std::p rintf ("host byte order is big-endian\n");
else {std::p rintf ("host byte order is little-endian\n"); for (int i = 0; i < ++i) std::printf ("");
if (mc::maybe_big_endian::value) std::p rintf ("H <<<< L H <<<< l\n");
Else std::p rintf ("L >>>> H L >>>> h\n");
Test ();
return 0;
}
The
function is also gradually improving, the small partners remember to pay attention to.