span support for initializer_list

This commit is contained in:
Glen Fernandes
2023-01-28 09:31:12 -05:00
parent 90231ed7e0
commit 7736b0b8ce
4 changed files with 69 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2019 Glen Joseph Fernandes Copyright 2019-2023 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_CORE_SPAN_HPP #define BOOST_CORE_SPAN_HPP
#include <array> #include <array>
#include <initializer_list>
#include <iterator> #include <iterator>
#include <type_traits> #include <type_traits>
#include <cstddef> #include <cstddef>
@@ -39,10 +40,8 @@ struct span_compatible {
}; };
template<class T> template<class T>
struct span_uncvref { using span_uncvref = typename std::remove_cv<typename
typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type;
std::remove_reference<T>::type>::type type;
};
template<class> template<class>
struct span_is_span { struct span_is_span {
@@ -64,15 +63,37 @@ struct span_is_array<std::array<T, N> > {
static constexpr bool value = true; static constexpr bool value = true;
}; };
template<class C>
inline constexpr auto
span_begin(C& c) noexcept(noexcept(c.data())) -> decltype(c.data())
{
return c.data();
}
template<class C>
inline constexpr auto
span_begin(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data())
{
return c.data();
}
template<class T>
inline constexpr const T*
span_begin(std::initializer_list<T> l) noexcept
{
return l.begin();
}
template<class T>
using span_ptr = decltype(boost::detail::span_begin(std::declval<T&>()));
template<class, class = void> template<class, class = void>
struct span_data { }; struct span_data { };
template<class T> template<class T>
struct span_data<T, struct span_data<T,
typename std::enable_if<std::is_pointer<decltype(std::declval<T typename std::enable_if<std::is_pointer<span_ptr<T> >::value>::type> {
&>().data())>::value>::type> { typedef typename std::remove_pointer<span_ptr<T> >::type type;
typedef typename std::remove_pointer<decltype(std::declval<T
&>().data())>::type type;
}; };
template<class, class, class = void> template<class, class, class = void>
@@ -102,9 +123,9 @@ template<class R, class T>
struct span_is_range { struct span_is_range {
static constexpr bool value = (std::is_const<T>::value || static constexpr bool value = (std::is_const<T>::value ||
std::is_lvalue_reference<R>::value) && std::is_lvalue_reference<R>::value) &&
!span_is_span<typename span_uncvref<R>::type>::value && !span_is_span<span_uncvref<R> >::value &&
!span_is_array<typename span_uncvref<R>::type>::value && !span_is_array<span_uncvref<R> >::value &&
!std::is_array<typename span_uncvref<R>::type>::value && !std::is_array<span_uncvref<R> >::value &&
span_has_data<R, T>::value && span_has_data<R, T>::value &&
span_has_size<R>::value; span_has_size<R>::value;
}; };
@@ -224,15 +245,16 @@ public:
template<class R, template<class R,
typename std::enable_if<E == dynamic_extent && typename std::enable_if<E == dynamic_extent &&
detail::span_is_range<R, T>::value, int>::type = 0> detail::span_is_range<R, T>::value, int>::type = 0>
constexpr span(R&& r) noexcept(noexcept(r.data()) && noexcept(r.size())) constexpr span(R&& r) noexcept(noexcept(detail::span_begin(r)) &&
: s_(r.data(), r.size()) { } noexcept(r.size()))
: s_(detail::span_begin(r), r.size()) { }
template<class R, template<class R,
typename std::enable_if<E != dynamic_extent && typename std::enable_if<E != dynamic_extent &&
detail::span_is_range<R, T>::value, int>::type = 0> detail::span_is_range<R, T>::value, int>::type = 0>
explicit constexpr span(R&& r) noexcept(noexcept(r.data()) && explicit constexpr span(R&& r) noexcept(noexcept(detail::span_begin(r)) &&
noexcept(r.size())) noexcept(r.size()))
: s_(r.data(), r.size()) { } : s_(detail::span_begin(r), r.size()) { }
template<class U, std::size_t N, template<class U, std::size_t N,
typename std::enable_if<detail::span_implicit<E, N>::value && typename std::enable_if<detail::span_implicit<E, N>::value &&

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2019 Glen Joseph Fernandes Copyright 2019-2023 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -140,6 +140,14 @@ void test_range()
range<derived>&>)); range<derived>&>));
} }
void test_initializer_list()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
std::initializer_list<int> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
std::initializer_list<int> >));
}
void test_span() void test_span()
{ {
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>, BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
@@ -187,6 +195,7 @@ int main()
test_std_array(); test_std_array();
test_const_std_array(); test_const_std_array();
test_range(); test_range();
test_initializer_list();
test_span(); test_span();
test_copy(); test_copy();
test_assign(); test_assign();

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2019 Glen Joseph Fernandes Copyright 2019-2023 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -78,6 +78,15 @@ void test_range()
BOOST_TEST_EQ(s.size(), c.size()); BOOST_TEST_EQ(s.size(), c.size());
} }
void test_initializer_list()
{
std::initializer_list<int> l{1, 2};
boost::span s(l);
BOOST_TEST_EQ(s.extent, boost::dynamic_extent);
BOOST_TEST_EQ(s.data(), l.begin());
BOOST_TEST_EQ(s.size(), l.size());
}
void test_span_dynamic() void test_span_dynamic()
{ {
int a[4]; int a[4];
@@ -104,6 +113,7 @@ int main()
test_std_array(); test_std_array();
test_const_std_array(); test_const_std_array();
test_range(); test_range();
test_initializer_list();
test_span_dynamic(); test_span_dynamic();
test_span_static(); test_span_static();
return boost::report_errors(); return boost::report_errors();

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2019 Glen Joseph Fernandes Copyright 2019-2023 Glen Joseph Fernandes
(glenjofe@gmail.com) (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
@@ -118,6 +118,14 @@ void test_construct_range()
BOOST_TEST_EQ(s.size(), c.size()); BOOST_TEST_EQ(s.size(), c.size());
} }
void test_construct_initializer_list()
{
std::initializer_list<int> l{1, 2};
boost::span<const int> s(l);
BOOST_TEST_EQ(s.data(), l.begin());
BOOST_TEST_EQ(s.size(), l.size());
}
void test_construct_span_dynamic() void test_construct_span_dynamic()
{ {
int a[4]; int a[4];
@@ -376,6 +384,7 @@ int main()
test_construct_const_std_array_dynamic(); test_construct_const_std_array_dynamic();
test_construct_const_std_array_static(); test_construct_const_std_array_static();
test_construct_range(); test_construct_range();
test_construct_initializer_list();
test_construct_span_dynamic(); test_construct_span_dynamic();
test_construct_span_dynamic_static(); test_construct_span_dynamic_static();
test_construct_span_static(); test_construct_span_static();