diff --git a/lib/include/srslte/adt/span.h b/lib/include/srslte/adt/span.h index 0ea409a78..0749b8b5b 100644 --- a/lib/include/srslte/adt/span.h +++ b/lib/include/srslte/adt/span.h @@ -31,55 +31,63 @@ namespace srslte { +template +class span; + +namespace detail { + +/// Helper traits used by SFINAE expressions in constructors. + +template +struct make_void { + typedef void type; +}; + +template +using void_t = typename make_void::type; + +template +struct is_span : std::false_type {}; +template +struct is_span > : std::true_type {}; + +template +struct is_std_array : std::false_type {}; +template +struct is_std_array > : std::true_type {}; + +template +using remove_cvref_t = typename std::remove_cv::type>::type; + +template +struct is_container_compatible : public std::false_type {}; +template +struct is_container_compatible< + Container, + U, + void_t< + // Check if the container type has data and size members. + decltype(std::declval().data()), + decltype(std::declval().size()), + // Container should not be a span. + typename std::enable_if >::value, int>::type, + // Container should not be a std::array. + typename std::enable_if >::value, int>::type, + // Container should not be an array. + typename std::enable_if >::value, int>::type, + // Check type compatibility between the contained type and the span type. + typename std::enable_if< + std::is_convertible().data())>::type (*)[], + U (*)[]>::value, + int>::type> > : public std::true_type {}; + +} // namespace detail + /// The class template span describes an object that can refer to a contiguous sequence of objects with the first /// element of the sequence at position zero. template class span { - /// Helper traits used by SFINAE expressions in constructors. - - template - struct make_void { - typedef void type; - }; - template - using void_t = typename make_void::type; - - template - struct is_span : std::false_type {}; - template - struct is_span > : std::true_type {}; - - template - struct is_std_array : std::false_type {}; - template - struct is_std_array > : std::true_type {}; - - template - using remove_cvref_t = typename std::remove_cv::type>::type; - - template - struct is_container_compatible : public std::false_type {}; - template - struct is_container_compatible< - Container, - U, - void_t< - // Check if the container type has data and size members. - decltype(std::declval().data()), - decltype(std::declval().size()), - // Container should not be a span. - typename std::enable_if >::value, int>::type, - // Container should not be a std::array. - typename std::enable_if >::value, int>::type, - // Container should not be an array. - typename std::enable_if >::value, int>::type, - // Check type compatibility between the contained type and the span type. - typename std::enable_if< - std::is_convertible().data())>::type (*)[], - U (*)[]>::value, - int>::type> > : public std::true_type {}; - public: /// Member types. using element_type = T; @@ -123,13 +131,14 @@ public: /// Constructs a span that is a view over the container c. template ::value, int>::type = 0> + typename std::enable_if::value, int>::type = 0> constexpr span(Container& c) noexcept : ptr(c.data()), len(c.size()) {} /// Constructs a span that is a view over the container c. - template ::value, int>::type = 0> + template < + typename Container, + typename std::enable_if::value, int>::type = 0> constexpr span(const Container& c) noexcept : ptr(c.data()), len(c.size()) {}