Merge pull request #488 from ethereum/literals

C++: Add uint64_t -> {bytes32, address} constructors
This commit is contained in:
Paweł Bylica 2019-12-12 21:12:08 +01:00 committed by GitHub
commit d92d349ad2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 113 additions and 4 deletions

View File

@ -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<uint8_t>(v >> 56),
static_cast<uint8_t>(v >> 48),
static_cast<uint8_t>(v >> 40),
static_cast<uint8_t>(v >> 32),
static_cast<uint8_t>(v >> 24),
static_cast<uint8_t>(v >> 16),
static_cast<uint8_t>(v >> 8),
static_cast<uint8_t>(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<uint8_t>(v >> 56),
static_cast<uint8_t>(v >> 48),
static_cast<uint8_t>(v >> 40),
static_cast<uint8_t>(v >> 32),
static_cast<uint8_t>(v >> 24),
static_cast<uint8_t>(v >> 16),
static_cast<uint8_t>(v >> 8),
static_cast<uint8_t>(v >> 0)}}
{}
/// Explicit operator converting to bool.
constexpr inline explicit operator bool() const noexcept;
};
@ -189,16 +255,16 @@ namespace literals
{
namespace internal
{
template <typename T, T... Ints>
struct integer_sequence
template <typename T, T...>
struct sequence
{
};
template <uint8_t... Bytes>
using byte_sequence = integer_sequence<uint8_t, Bytes...>;
using byte_sequence = sequence<uint8_t, Bytes...>;
template <char... Chars>
using char_sequence = integer_sequence<char, Chars...>;
using char_sequence = sequence<char, Chars...>;
template <typename, typename>

View File

@ -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;