7f0f37fca7
Previously the constructor for all of these would run at program startup, consuming time before the application can enter main(). This is also particularly dangerous, given the logging system wouldn't have been initialized properly yet, yet the program would use the logs to signify an error. To rectify this, we can replace the literals with constexpr functions that perform the conversion at compile-time, completely eliminating the runtime cost of initializing these arrays.
71 lines
1.8 KiB
C++
71 lines
1.8 KiB
C++
// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
#include <fmt/format.h>
|
|
#include "common/common_types.h"
|
|
|
|
namespace Common {
|
|
|
|
constexpr u8 ToHexNibble(char c) {
|
|
if (c >= 65 && c <= 70) {
|
|
return c - 55;
|
|
}
|
|
|
|
if (c >= 97 && c <= 102) {
|
|
return c - 87;
|
|
}
|
|
|
|
return c - 48;
|
|
}
|
|
|
|
std::vector<u8> HexStringToVector(std::string_view str, bool little_endian);
|
|
|
|
template <std::size_t Size, bool le = false>
|
|
constexpr std::array<u8, Size> HexStringToArray(std::string_view str) {
|
|
std::array<u8, Size> out{};
|
|
if constexpr (le) {
|
|
for (std::size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) {
|
|
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
|
|
}
|
|
} else {
|
|
for (std::size_t i = 0; i < 2 * Size; i += 2) {
|
|
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
template <typename ContiguousContainer>
|
|
std::string HexToString(const ContiguousContainer& data, bool upper = true) {
|
|
static_assert(std::is_same_v<typename ContiguousContainer::value_type, u8>,
|
|
"Underlying type within the contiguous container must be u8.");
|
|
|
|
constexpr std::size_t pad_width = 2;
|
|
|
|
std::string out;
|
|
out.reserve(std::size(data) * pad_width);
|
|
|
|
for (const u8 c : data) {
|
|
out += fmt::format(upper ? "{:02X}" : "{:02x}", c);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
constexpr std::array<u8, 16> AsArray(const char (&data)[17]) {
|
|
return HexStringToArray<16>(data);
|
|
}
|
|
|
|
constexpr std::array<u8, 32> AsArray(const char (&data)[65]) {
|
|
return HexStringToArray<32>(data);
|
|
}
|
|
|
|
} // namespace Common
|