Reland [libc++] [P0325] Implement to_array from LFTS with updates.

Fixed expected errors and notes.

Summary:
This patch implements https://wg21.link/P0325.

Reviewers: EricWF, mclow.lists, ldionne, lichray

Reviewed By: ldionne, lichray

Subscribers: lichray, dexonsmith, zoecarver, christof, ldionne, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D69882

Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: e93e58c6c40a365bc9275dd8a8242598343cc835
diff --git a/include/array b/include/array
index 88e9d57..64ca68d 100644
--- a/include/array
+++ b/include/array
@@ -479,6 +479,47 @@
 
 #endif  // !_LIBCPP_CXX03_LANG
 
+#if _LIBCPP_STD_VER > 17
+
+template <typename _Tp, size_t _Size, size_t... _Index>
+_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
+__to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) {
+  return {{__arr[_Index]...}};
+}
+
+template <typename _Tp, size_t _Size, size_t... _Index>
+_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
+__to_array_rvalue_impl(_Tp(&&__arr)[_Size], index_sequence<_Index...>) {
+  return {{_VSTD::move(__arr[_Index])...}};
+}
+
+template <typename _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
+to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
+  static_assert(
+      !is_array_v<_Tp>,
+      "[array.creation]/1: to_array does not accept multidimensional arrays.");
+  static_assert(
+      is_constructible_v<_Tp, _Tp&>,
+      "[array.creation]/1: to_array requires copy constructible elements.");
+  return __to_array_lvalue_impl(__arr, make_index_sequence<_Size>());
+}
+
+template <typename _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
+to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
+  static_assert(
+      !is_array_v<_Tp>,
+      "[array.creation]/4: to_array does not accept multidimensional arrays.");
+  static_assert(
+      is_move_constructible_v<_Tp>,
+      "[array.creation]/4: to_array requires move constructible elements.");
+  return __to_array_rvalue_impl(_VSTD::move(__arr),
+                                make_index_sequence<_Size>());
+}
+
+#endif // _LIBCPP_STD_VER > 17
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_ARRAY