[libcxx-commits] [libcxx] r354988 - Implment the last part of P1024: tuple-like interface to span. Reviewed as https://reviews.llvm.org/D58706.

Marshall Clow via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 27 07:41:38 PST 2019


Author: marshall
Date: Wed Feb 27 07:41:37 2019
New Revision: 354988

URL: http://llvm.org/viewvc/llvm-project?rev=354988&view=rev
Log:
Implment the last part of P1024: tuple-like interface to span. Reviewed as https://reviews.llvm.org/D58706.

Added:
    libcxx/trunk/test/std/containers/views/span.tuple/
    libcxx/trunk/test/std/containers/views/span.tuple/get.fail.cpp
    libcxx/trunk/test/std/containers/views/span.tuple/get.pass.cpp
    libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.fail.cpp
    libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.pass.cpp
    libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.fail.cpp
    libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.pass.cpp
Modified:
    libcxx/trunk/include/span
    libcxx/trunk/www/cxx2a_status.html

Modified: libcxx/trunk/include/span
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/span?rev=354988&r1=354987&r2=354988&view=diff
==============================================================================
--- libcxx/trunk/include/span (original)
+++ libcxx/trunk/include/span Wed Feb 27 07:41:37 2019
@@ -522,20 +522,52 @@ private:
     index_type __size;
 };
 
+//  tuple interface
+template <class _Tp, size_t _Size>
+struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, _Size>>
+    : public integral_constant<size_t, _Size> {};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, dynamic_extent>>; // declared but not defined
+
+
+template <size_t _Ip, class _Tp, size_t _Size>
+class _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, span<_Tp, _Size>>
+{
+    static_assert( dynamic_extent != _Size, "std::tuple_element<> not supported for std::span<T, dynamic_extent>");
+    static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::span)");
+public:
+    typedef _Tp type;
+};
+
+template <size_t _Ip, class _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY constexpr
+_Tp&
+get(span<_Tp, _Size> __s) noexcept
+{
+    static_assert( dynamic_extent != _Size, "std::get<> not supported for std::span<T, dynamic_extent>");
+    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::span)");
+    return __s[_Ip];
+}
+
+
 //  as_bytes & as_writeable_bytes
 template <class _Tp, size_t _Extent>
-    auto as_bytes(span<_Tp, _Extent> __s) noexcept
-    -> decltype(__s.__as_bytes())
-    { return __s.__as_bytes(); }
+_LIBCPP_INLINE_VISIBILITY
+auto as_bytes(span<_Tp, _Extent> __s) noexcept
+-> decltype(__s.__as_bytes())
+{ return    __s.__as_bytes(); }
 
 template <class _Tp, size_t _Extent>
-    auto as_writeable_bytes(span<_Tp, _Extent> __s) noexcept
-    -> typename enable_if<!is_const_v<_Tp>, decltype(__s.__as_writeable_bytes())>::type
-    { return __s.__as_writeable_bytes(); }
+_LIBCPP_INLINE_VISIBILITY
+auto as_writeable_bytes(span<_Tp, _Extent> __s) noexcept
+-> typename enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writeable_bytes())>
+{ return __s.__as_writeable_bytes(); }
 
 template <class _Tp, size_t _Extent>
-    constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept
-    { __lhs.swap(__rhs); }
+_LIBCPP_INLINE_VISIBILITY
+constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept
+{ __lhs.swap(__rhs); }
 
 
 //  Deduction guides

