Sequoia
Loading...
Searching...
No Matches
ArrayUtilities.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2018. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
15#include <array>
16#include <span>
17#include <string>
18#include <stdexcept>
19#include <type_traits>
20#include <utility>
21
22namespace sequoia::utilities
23{
24 namespace impl
25 {
26 template<class T, class InitType, class Fn>
27 requires std::is_invocable_r_v<T, Fn, InitType>
28 [[nodiscard]]
29 constexpr T to_element(std::initializer_list<InitType> l, const std::size_t i, Fn fn)
30 {
31 if constexpr(std::is_default_constructible_v<InitType>)
32 {
33 return fn((i < l.size()) ? *(l.begin() + i) : InitType{});
34 }
35 else
36 {
37 if(i > l.size())
38 throw std::logic_error("Insuffucient arguments to initialize an array of objects which cannot be default constructed.");
39
40 return fn(*(l.begin() + i));
41 }
42 }
43
44 template<class T, std::size_t N, class InitType, std::size_t... I, class Fn>
45 requires std::is_invocable_r_v<T, Fn, InitType>
46 [[nodiscard]]
47 constexpr std::array<T, N> to_array([[maybe_unused]] std::initializer_list<InitType> l, [[maybe_unused]] std::index_sequence<I...>, Fn&& fn)
48 {
49 return std::array<T, N>{ to_element<T>(l, I, std::forward<Fn>(fn))...};
50 }
51 }
52
53 template<class T, std::size_t N, class InitType=T, class Fn=std::identity>
54 requires std::is_invocable_r_v<T, Fn, InitType>
55 [[nodiscard]]
56 constexpr std::array<T, N> to_array(std::initializer_list<InitType> l, Fn fn = Fn{})
57 {
58 if(l.size() > N)
59 throw std::out_of_range{std::string{"initializer_list of size "}.append(std::to_string(l.size())).append(" too big for array: expected at most ")
60 .append(std::to_string(N)).append(" elements")};
61
62 return impl::to_array<T, N>(l, std::make_index_sequence<N>{}, fn);
63 }
64
68 template<class T, std::size_t N, class Fn>
69 requires std::is_invocable_r_v<T, Fn, std::size_t>
70 [[nodiscard]]
71 constexpr std::array<T, N> make_array(Fn f) {
72 return [&] <std::size_t... Is>(std::index_sequence<Is...>){
73 return std::array<T, N>{f(Is)...};
74 }(std::make_index_sequence<N>{});
75 }
76
80 template<class T, std::size_t N, class Fn = std::identity>
81 requires std::is_invocable_r_v<T, Fn, T>
82 [[nodiscard]]
83 constexpr std::array<T, N> to_array(std::span<const T, N> data, Fn f = {})
84 {
85 return [&] <std::size_t... Is> (std::index_sequence<Is...>){
86 return std::array<T, N>{f(data[Is])...};
87 }(std::make_index_sequence<N>{});
88 }
89}
constexpr std::array< T, N > make_array(Fn f)
Definition: ArrayUtilities.hpp:71