1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 6 #pragma once 7 8 #include <array> 9 #include <type_traits> 10 #include <utility> 11 12 #include <folly/Traits.h> 13 #include <folly/Utility.h> 14 15 namespace folly { 16 17 namespace array_detail { 18 template <typename> 19 struct is_ref_wrapper : std::false_type {}; 20 template <typename T> 21 struct is_ref_wrapper<std::reference_wrapper<T>> : std::true_type {}; 22 23 template <typename T> 24 using not_ref_wrapper = 25 folly::Negation<is_ref_wrapper<typename std::decay<T>::type>>; 26 27 template <typename D, typename...> 28 struct return_type_helper { 29 using type = D; 30 }; 31 template <typename... TList> 32 struct return_type_helper<void, TList...> { 33 static_assert( 34 folly::Conjunction<not_ref_wrapper<TList>...>::value, 35 "TList cannot contain reference_wrappers when D is void"); 36 using type = typename std::common_type<TList...>::type; 37 }; 38 39 template <typename D, typename... TList> 40 using return_type = std:: 41 array<typename return_type_helper<D, TList...>::type, sizeof...(TList)>; 42 } // namespace array_detail 43 44 template <typename D = void, typename... TList> 45 constexpr array_detail::return_type<D, TList...> make_array(TList&&... t) { 46 using value_type = 47 typename array_detail::return_type_helper<D, TList...>::type; 48 return {{static_cast<value_type>(std::forward<TList>(t))...}}; 49 } 50 51 namespace array_detail { 52 template <typename MakeItem, std::size_t... Index> 53 inline constexpr auto make_array_with( 54 MakeItem const& make, 55 folly::index_sequence<Index...>) 56 -> std::array<decltype(make(0)), sizeof...(Index)> { 57 return std::array<decltype(make(0)), sizeof...(Index)>{{make(Index)...}}; 58 } 59 } // namespace array_detail 60 61 // make_array_with 62 // 63 // Constructs a std::array<..., Size> with elements m(i) for i in [0, Size). 64 template <std::size_t Size, typename MakeItem> 65 constexpr auto make_array_with(MakeItem const& make) 66 -> decltype(array_detail::make_array_with( 67 make, 68 folly::make_index_sequence<Size>{})) { 69 return array_detail::make_array_with( 70 make, 71 folly::make_index_sequence<Size>{}); 72 } 73 74 } // namespace folly 75