23#include "pw_polyfill/language_feature_macros.h"
29constexpr bool UseBytesDirectly = std::is_integral_v<T> || std::is_enum_v<T>;
34template <
typename B,
typename T,
typename... Args>
35PW_CONSTEVAL
void CopyBytes(B* array, T value, Args... args) {
36 static_assert(
sizeof(B) ==
sizeof(std::byte));
38 if constexpr (UseBytesDirectly<T>) {
39 if constexpr (
sizeof(T) == 1u) {
40 *array++ =
static_cast<B
>(value);
42 for (
size_t i = 0; i <
sizeof(T); ++i) {
43 *array++ =
static_cast<B
>(value & 0xFF);
48 static_assert(
sizeof(value[0]) ==
sizeof(B));
49 for (
auto b : value) {
50 *array++ =
static_cast<B
>(b);
54 if constexpr (
sizeof...(args) > 0u) {
55 CopyBytes(array, args...);
61PW_CONSTEVAL
size_t SizeOfBytes(
const T& arg) {
62 if constexpr (UseBytesDirectly<T>) {
65 static_assert(
sizeof(arg[0]) ==
sizeof(std::byte));
66 return std::size(arg);
70template <
typename B,
typename T,
size_t... kIndex>
71PW_CONSTEVAL
auto String(
const T& array, std::index_sequence<kIndex...>) {
72 return std::array{
static_cast<B
>(array[kIndex])...};
75template <
typename T,
typename U>
76PW_CONSTEVAL
bool CanBeRepresentedAsByteType(
const U& value) {
77 return static_cast<U
>(
static_cast<T
>(value)) == value;
84template <
typename B = std::byte,
typename... Args>
85PW_CONSTEVAL
auto Concat(Args... args) {
86 std::array<B, (internal::SizeOfBytes(args) + ...)> bytes{};
87 internal::CopyBytes(bytes.data(), args...);
92template <
typename B = std::byte,
94 typename Indices = std::make_index_sequence<kSize - 1>>
95PW_CONSTEVAL
auto String(
const char (&str)[kSize]) {
96 return internal::String<B>(str, Indices{});
100template <
typename B = std::
byte>
101PW_CONSTEVAL
auto String(
const char (&)[1]) {
102 return std::array<B, 0>{};
107template <
typename B,
auto... values>
108PW_CONSTEVAL
auto Array() {
109 static_assert((internal::CanBeRepresentedAsByteType<B>(values) && ...));
110 return std::array<B,
sizeof...(values)>{
static_cast<B
>(values)...};
114template <
auto... values>
115PW_CONSTEVAL
auto Array() {
116 return Array<std::byte, values...>();
121template <
typename B,
size_t kSize,
typename T>
122constexpr auto Initialized(
const T& value_or_function) {
123 std::array<B, kSize> array{};
125 for (
size_t i = 0; i < kSize; ++i) {
126 if constexpr (std::is_integral_v<T>) {
127 array[i] =
static_cast<B
>(value_or_function);
129 array[i] =
static_cast<B
>(value_or_function(i));
136template <
size_t kSize,
typename T>
137constexpr auto Initialized(
const T& value_or_function) {
138 return Initialized<std::byte, kSize>(value_or_function);
144template <
typename B = std::byte,
typename... Args>
145constexpr auto MakeArray(
const Args&... args) {
146 return std::array<B,
sizeof...(args)>{
static_cast<B
>(args)...};