diff options
author | pasta <pasta@dashboost.org> | 2022-10-19 15:16:04 -0500 |
---|---|---|
committer | pasta <pasta@dashboost.org> | 2022-12-10 14:34:44 -0600 |
commit | 935acdcc79d1dc5ac04a83b92e5919ddbfa29329 (patch) | |
tree | d38d0afc26dd7d85a346a676d6ab93ca2e7a6fba /src/uint256.h | |
parent | 1ea02791f3d81c7716d9ea455971203f74d7a107 (diff) | |
download | bitcoin-935acdcc79d1dc5ac04a83b92e5919ddbfa29329.tar.xz |
refactor: modernize the implementation of uint256.*
- Constructors of uint256 to utilize Span instead of requiring a std::vector
- converts m_data into a std::array
- Prefers using `WIDTH` instead of `sizeof(m_data)`
- make all the things constexpr
- replace C style functions with c++ equivalents
- memset -> std::fill
- memcpy -> std::copy
Note: In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable and the iterator types satisfy LegacyContiguousIterator. (https://en.cppreference.com/w/cpp/algorithm/copy)
- memcmp -> std::memcmp
Diffstat (limited to 'src/uint256.h')
-rw-r--r-- | src/uint256.h | 80 |
1 files changed, 33 insertions, 47 deletions
diff --git a/src/uint256.h b/src/uint256.h index e74b9ff7b1..782fec8e51 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -9,11 +9,12 @@ #include <crypto/common.h> #include <span.h> -#include <assert.h> +#include <algorithm> +#include <array> +#include <cassert> #include <cstring> #include <stdint.h> #include <string> -#include <vector> /** Template base class for fixed-sized opaque blobs. */ template<unsigned int BITS> @@ -21,7 +22,9 @@ class base_blob { protected: static constexpr int WIDTH = BITS / 8; - uint8_t m_data[WIDTH]; + std::array<uint8_t, WIDTH> m_data; + static_assert(WIDTH == sizeof(m_data), "Sanity check"); + public: /* construct 0 value by default */ constexpr base_blob() : m_data() {} @@ -29,64 +32,47 @@ public: /* constructor for constants between 1 and 255 */ constexpr explicit base_blob(uint8_t v) : m_data{v} {} - explicit base_blob(const std::vector<unsigned char>& vch); + constexpr explicit base_blob(Span<const unsigned char> vch) + { + assert(vch.size() == WIDTH); + std::copy(vch.begin(), vch.end(), m_data.begin()); + } - bool IsNull() const + constexpr bool IsNull() const { - for (int i = 0; i < WIDTH; i++) - if (m_data[i] != 0) - return false; - return true; + return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { + return val == 0; + }); } - void SetNull() + constexpr void SetNull() { - memset(m_data, 0, sizeof(m_data)); + std::fill(m_data.begin(), m_data.end(), 0); } - inline int Compare(const base_blob& other) const { return memcmp(m_data, other.m_data, sizeof(m_data)); } + constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); } - friend inline bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } - friend inline bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } - friend inline bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } + friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } + friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } + friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } std::string GetHex() const; void SetHex(const char* psz); void SetHex(const std::string& str); std::string ToString() const; - const unsigned char* data() const { return m_data; } - unsigned char* data() { return m_data; } + constexpr const unsigned char* data() const { return m_data.data(); } + constexpr unsigned char* data() { return m_data.data(); } - unsigned char* begin() - { - return &m_data[0]; - } + constexpr unsigned char* begin() { return m_data.data(); } + constexpr unsigned char* end() { return m_data.data() + WIDTH; } - unsigned char* end() - { - return &m_data[WIDTH]; - } + constexpr const unsigned char* begin() const { return m_data.data(); } + constexpr const unsigned char* end() const { return m_data.data() + WIDTH; } - const unsigned char* begin() const - { - return &m_data[0]; - } + static constexpr unsigned int size() { return WIDTH; } - const unsigned char* end() const - { - return &m_data[WIDTH]; - } - - static constexpr unsigned int size() - { - return sizeof(m_data); - } - - uint64_t GetUint64(int pos) const - { - return ReadLE64(m_data + pos * 8); - } + constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); } template<typename Stream> void Serialize(Stream& s) const @@ -107,8 +93,8 @@ public: */ class uint160 : public base_blob<160> { public: - constexpr uint160() {} - explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {} + constexpr uint160() = default; + constexpr explicit uint160(Span<const unsigned char> vch) : base_blob<160>(vch) {} }; /** 256-bit opaque blob. @@ -118,9 +104,9 @@ public: */ class uint256 : public base_blob<256> { public: - constexpr uint256() {} + constexpr uint256() = default; constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} - explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {} + constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {} static const uint256 ZERO; static const uint256 ONE; }; |