diff --git a/include/evmc/evmc.hpp b/include/evmc/evmc.hpp index 5ff85fb..d727b6c 100644 --- a/include/evmc/evmc.hpp +++ b/include/evmc/evmc.hpp @@ -25,6 +25,33 @@ struct address : evmc_address /// Initializes bytes to zeros if not other @p init value provided. constexpr address(evmc_address init = {}) noexcept : evmc_address{init} {} + /// Converting constructor from unsigned integer value. + /// + /// This constructor assigns the @p v value to the last 8 bytes [12:19] + /// in big-endian order. + constexpr explicit address(uint64_t v) noexcept + : evmc_address{{0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + static_cast(v >> 56), + static_cast(v >> 48), + static_cast(v >> 40), + static_cast(v >> 32), + static_cast(v >> 24), + static_cast(v >> 16), + static_cast(v >> 8), + static_cast(v >> 0)}} + {} + /// Explicit operator converting to bool. constexpr inline explicit operator bool() const noexcept; }; @@ -39,6 +66,45 @@ struct bytes32 : evmc_bytes32 /// Initializes bytes to zeros if not other @p init value provided. constexpr bytes32(evmc_bytes32 init = {}) noexcept : evmc_bytes32{init} {} + /// Converting constructor from unsigned integer value. + /// + /// This constructor assigns the @p v value to the last 8 bytes [24:31] + /// in big-endian order. + constexpr explicit bytes32(uint64_t v) noexcept + : evmc_bytes32{{0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + static_cast(v >> 56), + static_cast(v >> 48), + static_cast(v >> 40), + static_cast(v >> 32), + static_cast(v >> 24), + static_cast(v >> 16), + static_cast(v >> 8), + static_cast(v >> 0)}} + {} + /// Explicit operator converting to bool. constexpr inline explicit operator bool() const noexcept; }; @@ -189,16 +255,16 @@ namespace literals { namespace internal { -template -struct integer_sequence +template +struct sequence { }; template -using byte_sequence = integer_sequence; +using byte_sequence = sequence; template -using char_sequence = integer_sequence; +using char_sequence = sequence; template diff --git a/test/unittests/cpp_test.cpp b/test/unittests/cpp_test.cpp index 3a79632..6d4e52f 100644 --- a/test/unittests/cpp_test.cpp +++ b/test/unittests/cpp_test.cpp @@ -330,6 +330,49 @@ TEST(cpp, literals) EXPECT_EQ(h1, f1); } +TEST(cpp, bytes32_from_uint) +{ + using evmc::bytes32; + using evmc::operator""_bytes32; + +#if !defined(_MSC_VER) || (_MSC_VER >= 1910 /* Only for Visual Studio 2017+ */) + static_assert(bytes32{0} == bytes32{}, ""); + static_assert(bytes32{3}.bytes[31] == 3, ""); + static_assert(bytes32{0xfe00000000000000}.bytes[24] == 0xfe, ""); +#endif + + EXPECT_EQ(bytes32{0}, bytes32{}); + EXPECT_EQ(bytes32{0x01}, + 0x0000000000000000000000000000000000000000000000000000000000000001_bytes32); + EXPECT_EQ(bytes32{0xff}, + 0x00000000000000000000000000000000000000000000000000000000000000ff_bytes32); + EXPECT_EQ(bytes32{0x500}, + 0x0000000000000000000000000000000000000000000000000000000000000500_bytes32); + EXPECT_EQ(bytes32{0x8000000000000000}, + 0x0000000000000000000000000000000000000000000000008000000000000000_bytes32); + EXPECT_EQ(bytes32{0xc1c2c3c4c5c6c7c8}, + 0x000000000000000000000000000000000000000000000000c1c2c3c4c5c6c7c8_bytes32); +} + +TEST(cpp, address_from_uint) +{ + using evmc::address; + using evmc::operator""_address; + +#if !defined(_MSC_VER) || (_MSC_VER >= 1910 /* Only for Visual Studio 2017+ */) + static_assert(address{0} == address{}, ""); + static_assert(address{3}.bytes[19] == 3, ""); + static_assert(address{0xfe00000000000000}.bytes[12] == 0xfe, ""); +#endif + + EXPECT_EQ(address{0}, address{}); + EXPECT_EQ(address{0x01}, 0x0000000000000000000000000000000000000001_address); + EXPECT_EQ(address{0xff}, 0x00000000000000000000000000000000000000ff_address); + EXPECT_EQ(address{0x500}, 0x0000000000000000000000000000000000000500_address); + EXPECT_EQ(address{0x8000000000000000}, 0x0000000000000000000000008000000000000000_address); + EXPECT_EQ(address{0xc1c2c3c4c5c6c7c8}, 0x000000000000000000000000c1c2c3c4c5c6c7c8_address); +} + TEST(cpp, result) { static const uint8_t output = 0;