diff --git a/src/ripple/basics/base_uint.h b/src/ripple/basics/base_uint.h index f38317da2..bfffe34a6 100644 --- a/src/ripple/basics/base_uint.h +++ b/src/ripple/basics/base_uint.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -51,13 +52,13 @@ class base_uint "The length of a base_uint in bits must be at least 64."); protected: - enum { WIDTH = Bits / 32 }; + static constexpr std::size_t WIDTH = Bits / 32; // This is really big-endian in byte order. // We sometimes use std::uint32_t for speed. - // NIKB TODO: migrate to std::array - std::uint32_t pn[WIDTH]; + using array_type = std::array; + array_type pn; public: //-------------------------------------------------------------------------- @@ -65,7 +66,8 @@ public: // STL Container Interface // - static std::size_t const bytes = Bits / 8; + static std::size_t constexpr bytes = Bits / 8; + static_assert(sizeof(array_type) == bytes, ""); using size_type = std::size_t; using difference_type = std::ptrdiff_t; @@ -80,8 +82,8 @@ public: using const_reverse_iterator = std::reverse_iterator; using tag_type = Tag; - pointer data() { return reinterpret_cast(pn); } - const_pointer data() const { return reinterpret_cast(pn); } + pointer data() { return reinterpret_cast(pn.data ()); } + const_pointer data() const { return reinterpret_cast(pn.data ()); } iterator begin() { return data(); } iterator end() { return data()+bytes; } @@ -124,7 +126,7 @@ private: explicit base_uint (void const* data, VoidHelper) { - memcpy (&pn [0], data, bytes); + memcpy (pn.data (), data, bytes); } public: @@ -143,7 +145,7 @@ public: assert (vch.size () == size ()); if (vch.size () == size ()) - memcpy (pn, &vch[0], size ()); + memcpy (pn.data (), vch.data (), size ()); else *this = beast::zero; } @@ -153,12 +155,10 @@ public: *this = b; } - base_uint (base_uint const& other) = default; - template void copyFrom (base_uint const& other) { - memcpy (&pn [0], other.data(), bytes); + memcpy (pn.data (), other.data(), bytes); } /* Construct from a raw pointer. @@ -194,14 +194,6 @@ public: return ret; } - base_uint& operator= (const base_uint& b) - { - for (int i = 0; i < WIDTH; i++) - pn[i] = b.pn[i]; - - return *this; - } - base_uint& operator= (std::uint64_t uHost) { *this = beast::zero; @@ -314,7 +306,7 @@ public: Hasher& h, base_uint const& a) noexcept { // Do not allow any endian transformations on this memory - h(a.pn, sizeof(a.pn)); + h(a.pn.data (), sizeof(a.pn)); } /** Parse a hex string into a base_uint @@ -325,7 +317,6 @@ public: { unsigned char* pOut = begin (); - assert(sizeof(pn) == bytes); for (int i = 0; i < sizeof (pn); ++i) { auto hi = charUnHex(*psz++); @@ -419,7 +410,7 @@ public: base_uint& operator=(Zero) { - memset (&pn[0], 0, sizeof (pn)); + pn.fill(0); return *this; } diff --git a/src/test/basics/base_uint_test.cpp b/src/test/basics/base_uint_test.cpp index ed2820e55..523c37cef 100644 --- a/src/test/basics/base_uint_test.cpp +++ b/src/test/basics/base_uint_test.cpp @@ -22,6 +22,8 @@ #include #include +#include + namespace ripple { namespace test { @@ -50,6 +52,8 @@ struct nonhash struct base_uint_test : beast::unit_test::suite { using test96 = base_uint<96>; + static_assert(std::is_copy_constructible::value, ""); + static_assert(std::is_copy_assignable::value, ""); void run() override {