#ifndef format_hh_INCLUDED #define format_hh_INCLUDED #include "string.hh" #include "utils.hh" namespace Kakoune { template struct InplaceString { static_assert(N < 256, "InplaceString cannot handle sizes >= 256"); constexpr operator StringView() const { return {m_data, ByteCount{m_length}}; } operator String() const { return {m_data, ByteCount{m_length}}; } unsigned char m_length{}; char m_data[N]; }; struct Hex { size_t val; }; constexpr Hex hex(size_t val) { return {val}; } struct Grouped { size_t val; }; constexpr Grouped grouped(size_t val) { return {val}; } InplaceString<15> to_string(int val); InplaceString<15> to_string(unsigned val); InplaceString<23> to_string(long int val); InplaceString<23> to_string(unsigned long val); InplaceString<23> to_string(long long int val); InplaceString<23> to_string(Hex val); InplaceString<23> to_string(Grouped val); InplaceString<23> to_string(float val); InplaceString<7> to_string(Codepoint c); template decltype(auto) to_string(const StronglyTypedNumber& val) { return to_string((ValueType)val); } namespace detail { template requires std::is_convertible_v StringView format_param(const T& val) { return val; } template requires (not std::is_convertible_v) decltype(auto) format_param(const T& val) { return to_string(val); } } String format(StringView fmt, ArrayView params); template String format(StringView fmt, Types&&... params) { return format(fmt, ArrayView{detail::format_param(std::forward(params))...}); } StringView format_to(ArrayView buffer, StringView fmt, ArrayView params); template StringView format_to(ArrayView buffer, StringView fmt, Types&&... params) { return format_to(buffer, fmt, ArrayView{detail::format_param(std::forward(params))...}); } void format_with(FunctionRef append, StringView fmt, ArrayView params); template void format_with(FunctionRef append, StringView fmt, Types&&... params) { return format_with(append, fmt, ArrayView{detail::format_param(std::forward(params))...}); } } #endif // format_hh_INCLUDED