mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-06 01:22:41 +00:00
[libcxx][span] Implement solution to LWG-3255
This implements the relaxed requirements on the std::array constructors of span, where the type only needs to be convertible to the element type of the span. Note that the previous tests were not sufficient, as the const array<T, n> constructor was only tested for compile time and the array<T, N> only during runtime. Restructure the tests so that we can test conversions as well as both constructors. Differential Revision: https://reviews.llvm.org/D75706
This commit is contained in:
parent
ce4ebc14a8
commit
ab9f11168f
@ -212,8 +212,16 @@ public:
|
||||
{ (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {}
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr span( array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
|
||||
|
||||
template <class _OtherElementType,
|
||||
enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
|
||||
|
||||
template <class _OtherElementType,
|
||||
enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
|
||||
|
||||
template <class _Container>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@ -386,13 +394,15 @@ public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {}
|
||||
|
||||
template <size_t _Sz>
|
||||
template <class _OtherElementType, size_t _Sz,
|
||||
enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
|
||||
constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
|
||||
|
||||
template <size_t _Sz>
|
||||
template <class _OtherElementType, size_t _Sz,
|
||||
enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
|
||||
constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
|
||||
|
||||
template <class _Container>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
@ -68,49 +68,58 @@ void checkCV()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
constexpr bool testConstexprSpan()
|
||||
template <typename T, typename U = T>
|
||||
constexpr bool testConstructorArray()
|
||||
{
|
||||
constexpr std::array<T,2> val = { T(), T() };
|
||||
ASSERT_NOEXCEPT(std::span<const T> {val});
|
||||
ASSERT_NOEXCEPT(std::span<const T, 2>{val});
|
||||
std::span<const T> s1{val};
|
||||
std::span<const T, 2> s2{val};
|
||||
return
|
||||
s1.data() == &val[0] && s1.size() == 2
|
||||
&& s2.data() == &val[0] && s2.size() == 2;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void testRuntimeSpan()
|
||||
{
|
||||
std::array<T,2> val;
|
||||
std::array<U,2> val = { U(), U() };
|
||||
ASSERT_NOEXCEPT(std::span<T> {val});
|
||||
ASSERT_NOEXCEPT(std::span<T, 2>{val});
|
||||
std::span<T> s1{val};
|
||||
std::span<T, 2> s2{val};
|
||||
assert(s1.data() == &val[0] && s1.size() == 2);
|
||||
assert(s2.data() == &val[0] && s2.size() == 2);
|
||||
return s1.data() == &val[0] && s1.size() == 2
|
||||
&& s2.data() == &val[0] && s2.size() == 2;
|
||||
}
|
||||
|
||||
template <typename T, typename U = T>
|
||||
constexpr bool testConstructorConstArray()
|
||||
{
|
||||
const std::array<U,2> val = { U(), U() };
|
||||
ASSERT_NOEXCEPT(std::span<const T> {val});
|
||||
ASSERT_NOEXCEPT(std::span<const T, 2>{val});
|
||||
std::span<const T> s1{val};
|
||||
std::span<const T, 2> s2{val};
|
||||
return s1.data() == &val[0] && s1.size() == 2
|
||||
&& s2.data() == &val[0] && s2.size() == 2;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool testConstructors() {
|
||||
static_assert(testConstructorArray<T>(), "");
|
||||
static_assert(testConstructorArray<const T, T>(), "");
|
||||
static_assert(testConstructorConstArray<T>(), "");
|
||||
static_assert(testConstructorConstArray<const T, T>(), "");
|
||||
|
||||
return testConstructorArray<T>()
|
||||
&& testConstructorArray<const T, T>()
|
||||
&& testConstructorConstArray<T>()
|
||||
&& testConstructorConstArray<const T, T>();
|
||||
}
|
||||
|
||||
struct A{};
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
static_assert(testConstexprSpan<int>(), "");
|
||||
static_assert(testConstexprSpan<long>(), "");
|
||||
static_assert(testConstexprSpan<double>(), "");
|
||||
static_assert(testConstexprSpan<A>(), "");
|
||||
assert(testConstructors<int>());
|
||||
assert(testConstructors<long>());
|
||||
assert(testConstructors<double>());
|
||||
assert(testConstructors<A>());
|
||||
|
||||
testRuntimeSpan<int>();
|
||||
testRuntimeSpan<long>();
|
||||
testRuntimeSpan<double>();
|
||||
testRuntimeSpan<std::string>();
|
||||
testRuntimeSpan<A>();
|
||||
assert(testConstructors<int*>());
|
||||
assert(testConstructors<int* const>());
|
||||
assert(testConstructors<const int*>());
|
||||
assert(testConstructors<const int* const>());
|
||||
|
||||
checkCV();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -490,7 +490,7 @@
|
||||
<tr><td><a href="https://wg21.link/LWG3251">3251</a></td><td>Are <tt>std::format</tt> alignment specifiers applied to string arguments?</td><td>Prague</td><td></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG3252">3252</a></td><td>Parse locale's aware modifiers for commands are not consistent with POSIX spec</td><td>Prague</td><td></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG3254">3254</a></td><td>Strike <tt>stop_token</tt>'s <tt>operator!=</tt></td><td>Prague</td><td></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG3255">3255</a></td><td><tt>span</tt>'s <tt>array</tt> constructor is too strict</td><td>Prague</td><td></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG3255">3255</a></td><td><tt>span</tt>'s <tt>array</tt> constructor is too strict</td><td>Prague</td><td>Complete</td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG3260">3260</a></td><td><tt>year_month*</tt> arithmetic rejects durations convertible to years</td><td>Prague</td><td></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG3262">3262</a></td><td>Formatting of negative durations is not specified</td><td>Prague</td><td></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG3264">3264</a></td><td><tt>sized_range</tt> and <tt>ranges::size</tt> redundantly use <tt>disable_sized_range</tt></td><td>Prague</td><td></td></tr>
|
||||
|
Loading…
x
Reference in New Issue
Block a user