C++ Library Extensions 2022.12.09
To help learn modern C++ programming
cpg_vector_operations.hpp
Go to the documentation of this file.
1/*
2 Author: Thomas Kim
3 First Edit: Dec. 03, 2021
4 Second Edit: Dec. 05, 2021
5 Third Edit: Dec. 09, 2021 - safe binary operation
6 Fourth Edit: Dec. 12, 2021 - std::array - std::vector operation
7*/
8
9#ifndef _CGP_VECTOR_OPERATIONS_HPP
10#define _CGP_VECTOR_OPERATIONS_HPP
11
12#ifndef NOMINMAX
13#define NOMINMAX
14#endif
15
16#include "cpg_types.hpp"
17
18namespace std::inline stl_extensions
19{
20 namespace cgt = cpg::types;
21
22 template<cgt::vector_c LeftType, cgt::vector_c RightType>
23 requires cgt::common_vector_c<LeftType, RightType>
24 constexpr decltype(auto) operator+(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
25 {
26 assert(A.size() == B.size());
27
28 using element_t_a = cgt::first_type_t<LeftType>;
29 using element_t_b = cgt::first_type_t<RightType>;
30
31 std::size_t Size = A.size();
32
33 if constexpr( std::same_as<element_t_a, element_t_b> &&
34 std::is_rvalue_reference_v<decltype(A) >)
35 {
36 for(std::size_t i=0; i < Size; ++i)
37 A[i] = cgt::sbo(A[i]) + cgt::sbo(B[i]);
38
39 return std::move(A);
40 }
41 else if constexpr( std::same_as<element_t_a, element_t_b> &&
42 std::is_rvalue_reference_v<decltype(B) >)
43 {
44 for(std::size_t i=0; i < Size; ++i)
45 B[i] = cgt::sbo(A[i]) + cgt::sbo(B[i]);
46
47 return std::move(B);
48 }
49 else
50 {
51 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
52
53 for(std::size_t i=0; i < Size; ++i)
54 C[i] = cgt::sbo(A[i]) + cgt::sbo(B[i]);
55
56 return C;
57 }
58 }
59
60 template<cgt::vector_c LeftType, cgt::vector_c RightType>
61 requires cgt::common_vector_c<LeftType, RightType>
62 constexpr decltype(auto) operator-(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
63 {
64 assert(A.size() == B.size());
65
66 using element_t_a = cgt::first_type_t<LeftType>;
67 using element_t_b = cgt::first_type_t<RightType>;
68
69 std::size_t Size = A.size();
70
71 if constexpr( std::same_as<element_t_a, element_t_b> &&
72 std::is_rvalue_reference_v<decltype(A) >)
73 {
74 for(std::size_t i=0; i < Size; ++i)
75 A[i] = cgt::sbo(A[i]) - cgt::sbo(B[i]);
76
77 return std::move(A);
78 }
79 else if constexpr( std::same_as<element_t_a, element_t_b> &&
80 std::is_rvalue_reference_v<decltype(B) >)
81 {
82 for(std::size_t i=0; i < Size; ++i)
83 B[i] = cgt::sbo(A[i]) - cgt::sbo(B[i]);
84
85 return std::move(B);
86 }
87 else
88 {
89 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
90
91 for(std::size_t i=0; i < Size; ++i)
92 C[i] = cgt::sbo(A[i]) - cgt::sbo(B[i]);
93
94 return C;
95 }
96 }
97
98 template<cgt::vector_c LeftType, cgt::vector_c RightType>
99 requires cgt::common_vector_c<LeftType, RightType>
100 constexpr decltype(auto) operator*(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
101 {
102 assert(A.size() == B.size());
103
104 using element_t_a = cgt::first_type_t<LeftType>;
105 using element_t_b = cgt::first_type_t<RightType>;
106
107 std::size_t Size = A.size();
108
109 if constexpr( std::same_as<element_t_a, element_t_b> &&
110 std::is_rvalue_reference_v<decltype(A) >)
111 {
112 for(std::size_t i=0; i < Size; ++i)
113 A[i] = cgt::sbo(A[i]) * cgt::sbo(B[i]);
114
115 return std::move(A);
116 }
117 else if constexpr( std::same_as<element_t_a, element_t_b> &&
118 std::is_rvalue_reference_v<decltype(B) >)
119 {
120 for(std::size_t i=0; i < Size; ++i)
121 B[i] = cgt::sbo(A[i]) * cgt::sbo(B[i]);
122
123 return std::move(B);
124 }
125 else
126 {
127 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
128
129 for(std::size_t i=0; i < Size; ++i)
130 C[i] = cgt::sbo(A[i]) * cgt::sbo(B[i]);
131
132 return C;
133 }
134 }
135
136 template<cgt::vector_c LeftType, cgt::vector_c RightType>
137 requires cgt::common_vector_c<LeftType, RightType>
138 constexpr decltype(auto) operator/(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
139 {
140 assert(A.size() == B.size());
141
142 using element_t_a = cgt::first_type_t<LeftType>;
143 using element_t_b = cgt::first_type_t<RightType>;
144
145 std::size_t Size = A.size();
146
147 if constexpr( std::same_as<element_t_a, element_t_b> &&
148 std::is_rvalue_reference_v<decltype(A) >)
149 {
150 for(std::size_t i=0; i < Size; ++i)
151 A[i] = cgt::sbo(A[i]) / cgt::sbo(B[i]);
152
153 return std::move(A);
154 }
155 else if constexpr( std::same_as<element_t_a, element_t_b> &&
156 std::is_rvalue_reference_v<decltype(B) >)
157 {
158 for(std::size_t i=0; i < Size; ++i)
159 B[i] = cgt::sbo(A[i]) / cgt::sbo(B[i]);
160
161 return std::move(B);
162 }
163 else
164 {
165 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
166
167 for(std::size_t i=0; i < Size; ++i)
168 C[i] = cgt::sbo(A[i]) / cgt::sbo(B[i]);
169
170 return C;
171 }
172 }
173
174 // vector cross product
175 template<cgt::vector_c LeftType, cgt::vector_c RightType>
176 requires cgt::common_vector_c<LeftType, RightType>
177 && (cgt::std_array_c<cgt::first_type_t<LeftType>>)
178 && (cgt::std_array_c<cgt::first_type_t<RightType>>)
179 constexpr decltype(auto) operator%(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
180 {
181 assert(A.size() == B.size());
182
183 using element_t_a = cgt::first_type_t<LeftType>;
184 using element_t_b = cgt::first_type_t<RightType>;
185
186 std::size_t Size = A.size();
187
188 if constexpr( std::same_as<element_t_a, element_t_b> &&
189 std::is_rvalue_reference_v<decltype(A) >)
190 {
191 for(std::size_t i=0; i < Size; ++i)
192 A[i] = A[i] % B[i];
193
194 return std::move(A);
195 }
196 else if constexpr( std::same_as<element_t_a, element_t_b> &&
197 std::is_rvalue_reference_v<decltype(B) >)
198 {
199 for(std::size_t i=0; i < Size; ++i)
200 B[i] = A[i] % B[i];
201
202 return std::move(B);
203 }
204 else
205 {
206 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
207
208 for(std::size_t i=0; i < Size; ++i)
209 C[i] = A[i] % B[i];
210
211 return C;
212 }
213 }
214
215 // vector inner product
216 template<cgt::vector_c LeftType, cgt::vector_c RightType>
217 requires cgt::common_vector_c<LeftType, RightType>
218 && (cgt::std_array_c<cgt::first_type_t<LeftType>>)
219 && (cgt::std_array_c<cgt::first_type_t<RightType>>)
220 constexpr decltype(auto) operator&(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
221 {
222 assert(A.size() == B.size());
223
224 using element_t_a = cgt::first_type_t<LeftType>;
225 using element_t_b = cgt::first_type_t<RightType>;
226
227 std::size_t Size = A.size();
228
230 using element_t =std::tuple_element_t<0, cgt::first_type_t<c_t>>;
231 using vector_t = std::vector<element_t>;
232
233 vector_t R(A.size());
234
235 for(std::size_t i=0; i < A.size(); ++i)
236 R[i] = A[i] & B[i];
237
238 return R;
239 }
240
242 template<cgt::vector_c LeftType, cgt::std_array_flat_c RightType>
243 requires cgt::common_vector_c<LeftType, RightType>
244 && (cgt::std_array_c<cgt::first_type_t<LeftType>>)
245 && (cgt::numerical_c<cgt::first_type_t<RightType>>)
246 constexpr decltype(auto) operator+(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
247 {
248 std::size_t Size = A.size();
249
250 if constexpr(std::is_rvalue_reference_v<decltype(A)>)
251 {
252 for(std::size_t i=0; i < Size; ++i) A[i] = A[i] + B;
253
254 return std::move(A);
255 }
256 else
257 {
258 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
259
260 for(std::size_t i=0; i < Size; ++i) C[i] = A[i] + B;
261
262 return C;
263 }
264 }
265
266 template<cgt::std_array_flat_c LeftType, cgt::vector_c RightType>
267 requires cgt::common_vector_c<LeftType, RightType>
268 && (cgt::numerical_c<cgt::first_type_t<LeftType>>)
269 && (cgt::std_array_c<cgt::first_type_t<RightType>>)
270 constexpr decltype(auto) operator+(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
271 {
272 std::size_t Size = B.size();
273
274 if constexpr(std::is_rvalue_reference_v<decltype(B)>)
275 {
276 for(std::size_t i=0; i < Size; ++i) B[i] = A + B[i];
277
278 return std::move(B);
279 }
280 else
281 {
282 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
283
284 for(std::size_t i=0; i < Size; ++i) C[i] = A + B[i];
285
286 return C;
287 }
288 }
289
291 template<cgt::vector_c LeftType, cgt::std_array_flat_c RightType>
292 requires cgt::common_vector_c<LeftType, RightType>
293 && (cgt::std_array_c<cgt::first_type_t<LeftType>>)
294 && (cgt::numerical_c<cgt::first_type_t<RightType>>)
295 constexpr decltype(auto) operator-(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
296 {
297 std::size_t Size = A.size();
298
299 if constexpr(std::is_rvalue_reference_v<decltype(A)>)
300 {
301 for(std::size_t i=0; i < Size; ++i) A[i] = A[i] - B;
302
303 return std::move(A);
304 }
305 else
306 {
307 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
308
309 for(std::size_t i=0; i < Size; ++i) C[i] = A[i] - B;
310
311 return C;
312 }
313 }
314
315 template<cgt::std_array_flat_c LeftType, cgt::vector_c RightType>
316 requires cgt::common_vector_c<LeftType, RightType>
317 && (cgt::numerical_c<cgt::first_type_t<LeftType>>)
318 && (cgt::std_array_c<cgt::first_type_t<RightType>>)
319 constexpr decltype(auto) operator-(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
320 {
321 std::size_t Size = B.size();
322
323 if constexpr(std::is_rvalue_reference_v<decltype(B)>)
324 {
325 for(std::size_t i=0; i < Size; ++i) B[i] = A - B[i];
326
327 return std::move(B);
328 }
329 else
330 {
331 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
332
333 for(std::size_t i=0; i < Size; ++i) C[i] = A - B[i];
334
335 return C;
336 }
337 }
338
340 template<cgt::vector_c LeftType, cgt::std_array_flat_c RightType>
341 requires cgt::common_vector_c<LeftType, RightType>
342 && (cgt::std_array_c<cgt::first_type_t<LeftType>>)
343 && (cgt::numerical_c<cgt::first_type_t<RightType>>)
344 constexpr decltype(auto) operator*(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
345 {
346 std::size_t Size = A.size();
347
348 if constexpr(std::is_rvalue_reference_v<decltype(A)>)
349 {
350 for(std::size_t i=0; i < Size; ++i) A[i] = A[i] * B;
351
352 return std::move(A);
353 }
354 else
355 {
356 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
357
358 for(std::size_t i=0; i < Size; ++i) C[i] = A[i] * B;
359
360 return C;
361 }
362 }
363
364 template<cgt::std_array_flat_c LeftType, cgt::vector_c RightType>
365 requires cgt::common_vector_c<LeftType, RightType>
366 && (cgt::numerical_c<cgt::first_type_t<LeftType>>)
367 && (cgt::std_array_c<cgt::first_type_t<RightType>>)
368 constexpr decltype(auto) operator*(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
369 {
370 std::size_t Size = B.size();
371
372 if constexpr(std::is_rvalue_reference_v<decltype(B)>)
373 {
374 for(std::size_t i=0; i < Size; ++i) B[i] = A * B[i];
375
376 return std::move(B);
377 }
378 else
379 {
380 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
381
382 for(std::size_t i=0; i < Size; ++i) C[i] = A * B[i];
383
384 return C;
385 }
386 }
387
389 template<cgt::vector_c LeftType, cgt::std_array_flat_c RightType>
390 requires cgt::common_vector_c<LeftType, RightType>
391 && (cgt::std_array_c<cgt::first_type_t<LeftType>>)
392 && (cgt::numerical_c<cgt::first_type_t<RightType>>)
393 constexpr decltype(auto) operator/(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
394 {
395 std::size_t Size = A.size();
396
397 if constexpr(std::is_rvalue_reference_v<decltype(A)>)
398 {
399 for(std::size_t i=0; i < Size; ++i) A[i] = A[i] / B;
400
401 return std::move(A);
402 }
403 else
404 {
405 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
406
407 for(std::size_t i=0; i < Size; ++i) C[i] = A[i] / B;
408
409 return C;
410 }
411 }
412
413 template<cgt::std_array_flat_c LeftType, cgt::vector_c RightType>
414 requires cgt::common_vector_c<LeftType, RightType>
415 && (cgt::numerical_c<cgt::first_type_t<LeftType>>)
416 && (cgt::std_array_c<cgt::first_type_t<RightType>>)
417 constexpr decltype(auto) operator/(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
418 {
419 std::size_t Size = B.size();
420
421 if constexpr(std::is_rvalue_reference_v<decltype(B)>)
422 {
423 for(std::size_t i=0; i < Size; ++i) B[i] = A / B[i];
424
425 return std::move(B);
426 }
427 else
428 {
429 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
430
431 for(std::size_t i=0; i < Size; ++i) C[i] = A / B[i];
432
433 return C;
434 }
435 }
436
438 template<cgt::vector_c LeftType, cgt::std_array_flat_c RightType>
439 requires cgt::common_vector_c<LeftType, RightType>
440 && (cgt::std_array_c<cgt::first_type_t<LeftType>>)
441 && (cgt::numerical_c<cgt::first_type_t<RightType>>)
442 constexpr decltype(auto) operator%(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
443 {
444 std::size_t Size = A.size();
445
446 // std::cout << "cgt::first_type_t<RightType> ' type : "
447 // >> cgt::first_type_t<RightType>{} << std::endl;
448
449 if constexpr(std::is_rvalue_reference_v<decltype(A)>)
450 {
451 for(std::size_t i=0; i < Size; ++i) A[i] = A[i] % B;
452
453 return std::move(A);
454 }
455 else
456 {
457 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
458
459 for(std::size_t i=0; i < Size; ++i) C[i] = A[i] % B;
460
461 return C;
462 }
463 }
464
465 template<cgt::std_array_flat_c LeftType, cgt::vector_c RightType>
466 requires cgt::common_vector_c<LeftType, RightType>
467 && (cgt::numerical_c<cgt::first_type_t<LeftType>>)
468 && (cgt::std_array_c<cgt::first_type_t<RightType>>)
469 constexpr decltype(auto) operator%(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
470 {
471 std::size_t Size = B.size();
472
473 if constexpr(std::is_rvalue_reference_v<decltype(B)>)
474 {
475 for(std::size_t i=0; i < Size; ++i) B[i] = A % B[i];
476
477 return std::move(B);
478 }
479 else
480 {
481 using c_t = cgt::common_vector_t<LeftType, RightType>; c_t C(Size);
482
483 for(std::size_t i=0; i < Size; ++i) C[i] = A % B[i];
484
485 return C;
486 }
487 }
488
490 template<cgt::vector_c LeftType, cgt::std_array_flat_c RightType>
491 requires cgt::std_array_c<cgt::first_type_t<LeftType>>
492 && cgt::numerical_c<cgt::first_type_t<RightType>>
493 && (std::tuple_size_v<cgt::first_type_t<LeftType>>
494 == std::tuple_size_v<std::remove_cvref_t<RightType>>)
495 constexpr decltype(auto) operator&(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
496 {
498 using element_t_b = cgt::first_type_t<RightType>;
499
500 std::size_t Size = A.size();
501
503 using vector_t = std::vector<element_t>;
504
505 vector_t R(Size);
506
507 for(std::size_t i=0; i < Size; ++i) R[i] = A[i] & B;
508
509 return R;
510 }
511
512 template<cgt::std_array_flat_c LeftType, cgt::vector_c RightType>
513 requires cgt::numerical_c<cgt::first_type_t<LeftType>>
514 && cgt::std_array_c<cgt::first_type_t<RightType>>
515 && (std::tuple_size_v<std::remove_cvref_t<LeftType>>
516 == std::tuple_size_v<cgt::first_type_t<RightType>>)
517 constexpr decltype(auto) operator&(LeftType&& A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
518 {
519 using element_t_a = cgt::first_type_t<LeftType>;
521
522 std::size_t Size = B.size();
523
525 using vector_t = std::vector<element_t>;
526
527 vector_t R(Size);
528
529 for(std::size_t i=0; i < Size; ++i) R[i] = A & B[i];
530
531 return R;
532 }
533
535 template<cgt::vector_c LeftType, cgt::numerical_c RightType>
536 requires cgt::common_vector_c<LeftType, RightType>
537 constexpr decltype(auto) operator+(LeftType&& A, RightType B) noexcept(!cpg::bDetectOverFlow)
538 {
540
541 std::size_t Size = A.size();
542
543 if constexpr( std::same_as<c_t, std::remove_cvref_t<LeftType>> &&
544 std::is_rvalue_reference_v<decltype(A)>)
545 {
546 for(std::size_t i=0; i < Size; ++i)
547 A[i] = cgt::sbo(A[i]) + cgt::sbo(B);
548
549 return std::move(A);
550 }
551 else
552 {
553 c_t C(Size);
554
555 for(std::size_t i=0; i < Size; ++i)
556 C[i] = cgt::sbo(A[i]) + cgt::sbo(B);
557
558 return C;
559 }
560 }
561
562 template<cgt::numerical_c LeftType, cgt::vector_c RightType>
563 requires cgt::common_vector_c<LeftType, RightType>
564 constexpr decltype(auto) operator+(LeftType A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
565 {
567
568 std::size_t Size = B.size();
569
570 if constexpr(std::same_as<c_t, std::remove_cvref_t<RightType>> &&
571 std::is_rvalue_reference_v<decltype(B)>)
572 {
573 for(std::size_t i=0; i < Size; ++i)
574 B[i] = cgt::sbo(A) + cgt::sbo(B[i]);
575
576 return std::move(B);
577 }
578 else
579 {
580 c_t C(Size);
581
582 for(std::size_t i=0; i < Size; ++i)
583 C[i] = cgt::sbo(A) + cgt::sbo(B[i]);
584
585 return C;
586 }
587 }
588
589 template<cgt::vector_c LeftType, cgt::numerical_c RightType>
590 requires cgt::common_vector_c<LeftType, RightType>
591 constexpr decltype(auto) operator-(LeftType&& A, RightType B) noexcept(!cpg::bDetectOverFlow)
592 {
594
595 std::size_t Size = A.size();
596
597 if constexpr( std::same_as<c_t, std::remove_cvref_t<LeftType>> &&
598 std::is_rvalue_reference_v<decltype(A)>)
599 {
600 for(std::size_t i=0; i < Size; ++i)
601 A[i] = cgt::sbo(A[i]) - cgt::sbo(B);
602
603 return std::move(A);
604 }
605 else
606 {
607 c_t C(Size);
608
609 for(std::size_t i=0; i < Size; ++i)
610 C[i] = cgt::sbo(A[i]) - cgt::sbo(B);
611
612 return C;
613 }
614 }
615
616 template<cgt::numerical_c LeftType, cgt::vector_c RightType>
617 requires cgt::common_vector_c<LeftType, RightType>
618 constexpr decltype(auto) operator-(LeftType A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
619 {
621
622 std::size_t Size = B.size();
623
624 if constexpr(std::same_as<c_t, std::remove_cvref_t<RightType>> &&
625 std::is_rvalue_reference_v<decltype(B)>)
626 {
627 for(std::size_t i=0; i < Size; ++i)
628 B[i] = cgt::sbo(A) - cgt::sbo(B[i]);
629
630 return std::move(B);
631 }
632 else
633 {
634 c_t C(Size);
635
636 for(std::size_t i=0; i < Size; ++i)
637 C[i] = cgt::sbo(A) - cgt::sbo(B[i]);
638
639 return C;
640 }
641 }
642
643 template<cgt::vector_c LeftType, cgt::numerical_c RightType>
644 requires cgt::common_vector_c<LeftType, RightType>
645 constexpr decltype(auto) operator*(LeftType&& A, RightType B) noexcept(!cpg::bDetectOverFlow)
646 {
648
649 std::size_t Size = A.size();
650
651 if constexpr( std::same_as<c_t, std::remove_cvref_t<LeftType>> &&
652 std::is_rvalue_reference_v<decltype(A)>)
653 {
654 for(std::size_t i=0; i < Size; ++i)
655 A[i] = cgt::sbo(A[i]) * cgt::sbo(B);
656
657 return std::move(A);
658 }
659 else
660 {
661 c_t C(Size);
662
663 for(std::size_t i=0; i < Size; ++i)
664 C[i] = cgt::sbo(A[i]) * cgt::sbo(B);
665
666 return C;
667 }
668 }
669
670 template<cgt::numerical_c LeftType, cgt::vector_c RightType>
671 requires cgt::common_vector_c<LeftType, RightType>
672 constexpr decltype(auto) operator*(LeftType A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
673 {
675
676 std::size_t Size = B.size();
677
678 if constexpr(std::same_as<c_t, std::remove_cvref_t<RightType>> &&
679 std::is_rvalue_reference_v<decltype(B)>)
680 {
681 for(std::size_t i=0; i < Size; ++i)
682 B[i] = cgt::sbo(A) * cgt::sbo(B[i]);
683
684 return std::move(B);
685 }
686 else
687 {
688 c_t C(Size);
689
690 for(std::size_t i=0; i < Size; ++i)
691 C[i] = cgt::sbo(A) * cgt::sbo(B[i]);
692
693 return C;
694 }
695 }
696
697 template<cgt::vector_c LeftType, cgt::numerical_c RightType>
698 requires cgt::common_vector_c<LeftType, RightType>
699 constexpr decltype(auto) operator/(LeftType&& A, RightType B) noexcept(!cpg::bDetectOverFlow)
700 {
702
703 std::size_t Size = A.size();
704
705 if constexpr( std::same_as<c_t, std::remove_cvref_t<LeftType>> &&
706 std::is_rvalue_reference_v<decltype(A)>)
707 {
708 for(std::size_t i=0; i < Size; ++i)
709 A[i] = cgt::sbo(A[i]) / cgt::sbo(B);
710
711 return std::move(A);
712 }
713 else
714 {
715 c_t C(Size);
716
717 for(std::size_t i=0; i < Size; ++i)
718 C[i] = cgt::sbo(A[i]) / cgt::sbo(B);
719
720 return C;
721 }
722 }
723
724 template<cgt::numerical_c LeftType, cgt::vector_c RightType>
725 requires cgt::common_vector_c<LeftType, RightType>
726 constexpr decltype(auto) operator/(LeftType A, RightType&& B) noexcept(!cpg::bDetectOverFlow)
727 {
729
730 std::size_t Size = B.size();
731
732 if constexpr(std::same_as<c_t, std::remove_cvref_t<RightType>> &&
733 std::is_rvalue_reference_v<decltype(B)>)
734 {
735 for(std::size_t i=0; i < Size; ++i)
736 B[i] = cgt::sbo(A) / cgt::sbo(B[i]);
737
738 return std::move(B);
739 }
740 else
741 {
742 c_t C(Size);
743
744 for(std::size_t i=0; i < Size; ++i)
745 C[i] = cgt::sbo(A) / cgt::sbo(B[i]);
746
747 return C;
748 }
749 }
750}
751// end of namespace std
752
753#endif
754// end of file
std::vector< Type > vector_t
typename hidden::st_first_element< std::remove_cvref_t< T > >::type first_type_t
Definition: cpg_types.hpp:2643
typename hidden::st_common_vector< std::remove_cvref_t< A >, std::remove_cvref_t< B > >::type common_vector_t
Definition: cpg_types.hpp:2808
constexpr auto sbo(T &&value) noexcept(!cpg::bDetectOverFlow)
Definition: cpg_types.hpp:2549
Includes subnamespace conversion.
constexpr const bool bDetectOverFlow
Definition: cpg_types.hpp:754
constexpr decltype(auto) operator&(LeftType &&A, RightType &&B) noexcept(!cpg::bDetectOverFlow)