mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			99 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* EVMC: Ethereum Client-VM Connector API.
 | 
						|
 * Copyright 2018-2019 The EVMC Authors.
 | 
						|
 * Licensed under the Apache License, Version 2.0.
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * @file
 | 
						|
 * A collection of helpers (overloaded operators) for using EVMC types effectively in C++.
 | 
						|
 *
 | 
						|
 * @addtogroup helpers
 | 
						|
 * @{
 | 
						|
 */
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include <evmc/evmc.h>
 | 
						|
 | 
						|
#include <cstring>
 | 
						|
#include <functional>
 | 
						|
 | 
						|
/// The comparator for std::map<evmc_address, ...>.
 | 
						|
inline bool operator<(const evmc_address& a, const evmc_address& b)
 | 
						|
{
 | 
						|
    return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) < 0;
 | 
						|
}
 | 
						|
 | 
						|
/// The comparator for std::map<evmc_bytes32, ...>.
 | 
						|
inline bool operator<(const evmc_bytes32& a, const evmc_bytes32& b)
 | 
						|
{
 | 
						|
    return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) < 0;
 | 
						|
}
 | 
						|
 | 
						|
/// The comparator for equality.
 | 
						|
inline bool operator==(const evmc_address& a, const evmc_address& b)
 | 
						|
{
 | 
						|
    return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) == 0;
 | 
						|
}
 | 
						|
 | 
						|
/// The comparator for equality.
 | 
						|
inline bool operator==(const evmc_bytes32& a, const evmc_bytes32& b)
 | 
						|
{
 | 
						|
    return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) == 0;
 | 
						|
}
 | 
						|
 | 
						|
/// Check if the address is zero (all bytes are zeros).
 | 
						|
inline bool is_zero(const evmc_address& address) noexcept
 | 
						|
{
 | 
						|
    return address == evmc_address{};
 | 
						|
}
 | 
						|
 | 
						|
/// Check if the hash is zero (all bytes are zeros).
 | 
						|
inline bool is_zero(const evmc_bytes32& x) noexcept
 | 
						|
{
 | 
						|
    return x == evmc_bytes32{};
 | 
						|
}
 | 
						|
 | 
						|
/// FNV1a hash function with 64-bit result.
 | 
						|
inline uint64_t fnv1a_64(const uint8_t* ptr, size_t len)
 | 
						|
{
 | 
						|
    constexpr uint64_t prime = 1099511628211ULL;
 | 
						|
    constexpr uint64_t offset_basis = 14695981039346656037ULL;
 | 
						|
 | 
						|
    uint64_t ret = offset_basis;
 | 
						|
    for (size_t i = 0; i < len; i++)
 | 
						|
    {
 | 
						|
        ret ^= ptr[i];
 | 
						|
        ret *= prime;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
namespace std
 | 
						|
{
 | 
						|
/// 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 <>
 | 
						|
struct hash<evmc_bytes32>
 | 
						|
{
 | 
						|
    /// Hash operator using FNV1a.
 | 
						|
    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));
 | 
						|
    }
 | 
						|
};
 | 
						|
}  // namespace std
 | 
						|
 | 
						|
/** @} */
 |