mirror of
https://github.com/status-im/evmc.git
synced 2025-02-22 07:58:19 +00:00
Improve C++ helpers
This commit is contained in:
parent
da9c03ffb5
commit
5c8e64915a
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
#include "example_host.h"
|
#include "example_host.h"
|
||||||
|
|
||||||
#include <evmc/helpers.hpp>
|
|
||||||
#include <evmc/helpers.h>
|
#include <evmc/helpers.h>
|
||||||
|
#include <evmc/helpers.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
* These are convenient for languages where invoking function pointers
|
* These are convenient for languages where invoking function pointers
|
||||||
* is "ugly" or impossible (such as Go).
|
* is "ugly" or impossible (such as Go).
|
||||||
*
|
*
|
||||||
|
* It also contains helpers (overloaded operators) for using EVMC types effectively in C++.
|
||||||
|
*
|
||||||
* @defgroup helpers EVMC Helpers
|
* @defgroup helpers EVMC Helpers
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
@ -4,11 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EVMC C++ helpers
|
* @file
|
||||||
|
* A collection of helpers (overloaded operators) for using EVMC types effectively in C++.
|
||||||
*
|
*
|
||||||
* A collection of helpers (overloaded operators) for using EVMC effectively in C++.
|
* @addtogroup helpers
|
||||||
*
|
|
||||||
* @defgroup cpphelpers EVMC C++ helpers
|
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -19,31 +18,31 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
/// The comparator for std::map<evmc_address, ...>.
|
/// The comparator for std::map<evmc_address, ...>.
|
||||||
bool operator<(const evmc_address& a, const evmc_address& b)
|
inline bool operator<(const evmc_address& a, const evmc_address& b)
|
||||||
{
|
{
|
||||||
return std::memcmp(a.bytes, b.bytes, sizeof(a)) < 0;
|
return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The comparator for std::map<evmc_bytes32, ...>.
|
/// The comparator for std::map<evmc_bytes32, ...>.
|
||||||
bool operator<(const evmc_bytes32& a, const evmc_bytes32& b)
|
inline bool operator<(const evmc_bytes32& a, const evmc_bytes32& b)
|
||||||
{
|
{
|
||||||
return std::memcmp(a.bytes, b.bytes, sizeof(a)) < 0;
|
return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The comparator for equality.
|
/// The comparator for equality.
|
||||||
bool operator==(const evmc_address& a, const evmc_address& b)
|
inline bool operator==(const evmc_address& a, const evmc_address& b)
|
||||||
{
|
{
|
||||||
return std::memcmp(a.bytes, b.bytes, sizeof(a)) == 0;
|
return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The comparator for equality.
|
/// The comparator for equality.
|
||||||
bool operator==(const evmc_bytes32& a, const evmc_bytes32& b)
|
inline bool operator==(const evmc_bytes32& a, const evmc_bytes32& b)
|
||||||
{
|
{
|
||||||
return std::memcmp(a.bytes, b.bytes, sizeof(a)) == 0;
|
return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FNV1a hash function with 64-bit result.
|
/// FNV1a hash function with 64-bit result.
|
||||||
static inline uint64_t fnv1a_64(const uint8_t* ptr, size_t len)
|
inline uint64_t fnv1a_64(const uint8_t* ptr, size_t len)
|
||||||
{
|
{
|
||||||
constexpr uint64_t prime = 1099511628211ULL;
|
constexpr uint64_t prime = 1099511628211ULL;
|
||||||
constexpr uint64_t offset_basis = 14695981039346656037ULL;
|
constexpr uint64_t offset_basis = 14695981039346656037ULL;
|
||||||
@ -57,20 +56,27 @@ static inline uint64_t fnv1a_64(const uint8_t* ptr, size_t len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(size_t) == sizeof(uint64_t), "size_t is not 64-bit wide");
|
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
/// Hash operator template needed for std::ordered_set and others using hashes.
|
/// Hash operator template specialization for evmc_address needed for unordered containers.
|
||||||
|
template <>
|
||||||
|
struct hash<evmc_address>
|
||||||
|
{
|
||||||
|
/// Hash operator using FNV1a.
|
||||||
|
std::enable_if<sizeof(size_t) == 8, std::size_t>::type operator()(const evmc_address& s) const
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return fnv1a_64(s.bytes, sizeof(s.bytes));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Hash operator template needed for std::unordered_set and others using hashes.
|
||||||
template <>
|
template <>
|
||||||
struct hash<evmc_bytes32>
|
struct hash<evmc_bytes32>
|
||||||
{
|
{
|
||||||
/// The argument type.
|
|
||||||
typedef evmc_bytes32 argument_type;
|
|
||||||
/// The result type.
|
|
||||||
typedef std::size_t result_type;
|
|
||||||
/// Hash operator using FNV1a.
|
/// Hash operator using FNV1a.
|
||||||
result_type operator()(argument_type const& s) const noexcept
|
std::enable_if<sizeof(size_t) == 8, std::size_t>::type operator()(const evmc_bytes32& s) const
|
||||||
|
noexcept
|
||||||
{
|
{
|
||||||
return fnv1a_64(s.bytes, sizeof(s.bytes));
|
return fnv1a_64(s.bytes, sizeof(s.bytes));
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ add_custom_command(
|
|||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
evmc-test
|
evmc-test
|
||||||
|
test_helpers.cpp
|
||||||
test_instructions.cpp
|
test_instructions.cpp
|
||||||
test_loader.cpp
|
test_loader.cpp
|
||||||
)
|
)
|
||||||
|
29
test/unittests/test_helpers.cpp
Normal file
29
test/unittests/test_helpers.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// EVMC: Ethereum Client-VM Connector API.
|
||||||
|
// Copyright 2018 The EVMC Authors.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||||
|
|
||||||
|
#include <evmc/helpers.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
TEST(helpers, maps)
|
||||||
|
{
|
||||||
|
std::map<evmc_address, bool> addresses;
|
||||||
|
addresses[{}] = true;
|
||||||
|
ASSERT_EQ(addresses.size(), 1);
|
||||||
|
|
||||||
|
std::unordered_map<evmc_address, bool> unordered_addresses;
|
||||||
|
unordered_addresses.emplace(*addresses.begin());
|
||||||
|
EXPECT_EQ(unordered_addresses.size(), 1);
|
||||||
|
|
||||||
|
std::map<evmc_bytes32, bool> storage;
|
||||||
|
storage[{}] = true;
|
||||||
|
ASSERT_EQ(storage.size(), 1);
|
||||||
|
|
||||||
|
std::unordered_map<evmc_bytes32, bool> unordered_storage;
|
||||||
|
unordered_storage.emplace(*storage.begin());
|
||||||
|
EXPECT_EQ(unordered_storage.size(), 1);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user