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