diff --git a/include/ircd/buffer/const_buffer.h b/include/ircd/buffer/const_buffer.h index ba741b534..bccb569f2 100644 --- a/include/ircd/buffer/const_buffer.h +++ b/include/ircd/buffer/const_buffer.h @@ -17,6 +17,10 @@ struct ircd::buffer::const_buffer // Definition for this is somewhere in the .cc files where boost is incl. operator boost::asio::const_buffer() const noexcept; + template + explicit operator const R *() const noexcept(!safety); + // For boost::spirit conceptual compliance; illegal/noop void insert(const char *const &, const char &); @@ -92,3 +96,17 @@ ircd::buffer::const_buffer::insert(const char *const &, assert(0); __builtin_unreachable(); } + +template +inline ircd::buffer::const_buffer::operator +const R *() +const noexcept(!safety) +{ + assert(sizeof(R) <= size(*this)); + if constexpr(safety) + if(unlikely(sizeof(R) > size(*this))) + throw std::bad_cast{}; + + return reinterpret_cast(data(*this)); +} diff --git a/include/ircd/buffer/mutable_buffer.h b/include/ircd/buffer/mutable_buffer.h index 3195b892a..49e8a61c4 100644 --- a/include/ircd/buffer/mutable_buffer.h +++ b/include/ircd/buffer/mutable_buffer.h @@ -21,6 +21,10 @@ struct ircd::buffer::mutable_buffer /// Conversion offered for the analogous asio buffer. operator boost::asio::mutable_buffer() const noexcept; + template + explicit operator R *() const noexcept(!safety); + /// Allows boost::spirit to append to the buffer; this means the size() of /// this buffer becomes a consumption counter and the real size of the buffer /// must be kept separately. This is the lowlevel basis for a stream buffer. @@ -86,3 +90,16 @@ ircd::buffer::mutable_buffer::insert(char *const &it, ++std::get<1>(*this); } +template +inline ircd::buffer::mutable_buffer::operator +R *() +const noexcept(!safety) +{ + assert(sizeof(R) <= size(*this)); + if constexpr(safety) + if(unlikely(sizeof(R) > size(*this))) + throw std::bad_cast{}; + + return reinterpret_cast(data(*this)); +}