hamzasood created this revision.

This patch implements make_array and to_array from the Library Fundamentals V2 
TS.


https://reviews.llvm.org/D38919

Files:
  include/experimental/array
  test/std/experimental/container/array/creation/make_array.fail.cpp
  test/std/experimental/container/array/creation/make_array.pass.cpp
  test/std/experimental/container/array/creation/to_array.pass.cpp

Index: test/std/experimental/container/array/creation/to_array.pass.cpp
===================================================================
--- test/std/experimental/container/array/creation/to_array.pass.cpp
+++ test/std/experimental/container/array/creation/to_array.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <array>
+#include <experimental/array>
+#include <type_traits>
+
+int main() {
+  using std::experimental::to_array;
+
+  {
+    constexpr int raw[4] = {0, 1, 2, 3};
+    constexpr auto a = to_array(raw);
+
+    static_assert(std::is_same<decltype(a), const std::array<int, 4>>::value,
+                  "Incorrect type");
+    static_assert(a[0] == 0 && a[1] == 1 && a[2] == 2 && a[3] == 3,
+                  "Incorrect values");
+  }
+
+  {
+    struct S { char c; };
+
+    constexpr S raw[6] = { {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, };
+    constexpr auto a = to_array(raw);
+
+    static_assert(std::is_same<decltype(a), const std::array<S, 6>>::value,
+                  "Incorrect type");
+    static_assert(a[0].c == 'a' &&
+                  a[1].c == 'b' &&
+                  a[2].c == 'c' &&
+                  a[3].c == 'd' &&
+                  a[4].c == 'e' &&
+                  a[5].c == 'f',
+                  "Incorrect values");
+  }
+}
Index: test/std/experimental/container/array/creation/make_array.pass.cpp
===================================================================
--- test/std/experimental/container/array/creation/make_array.pass.cpp
+++ test/std/experimental/container/array/creation/make_array.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <array>
+#include <cassert>
+#include <experimental/array>
+#include <functional>
+#include <type_traits>
+
+#define CHECK_ARRAY(a, Ty, ...)                       \
+do {                                                  \
+  static_assert(std::is_same<decltype(a), Ty>::value, \
+                #a"'s type is incorrect");            \
+  if (a != Ty{{__VA_ARGS__}})                         \
+    assert(false && #a"'s values are incorrect");     \
+} while(0)
+
+#define STD_ARRAY(T, N) ::std::array<T, N>
+
+int main() {
+  using std::experimental::make_array;
+
+  // This is the example given in the specification.
+  {
+    int i = 1; int &ri = i;
+    auto a1 = make_array(i, ri);
+    auto a2 = make_array(i, ri, 42L);
+    auto a3 = make_array<long>(i, ri);
+    auto a4 = make_array<long>();
+
+    CHECK_ARRAY(a1, STD_ARRAY(int,  2), 1,  1);
+    CHECK_ARRAY(a2, STD_ARRAY(long, 3), 1L, 1L, 42L);
+    CHECK_ARRAY(a3, STD_ARRAY(long, 2), 1L, 1L);
+    CHECK_ARRAY(a4, STD_ARRAY(long, 0));
+  }
+
+  // Make sure that reference_wrappers can be used when an explicit element
+  // type is given.
+  {
+    int i = 1;
+    auto with_ref_wrapper = make_array<int>(0, std::reference_wrapper<int>(i));
+    CHECK_ARRAY(with_ref_wrapper, STD_ARRAY(int, 2), 0, 1);
+  }
+
+  // Make sure that it works correctly with constexpr.
+  {
+    constexpr auto a = make_array(0, 1, 2);
+    static_assert(std::is_same<decltype(a), const std::array<int, 3>>::value
+                  && a[0] == 0 && a[1] == 1 && a[2] == 2,
+                  "constexpr array was made incorrectly.");
+  }
+}
Index: test/std/experimental/container/array/creation/make_array.fail.cpp
===================================================================
--- test/std/experimental/container/array/creation/make_array.fail.cpp
+++ test/std/experimental/container/array/creation/make_array.fail.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <array>
+#include <experimental/array>
+#include <functional>
+
+static int i = 0;
+
+int main() {
+  using std::experimental::make_array;
+
+  // expected-error@experimental/array:* {{static_assert failed}}
+  auto a = make_array(); // expected-error {{no matching function}}
+
+  // expected-error@experimental/array:* {{static_assert failed}}
+  auto b = make_array(0, std::reference_wrapper<int>(i)); // expected-error {{no matching function}}
+}
Index: include/experimental/array
===================================================================
--- include/experimental/array
+++ include/experimental/array
@@ -0,0 +1,97 @@
+// -*- C++ -*-
+//===------------------------------- array -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL_ARRAY
+#define _LIBCPP_EXPERIMENTAL_ARRAY
+
+/*
+  experimental/array synopsis
+
+#include <array>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v2 {
+
+  // [container.array.creation], Array creation functions
+  template <class D = void, class... Types>
+    constexpr array<VT, sizeof...(Types)> make_array(Types&&... t);
+  template <class T, size_t N>
+    constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
+
+} // namespace fundamentals_v2
+} // namespace experimental
+} // namespace std
+
+*/
+
+#include <experimental/__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER > 11
+
+#include <array>
+#include <cstddef>
+#include <experimental/type_traits>
+#include <functional>
+#include <utility>
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
+
+template <class _D_Ty, class...>
+struct __make_array_value_type {
+  using type = _D_Ty;
+};
+
+template <class... _Types>
+struct __make_array_value_type<void, _Types...> : common_type<_Types...> {
+  static_assert(sizeof...(_Types) > 0,
+                "An element type must be specified if there are no given values.");
+
+  template <class>
+    struct __is_ref_wrapper : false_type { };
+  template <class _Tp>
+    struct __is_ref_wrapper<reference_wrapper<_Tp>> : true_type { };
+  static_assert(!disjunction_v<__is_ref_wrapper<decay_t<_Types>>...>,
+                "An element type must be specified if any of the given values "
+                "are reference_wrappers.");
+};
+
+template <class _D_Ty = void, class... _Types>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+array<typename __make_array_value_type<_D_Ty, _Types...>::type, sizeof...(_Types)>
+make_array(_Types &&... __ts) {
+  return {{forward<_Types>(__ts)...}};
+}
+
+template <class _Tp, size_t _Num, size_t... _Is>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+array<remove_cv_t<_Tp>, _Num>
+__to_array_impl(_Tp (&__a)[_Num], index_sequence<_Is...>) {
+  return {{__a[_Is]...}};
+}
+
+template <class _Tp, size_t _Num>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+auto to_array(_Tp (&__a)[_Num]) -> decltype(__to_array_impl(__a, {})) {
+  return __to_array_impl(__a, make_index_sequence<_Num>{});;
+}
+
+_LIBCPP_END_NAMESPACE_LFTS_V2
+
+#endif // _LIBCPP_STD_VER > 11
+
+#endif // _LIBCPP_EXPERIMENTAL_ARRAY
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to