Added: libcxx/trunk/test/std/containers/views/span.tuple/get.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/views/span.tuple/get.fail.cpp?rev=354988&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/views/span.tuple/get.fail.cpp (added)
+++ libcxx/trunk/test/std/containers/views/span.tuple/get.fail.cpp Wed Feb 27 07:41:37 2019
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <span>
+
+// template <size_t _Ip, ElementType, size_t Extent>
+//   constexpr ElementType& get(span<ElementType, Extent> s) noexcept;
+
+#include <span>
+
+#include "test_macros.h"
+
+
+int main(int, char**)
+{
+//  No get for dynamic spans
+    constexpr int arr [] = {0,1,2,3,4,5,6,7,8,9};
+    (void) std::get< 0>(std::span<const int,  0>(arr, (size_t)0)); // expected-error-re at span:* {{static_assert failed{{( due to requirement '.*')?}} "Index out of bounds in std::get<> (std::span)"}}
+    (void) std::get< 5>(std::span<const int,  5>(arr,         5)); // expected-error-re at span:* {{static_assert failed{{( due to requirement '.*')?}} "Index out of bounds in std::get<> (std::span)"}}
+    (void) std::get<20>(std::span<const int, 10>(arr,        10)); // expected-error-re at span:* {{static_assert failed{{( due to requirement '.*')?}} "Index out of bounds in std::get<> (std::span)"}}
+
+  return 0;
+}

Added: libcxx/trunk/test/std/containers/views/span.tuple/get.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/views/span.tuple/get.pass.cpp?rev=354988&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/views/span.tuple/get.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/views/span.tuple/get.pass.cpp Wed Feb 27 07:41:37 2019
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+//===------------------------------ span ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <span>
+
+// template <size_t _Ip, ElementType, size_t Extent>
+//   constexpr ElementType& get(span<ElementType, Extent> s) noexcept;
+//
+
+
+#include <span>
+#include <cassert>
+#include <string>
+
+#include "test_macros.h"
+
+
+template <size_t Idx, typename Span>
+constexpr bool testConstexprSpan(Span sp, typename Span::pointer ptr)
+{
+    ASSERT_NOEXCEPT(std::get<Idx>(sp));
+    return std::addressof(std::get<Idx>(sp)) == ptr;
+}
+
+
+template <size_t Idx, typename Span>
+void testRuntimeSpan(Span sp, typename Span::pointer ptr)
+{
+    ASSERT_NOEXCEPT(std::get<Idx>(sp));
+    assert(std::addressof(std::get<Idx>(sp)) == ptr);
+}
+
+struct A{};
+constexpr int iArr1[] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9};
+          int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
+
+int main(int, char**)
+{
+
+//  static size
+    static_assert(testConstexprSpan<0>(std::span<const int, 4>(iArr1, 1), iArr1 + 0), "");
+    static_assert(testConstexprSpan<1>(std::span<const int, 4>(iArr1, 2), iArr1 + 1), "");
+    static_assert(testConstexprSpan<2>(std::span<const int, 4>(iArr1, 3), iArr1 + 2), "");
+    static_assert(testConstexprSpan<3>(std::span<const int, 4>(iArr1, 4), iArr1 + 3), "");
+
+    static_assert(testConstexprSpan<0>(std::span<const int, 1>(iArr1 + 1, 1), iArr1 + 1), "");
+    static_assert(testConstexprSpan<1>(std::span<const int, 2>(iArr1 + 2, 2), iArr1 + 3), "");
+    static_assert(testConstexprSpan<2>(std::span<const int, 3>(iArr1 + 3, 3), iArr1 + 5), "");
+    static_assert(testConstexprSpan<3>(std::span<const int, 4>(iArr1 + 4, 4), iArr1 + 7), "");
+
+//  static size
+    testRuntimeSpan<0>(std::span<int, 4>(iArr2, 4), iArr2);
+    testRuntimeSpan<1>(std::span<int, 4>(iArr2, 1), iArr2 + 1);
+    testRuntimeSpan<2>(std::span<int, 4>(iArr2, 2), iArr2 + 2);
+    testRuntimeSpan<3>(std::span<int, 4>(iArr2, 3), iArr2 + 3);
+
+    testRuntimeSpan<0>(std::span<int, 4>(iArr2 + 1, 1), iArr2 + 1);
+    testRuntimeSpan<1>(std::span<int, 4>(iArr2 + 2, 2), iArr2 + 3);
+    testRuntimeSpan<2>(std::span<int, 4>(iArr2 + 3, 3), iArr2 + 5);
+    testRuntimeSpan<3>(std::span<int, 4>(iArr2 + 4, 4), iArr2 + 7);
+
+
+    std::string s;
+    testRuntimeSpan<0>(std::span<std::string, 1>(&s, 1), &s);
+
+
+  return 0;
+}

