util: Add consteval ""_hex[_v][_u8] literals

""_hex is a compile-time user-defined literal returning std::array<std::byte>, equivalent of ParseHex.

Variants:
- ""_hex_v returns std::vector<std::byte>
- ""_hex_u8 returns std::array<uint8_t>
- ""_hex_v_u8 returns std::vector<uint8_t> - Directly serializable as a size-prefixed OP_PUSH CScript payload using operator<<.

Also extracts from_hex into shared util::ConstevalHexDigit function.

Co-Authored-By: hodlinator <172445034+hodlinator@users.noreply.github.com>
Co-Authored-By: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
Co-Authored-By: Ryan Ofsky <ryan@ofsky.org>
Co-Authored-By: stickies-v <stickies-v@protonmail.com>
This commit is contained in:
l0rinc
2024-08-28 13:28:25 +02:00
committed by Hodlinator
parent dc5f6f6812
commit 5b74a849cf
3 changed files with 108 additions and 10 deletions

View File

@@ -7,6 +7,7 @@
#include <hash.h> // For Hash()
#include <key.h> // For CKey
#include <script/parsing.h>
#include <span.h>
#include <sync.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
@@ -45,6 +46,8 @@
#include <boost/test/unit_test.hpp>
using namespace std::literals;
using namespace util::hex_literals;
using util::ConstevalHexDigit;
using util::Join;
using util::RemovePrefix;
using util::RemovePrefixView;
@@ -151,6 +154,20 @@ BOOST_AUTO_TEST_CASE(parse_hex)
// Basic test vector
std::vector<unsigned char> expected(std::begin(HEX_PARSE_OUTPUT), std::end(HEX_PARSE_OUTPUT));
constexpr std::array<std::byte, 65> hex_literal_array{operator""_hex<util::detail::Hex(HEX_PARSE_INPUT)>()};
auto hex_literal_span{MakeUCharSpan(hex_literal_array)};
BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_span.begin(), hex_literal_span.end(), expected.begin(), expected.end());
const std::vector<std::byte> hex_literal_vector{operator""_hex_v<util::detail::Hex(HEX_PARSE_INPUT)>()};
hex_literal_span = MakeUCharSpan(hex_literal_vector);
BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_span.begin(), hex_literal_span.end(), expected.begin(), expected.end());
constexpr std::array<uint8_t, 65> hex_literal_array_uint8{operator""_hex_u8<util::detail::Hex(HEX_PARSE_INPUT)>()};
BOOST_CHECK_EQUAL_COLLECTIONS(hex_literal_array_uint8.begin(), hex_literal_array_uint8.end(), expected.begin(), expected.end());
result = operator""_hex_v_u8<util::detail::Hex(HEX_PARSE_INPUT)>();
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
result = ParseHex(HEX_PARSE_INPUT);
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
@@ -179,6 +196,10 @@ BOOST_AUTO_TEST_CASE(parse_hex)
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
// Empty string is supported
static_assert(""_hex.empty());
static_assert(""_hex_u8.empty());
BOOST_CHECK_EQUAL(""_hex_v.size(), 0);
BOOST_CHECK_EQUAL(""_hex_v_u8.size(), 0);
BOOST_CHECK_EQUAL(ParseHex("").size(), 0);
BOOST_CHECK_EQUAL(TryParseHex<uint8_t>("").value().size(), 0);
@@ -203,6 +224,14 @@ BOOST_AUTO_TEST_CASE(parse_hex)
BOOST_CHECK(!TryParseHex("12 3").has_value());
}
BOOST_AUTO_TEST_CASE(consteval_hex_digit)
{
BOOST_CHECK_EQUAL(ConstevalHexDigit('0'), 0);
BOOST_CHECK_EQUAL(ConstevalHexDigit('9'), 9);
BOOST_CHECK_EQUAL(ConstevalHexDigit('a'), 0xa);
BOOST_CHECK_EQUAL(ConstevalHexDigit('f'), 0xf);
}
BOOST_AUTO_TEST_CASE(util_HexStr)
{
BOOST_CHECK_EQUAL(HexStr(HEX_PARSE_OUTPUT), HEX_PARSE_INPUT);