0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2025-01-14 00:34:18 +01:00

ircd: Add std::chrono lex_cast; cleanup lex_cast buffer argument related.

This commit is contained in:
Jason Volk 2017-10-17 00:41:51 -07:00
parent 0be93870ea
commit cdcd2e2fb9
2 changed files with 155 additions and 78 deletions

View file

@ -38,7 +38,7 @@ namespace ircd
template<class T> T lex_cast(const string_view &); template<class T> T lex_cast(const string_view &);
// User supplied destination buffer // User supplied destination buffer
template<class T> string_view lex_cast(T, char *const &buf, const size_t &max); template<class T> string_view lex_cast(T, const mutable_buffer &buf);
// Circular static thread_local buffer // Circular static thread_local buffer
const size_t LEX_CAST_BUFS {256}; // plenty const size_t LEX_CAST_BUFS {256}; // plenty
@ -77,6 +77,10 @@ namespace ircd
template<> bool try_lex_cast<uint8_t>(const string_view &); template<> bool try_lex_cast<uint8_t>(const string_view &);
template<> bool try_lex_cast<int8_t>(const string_view &); template<> bool try_lex_cast<int8_t>(const string_view &);
template<> bool try_lex_cast<bool>(const string_view &); template<> bool try_lex_cast<bool>(const string_view &);
template<> bool try_lex_cast<seconds>(const string_view &);
template<> bool try_lex_cast<milliseconds>(const string_view &);
template<> bool try_lex_cast<microseconds>(const string_view &);
template<> bool try_lex_cast<nanoseconds>(const string_view &);
template<> std::string &lex_cast(std::string &); // trivial template<> std::string &lex_cast(std::string &); // trivial
template<> std::string lex_cast(const 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<> uint8_t lex_cast(const string_view &);
template<> int8_t lex_cast(const string_view &); template<> int8_t lex_cast(const string_view &);
template<> bool 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 &, const mutable_buffer &buf);
template<> string_view lex_cast(const std::string_view &, char *const &buf, const size_t &max); template<> string_view lex_cast(const std::string_view &, const mutable_buffer &buf);
template<> string_view lex_cast(const string_view &, char *const &buf, const size_t &max); template<> string_view lex_cast(const string_view &, const mutable_buffer &buf);
template<> string_view lex_cast(long double, char *const &buf, const size_t &max); template<> string_view lex_cast(seconds, const mutable_buffer &buf);
template<> string_view lex_cast(double, char *const &buf, const size_t &max); template<> string_view lex_cast(milliseconds, const mutable_buffer &buf);
template<> string_view lex_cast(ulong, char *const &buf, const size_t &max); template<> string_view lex_cast(microseconds, const mutable_buffer &buf);
template<> string_view lex_cast(long, char *const &buf, const size_t &max); template<> string_view lex_cast(nanoseconds, const mutable_buffer &buf);
template<> string_view lex_cast(uint, char *const &buf, const size_t &max); template<> string_view lex_cast(long double, const mutable_buffer &buf);
template<> string_view lex_cast(int, char *const &buf, const size_t &max); template<> string_view lex_cast(double, const mutable_buffer &buf);
template<> string_view lex_cast(ushort, char *const &buf, const size_t &max); template<> string_view lex_cast(ulong, const mutable_buffer &buf);
template<> string_view lex_cast(short, char *const &buf, const size_t &max); template<> string_view lex_cast(long, const mutable_buffer &buf);
template<> string_view lex_cast(uint8_t, char *const &buf, const size_t &max); template<> string_view lex_cast(uint, const mutable_buffer &buf);
template<> string_view lex_cast(int8_t, char *const &buf, const size_t &max); template<> string_view lex_cast(int, const mutable_buffer &buf);
template<> string_view lex_cast(bool, char *const &buf, const size_t &max); 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 /// Convert a native number to a string. The returned value is a view of the
@ -117,7 +129,7 @@ template<class T>
ircd::string_view ircd::string_view
ircd::lex_cast(const T &t) ircd::lex_cast(const T &t)
{ {
return lex_cast<T>(t, nullptr, 0); return lex_cast<T>(t, null_buffer);
} }
/// Conversion to an std::string creates a copy when the input is a /// Conversion to an std::string creates a copy when the input is a
@ -192,11 +204,10 @@ template<>
__attribute__((warning("unnecessary lexical cast"))) __attribute__((warning("unnecessary lexical cast")))
inline ircd::string_view inline ircd::string_view
ircd::lex_cast(const string_view &s, ircd::lex_cast(const string_view &s,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
s.copy(buf, max); s.copy(data(buf), size(buf));
return { buf, max }; return { data(buf), s.size() };
} }
/// Specialization of a string to string conversion to user's buffer; /// Specialization of a string to string conversion to user's buffer;
@ -206,11 +217,10 @@ template<>
__attribute__((warning("unnecessary lexical cast"))) __attribute__((warning("unnecessary lexical cast")))
inline ircd::string_view inline ircd::string_view
ircd::lex_cast(const std::string_view &s, ircd::lex_cast(const std::string_view &s,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
s.copy(buf, max); s.copy(data(buf), size(buf));
return { buf, max }; return { data(buf), s.size() };
} }
/// Specialization of a string to string conversion to user's buffer; /// Specialization of a string to string conversion to user's buffer;
@ -220,11 +230,10 @@ template<>
__attribute__((warning("unnecessary lexical cast"))) __attribute__((warning("unnecessary lexical cast")))
inline ircd::string_view inline ircd::string_view
ircd::lex_cast(const std::string &s, ircd::lex_cast(const std::string &s,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
s.copy(buf, max); s.copy(data(buf), size(buf));
return { buf, max }; return { data(buf), s.size() };
} }
/// Template basis; if no specialization is matched there is no fallback here /// Template basis; if no specialization is matched there is no fallback here
@ -232,8 +241,7 @@ template<class T>
__attribute__((error("unsupported lexical cast"))) __attribute__((error("unsupported lexical cast")))
ircd::string_view ircd::string_view
ircd::lex_cast(T t, ircd::lex_cast(T t,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
assert(0); assert(0);
return {}; return {};

View file

@ -161,23 +161,21 @@ ircd::token_count(const string_view &str,
size_t size_t
ircd::tokens(const string_view &str, ircd::tokens(const string_view &str,
const char &sep, const char &sep,
char *const &buf, const mutable_buffer &buf,
const size_t &max,
const token_view &closure) const token_view &closure)
{ {
const char ssep[2] { sep, '\0' }; const char ssep[2] { sep, '\0' };
return tokens(str, ssep, buf, max, closure); return tokens(str, ssep, buf, closure);
} }
size_t size_t
ircd::tokens(const string_view &str, ircd::tokens(const string_view &str,
const char *const &sep, const char *const &sep,
char *const &buf, const mutable_buffer &buf,
const size_t &max,
const token_view &closure) const token_view &closure)
{ {
char *ptr(buf); char *ptr(data(buf));
char *const stop(buf + max); char *const stop(data(buf) + size(buf));
tokens(str, sep, [&closure, &ptr, &stop] tokens(str, sep, [&closure, &ptr, &stop]
(const string_view &token) (const string_view &token)
{ {
@ -191,7 +189,7 @@ ircd::tokens(const string_view &str,
closure(string_view(dest, token.size())); closure(string_view(dest, token.size()));
}); });
return std::distance(buf, ptr); return std::distance(data(buf), ptr);
} }
size_t size_t
@ -266,7 +264,7 @@ namespace ircd
thread_local char lex_cast_buf[LEX_CAST_BUFS][LEX_CAST_BUFSIZE]; thread_local char lex_cast_buf[LEX_CAST_BUFS][LEX_CAST_BUFSIZE];
thread_local uint lex_cast_cur; thread_local uint lex_cast_cur;
template<size_t N, class T> static string_view _lex_cast(const T &i, char *buf, size_t max); template<size_t N, class T> static string_view _lex_cast(const T &i, mutable_buffer buf);
template<class T> static T _lex_cast(const string_view &s); template<class T> static T _lex_cast(const string_view &s);
} }
@ -276,8 +274,7 @@ template<size_t N,
class T> class T>
ircd::string_view ircd::string_view
ircd::_lex_cast(const T &i, ircd::_lex_cast(const T &i,
char *buf, mutable_buffer buf)
size_t max)
try try
{ {
using array = std::array<char, N>; using array = std::array<char, N>;
@ -285,14 +282,13 @@ try
if(!buf) if(!buf)
{ {
buf = lex_cast_buf[lex_cast_cur++]; buf = lex_cast_buf[lex_cast_cur++];
max = LEX_CAST_BUFSIZE;
lex_cast_cur %= LEX_CAST_BUFS; lex_cast_cur %= LEX_CAST_BUFS;
} }
assert(max >= N); assert(size(buf) >= N);
auto &a(*reinterpret_cast<array *>(buf)); auto &a(*reinterpret_cast<array *>(data(buf)));
a = boost::lexical_cast<array>(i); a = boost::lexical_cast<array>(i);
return { buf, strnlen(buf, max) }; return { data(buf), strnlen(data(buf), size(buf)) };
} }
catch(const boost::bad_lexical_cast &e) catch(const boost::bad_lexical_cast &e)
{ {
@ -315,101 +311,122 @@ catch(const boost::bad_lexical_cast &e)
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(bool i, ircd::lex_cast(bool i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(8); static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(int8_t i, ircd::lex_cast(int8_t i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(8); static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(uint8_t i, ircd::lex_cast(uint8_t i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(8); static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(short i, ircd::lex_cast(short i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(8); static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(ushort i, ircd::lex_cast(ushort i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(8); static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(int i, ircd::lex_cast(int i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(16); static const size_t MAX(16);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(uint i, ircd::lex_cast(uint i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(16); static const size_t MAX(16);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(long i, ircd::lex_cast(long i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(32); static const size_t MAX(32);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(ulong i, ircd::lex_cast(ulong i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(32); static const size_t MAX(32);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(double i, ircd::lex_cast(double i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(64); static const size_t MAX(64);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
} }
template<> ircd::string_view template<> ircd::string_view
ircd::lex_cast(long double i, ircd::lex_cast(long double i,
char *const &buf, const mutable_buffer &buf)
const size_t &max)
{ {
static const size_t MAX(64); static const size_t MAX(64);
return _lex_cast<MAX>(i, buf, max); return _lex_cast<MAX>(i, buf);
}
template<> ircd::string_view
ircd::lex_cast(nanoseconds i,
const mutable_buffer &buf)
{
static const size_t MAX(64);
return _lex_cast<MAX>(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<MAX>(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<MAX>(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<MAX>(i.count(), buf);
} }
template<> bool template<> bool
@ -480,6 +497,30 @@ ircd::lex_cast(const string_view &s)
return _lex_cast<long double>(s); return _lex_cast<long double>(s);
} }
template<> ircd::nanoseconds
ircd::lex_cast(const string_view &s)
{
return std::chrono::duration<time_t, std::ratio<1L, 1000000000L>>(_lex_cast<time_t>(s));
}
template<> ircd::microseconds
ircd::lex_cast(const string_view &s)
{
return std::chrono::duration<time_t, std::ratio<1L, 1000000L>>(_lex_cast<time_t>(s));
}
template<> ircd::milliseconds
ircd::lex_cast(const string_view &s)
{
return std::chrono::duration<time_t, std::ratio<1L, 1000L>>(_lex_cast<time_t>(s));
}
template<> ircd::seconds
ircd::lex_cast(const string_view &s)
{
return std::chrono::duration<time_t, std::ratio<1L, 1L>>(_lex_cast<time_t>(s));
}
template<> bool template<> bool
ircd::try_lex_cast<bool>(const string_view &s) ircd::try_lex_cast<bool>(const string_view &s)
{ {
@ -557,6 +598,34 @@ ircd::try_lex_cast<long double>(const string_view &s)
return boost::conversion::try_lexical_convert(s, i); return boost::conversion::try_lexical_convert(s, i);
} }
template<> bool
ircd::try_lex_cast<ircd::nanoseconds>(const string_view &s)
{
time_t i; //TODO: XXX
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<ircd::microseconds>(const string_view &s)
{
time_t i; //TODO: XXX
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<ircd::milliseconds>(const string_view &s)
{
time_t i; //TODO: XXX
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<ircd::seconds>(const string_view &s)
{
time_t i; //TODO: XXX
return boost::conversion::try_lexical_convert(s, i);
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// ircd/stringops.h // ircd/stringops.h