view: prefer static_assert over SFINAE for extract

This produces more readable error messages, and we are not using
`extract` in a context where we need to disambiguate calls anyway.
This commit is contained in:
Danny Robson 2020-01-05 08:28:57 +11:00
parent cff7375cc1
commit 4bea2668c3

View File

@ -724,20 +724,24 @@ namespace cruft {
/// It is assumed the user has taken care of alignment concerns /// It is assumed the user has taken care of alignment concerns
template < template <
typename ValueT, typename ValueT,
typename WordT, typename WordT
typename = std::enable_if_t<
// Only allow calls if the value is a multiple of the word size.
// It's useful to allow non-unit words for areas like TCP/IP which
// tend to include protocols that utilise u16 words.
sizeof (ValueT) % sizeof (WordT) == 0 &&
// If WordT is const then ValueT must be const. Otherwise the user
// is free to choose.
std::is_const_v<WordT> ? std::is_const_v<ValueT> : true
>
> >
ValueT& ValueT&
extract (view<WordT*> &buffer) extract (view<WordT*> &buffer)
{ {
// Only allow calls if the value is a multiple of the word size.
// It's useful to allow non-unit words for areas like TCP/IP which
// tend to include protocols that utilise u16 words.
static_assert (
sizeof (ValueT) % sizeof (WordT) == 0,
"The value type must be a multiple of the word size"
);
static_assert (
!std::is_const_v<WordT> or std::is_const_v<ValueT>,
"buffer and output types must have matching constness"
);
if (unlikely (sizeof (ValueT) > buffer.size () * sizeof (WordT))) if (unlikely (sizeof (ValueT) > buffer.size () * sizeof (WordT)))
throw std::runtime_error ("insufficient data for extraction"); throw std::runtime_error ("insufficient data for extraction");