mirror of
https://github.com/matrix-construct/construct
synced 2024-06-02 18:18:56 +02:00
fixup! ircd: Add the va_rtti construct.
This commit is contained in:
parent
9c137d7c50
commit
fa1c393d7a
|
@ -35,7 +35,8 @@ IRCD_EXCEPTION(error, illegal);
|
|||
//
|
||||
extern const char SPECIFIER;
|
||||
extern const char SPECIFIER_TERMINATOR;
|
||||
using arg = std::tuple<const void *const &, const std::type_index &>;
|
||||
|
||||
using arg = std::tuple<const void *, std::type_index>;
|
||||
|
||||
// Structural representation of a format specifier
|
||||
struct spec
|
||||
|
@ -94,14 +95,27 @@ class snprintf
|
|||
public:
|
||||
operator ssize_t() const { return consumed(); }
|
||||
|
||||
template<class... A>
|
||||
template<class... Args>
|
||||
snprintf(char *const &buf,
|
||||
const size_t &max,
|
||||
const char *const &fmt,
|
||||
A&&... args)
|
||||
Args&&... args)
|
||||
:snprintf
|
||||
{
|
||||
internal, buf, max, fmt, va_rtti{std::forward<A>(args)...}
|
||||
internal, buf, max, fmt, va_rtti(args...)
|
||||
}{}
|
||||
};
|
||||
|
||||
struct vsnprintf
|
||||
:snprintf
|
||||
{
|
||||
vsnprintf(char *const &buf,
|
||||
const size_t &max,
|
||||
const char *const &fmt,
|
||||
const va_rtti &ap)
|
||||
:snprintf
|
||||
{
|
||||
internal, buf, max, fmt, ap
|
||||
}{}
|
||||
};
|
||||
|
||||
|
|
|
@ -504,18 +504,25 @@ syscall(function&& f,
|
|||
|
||||
|
||||
struct va_rtti
|
||||
:std::tuple<std::initializer_list<const void *>,
|
||||
std::initializer_list<std::type_index>>
|
||||
:std::array<std::pair<const void *, const std::type_info *>, 8>
|
||||
{
|
||||
size_t argc;
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return argc;
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
va_rtti(Args&&... args)
|
||||
:std::tuple<std::initializer_list<const void *>,
|
||||
std::initializer_list<std::type_index>>
|
||||
:std::array<std::pair<const void *, const std::type_info *>, 8>
|
||||
{{
|
||||
std::make_pair(std::addressof(args), std::addressof(typeid(Args)))...
|
||||
}}
|
||||
,argc
|
||||
{
|
||||
{ std::addressof(args)... },
|
||||
{ typeid(Args)... },
|
||||
}
|
||||
{}
|
||||
sizeof...(args)
|
||||
}{}
|
||||
};
|
||||
|
||||
|
||||
|
|
42
ircd/fmt.cc
42
ircd/fmt.cc
|
@ -208,9 +208,6 @@ try
|
|||
,out{out}
|
||||
,idx{0}
|
||||
{
|
||||
const auto &ptrs(get<0>(v));
|
||||
const auto &types(get<1>(v));
|
||||
|
||||
if(unlikely(!max))
|
||||
{
|
||||
fstart = nullptr;
|
||||
|
@ -224,15 +221,18 @@ try
|
|||
}
|
||||
|
||||
append(fstr, fstart);
|
||||
auto itp(begin(ptrs));
|
||||
auto itt(begin(types));
|
||||
for(; itp != end(ptrs); ++itp, ++itt)
|
||||
argument(arg{*itp, *itt});
|
||||
|
||||
auto it(begin(v));
|
||||
for(size_t i(0); i < v.size(); ++it, i++)
|
||||
{
|
||||
const auto &ptr(get<0>(*it));
|
||||
const auto &type(get<1>(*it));
|
||||
argument(std::make_tuple(ptr, std::type_index(*type)));
|
||||
}
|
||||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
throw invalid_format("Format string requires more than %zu arguments.",
|
||||
get<0>(v).size());
|
||||
throw invalid_format("Format string requires more than %zu arguments.", v.size());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -283,7 +283,7 @@ fmt::specifier::specifier(const std::initializer_list<std::string> &names)
|
|||
if(is_specifier(name))
|
||||
throw error("Specifier '%c%s' already registered\n",
|
||||
SPECIFIER,
|
||||
name.c_str());
|
||||
name);
|
||||
|
||||
for(const auto &name : this->names)
|
||||
_specifiers.emplace(name, this);
|
||||
|
@ -316,21 +316,21 @@ try
|
|||
throw invalid_type("`%s' for format specifier '%c%s' for argument #%u",
|
||||
type.name(),
|
||||
SPECIFIER,
|
||||
std::string(spec.name).c_str(),
|
||||
spec.name,
|
||||
idx);
|
||||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
throw invalid_format("Unhandled specifier `%c%s' for argument #%u in format string",
|
||||
SPECIFIER,
|
||||
std::string(spec.name).c_str(),
|
||||
spec.name,
|
||||
idx);
|
||||
}
|
||||
catch(const illegal &e)
|
||||
{
|
||||
throw illegal("Specifier `%c%s' for argument #%u: %s",
|
||||
SPECIFIER,
|
||||
std::string(spec.name).c_str(),
|
||||
spec.name,
|
||||
idx,
|
||||
e.what());
|
||||
}
|
||||
|
@ -483,15 +483,15 @@ const
|
|||
});
|
||||
|
||||
struct generator
|
||||
:karma::grammar<char *, string_view>
|
||||
:karma::grammar<char *, const string_view &>
|
||||
{
|
||||
karma::rule<char *, string_view> printable
|
||||
karma::rule<char *, const string_view &> string
|
||||
{
|
||||
*(~karma::ascii::cntrl)
|
||||
,"printable string"
|
||||
*(karma::print)
|
||||
,"string"
|
||||
};
|
||||
|
||||
generator() :generator::base_type{printable} {}
|
||||
generator() :generator::base_type{string} {}
|
||||
}
|
||||
static const generator;
|
||||
|
||||
|
@ -745,8 +745,8 @@ fmt::generate_string(char *&out,
|
|||
}
|
||||
else if(type == typeid(const char *))
|
||||
{
|
||||
const auto &str(*reinterpret_cast<const char *const *>(ptr));
|
||||
karma::generate(out, gen, str);
|
||||
const char *const str{*reinterpret_cast<const char *const *const>(ptr)};
|
||||
karma::generate(out, gen, string_view{str});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -755,5 +755,5 @@ fmt::generate_string(char *&out,
|
|||
// grammar will fail gracefully (most of the time) or not print something bogus when
|
||||
// it happens to be legal.
|
||||
const auto &str(reinterpret_cast<const char *>(ptr));
|
||||
return karma::generate(out, gen, str);
|
||||
return karma::generate(out, gen, string_view{str});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue