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