number to string conversion avoids memory allocations

This commit is contained in:
Maxime Coste 2015-03-31 13:53:40 +01:00
parent 519254dfdc
commit 758bfe7284
3 changed files with 36 additions and 24 deletions

View File

@ -64,7 +64,7 @@ void register_env_vars()
{ return b->display_name(); }), ':'); } { return b->display_name(); }), ':'); }
}, { }, {
"timestamp", "timestamp",
[](StringView name, const Context& context) [](StringView name, const Context& context) -> String
{ return to_string(context.buffer().timestamp()); } { return to_string(context.buffer().timestamp()); }
}, { }, {
"selection", "selection",
@ -101,15 +101,15 @@ void register_env_vars()
{ return context.name(); } { return context.name(); }
}, { }, {
"cursor_line", "cursor_line",
[](StringView name, const Context& context) [](StringView name, const Context& context) -> String
{ return to_string(context.selections().main().cursor().line + 1); } { return to_string(context.selections().main().cursor().line + 1); }
}, { }, {
"cursor_column", "cursor_column",
[](StringView name, const Context& context) [](StringView name, const Context& context) -> String
{ return to_string(context.selections().main().cursor().column + 1); } { return to_string(context.selections().main().cursor().column + 1); }
}, { }, {
"cursor_char_column", "cursor_char_column",
[](StringView name, const Context& context) [](StringView name, const Context& context) -> String
{ auto coord = context.selections().main().cursor(); { auto coord = context.selections().main().cursor();
return to_string(context.buffer()[coord.line].char_count_to(coord.column) + 1); } return to_string(context.buffer()[coord.line].char_count_to(coord.column) + 1); }
}, { }, {
@ -129,11 +129,11 @@ void register_env_vars()
}), ':'); } }), ':'); }
}, { }, {
"window_width", "window_width",
[](StringView name, const Context& context) [](StringView name, const Context& context) -> String
{ return to_string(context.window().dimensions().column); } { return to_string(context.window().dimensions().column); }
}, { }, {
"window_height", "window_height",
[](StringView name, const Context& context) [](StringView name, const Context& context) -> String
{ return to_string(context.window().dimensions().line); } { return to_string(context.window().dimensions().line); }
} }; } };

View File

@ -115,25 +115,25 @@ int str_to_int(StringView str)
return negative ? -(int)res : (int)res; return negative ? -(int)res : (int)res;
} }
String to_string(int val) InplaceString<16> to_string(int val)
{ {
char buf[16]; InplaceString<16> res;
sprintf(buf, "%i", val); res.m_length = sprintf(res.m_data, "%i", val);
return buf; return res;
} }
String to_string(size_t val) InplaceString<24> to_string(size_t val)
{ {
char buf[16]; InplaceString<24> res;
sprintf(buf, "%zu", val); res.m_length = sprintf(res.m_data, "%zu", val);
return buf; return res;
} }
String to_string(float val) InplaceString<24> to_string(float val)
{ {
char buf[32]; InplaceString<24> res;
sprintf(buf, "%f", val); res.m_length = sprintf(res.m_data, "%f", val);
return buf; return res;
} }
bool subsequence_match(StringView str, StringView subseq) bool subsequence_match(StringView str, StringView subseq)

View File

@ -92,6 +92,7 @@ public:
String() {} String() {}
String(const char* content) : m_data(content) {} 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(char content, CharCount count = 1) : m_data((size_t)(int)count, content) {}
explicit String(Codepoint cp, CharCount count = 1) explicit String(Codepoint cp, CharCount count = 1)
{ {
@ -256,12 +257,23 @@ inline String codepoint_to_str(Codepoint cp)
int str_to_int(StringView str); int str_to_int(StringView str);
String to_string(int val); template<size_t N>
String to_string(size_t val); struct InplaceString
String to_string(float val); {
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<typename RealType, typename ValueType> template<typename RealType, typename ValueType>
String to_string(const StronglyTypedNumber<RealType, ValueType>& val) decltype(to_string(std::declval<ValueType>()))
to_string(const StronglyTypedNumber<RealType, ValueType>& val)
{ {
return to_string((ValueType)val); return to_string((ValueType)val);
} }
@ -283,7 +295,7 @@ namespace detail
template<typename T> using IsString = std::is_convertible<T, StringView>; template<typename T> using IsString = std::is_convertible<T, StringView>;
template<typename T, class = typename std::enable_if<!IsString<T>::value>::type> template<typename T, class = typename std::enable_if<!IsString<T>::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<typename T, class = typename std::enable_if<IsString<T>::value>::type> template<typename T, class = typename std::enable_if<IsString<T>::value>::type>
StringView format_param(const T& val) { return val; } StringView format_param(const T& val) { return val; }
@ -295,7 +307,7 @@ String format(StringView fmt, ArrayView<const StringView> params);
template<typename... Types> template<typename... Types>
String format(StringView fmt, Types... params) String format(StringView fmt, Types... params)
{ {
return format(fmt, ArrayView<const StringView>{{detail::format_param(params)...}}); return format(fmt, ArrayView<const StringView>{detail::format_param(params)...});
} }
} }