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:
parent
0be93870ea
commit
cdcd2e2fb9
2 changed files with 155 additions and 78 deletions
|
@ -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 {};
|
||||
|
|
165
ircd/lexical.cc
165
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<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
|
||||
|
|
Loading…
Reference in a new issue