From cdcd2e2fb9c03a347ec9f67da77168edd4b638df Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 17 Oct 2017 00:41:51 -0700 Subject: [PATCH] ircd: Add std::chrono lex_cast; cleanup lex_cast buffer argument related. --- include/ircd/lex_cast.h | 68 +++++++++-------- ircd/lexical.cc | 165 ++++++++++++++++++++++++++++------------ 2 files changed, 155 insertions(+), 78 deletions(-) diff --git a/include/ircd/lex_cast.h b/include/ircd/lex_cast.h index 1372422e7..62b70ccd8 100644 --- a/include/ircd/lex_cast.h +++ b/include/ircd/lex_cast.h @@ -38,7 +38,7 @@ namespace ircd template T lex_cast(const string_view &); // User supplied destination buffer - template string_view lex_cast(T, char *const &buf, const size_t &max); + template string_view lex_cast(T, const mutable_buffer &buf); // Circular static thread_local buffer const size_t LEX_CAST_BUFS {256}; // plenty @@ -77,6 +77,10 @@ namespace ircd template<> bool try_lex_cast(const string_view &); template<> bool try_lex_cast(const string_view &); template<> bool try_lex_cast(const string_view &); + template<> bool try_lex_cast(const string_view &); + template<> bool try_lex_cast(const string_view &); + template<> bool try_lex_cast(const string_view &); + template<> bool try_lex_cast(const string_view &); template<> std::string &lex_cast(std::string &); // trivial template<> std::string lex_cast(const std::string &); // trivial @@ -93,21 +97,29 @@ namespace ircd template<> uint8_t lex_cast(const string_view &); template<> int8_t lex_cast(const string_view &); template<> bool lex_cast(const string_view &); + template<> seconds lex_cast(const string_view &); + template<> milliseconds lex_cast(const string_view &); + template<> microseconds lex_cast(const string_view &); + template<> nanoseconds lex_cast(const string_view &); - template<> string_view lex_cast(const std::string &, char *const &buf, const size_t &max); - template<> string_view lex_cast(const std::string_view &, char *const &buf, const size_t &max); - template<> string_view lex_cast(const string_view &, char *const &buf, const size_t &max); - template<> string_view lex_cast(long double, char *const &buf, const size_t &max); - template<> string_view lex_cast(double, char *const &buf, const size_t &max); - template<> string_view lex_cast(ulong, char *const &buf, const size_t &max); - template<> string_view lex_cast(long, char *const &buf, const size_t &max); - template<> string_view lex_cast(uint, char *const &buf, const size_t &max); - template<> string_view lex_cast(int, char *const &buf, const size_t &max); - template<> string_view lex_cast(ushort, char *const &buf, const size_t &max); - template<> string_view lex_cast(short, char *const &buf, const size_t &max); - template<> string_view lex_cast(uint8_t, char *const &buf, const size_t &max); - template<> string_view lex_cast(int8_t, char *const &buf, const size_t &max); - template<> string_view lex_cast(bool, char *const &buf, const size_t &max); + template<> string_view lex_cast(const std::string &, const mutable_buffer &buf); + template<> string_view lex_cast(const std::string_view &, const mutable_buffer &buf); + template<> string_view lex_cast(const string_view &, const mutable_buffer &buf); + template<> string_view lex_cast(seconds, const mutable_buffer &buf); + template<> string_view lex_cast(milliseconds, const mutable_buffer &buf); + template<> string_view lex_cast(microseconds, const mutable_buffer &buf); + template<> string_view lex_cast(nanoseconds, const mutable_buffer &buf); + template<> string_view lex_cast(long double, const mutable_buffer &buf); + template<> string_view lex_cast(double, const mutable_buffer &buf); + template<> string_view lex_cast(ulong, const mutable_buffer &buf); + template<> string_view lex_cast(long, const mutable_buffer &buf); + template<> string_view lex_cast(uint, const mutable_buffer &buf); + template<> string_view lex_cast(int, const mutable_buffer &buf); + template<> string_view lex_cast(ushort, const mutable_buffer &buf); + template<> string_view lex_cast(short, const mutable_buffer &buf); + template<> string_view lex_cast(uint8_t, const mutable_buffer &buf); + template<> string_view lex_cast(int8_t, const mutable_buffer &buf); + template<> string_view lex_cast(bool, const mutable_buffer &buf); } /// Convert a native number to a string. The returned value is a view of the @@ -117,7 +129,7 @@ template ircd::string_view ircd::lex_cast(const T &t) { - return lex_cast(t, nullptr, 0); + return lex_cast(t, null_buffer); } /// Conversion to an std::string creates a copy when the input is a @@ -192,11 +204,10 @@ template<> __attribute__((warning("unnecessary lexical cast"))) inline ircd::string_view ircd::lex_cast(const string_view &s, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { - s.copy(buf, max); - return { buf, max }; + s.copy(data(buf), size(buf)); + return { data(buf), s.size() }; } /// Specialization of a string to string conversion to user's buffer; @@ -206,11 +217,10 @@ template<> __attribute__((warning("unnecessary lexical cast"))) inline ircd::string_view ircd::lex_cast(const std::string_view &s, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { - s.copy(buf, max); - return { buf, max }; + s.copy(data(buf), size(buf)); + return { data(buf), s.size() }; } /// Specialization of a string to string conversion to user's buffer; @@ -220,11 +230,10 @@ template<> __attribute__((warning("unnecessary lexical cast"))) inline ircd::string_view ircd::lex_cast(const std::string &s, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { - s.copy(buf, max); - return { buf, max }; + s.copy(data(buf), size(buf)); + return { data(buf), s.size() }; } /// Template basis; if no specialization is matched there is no fallback here @@ -232,8 +241,7 @@ template __attribute__((error("unsupported lexical cast"))) ircd::string_view ircd::lex_cast(T t, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { assert(0); return {}; diff --git a/ircd/lexical.cc b/ircd/lexical.cc index 9e2b3b173..6147fb910 100644 --- a/ircd/lexical.cc +++ b/ircd/lexical.cc @@ -161,23 +161,21 @@ ircd::token_count(const string_view &str, size_t ircd::tokens(const string_view &str, const char &sep, - char *const &buf, - const size_t &max, + const mutable_buffer &buf, const token_view &closure) { const char ssep[2] { sep, '\0' }; - return tokens(str, ssep, buf, max, closure); + return tokens(str, ssep, buf, closure); } size_t ircd::tokens(const string_view &str, const char *const &sep, - char *const &buf, - const size_t &max, + const mutable_buffer &buf, const token_view &closure) { - char *ptr(buf); - char *const stop(buf + max); + char *ptr(data(buf)); + char *const stop(data(buf) + size(buf)); tokens(str, sep, [&closure, &ptr, &stop] (const string_view &token) { @@ -191,7 +189,7 @@ ircd::tokens(const string_view &str, closure(string_view(dest, token.size())); }); - return std::distance(buf, ptr); + return std::distance(data(buf), ptr); } size_t @@ -266,7 +264,7 @@ namespace ircd thread_local char lex_cast_buf[LEX_CAST_BUFS][LEX_CAST_BUFSIZE]; thread_local uint lex_cast_cur; - template static string_view _lex_cast(const T &i, char *buf, size_t max); + template static string_view _lex_cast(const T &i, mutable_buffer buf); template static T _lex_cast(const string_view &s); } @@ -276,8 +274,7 @@ template ircd::string_view ircd::_lex_cast(const T &i, - char *buf, - size_t max) + mutable_buffer buf) try { using array = std::array; @@ -285,14 +282,13 @@ try if(!buf) { buf = lex_cast_buf[lex_cast_cur++]; - max = LEX_CAST_BUFSIZE; lex_cast_cur %= LEX_CAST_BUFS; } - assert(max >= N); - auto &a(*reinterpret_cast(buf)); + assert(size(buf) >= N); + auto &a(*reinterpret_cast(data(buf))); a = boost::lexical_cast(i); - return { buf, strnlen(buf, max) }; + return { data(buf), strnlen(data(buf), size(buf)) }; } catch(const boost::bad_lexical_cast &e) { @@ -315,101 +311,122 @@ catch(const boost::bad_lexical_cast &e) template<> ircd::string_view ircd::lex_cast(bool i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(8); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(int8_t i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(8); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(uint8_t i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(8); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(short i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(8); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(ushort i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(8); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(int i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(16); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(uint i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(16); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(long i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(32); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(ulong i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(32); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(double i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(64); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); } template<> ircd::string_view ircd::lex_cast(long double i, - char *const &buf, - const size_t &max) + const mutable_buffer &buf) { static const size_t MAX(64); - return _lex_cast(i, buf, max); + return _lex_cast(i, buf); +} + +template<> ircd::string_view +ircd::lex_cast(nanoseconds i, + const mutable_buffer &buf) +{ + static const size_t MAX(64); + return _lex_cast(i.count(), buf); +} + +template<> ircd::string_view +ircd::lex_cast(microseconds i, + const mutable_buffer &buf) +{ + static const size_t MAX(64); + return _lex_cast(i.count(), buf); +} + +template<> ircd::string_view +ircd::lex_cast(milliseconds i, + const mutable_buffer &buf) +{ + static const size_t MAX(64); + return _lex_cast(i.count(), buf); +} + +template<> ircd::string_view +ircd::lex_cast(seconds i, + const mutable_buffer &buf) +{ + static const size_t MAX(64); + return _lex_cast(i.count(), buf); } template<> bool @@ -480,6 +497,30 @@ ircd::lex_cast(const string_view &s) return _lex_cast(s); } +template<> ircd::nanoseconds +ircd::lex_cast(const string_view &s) +{ + return std::chrono::duration>(_lex_cast(s)); +} + +template<> ircd::microseconds +ircd::lex_cast(const string_view &s) +{ + return std::chrono::duration>(_lex_cast(s)); +} + +template<> ircd::milliseconds +ircd::lex_cast(const string_view &s) +{ + return std::chrono::duration>(_lex_cast(s)); +} + +template<> ircd::seconds +ircd::lex_cast(const string_view &s) +{ + return std::chrono::duration>(_lex_cast(s)); +} + template<> bool ircd::try_lex_cast(const string_view &s) { @@ -557,6 +598,34 @@ ircd::try_lex_cast(const string_view &s) return boost::conversion::try_lexical_convert(s, i); } +template<> bool +ircd::try_lex_cast(const string_view &s) +{ + time_t i; //TODO: XXX + return boost::conversion::try_lexical_convert(s, i); +} + +template<> bool +ircd::try_lex_cast(const string_view &s) +{ + time_t i; //TODO: XXX + return boost::conversion::try_lexical_convert(s, i); +} + +template<> bool +ircd::try_lex_cast(const string_view &s) +{ + time_t i; //TODO: XXX + return boost::conversion::try_lexical_convert(s, i); +} + +template<> bool +ircd::try_lex_cast(const string_view &s) +{ + time_t i; //TODO: XXX + return boost::conversion::try_lexical_convert(s, i); +} + /////////////////////////////////////////////////////////////////////////////// // // ircd/stringops.h