0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +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 &);
// 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
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<int8_t>(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(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<class T>
ircd::string_view
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
@ -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<class T>
__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 {};

View file

@ -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<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);
}
@ -276,8 +274,7 @@ template<size_t N,
class T>
ircd::string_view
ircd::_lex_cast(const T &i,
char *buf,
size_t max)
mutable_buffer buf)
try
{
using array = std::array<char, N>;
@ -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<array *>(buf));
assert(size(buf) >= N);
auto &a(*reinterpret_cast<array *>(data(buf)));
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)
{
@ -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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<MAX>(i, buf, max);
return _lex_cast<MAX>(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<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
@ -480,6 +497,30 @@ ircd::lex_cast(const string_view &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
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);
}
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