From e9ae8dbfa2ba83a00e3bb315db46815e0d951715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 6 May 2022 09:21:18 +0200 Subject: [PATCH] =?UTF-8?q?C++:=20Conversion=20{address,=20bytes32}=20?= =?UTF-8?q?=E2=86=92=20bytes=5Fview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/evmc/evmc.hpp | 12 +++++++++++- test/unittests/cpp_test.cpp | 31 +++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/include/evmc/evmc.hpp b/include/evmc/evmc.hpp index fdf82d4f4..57f0faa9d 100644 --- a/include/evmc/evmc.hpp +++ b/include/evmc/evmc.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include static_assert(EVMC_LATEST_STABLE_REVISION <= EVMC_MAX_REVISION, @@ -18,6 +19,9 @@ static_assert(EVMC_LATEST_STABLE_REVISION <= EVMC_MAX_REVISION, /// @ingroup cpp namespace evmc { +/// String view of uint8_t chars. +using bytes_view = std::basic_string_view; + /// The big-endian 160-bit hash suitable for keeping an Ethereum address. /// /// This type wraps C ::evmc_address to make sure objects of this type are always initialized. @@ -57,6 +61,9 @@ struct address : evmc_address /// Explicit operator converting to bool. inline constexpr explicit operator bool() const noexcept; + + /// Implicit operator converting to bytes_view. + inline constexpr operator bytes_view() const noexcept { return {bytes, sizeof(bytes)}; } }; /// The fixed size array of 32 bytes for storing 256-bit EVM values. @@ -109,7 +116,10 @@ struct bytes32 : evmc_bytes32 {} /// Explicit operator converting to bool. - constexpr inline explicit operator bool() const noexcept; + inline constexpr explicit operator bool() const noexcept; + + /// Implicit operator converting to bytes_view. + inline constexpr operator bytes_view() const noexcept { return {bytes, sizeof(bytes)}; } }; /// The alias for evmc::bytes32 to represent a big-endian 256-bit integer. diff --git a/test/unittests/cpp_test.cpp b/test/unittests/cpp_test.cpp index b93955078..70525cdb0 100644 --- a/test/unittests/cpp_test.cpp +++ b/test/unittests/cpp_test.cpp @@ -415,6 +415,29 @@ TEST(cpp, address_from_uint) EXPECT_EQ(address{0xc1c2c3c4c5c6c7c8}, 0x000000000000000000000000c1c2c3c4c5c6c7c8_address); } +TEST(cpp, address_to_bytes_view) +{ + using evmc::operator""_address; + + constexpr auto a = 0xa0a1a2a3a4a5a6a7a8a9b0b1b2b3b4b5b6b7b8b9_address; + static_assert(evmc::bytes_view{a}.size() == 20); + const evmc::bytes_view v = a; + EXPECT_EQ(v, (evmc::bytes{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9})); +} + +TEST(cpp, bytes32_to_bytes_view) +{ + using evmc::operator""_bytes32; + + constexpr auto b = 0xa0a1a2a3a4a5a6a7a8a9b0b1b2b3b4b5b6b7b8b9c0c1c2c3c4c5c6c7c8c9d0d1_bytes32; + static_assert(evmc::bytes_view{b}.size() == 32); + const evmc::bytes_view v = b; + EXPECT_EQ(v, (evmc::bytes{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xb0, + 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xc0, 0xc1, + 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xd0, 0xd1})); +} + TEST(cpp, result) { static const uint8_t output = 0; @@ -796,8 +819,8 @@ TEST(cpp, status_code_to_string) }; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define TEST_CASE(STATUS_CODE) \ - TestCase { STATUS_CODE, #STATUS_CODE } +#define TEST_CASE(NAME) \ + TestCase { NAME, #NAME } constexpr TestCase test_cases[]{ TEST_CASE(EVMC_SUCCESS), TEST_CASE(EVMC_FAILURE), @@ -847,8 +870,8 @@ TEST(cpp, revision_to_string) }; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define TEST_CASE(STATUS_CODE) \ - TestCase { STATUS_CODE, #STATUS_CODE } +#define TEST_CASE(NAME) \ + TestCase { NAME, #NAME } constexpr TestCase test_cases[]{ TEST_CASE(EVMC_FRONTIER), TEST_CASE(EVMC_HOMESTEAD),