xref: /petsc/include/petsc/private/cpp/array.hpp (revision 9dd11ecf0918283bb567d8b33a92f53ac4ea7840)
1 #pragma once
2 
3 #include <petsc/private/cpp/macros.hpp>  // PETSC_DECLTYPE_NOEXCEPT_AUTO_RETURNS
4 #include <petsc/private/cpp/utility.hpp> // index_sequence
5 #include <petsc/private/cpp/type_traits.hpp>
6 
7 #include <array>
8 
9 namespace Petsc
10 {
11 
12 namespace util
13 {
14 
15 namespace detail
16 {
17 
18 template <class D, class...>
19 struct return_type_helper {
20   using type = D;
21 };
22 
23 template <class... T>
24 struct return_type_helper<void, T...> : std::common_type<T...> { };
25 
26 template <class D, class... T>
27 using array_return_type = std::array<typename return_type_helper<D, T...>::type, sizeof...(T)>;
28 
29 template <typename T, std::size_t NL, std::size_t... IL, std::size_t NR, std::size_t... IR>
concat_array_impl(const std::array<T,NL> & l,const std::array<T,NR> & r,index_sequence<IL...>,index_sequence<IR...>)30 inline constexpr std::array<T, NL + NR> concat_array_impl(const std::array<T, NL> &l, const std::array<T, NR> &r, index_sequence<IL...>, index_sequence<IR...>) noexcept(std::is_nothrow_copy_constructible<T>::value)
31 {
32   return {l[IL]..., r[IR]...};
33 }
34 
35 } // namespace detail
36 
37 template <class D = void, class... T>
make_array(T &&...t)38 PETSC_NODISCARD inline constexpr detail::array_return_type<D, T...> make_array(T &&...t) noexcept(std::is_nothrow_constructible<detail::array_return_type<D, T...>>::value)
39 {
40   return {std::forward<T>(t)...};
41 }
42 
43 template <typename T, std::size_t NL, std::size_t NR>
44 PETSC_NODISCARD inline constexpr auto concat_array(const std::array<T, NL> &l, const std::array<T, NR> &r) PETSC_DECLTYPE_NOEXCEPT_AUTO_RETURNS(detail::concat_array_impl(l, r, make_index_sequence<NL>{}, make_index_sequence<NR>{}))
45 
46 } // namespace util
47 
48 } // namespace Petsc
49