diff --git a/src/main.cc b/src/main.cc index 94a9ce8a..e8cab32a 100644 --- a/src/main.cc +++ b/src/main.cc @@ -64,7 +64,7 @@ void register_env_vars() { return b->display_name(); }), ':'); } }, { "timestamp", - [](StringView name, const Context& context) + [](StringView name, const Context& context) -> String { return to_string(context.buffer().timestamp()); } }, { "selection", @@ -101,15 +101,15 @@ void register_env_vars() { return context.name(); } }, { "cursor_line", - [](StringView name, const Context& context) + [](StringView name, const Context& context) -> String { return to_string(context.selections().main().cursor().line + 1); } }, { "cursor_column", - [](StringView name, const Context& context) + [](StringView name, const Context& context) -> String { return to_string(context.selections().main().cursor().column + 1); } }, { "cursor_char_column", - [](StringView name, const Context& context) + [](StringView name, const Context& context) -> String { auto coord = context.selections().main().cursor(); return to_string(context.buffer()[coord.line].char_count_to(coord.column) + 1); } }, { @@ -129,11 +129,11 @@ void register_env_vars() }), ':'); } }, { "window_width", - [](StringView name, const Context& context) + [](StringView name, const Context& context) -> String { return to_string(context.window().dimensions().column); } }, { "window_height", - [](StringView name, const Context& context) + [](StringView name, const Context& context) -> String { return to_string(context.window().dimensions().line); } } }; diff --git a/src/string.cc b/src/string.cc index a9840d45..02e79f3f 100644 --- a/src/string.cc +++ b/src/string.cc @@ -115,25 +115,25 @@ int str_to_int(StringView str) return negative ? -(int)res : (int)res; } -String to_string(int val) +InplaceString<16> to_string(int val) { - char buf[16]; - sprintf(buf, "%i", val); - return buf; + InplaceString<16> res; + res.m_length = sprintf(res.m_data, "%i", val); + return res; } -String to_string(size_t val) +InplaceString<24> to_string(size_t val) { - char buf[16]; - sprintf(buf, "%zu", val); - return buf; + InplaceString<24> res; + res.m_length = sprintf(res.m_data, "%zu", val); + return res; } -String to_string(float val) +InplaceString<24> to_string(float val) { - char buf[32]; - sprintf(buf, "%f", val); - return buf; + InplaceString<24> res; + res.m_length = sprintf(res.m_data, "%f", val); + return res; } bool subsequence_match(StringView str, StringView subseq) diff --git a/src/string.hh b/src/string.hh index 41dbccb8..6b66bce4 100644 --- a/src/string.hh +++ b/src/string.hh @@ -92,6 +92,7 @@ public: String() {} String(const char* content) : m_data(content) {} + String(const char* content, ByteCount len) : m_data(content, (size_t)(int)len) {} explicit String(char content, CharCount count = 1) : m_data((size_t)(int)count, content) {} explicit String(Codepoint cp, CharCount count = 1) { @@ -256,12 +257,23 @@ inline String codepoint_to_str(Codepoint cp) int str_to_int(StringView str); -String to_string(int val); -String to_string(size_t val); -String to_string(float val); +template +struct InplaceString +{ + constexpr operator StringView() const { return {m_data, m_length}; } + operator String() const { return {m_data, m_length}; } + + ByteCount m_length; + char m_data[N]; +}; + +InplaceString<16> to_string(int val); +InplaceString<24> to_string(size_t val); +InplaceString<24> to_string(float val); template -String to_string(const StronglyTypedNumber& val) +decltype(to_string(std::declval())) +to_string(const StronglyTypedNumber& val) { return to_string((ValueType)val); } @@ -283,7 +295,7 @@ namespace detail template using IsString = std::is_convertible; template::value>::type> -String format_param(const T& val) { return to_string(val); } +auto format_param(const T& val) -> decltype(to_string(val)) { return to_string(val); } template::value>::type> StringView format_param(const T& val) { return val; } @@ -295,7 +307,7 @@ String format(StringView fmt, ArrayView params); template String format(StringView fmt, Types... params) { - return format(fmt, ArrayView{{detail::format_param(params)...}}); + return format(fmt, ArrayView{detail::format_param(params)...}); } }