C++ Library Extensions 2022.12.09
To help learn modern C++ programming
cpg_functional.hpp
Go to the documentation of this file.
1/*
2 Author: Thomas Kim
3 First Edit: Dec. 06. 2021
4*/
5
6#ifndef _CPG_FUNCTIONAL_HPP
7#define _CPG_FUNCTIONAL_HPP
8
9#ifndef NOMINMAX
10#define NOMINMAX
11#endif
12
13#include "cpg_types.hpp"
14#include "cpg_iterator.hpp"
15
17{
18 namespace cgt = cpg::types;
19
20 template<typename T>
21 struct recursor
22 {
24 recursor(T v): value{v} { }
25
26 template<typename FuncType>
27 recursor& operator|(FuncType&& func)
28 requires requires
29 {
30 std::invoke(func, this->value);
31 }
32 {
33 this->value = std::invoke(func, this->value);
34 return *this;
35 }
36 };
37
38 template<typename InputType, typename... FuncTypes>
39 decltype(auto) operator|( std::tuple<FuncTypes...> const& func, std::vector<InputType> const& input )
40 {
41 using vector_t = std::vector<InputType>;
42
43 vector_t R; R.reserve(input.size());
44
45 auto process = [&](auto k)
46 {
47 cgt::for_stallion<sizeof...(FuncTypes)-1, -1, -1>([&]<auto...i>
49 {
50 auto a = ( recursor{ input[k] } | ... | std::get<i>(func) );
51 R.emplace_back(std::move(a.value));
52 });
53 };
54
55 std::for_each(std::execution::par,
56 tbb::counting_iterator{std::size_t{}},
57 tbb::counting_iterator{input.size()}, process);
58
59 return R;
60 }
61
62 template<typename InputType, typename... FuncTypes>
63 decltype(auto) operator|( std::vector<InputType> const& input, std::tuple<FuncTypes...> const& func )
64 {
65 using vector_t = std::vector<InputType>;
66
67 vector_t R; R.reserve(input.size());
68
69 auto process = [&](auto k)
70 {
71 cgt::for_stallion<sizeof...(FuncTypes)>([&]<auto...i>
73 {
74 auto a = ( recursor{ input[k] } | ... | std::get<i>(func) );
75 R.emplace_back(std::move(a.value));
76 });
77 };
78
79 std::for_each(std::execution::par,
80 tbb::counting_iterator{std::size_t{}},
81 tbb::counting_iterator{input.size()}, process);
82
83 return R;
84 }
85
87 template<typename InputType, std::size_t N, typename... FuncTypes>
88 decltype(auto) operator|( std::tuple<FuncTypes...> const& func, std::array<InputType, N> const& input )
89 {
90 using array_t = std::array<InputType, N>; array_t R;
91
92 auto process = [&](auto k)
93 {
94 cgt::for_stallion<sizeof...(FuncTypes)-1, -1, -1>([&]<auto...i>
96 {
97 auto a = ( recursor{ input[k] } | ... | std::get<i>(func) );
98 R[k] = std::move(a.value);
99 });
100 };
101
102 std::for_each(std::execution::par,
103 tbb::counting_iterator{std::size_t{}},
104 tbb::counting_iterator{input.size()}, process);
105
106 return R;
107 }
108
109 template<typename InputType, std::size_t N, typename... FuncTypes>
110 decltype(auto) operator|( std::array<InputType, N> const& input, std::tuple<FuncTypes...> const& func )
111 {
112 using array_t = std::array<InputType, N>; array_t R;
113
114 auto process = [&](auto k)
115 {
116 cgt::for_stallion<sizeof...(FuncTypes)>([&]<auto...i>
118 {
119 auto a = ( recursor{ input[k] } | ... | std::get<i>(func) );
120 R[k] = std::move(a.value);
121 });
122 };
123
124 std::for_each(std::execution::par,
125 tbb::counting_iterator{std::size_t{}},
126 tbb::counting_iterator{input.size()}, process);
127
128 return R;
129 }
130
132 template<cgt::tuple_flat_c TupleType, typename FuncType>
133 constexpr auto operator >> (TupleType&& args, FuncType&& func)
134 requires requires{ std::apply(func, args); }
135 {
136 return std::apply(std::forward<FuncType>(func),
137 std::forward<TupleType>(args));
138 }
139
140 template<cgt::std_array_flat_c ArrayType, typename FuncType>
141 constexpr auto operator >> (ArrayType&& args, FuncType&& func)
142 requires requires{ std::apply(func, args); }
143 {
144 return std::apply(std::forward<FuncType>(func),
145 std::forward<ArrayType>(args));
146 }
147
148 template<cgt::span_flat_c SpanType, typename FuncType>
149 constexpr auto operator >> (SpanType&& args, FuncType&& func)
150 requires requires{ std::apply(func, args); }
151 {
152 return std::apply(std::forward<FuncType>(func),
153 std::forward<SpanType>(args));
154 }
155
156 template<typename... ArgTypes, typename... FuncTypes>
157 constexpr auto operator >>
158 (std::tuple<ArgTypes...> const& args, std::tuple<FuncTypes...> const& func)
159 {
160 return cgt::for_stallion<sizeof...(FuncTypes)>
161 ([&]<auto...i>(cgt::sequence<i...>)
162 {
163 return std::tuple{ std::apply(std::get<i>(func), args)...};
164 });
165 }
166
167 template<typename ArgType, std::size_t N, typename... FuncTypes>
168 constexpr auto operator >>
169 (std::array<ArgType, N> const& args, std::tuple<FuncTypes...> const& func)
170 {
171 return cgt::for_stallion<sizeof...(FuncTypes)>
172 ([&]<auto...i>(cgt::sequence<i...>)
173 {
174 return std::tuple{ std::apply(std::get<i>(func), args)...};
175 });
176 }
177}
178// end of namespace cpg::functional
179
180#endif
181// end of file
std::vector< Type > vector_t
constexpr auto operator>>(TupleType &&args, FuncType &&func)
constexpr decltype(auto) for_stallion(WorkType &&work, std::integer_sequence< T, Indices... >, ArgTypes &&... args)
Definition: cpg_types.hpp:3858
std::integer_sequence< std::common_type_t< std::remove_cvref_t< decltype(Indices)>... >, Indices... > sequence
Definition: cpg_types.hpp:2665
constexpr decltype(auto) apply(F &&f, T(&&c_array)[N])
recursor & operator|(FuncType &&func)