2023-11-03 02:48:21 -07:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "glacier/memory/move.h"
|
|
|
|
#include "glacier/status/error.h"
|
|
|
|
#include "glacier/string/string_builder.h"
|
|
|
|
#include "glacier/string/string_view.h"
|
|
|
|
|
|
|
|
namespace glcr {
|
|
|
|
|
2023-11-19 20:33:15 -08:00
|
|
|
// FIXME: We need some meta-programming here to allow pass-by-value for pointers
|
|
|
|
// and primitives.
|
2023-11-03 02:48:21 -07:00
|
|
|
template <typename T>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const T& value, StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const uint8_t& value,
|
|
|
|
StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const uint16_t& value,
|
|
|
|
StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const int32_t& value,
|
|
|
|
StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const uint32_t& value,
|
|
|
|
StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const uint64_t& value,
|
|
|
|
StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const ErrorCode& value,
|
|
|
|
StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
2023-11-05 09:24:09 -08:00
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const char& value, StringView opts);
|
2023-11-05 09:24:09 -08:00
|
|
|
|
2023-11-03 02:48:21 -07:00
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, char const* const& value,
|
|
|
|
StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
|
|
|
template <>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatValue(StringBuilder& builder, const StringView& value,
|
|
|
|
StringView opts);
|
2023-11-03 02:48:21 -07:00
|
|
|
|
|
|
|
void StrFormatInternal(StringBuilder& builder, StringView format);
|
|
|
|
|
|
|
|
template <typename T, typename... Args>
|
2023-11-19 20:33:15 -08:00
|
|
|
void StrFormatInternal(StringBuilder& builder, StringView format,
|
|
|
|
const T& value, Args&&... args) {
|
2023-11-03 02:48:21 -07:00
|
|
|
uint64_t posl = format.find('{');
|
|
|
|
uint64_t posr = format.find('}', posl);
|
|
|
|
if (posl == format.npos || posr == format.npos) {
|
|
|
|
// TODO: Consider throwing an error since we still have values to consume.
|
|
|
|
return StrFormatInternal(builder, format);
|
|
|
|
}
|
|
|
|
|
|
|
|
builder.PushBack(format.substr(0, posl));
|
|
|
|
StrFormatValue(builder, value, format.substr(posl + 1, posr - posl - 1));
|
|
|
|
StrFormatInternal(builder, format.substr(posr + 1, format.size() - posr - 1),
|
|
|
|
args...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename... Args>
|
2023-11-19 20:33:15 -08:00
|
|
|
String StrFormat(StringView format, Args&&... args) {
|
2023-11-09 08:52:30 -08:00
|
|
|
VariableStringBuilder builder;
|
|
|
|
StrFormatInternal(builder, format, args...);
|
|
|
|
return builder.ToString();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename... Args>
|
2023-11-09 09:07:09 -08:00
|
|
|
void StrFormatIntoBuffer(StringBuilder& builder, StringView format,
|
2023-11-19 20:33:15 -08:00
|
|
|
Args&&... args) {
|
2023-11-03 02:48:21 -07:00
|
|
|
StrFormatInternal(builder, format, args...);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace glcr
|