8#ifndef _CGP_TUPLE_OPERATIONS_HPP
9#define _CGP_TUPLE_OPERATIONS_HPP
23 template<
bool bSigned, cgt::numerical_c Left, cgt::numerical_c Right>
32 template<
bool bSigned =
true,
typename... Elements, cgt::non_tuple_c Scalar>
35 return std::tuple{ tuple_common_elements<bSigned>( Elements{}, Scalar{}) ... };
38 template<
bool bSigned = true,
typename T, std::
size_t N, cgt::numerical_c Scalar>
41 return std::array<cgt::common_signed_t<T, Scalar>, N>{};
44 template<
bool bSigned = true,
typename T, std::
size_t N, cgt::numerical_c Scalar>
47 return std::array<cgt::common_signed_t<T, Scalar>, N>{};
50 template<
bool bSigned = true,
typename T, cgt::numerical_c Scalar>
53 return std::vector<cgt::common_signed_t<T, Scalar>>{};
56 template<
bool bSigned = true,
typename T, cgt::numerical_c Scalar>
59 return std::vector<cgt::common_signed_t<T, Scalar>>{};
62 template<
bool bSigned =
true,
typename... Lefts,
typename... Rights>
63 requires(
sizeof...(Lefts) ==
sizeof...(Rights) )
66 return std::tuple{ tuple_common_elements<bSigned>( Lefts{}, Rights{}) ... };
70 template<
typename... Lefts,
typename... Rights>
71 requires(
sizeof...(Lefts) ==
sizeof...(Rights) )
72 constexpr auto operator|(std::tuple<Lefts...>, std::tuple<Rights...>)
noexcept
74 return std::tuple{ tuple_common_elements<true>( Lefts{}, Rights{} )... };
77 template<
typename... Elements, cgt::non_tuple_c Scalar>
78 constexpr auto operator|(std::tuple<Elements...>, Scalar)
noexcept
80 using c_t = std::tuple<Elements...>;
81 return std::tuple{ tuple_common_elements<true>( Elements{}, Scalar{} )... };
84 template<
typename... Elements, cgt::non_tuple_c Scalar>
85 constexpr auto operator|(Scalar, std::tuple<Elements...>)
noexcept
87 using c_t = std::tuple<Elements...>;
88 return std::tuple{ tuple_common_elements<true>( Scalar{}, Elements{} )... };
92 template<
typename... Lefts,
typename... Rights>
93 requires(
sizeof...(Lefts) ==
sizeof...(Rights) )
94 constexpr auto operator||(std::tuple<Lefts...>, std::tuple<Rights...>)
noexcept
96 return std::tuple{ tuple_common_elements<false>( Lefts{}, Rights{} )... };
99 template<
typename... Elements, cgt::non_tuple_c Scalar>
100 constexpr auto operator||(std::tuple<Elements...>, Scalar)
noexcept
102 using c_t = std::tuple<Elements...>;
103 return std::tuple{ tuple_common_elements<false>( Elements{}, Scalar{} )... };
108 template<
typename T,
typename... Tails>
111 using namespace hidden;
112 return (arg | ... | args);
115 template<
typename T,
typename... Tails>
118 using namespace hidden;
119 return (arg || ... || args);
122 template<cgt::tuple_flat_c LeftType, cgt::tuple_flat_c RightType>
123 requires( std::tuple_size_v<std::remove_cvref_t<LeftType>>
124 == std::tuple_size_v<std::remove_cvref_t<RightType>>)
127 using container_a_t = std::remove_cvref_t<LeftType>;
128 using container_b_t = std::remove_cvref_t<RightType>;
130 if constexpr(std::same_as<container_a_t, container_b_t> &&
131 std::is_rvalue_reference_v<
decltype(
A)>)
140 else if constexpr(std::same_as<container_a_t, container_b_t> &&
141 std::is_rvalue_reference_v<
decltype(
B)>)
152 constexpr std::size_t N = std::tuple_size_v<container_a_t>;
155 auto opr = []<
typename L,
typename R>(L& a, R& b)
160 return std::tuple{ opr(std::get<i>(
A), std::get<i>(
B)) ... };
165 template<cgt::tuple_flat_c LeftType, cgt::tuple_flat_c RightType>
166 requires( std::tuple_size_v<std::remove_cvref_t<LeftType>>
167 == std::tuple_size_v<std::remove_cvref_t<RightType>>)
170 using container_a_t = std::remove_cvref_t<LeftType>;
171 using container_b_t = std::remove_cvref_t<RightType>;
173 if constexpr(std::same_as<container_a_t, container_b_t> &&
174 std::is_rvalue_reference_v<
decltype(
A)>)
183 else if constexpr(std::same_as<container_a_t, container_b_t> &&
184 std::is_rvalue_reference_v<
decltype(
B)>)
195 constexpr std::size_t N = std::tuple_size_v<container_a_t>;
198 auto opr = []<
typename L,
typename R>(L& a, R& b)
203 return std::tuple{ opr(std::get<i>(
A), std::get<i>(
B)) ... };
208 template<cgt::tuple_flat_c LeftType, cgt::tuple_flat_c RightType>
209 requires( std::tuple_size_v<std::remove_cvref_t<LeftType>>
210 == std::tuple_size_v<std::remove_cvref_t<RightType>>)
213 using container_a_t = std::remove_cvref_t<LeftType>;
214 using container_b_t = std::remove_cvref_t<RightType>;
216 if constexpr(std::same_as<container_a_t, container_b_t> &&
217 std::is_rvalue_reference_v<
decltype(
A)>)
226 else if constexpr(std::same_as<container_a_t, container_b_t> &&
227 std::is_rvalue_reference_v<
decltype(
B)>)
238 constexpr std::size_t N = std::tuple_size_v<container_a_t>;
241 auto opr = []<
typename L,
typename R>(L& a, R& b)
246 return std::tuple{ opr(std::get<i>(
A), std::get<i>(
B)) ... };
251 template<cgt::tuple_flat_c LeftType, cgt::tuple_flat_c RightType>
252 requires( std::tuple_size_v<std::remove_cvref_t<LeftType>>
253 == std::tuple_size_v<std::remove_cvref_t<RightType>>)
256 using container_a_t = std::remove_cvref_t<LeftType>;
257 using container_b_t = std::remove_cvref_t<RightType>;
259 if constexpr(std::same_as<container_a_t, container_b_t> &&
260 std::is_rvalue_reference_v<
decltype(
A)>)
269 else if constexpr(std::same_as<container_a_t, container_b_t> &&
270 std::is_rvalue_reference_v<
decltype(
B)>)
281 constexpr std::size_t N = std::tuple_size_v<container_a_t>;
284 auto opr = []<
typename L,
typename R>(L& a, R& b)
289 return std::tuple{ opr(std::get<i>(
A), std::get<i>(
B)) ... };
298 template<
typename T,
typename S>
304 template<
typename... Types, cgt::non_tuple_c ScalarType>
310 template<
typename T,
typename S>
316 template<
typename... Types, cgt::non_tuple_c ScalarType>
324 template<
typename T,
typename S>
327 template<
typename T,
typename S>
330 template<cgt::tuple_flat_c TupleType, cgt::numerical_c ScalarType>
333 using container_t = std::remove_cvref_t<TupleType>;
336 if constexpr(std::same_as<container_t, c_t>
337 && std::is_rvalue_reference_v<
decltype(
A)>)
348 constexpr std::size_t N = std::tuple_size_v<container_t>;
356 template<cgt::tuple_flat_c TupleType, cgt::numerical_c ScalarType>
359 using container_t = std::remove_cvref_t<TupleType>;
362 if constexpr(std::same_as<container_t, c_t>
363 && std::is_rvalue_reference_v<
decltype(
A)>)
374 constexpr std::size_t N = std::tuple_size_v<container_t>;
382 template<cgt::tuple_flat_c TupleType, cgt::numerical_c ScalarType>
385 using container_t = std::remove_cvref_t<TupleType>;
388 if constexpr(std::same_as<container_t, c_t>
389 && std::is_rvalue_reference_v<
decltype(
A)>)
400 constexpr std::size_t N = std::tuple_size_v<container_t>;
408 template<cgt::tuple_flat_c TupleType, cgt::numerical_c ScalarType>
411 using container_t = std::remove_cvref_t<TupleType>;
414 if constexpr(std::same_as<container_t, c_t>
415 && std::is_rvalue_reference_v<
decltype(
A)>)
426 constexpr std::size_t N = std::tuple_size_v<container_t>;
434 template<cgt::tuple_flat_c TupleType, cgt::numerical_c ScalarType>
437 using container_t = std::remove_cvref_t<TupleType>;
440 if constexpr(std::same_as<container_t, c_t>
441 && std::is_rvalue_reference_v<
decltype(
A)>)
452 constexpr std::size_t N = std::tuple_size_v<container_t>;
460 template<cgt::tuple_flat_c TupleType, cgt::numerical_c ScalarType>
463 using container_t = std::remove_cvref_t<TupleType>;
466 if constexpr(std::same_as<container_t, c_t>
467 && std::is_rvalue_reference_v<
decltype(
A)>)
478 constexpr std::size_t N = std::tuple_size_v<container_t>;
486 template<cgt::tuple_flat_c TupleType, cgt::numerical_c ScalarType>
489 using container_t = std::remove_cvref_t<TupleType>;
492 if constexpr(std::same_as<container_t, c_t>
493 && std::is_rvalue_reference_v<
decltype(
A)>)
504 constexpr std::size_t N = std::tuple_size_v<container_t>;
512 template<cgt::tuple_flat_c TupleType, cgt::numerical_c ScalarType>
515 using container_t = std::remove_cvref_t<TupleType>;
518 if constexpr(std::same_as<container_t, c_t>
519 && std::is_rvalue_reference_v<
decltype(
A)>)
530 constexpr std::size_t N = std::tuple_size_v<container_t>;
void for_workhorse(WorkType &&work, std::integer_sequence< T, Indices... >, ArgTypes &&... args)
make_signed_t< std::common_type_t< std::remove_cvref_t< Types >... > > common_signed_t
make_unsigned_t< std::common_type_t< std::remove_cvref_t< Types >... > > common_unsigned_t
constexpr auto sbo(T &&value) noexcept(!cpg::bDetectOverFlow)
std::integer_sequence< std::common_type_t< std::remove_cvref_t< decltype(Indices)>... >, Indices... > sequence
constexpr const bool bDetectOverFlow
auto operator-(const std::tuple< ArgTypes1... > &tuple_a, const std::tuple< ArgTypes2... > &tuple_b)
auto operator+(const std::tuple< ArgTypes1... > &tuple_a, const std::tuple< ArgTypes2... > &tuple_b)
auto operator/(const std::tuple< ArgTypes1... > &tuple_a, const std::tuple< ArgTypes2... > &tuple_b)
auto operator*(const std::tuple< ArgTypes1... > &tuple_a, const std::tuple< ArgTypes2... > &tuple_b)
constexpr auto operator|(Scalar, std::tuple< Elements... >) noexcept
constexpr auto operator||(std::tuple< Elements... >, Scalar) noexcept
constexpr auto tuple_common_elements(std::tuple< Lefts... >, std::tuple< Rights... >) noexcept
constexpr auto signed_tuple_operation(T arg, Tails... args) noexcept
typename hidden::st_tuple_scalar_signed_cast< T, S >::type tuple_scalar_signed_cast
typename hidden::st_tuple_scalar_unsigned_cast< T, S >::type tuple_scalar_unsigned_cast
constexpr auto unsigned_tuple_operation(T arg, Tails... args) noexcept
cgt::common_signed_t< T, S > type
cgt::common_unsigned_t< T, S > type