sandbox
Loading...
Searching...
No Matches
make_array.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_UTILITY_MAKE_ARRAY_HPP_
3#define LIBSBX_UTILITY_MAKE_ARRAY_HPP_
4
5#include <array>
6#include <utility>
7#include <concepts>
8#include <functional>
9
10namespace sbx::utility {
11
12namespace detail {
13
14template<bool Condition, typename Type, std::convertible_to<Type> Other = Type>
15constexpr auto conditional_value(Other value) noexcept -> Type {
16 if constexpr (Condition) {
17 return static_cast<Type>(value);
18 } else {
19 return Type{0};
20 }
21}
22
23template<typename Type, std::size_t... Indices, std::convertible_to<Type>... Args>
24requires (sizeof...(Args) == sizeof...(Indices))
25constexpr auto make_array_impl(std::index_sequence<Indices...>, Args&&... args) -> std::array<Type, sizeof...(Indices)> {
26 return std::array<Type, sizeof...(Indices)>{ static_cast<Type>(static_cast<void>(Indices), std::forward<Args>(args))... };
27}
28
29template<typename Type, std::size_t... Indices, std::convertible_to<Type> Other = Type>
30constexpr auto make_array_impl(std::index_sequence<Indices...>, const Other& value) -> std::array<Type, sizeof...(Indices)> {
31 return std::array<Type, sizeof...(Indices)>{ static_cast<Type>(static_cast<void>(Indices), value)... };
32}
33
34template<std::size_t Index, typename Type, std::size_t... Indices, std::convertible_to<Type> Other = Type>
35requires (Index >= 0 && Index < sizeof...(Indices))
36constexpr auto make_array_impl(std::index_sequence<Indices...>, const Other& value) -> std::array<Type, sizeof...(Indices)> {
37 return std::array<Type, sizeof...(Indices)>{ conditional_value<(Indices == Index), Type>(value)... };
38}
39
40template<typename Type, std::size_t... Indices, std::convertible_to<Type> Other = Type>
41constexpr auto make_array_impl(std::index_sequence<Indices...>, const std::array<Other, sizeof...(Indices)>& array) -> std::array<Type, sizeof...(Indices)> {
42 return std::array<Type, sizeof...(Indices)>{ static_cast<Type>(array[Indices])... };
43}
44
45} // namespace detail
46
47template<typename Type, std::size_t Size, std::convertible_to<Type>... Args>
48requires (sizeof...(Args) == Size)
49constexpr auto make_array(Args&&... args) -> std::array<Type, Size> {
50 return detail::make_array_impl<Type>(std::make_index_sequence<Size>(), std::forward<Args>(args)...);
51}
52
53template<typename Type, std::size_t Size, std::convertible_to<Type> Other = Type>
54constexpr auto make_array(const Other& value) -> std::array<Type, Size> {
55 return detail::make_array_impl<Type>(std::make_index_sequence<Size>(), value);
56}
57
58template<typename Type, std::size_t Size, std::size_t Index, std::convertible_to<Type> Other = Type>
59constexpr auto make_array(const Other& value) -> std::array<Type, Size> {
60 return detail::make_array_impl<Index, Type>(std::make_index_sequence<Size>(), value);
61}
62
63template<typename Type, std::size_t Size, std::convertible_to<Type> Other = Type>
64constexpr auto make_array(const std::array<Other, Size>& array) -> std::array<Type, Size> {
65 return detail::make_array_impl<Type>(std::make_index_sequence<Size>(), array);
66}
67
68} // namespace sbx::utility
69
70#endif // LIBSBX_UTILITY_MAKE_ARRAY_HPP_