Added: libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.fail.cpp?rev=354988&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.fail.cpp (added)
+++ libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.fail.cpp Wed Feb 27 07:41:37 2019
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <span>
+
+// tuple_element<I, span<T, N> >::type
+
+#include <span>
+
+#include "test_macros.h"
+
+
+int main(int, char**)
+{
+//  No tuple_element for dynamic spans
+    using T1 = typename std::tuple_element< 0, std::span<int,  0>>::type; // expected-error-re at span:* {{static_assert failed{{( due to requirement '.*')?}} "Index out of bounds in std::tuple_element<> (std::span)"}}
+    using T2 = typename std::tuple_element< 5, std::span<int,  5>>::type; // expected-error-re at span:* {{static_assert failed{{( due to requirement '.*')?}} "Index out of bounds in std::tuple_element<> (std::span)"}}
+    using T3 = typename std::tuple_element<20, std::span<int, 10>>::type; // expected-error-re at span:* {{static_assert failed{{( due to requirement '.*')?}} "Index out of bounds in std::tuple_element<> (std::span)"}}
+
+    return 0;
+}

Added: libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.pass.cpp?rev=354988&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/views/span.tuple/tuple_element.pass.cpp Wed Feb 27 07:41:37 2019
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <span>
+
+// tuple_element<I, span<T, N> >::type
+
+#include <span>
+
+#include "test_macros.h"
+
+template <class T, std::size_t N, std::size_t Idx>
+void test()
+{
+    {
+    typedef std::span<T, N> C;
+    ASSERT_SAME_TYPE(typename std::tuple_element<Idx, C>::type, T);
+    }
+    {
+    typedef std::span<T const, N> C;
+    ASSERT_SAME_TYPE(typename std::tuple_element<Idx, C>::type, T const);
+    }
+    {
+    typedef std::span<T volatile, N> C;
+    ASSERT_SAME_TYPE(typename std::tuple_element<Idx, C>::type, T volatile);
+    }
+    {
+    typedef std::span<T const volatile, N> C;
+    ASSERT_SAME_TYPE(typename std::tuple_element<Idx, C>::type, T const volatile);
+    }
+}
+
+int main(int, char**)
+{
+    test<double, 3, 0>();
+    test<double, 3, 1>();
+    test<double, 3, 2>();
+
+    test<int, 5, 0>();
+    test<int, 5, 1>();
+    test<int, 5, 2>();
+    test<int, 5, 3>();
+    test<int, 5, 4>();
+
+  return 0;
+}

Added: libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.fail.cpp?rev=354988&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.fail.cpp (added)
+++ libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.fail.cpp Wed Feb 27 07:41:37 2019
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <span>
+
+// tuple_size<span<T, N> >::value
+
+#include <span>
+
+int main(int, char**)
+{
+    (void) std::tuple_size<std::span<double>>::value; // expected-error-re {{implicit instantiation of undefined template 'std::__1::tuple_size<std::__1::span<double, {{.*}}}}
+    (void) std::tuple_size<std::span<int>>::value;    // expected-error-re {{implicit instantiation of undefined template 'std::__1::tuple_size<std::__1::span<int, {{.*}}}}
+    return 0;
+}

