aboutsummaryrefslogtreecommitdiff
path: root/src/uint256.h
diff options
context:
space:
mode:
authorAndrew Chow <github@achow101.com>2023-02-06 13:56:32 -0500
committerAndrew Chow <github@achow101.com>2023-02-06 13:56:51 -0500
commit52ddbd52f980c0e733682401056d8131f1d513c0 (patch)
tree44df731e2e1ba34dea80e289e65de49800b47741 /src/uint256.h
parentaff75463e2c75a7a969cdaa535c7be05fd146420 (diff)
parent935acdcc79d1dc5ac04a83b92e5919ddbfa29329 (diff)
downloadbitcoin-52ddbd52f980c0e733682401056d8131f1d513c0.tar.xz
Merge bitcoin/bitcoin#26345: refactor: modernize the implementation of uint256.*
935acdcc79d1dc5ac04a83b92e5919ddbfa29329 refactor: modernize the implementation of uint256.* (pasta) Pull request description: - 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 This may also be replaced by std::memset, but I think that std::fill is more idiomatic of modern c++ and readable. - 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) This could also likely be replaced by std::memcpy, but as said above, I believe the using std::copy is the more c++ way to do anything and is almost guaranteed to compile to the same asm - memcmp -> std::memcmp ACKs for top commit: achow101: ACK 935acdcc79d1dc5ac04a83b92e5919ddbfa29329 hebasto: Approach ACK 935acdcc79d1dc5ac04a83b92e5919ddbfa29329. aureleoules: reACK 935acdcc79d1dc5ac04a83b92e5919ddbfa29329 john-moffett: ACK 935acdcc79d1dc5ac04a83b92e5919ddbfa29329 stickies-v: Approach ACK 935acdcc7 Tree-SHA512: 4f1ba54ff2198eea0e505d41e73d552c84c60f6878d5c85a94a8ab57f39afc94ef8d79258e7afd01fa84ec2a99f4404bb877eecd671f65e1ee9273f3129fc650
Diffstat (limited to 'src/uint256.h')
-rw-r--r--src/uint256.h80
1 files changed, 33 insertions, 47 deletions
diff --git a/src/uint256.h b/src/uint256.h
index 58e595c4ca..1cc3721487 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;
};