Added: libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.pass.cpp?rev=354988&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/views/span.tuple/tuple_size.pass.cpp Wed Feb 27 07:41:37 2019
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
+
+// <span>
+
+// tuple_size<span<T, N> >::value
+
+#include <span>
+
+template <class T, std::size_t N>
+void test()
+{
+    {
+    typedef std::span<T, N> C;
+    static_assert((std::tuple_size<C>::value == N), "");
+    }
+    {
+    typedef std::span<T const, N> C;
+    static_assert((std::tuple_size<C>::value == N), "");
+    }
+    {
+    typedef std::span<T volatile, N> C;
+    static_assert((std::tuple_size<C>::value == N), "");
+    }
+    {
+    typedef std::span<T const volatile, N> C;
+    static_assert((std::tuple_size<C>::value == N), "");
+    }
+}
+
+int main(int, char**)
+{
+    test<double, 0>();
+    test<double, 3>();
+    test<double, 5>();
+
+  return 0;
+}

Modified: libcxx/trunk/www/cxx2a_status.html
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx2a_status.html?rev=354988&r1=354987&r2=354988&view=diff
==============================================================================
--- libcxx/trunk/www/cxx2a_status.html (original)
+++ libcxx/trunk/www/cxx2a_status.html Wed Feb 27 07:41:37 2019
@@ -144,9 +144,9 @@
 	<tr><td><a href="https://wg21.link/P0811R3">P0811R3</a></td><td>LWG</td><td>Well-behaved interpolation for numbers and pointers</td><td>Kona</td><td></td><td></td></tr>
 	<tr><td><a href="https://wg21.link/P0920R2">P0920R2</a></td><td>LWG</td><td>Precalculated hash values in lookup</td><td>Kona</td><td></td><td></td></tr>
 	<tr><td><a href="https://wg21.link/P1001R2">P1001R2</a></td><td>LWG</td><td>Target Vectorization Policies from Parallelism V2 TS to C++20</td><td>Kona</td><td></td><td></td></tr>
-	<tr><td><a href="https://wg21.link/P1024R3">P1024R3</a></td><td>LWG</td><td>Usability Enhancements for std::span</td><td>Kona</td><td></td><td></td></tr>
+	<tr><td><a href="https://wg21.link/P1024R3">P1024R3</a></td><td>LWG</td><td>Usability Enhancements for std::span</td><td>Kona</td><td>Complete</td><td>9.0</td></tr>
 	<tr><td><a href="https://wg21.link/P1164R1">P1164R1</a></td><td>LWG</td><td>Make create_directory() Intuitive</td><td>Kona</td><td></td><td></td></tr>
-	<tr><td><a href="https://wg21.link/P1227R2">P1227R2</a></td><td>LWG</td><td>Signed ssize() functions, unsigned size() functions </td><td>Kona</td><td></td><td></td></tr>
+	<tr><td><a href="https://wg21.link/P1227R2">P1227R2</a></td><td>LWG</td><td>Signed ssize() functions, unsigned size() functions </td><td>Kona</td><td>Complete</td><td>9.0</td></tr>
 	<tr><td><a href="https://wg21.link/P1252R2">P1252R2</a></td><td>LWG</td><td>Ranges Design Cleanup</td><td>Kona</td><td></td><td></td></tr>
 	<tr><td><a href="https://wg21.link/P1286R2">P1286R2</a></td><td>CWG</td><td>Contra CWG DR1778</td><td>Kona</td><td></td><td></td></tr>
 	<tr><td><a href="https://wg21.link/P1357R1">P1357R1</a></td><td>LWG</td><td>Traits for [Un]bounded Arrays</td><td>Kona</td><td>Complete</td><td>9.0</td></tr>
@@ -323,7 +323,7 @@
 <!-- 	<tr><td></td><td></td><td></td><td></td></tr> -->
   </table>
 
-  <p>Last Updated: 26-Feb-2018</p>
+  <p>Last Updated: 27-Feb-2018</p>
 </div>
 </body>
 </html>




More information about the libcxx-commits mailing list