File indexing completed on 2025-08-28 09:11:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef XSIMD_API_HPP
0013 #define XSIMD_API_HPP
0014
0015 #include <complex>
0016 #include <cstddef>
0017 #include <limits>
0018 #include <ostream>
0019
0020 #include "../arch/xsimd_isa.hpp"
0021 #include "../types/xsimd_batch.hpp"
0022 #include "../types/xsimd_traits.hpp"
0023
0024 namespace xsimd
0025 {
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 template <class T, class A>
0057 XSIMD_INLINE batch<T, A> abs(batch<T, A> const& x) noexcept
0058 {
0059 detail::static_check_supported_config<T, A>();
0060 return kernel::abs<A>(x, A {});
0061 }
0062
0063
0064
0065
0066
0067
0068
0069
0070 template <class T, class A>
0071 XSIMD_INLINE batch<T, A> abs(batch<std::complex<T>, A> const& z) noexcept
0072 {
0073 detail::static_check_supported_config<T, A>();
0074 return kernel::abs<A>(z, A {});
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 template <class T, class A>
0086 XSIMD_INLINE auto add(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x + y)
0087 {
0088 detail::static_check_supported_config<T, A>();
0089 return x + y;
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099 template <class T, class A>
0100 XSIMD_INLINE batch<T, A> acos(batch<T, A> const& x) noexcept
0101 {
0102 detail::static_check_supported_config<T, A>();
0103 return kernel::acos<A>(x, A {});
0104 }
0105
0106
0107
0108
0109
0110
0111
0112
0113 template <class T, class A>
0114 XSIMD_INLINE batch<T, A> acosh(batch<T, A> const& x) noexcept
0115 {
0116 detail::static_check_supported_config<T, A>();
0117 return kernel::acosh<A>(x, A {});
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127 template <class T, class A>
0128 XSIMD_INLINE real_batch_type_t<batch<T, A>> arg(batch<T, A> const& z) noexcept
0129 {
0130 detail::static_check_supported_config<T, A>();
0131 return kernel::arg<A>(z, A {});
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141 template <class T, class A>
0142 XSIMD_INLINE batch<T, A> asin(batch<T, A> const& x) noexcept
0143 {
0144 detail::static_check_supported_config<T, A>();
0145 return kernel::asin<A>(x, A {});
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155 template <class T, class A>
0156 XSIMD_INLINE batch<T, A> asinh(batch<T, A> const& x) noexcept
0157 {
0158 detail::static_check_supported_config<T, A>();
0159 return kernel::asinh<A>(x, A {});
0160 }
0161
0162
0163
0164
0165
0166
0167
0168
0169 template <class T, class A>
0170 XSIMD_INLINE batch<T, A> atan(batch<T, A> const& x) noexcept
0171 {
0172 detail::static_check_supported_config<T, A>();
0173 return kernel::atan<A>(x, A {});
0174 }
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 template <class T, class A>
0186 XSIMD_INLINE batch<T, A> atan2(batch<T, A> const& x, batch<T, A> const& y) noexcept
0187 {
0188 detail::static_check_supported_config<T, A>();
0189 return kernel::atan2<A>(x, y, A {});
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199 template <class T, class A>
0200 XSIMD_INLINE batch<T, A> atanh(batch<T, A> const& x) noexcept
0201 {
0202 detail::static_check_supported_config<T, A>();
0203 return kernel::atanh<A>(x, A {});
0204 }
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 template <class T, class A>
0215 XSIMD_INLINE batch<T, A> avg(batch<T, A> const& x, batch<T, A> const& y) noexcept
0216 {
0217 detail::static_check_supported_config<T, A>();
0218 return kernel::avg<A>(x, y, A {});
0219 }
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229 template <class T, class A>
0230 XSIMD_INLINE batch<T, A> avgr(batch<T, A> const& x, batch<T, A> const& y) noexcept
0231 {
0232 detail::static_check_supported_config<T, A>();
0233 return kernel::avgr<A>(x, y, A {});
0234 }
0235
0236
0237
0238
0239
0240
0241
0242
0243 template <class T_out, class T_in, class A>
0244 XSIMD_INLINE batch_bool<T_out, A> batch_bool_cast(batch_bool<T_in, A> const& x) noexcept
0245 {
0246 detail::static_check_supported_config<T_out, A>();
0247 detail::static_check_supported_config<T_in, A>();
0248 static_assert(batch_bool<T_out, A>::size == batch_bool<T_in, A>::size, "Casting between incompatibles batch_bool types.");
0249 return kernel::batch_bool_cast<A>(x, batch_bool<T_out, A> {}, A {});
0250 }
0251
0252
0253
0254
0255
0256
0257
0258
0259 template <class T_out, class T_in, class A>
0260 XSIMD_INLINE batch<T_out, A> batch_cast(batch<T_in, A> const& x) noexcept
0261 {
0262 detail::static_check_supported_config<T_out, A>();
0263 detail::static_check_supported_config<T_in, A>();
0264 return kernel::batch_cast<A>(x, batch<T_out, A> {}, A {});
0265 }
0266
0267
0268
0269
0270
0271
0272
0273
0274 template <class T, class A>
0275 XSIMD_INLINE batch<T, A> bitofsign(batch<T, A> const& x) noexcept
0276 {
0277 detail::static_check_supported_config<T, A>();
0278 return kernel::bitofsign<A>(x, A {});
0279 }
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 template <class T, class A>
0290 XSIMD_INLINE auto bitwise_and(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x & y)
0291 {
0292 detail::static_check_supported_config<T, A>();
0293 return x & y;
0294 }
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 template <class T, class A>
0305 XSIMD_INLINE auto bitwise_and(batch_bool<T, A> const& x, batch_bool<T, A> const& y) noexcept -> decltype(x & y)
0306 {
0307 detail::static_check_supported_config<T, A>();
0308 return x & y;
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 template <class T, class A>
0320 XSIMD_INLINE batch<T, A> bitwise_andnot(batch<T, A> const& x, batch<T, A> const& y) noexcept
0321 {
0322 detail::static_check_supported_config<T, A>();
0323 return kernel::bitwise_andnot<A>(x, y, A {});
0324 }
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334 template <class T, class A>
0335 XSIMD_INLINE batch_bool<T, A> bitwise_andnot(batch_bool<T, A> const& x, batch_bool<T, A> const& y) noexcept
0336 {
0337 detail::static_check_supported_config<T, A>();
0338 return kernel::bitwise_andnot<A>(x, y, A {});
0339 }
0340
0341
0342
0343
0344
0345
0346
0347
0348 template <class T_out, class T_in, class A>
0349 XSIMD_INLINE batch<T_out, A> bitwise_cast(batch<T_in, A> const& x) noexcept
0350 {
0351 detail::static_check_supported_config<T_in, A>();
0352 detail::static_check_supported_config<T_out, A>();
0353 return kernel::bitwise_cast<A>(x, batch<T_out, A> {}, A {});
0354 }
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 template <class T, class A>
0365 XSIMD_INLINE batch<T, A> bitwise_lshift(batch<T, A> const& x, int shift) noexcept
0366 {
0367 detail::static_check_supported_config<T, A>();
0368 return kernel::bitwise_lshift<A>(x, shift, A {});
0369 }
0370 template <class T, class A>
0371 XSIMD_INLINE batch<T, A> bitwise_lshift(batch<T, A> const& x, batch<T, A> const& shift) noexcept
0372 {
0373 detail::static_check_supported_config<T, A>();
0374 return kernel::bitwise_lshift<A>(x, shift, A {});
0375 }
0376
0377
0378
0379
0380
0381
0382
0383
0384 template <class T, class A>
0385 XSIMD_INLINE batch<T, A> bitwise_not(batch<T, A> const& x) noexcept
0386 {
0387 detail::static_check_supported_config<T, A>();
0388 return kernel::bitwise_not<A>(x, A {});
0389 }
0390
0391
0392
0393
0394
0395
0396
0397
0398 template <class T, class A>
0399 XSIMD_INLINE batch_bool<T, A> bitwise_not(batch_bool<T, A> const& x) noexcept
0400 {
0401 detail::static_check_supported_config<T, A>();
0402 return kernel::bitwise_not<A>(x, A {});
0403 }
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413 template <class T, class A>
0414 XSIMD_INLINE auto bitwise_or(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x | y)
0415 {
0416 detail::static_check_supported_config<T, A>();
0417 return x | y;
0418 }
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428 template <class T, class A>
0429 XSIMD_INLINE auto bitwise_or(batch_bool<T, A> const& x, batch_bool<T, A> const& y) noexcept -> decltype(x | y)
0430 {
0431 detail::static_check_supported_config<T, A>();
0432 return x | y;
0433 }
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443 template <class T, class A>
0444 XSIMD_INLINE batch<T, A> bitwise_rshift(batch<T, A> const& x, int shift) noexcept
0445 {
0446 detail::static_check_supported_config<T, A>();
0447 return kernel::bitwise_rshift<A>(x, shift, A {});
0448 }
0449 template <class T, class A>
0450 XSIMD_INLINE batch<T, A> bitwise_rshift(batch<T, A> const& x, batch<T, A> const& shift) noexcept
0451 {
0452 detail::static_check_supported_config<T, A>();
0453 return kernel::bitwise_rshift<A>(x, shift, A {});
0454 }
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464 template <class T, class A>
0465 XSIMD_INLINE auto bitwise_xor(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x ^ y)
0466 {
0467 detail::static_check_supported_config<T, A>();
0468 return x ^ y;
0469 }
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479 template <class T, class A>
0480 XSIMD_INLINE auto bitwise_xor(batch_bool<T, A> const& x, batch_bool<T, A> const& y) noexcept -> decltype(x ^ y)
0481 {
0482 detail::static_check_supported_config<T, A>();
0483 return x ^ y;
0484 }
0485
0486
0487
0488
0489
0490
0491
0492
0493 template <class T, class A = default_arch>
0494 XSIMD_INLINE batch<T, A> broadcast(T v) noexcept
0495 {
0496 detail::static_check_supported_config<T, A>();
0497 return batch<T, A>::broadcast(v);
0498 }
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 template <class To, class A = default_arch, class From>
0509 XSIMD_INLINE simd_return_type<From, To, A> broadcast_as(From v) noexcept
0510 {
0511 detail::static_check_supported_config<From, A>();
0512 using batch_value_type = typename simd_return_type<From, To, A>::value_type;
0513 using value_type = typename std::conditional<std::is_same<From, bool>::value,
0514 bool,
0515 batch_value_type>::type;
0516 return simd_return_type<From, To, A>(value_type(v));
0517 }
0518
0519
0520
0521
0522
0523
0524
0525
0526 template <class T, class A>
0527 XSIMD_INLINE batch<T, A> cbrt(batch<T, A> const& x) noexcept
0528 {
0529 detail::static_check_supported_config<T, A>();
0530 return kernel::cbrt<A>(x, A {});
0531 }
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541 template <class T, class A>
0542 XSIMD_INLINE batch<T, A> ceil(batch<T, A> const& x) noexcept
0543 {
0544 detail::static_check_supported_config<T, A>();
0545 return kernel::ceil<A>(x, A {});
0546 }
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557 template <class T, class A>
0558 XSIMD_INLINE batch<T, A> clip(batch<T, A> const& x, batch<T, A> const& lo, batch<T, A> const& hi) noexcept
0559 {
0560 detail::static_check_supported_config<T, A>();
0561 return kernel::clip(x, lo, hi, A {});
0562 }
0563
0564
0565
0566
0567
0568
0569
0570 template <class T, class A>
0571 XSIMD_INLINE batch<T, A> compress(batch<T, A> const& x, batch_bool<T, A> const& mask) noexcept
0572 {
0573 detail::static_check_supported_config<T, A>();
0574 return kernel::compress<A>(x, mask, A {});
0575 }
0576
0577
0578
0579
0580
0581
0582
0583
0584 template <class A, class T>
0585 XSIMD_INLINE complex_batch_type_t<batch<T, A>> conj(batch<T, A> const& z) noexcept
0586 {
0587 return kernel::conj(z, A {});
0588 }
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600 template <class T, class A>
0601 XSIMD_INLINE batch<T, A> copysign(batch<T, A> const& x, batch<T, A> const& y) noexcept
0602 {
0603 detail::static_check_supported_config<T, A>();
0604 return kernel::copysign<A>(x, y, A {});
0605 }
0606
0607
0608
0609
0610
0611
0612
0613
0614 template <class T, class A>
0615 XSIMD_INLINE batch<T, A> cos(batch<T, A> const& x) noexcept
0616 {
0617 detail::static_check_supported_config<T, A>();
0618 return kernel::cos<A>(x, A {});
0619 }
0620
0621
0622
0623
0624
0625
0626
0627
0628 template <class T, class A>
0629 XSIMD_INLINE batch<T, A> cosh(batch<T, A> const& x) noexcept
0630 {
0631 detail::static_check_supported_config<T, A>();
0632 return kernel::cosh<A>(x, A {});
0633 }
0634
0635
0636
0637
0638
0639
0640
0641
0642 template <class T, class A>
0643 XSIMD_INLINE size_t count(batch_bool<T, A> const& x) noexcept
0644 {
0645 detail::static_check_supported_config<T, A>();
0646 return kernel::count<A>(x, A {});
0647 }
0648
0649
0650
0651
0652
0653
0654
0655
0656 template <class T, class A>
0657 XSIMD_INLINE batch<T, A> decr(batch<T, A> const& x) noexcept
0658 {
0659 detail::static_check_supported_config<T, A>();
0660 return kernel::decr<A>(x, A {});
0661 }
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672 template <class T, class A, class Mask>
0673 XSIMD_INLINE batch<T, A> decr_if(batch<T, A> const& x, Mask const& mask) noexcept
0674 {
0675 detail::static_check_supported_config<T, A>();
0676 return kernel::decr_if<A>(x, mask, A {});
0677 }
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687 template <class T, class A>
0688 XSIMD_INLINE auto div(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x / y)
0689 {
0690 detail::static_check_supported_config<T, A>();
0691 return x / y;
0692 }
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702 template <class T, class A>
0703 XSIMD_INLINE auto eq(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x == y)
0704 {
0705 detail::static_check_supported_config<T, A>();
0706 return x == y;
0707 }
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717 template <class T, class A>
0718 XSIMD_INLINE auto eq(batch_bool<T, A> const& x, batch_bool<T, A> const& y) noexcept -> decltype(x == y)
0719 {
0720 detail::static_check_supported_config<T, A>();
0721 return x == y;
0722 }
0723
0724
0725
0726
0727
0728
0729
0730
0731 template <class T, class A>
0732 XSIMD_INLINE batch<T, A> exp(batch<T, A> const& x) noexcept
0733 {
0734 detail::static_check_supported_config<T, A>();
0735 return kernel::exp<A>(x, A {});
0736 }
0737
0738
0739
0740
0741
0742
0743
0744
0745 template <class T, class A>
0746 XSIMD_INLINE batch<T, A> exp10(batch<T, A> const& x) noexcept
0747 {
0748 detail::static_check_supported_config<T, A>();
0749 return kernel::exp10<A>(x, A {});
0750 }
0751
0752
0753
0754
0755
0756
0757
0758
0759 template <class T, class A>
0760 XSIMD_INLINE batch<T, A> exp2(batch<T, A> const& x) noexcept
0761 {
0762 detail::static_check_supported_config<T, A>();
0763 return kernel::exp2<A>(x, A {});
0764 }
0765
0766
0767
0768
0769
0770
0771
0772 template <class T, class A>
0773 XSIMD_INLINE batch<T, A> expand(batch<T, A> const& x, batch_bool<T, A> const& mask) noexcept
0774 {
0775 detail::static_check_supported_config<T, A>();
0776 return kernel::expand<A>(x, mask, A {});
0777 }
0778
0779
0780
0781
0782
0783
0784
0785
0786 template <class T, class A>
0787 XSIMD_INLINE batch<T, A> expm1(batch<T, A> const& x) noexcept
0788 {
0789 detail::static_check_supported_config<T, A>();
0790 return kernel::expm1<A>(x, A {});
0791 }
0792
0793
0794
0795
0796
0797
0798
0799
0800 template <class T, class A>
0801 XSIMD_INLINE batch<T, A> erf(batch<T, A> const& x) noexcept
0802 {
0803 detail::static_check_supported_config<T, A>();
0804 return kernel::erf<A>(x, A {});
0805 }
0806
0807
0808
0809
0810
0811
0812
0813
0814 template <class T, class A>
0815 XSIMD_INLINE batch<T, A> erfc(batch<T, A> const& x) noexcept
0816 {
0817 detail::static_check_supported_config<T, A>();
0818 return kernel::erfc<A>(x, A {});
0819 }
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831 template <class T, class A>
0832 XSIMD_INLINE batch<T, A> extract_pair(batch<T, A> const& x, batch<T, A> const& y, std::size_t i) noexcept
0833 {
0834 detail::static_check_supported_config<T, A>();
0835 return kernel::extract_pair<A>(x, y, i, A {});
0836 }
0837
0838
0839
0840
0841
0842
0843
0844
0845 template <class T, class A>
0846 XSIMD_INLINE batch<T, A> fabs(batch<T, A> const& x) noexcept
0847 {
0848 detail::static_check_supported_config<T, A>();
0849 return kernel::abs<A>(x, A {});
0850 }
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861 template <class T, class A>
0862 XSIMD_INLINE batch<T, A> fdim(batch<T, A> const& x, batch<T, A> const& y) noexcept
0863 {
0864 detail::static_check_supported_config<T, A>();
0865 return kernel::fdim<A>(x, y, A {});
0866 }
0867
0868
0869
0870
0871
0872
0873
0874
0875
0876 template <class T, class A>
0877 XSIMD_INLINE batch<T, A> floor(batch<T, A> const& x) noexcept
0878 {
0879 detail::static_check_supported_config<T, A>();
0880 return kernel::floor<A>(x, A {});
0881 }
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891
0892 template <class T, class A>
0893 XSIMD_INLINE batch<T, A> fma(batch<T, A> const& x, batch<T, A> const& y, batch<T, A> const& z) noexcept
0894 {
0895 detail::static_check_supported_config<T, A>();
0896 return kernel::fma<A>(x, y, z, A {});
0897 }
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907 template <class T, class A>
0908 XSIMD_INLINE batch<T, A> fmax(batch<T, A> const& x, batch<T, A> const& y) noexcept
0909 {
0910 detail::static_check_supported_config<T, A>();
0911 return kernel::max<A>(x, y, A {});
0912 }
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922 template <class T, class A>
0923 XSIMD_INLINE batch<T, A> fmin(batch<T, A> const& x, batch<T, A> const& y) noexcept
0924 {
0925 detail::static_check_supported_config<T, A>();
0926 return kernel::min<A>(x, y, A {});
0927 }
0928
0929
0930
0931
0932
0933
0934
0935
0936
0937 template <class T, class A>
0938 XSIMD_INLINE batch<T, A> fmod(batch<T, A> const& x, batch<T, A> const& y) noexcept
0939 {
0940 detail::static_check_supported_config<T, A>();
0941 return kernel::fmod<A>(x, y, A {});
0942 }
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953 template <class T, class A>
0954 XSIMD_INLINE batch<T, A> fms(batch<T, A> const& x, batch<T, A> const& y, batch<T, A> const& z) noexcept
0955 {
0956 detail::static_check_supported_config<T, A>();
0957 return kernel::fms<A>(x, y, z, A {});
0958 }
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969 template <class T, class A>
0970 XSIMD_INLINE batch<T, A> fnma(batch<T, A> const& x, batch<T, A> const& y, batch<T, A> const& z) noexcept
0971 {
0972 detail::static_check_supported_config<T, A>();
0973 return kernel::fnma<A>(x, y, z, A {});
0974 }
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985 template <class T, class A>
0986 XSIMD_INLINE batch<T, A> fnms(batch<T, A> const& x, batch<T, A> const& y, batch<T, A> const& z) noexcept
0987 {
0988 detail::static_check_supported_config<T, A>();
0989 return kernel::fnms<A>(x, y, z, A {});
0990 }
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000 template <class T, class A>
1001 XSIMD_INLINE batch<T, A> frexp(const batch<T, A>& x, batch<as_integer_t<T>, A>& y) noexcept
1002 {
1003 detail::static_check_supported_config<T, A>();
1004 return kernel::frexp<A>(x, y, A {});
1005 }
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 template <class T, class A>
1017 XSIMD_INLINE batch_bool<T, A> ge(batch<T, A> const& x, batch<T, A> const& y) noexcept
1018 {
1019 detail::static_check_supported_config<T, A>();
1020 return x >= y;
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 template <class T, class A>
1033 XSIMD_INLINE batch_bool<T, A> gt(batch<T, A> const& x, batch<T, A> const& y) noexcept
1034 {
1035 detail::static_check_supported_config<T, A>();
1036 return x > y;
1037 }
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048 template <class T, class A>
1049 XSIMD_INLINE batch<T, A> haddp(batch<T, A> const* row) noexcept
1050 {
1051 detail::static_check_supported_config<T, A>();
1052 return kernel::haddp<A>(row, A {});
1053 }
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064 template <class T, class A>
1065 XSIMD_INLINE batch<T, A> hypot(batch<T, A> const& x, batch<T, A> const& y) noexcept
1066 {
1067 detail::static_check_supported_config<T, A>();
1068 return kernel::hypot<A>(x, y, A {});
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078 template <class T, class A>
1079 XSIMD_INLINE real_batch_type_t<batch<T, A>> imag(batch<T, A> const& x) noexcept
1080 {
1081 detail::static_check_supported_config<T, A>();
1082 return kernel::imag<A>(x, A {});
1083 }
1084
1085
1086
1087
1088
1089
1090
1091
1092 template <class T, class A>
1093 XSIMD_INLINE batch<T, A> incr(batch<T, A> const& x) noexcept
1094 {
1095 detail::static_check_supported_config<T, A>();
1096 return kernel::incr<A>(x, A {});
1097 }
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108 template <class T, class A, class Mask>
1109 XSIMD_INLINE batch<T, A> incr_if(batch<T, A> const& x, Mask const& mask) noexcept
1110 {
1111 detail::static_check_supported_config<T, A>();
1112 return kernel::incr_if<A>(x, mask, A {});
1113 }
1114
1115
1116
1117
1118
1119
1120
1121 template <class B>
1122 XSIMD_INLINE B infinity()
1123 {
1124 using T = typename B::value_type;
1125 using A = typename B::arch_type;
1126 detail::static_check_supported_config<T, A>();
1127 return B(std::numeric_limits<T>::infinity());
1128 }
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139 template <class T, class A, size_t I>
1140 XSIMD_INLINE batch<T, A> insert(batch<T, A> const& x, T val, index<I> pos) noexcept
1141 {
1142 detail::static_check_supported_config<T, A>();
1143 return kernel::insert<A>(x, val, pos, A {});
1144 }
1145
1146
1147
1148
1149
1150
1151
1152
1153 template <class T, class A>
1154 XSIMD_INLINE batch_bool<T, A> is_even(batch<T, A> const& x) noexcept
1155 {
1156 detail::static_check_supported_config<T, A>();
1157 return kernel::is_even<A>(x, A {});
1158 }
1159
1160
1161
1162
1163
1164
1165
1166
1167 template <class T, class A>
1168 XSIMD_INLINE batch_bool<T, A> is_flint(batch<T, A> const& x) noexcept
1169 {
1170 detail::static_check_supported_config<T, A>();
1171 return kernel::is_flint<A>(x, A {});
1172 }
1173
1174
1175
1176
1177
1178
1179
1180
1181 template <class T, class A>
1182 XSIMD_INLINE batch_bool<T, A> is_odd(batch<T, A> const& x) noexcept
1183 {
1184 detail::static_check_supported_config<T, A>();
1185 return kernel::is_odd<A>(x, A {});
1186 }
1187
1188
1189
1190
1191
1192
1193
1194
1195 template <class T, class A>
1196 XSIMD_INLINE typename batch<T, A>::batch_bool_type isinf(batch<T, A> const& x) noexcept
1197 {
1198 detail::static_check_supported_config<T, A>();
1199 return kernel::isinf<A>(x, A {});
1200 }
1201
1202
1203
1204
1205
1206
1207
1208
1209 template <class T, class A>
1210 XSIMD_INLINE typename batch<T, A>::batch_bool_type isfinite(batch<T, A> const& x) noexcept
1211 {
1212 detail::static_check_supported_config<T, A>();
1213 return kernel::isfinite<A>(x, A {});
1214 }
1215
1216
1217
1218
1219
1220
1221
1222
1223 template <class T, class A>
1224 XSIMD_INLINE typename batch<T, A>::batch_bool_type isnan(batch<T, A> const& x) noexcept
1225 {
1226 detail::static_check_supported_config<T, A>();
1227 return kernel::isnan<A>(x, A {});
1228 }
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238 template <class T, class A>
1239 XSIMD_INLINE batch<T, A> ldexp(const batch<T, A>& x, const batch<as_integer_t<T>, A>& y) noexcept
1240 {
1241 detail::static_check_supported_config<T, A>();
1242 return kernel::ldexp<A>(x, y, A {});
1243 }
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253 template <class T, class A>
1254 XSIMD_INLINE batch_bool<T, A> le(batch<T, A> const& x, batch<T, A> const& y) noexcept
1255 {
1256 detail::static_check_supported_config<T, A>();
1257 return x <= y;
1258 }
1259
1260
1261
1262
1263
1264
1265
1266
1267 template <class T, class A>
1268 XSIMD_INLINE batch<T, A> lgamma(batch<T, A> const& x) noexcept
1269 {
1270 detail::static_check_supported_config<T, A>();
1271 return kernel::lgamma<A>(x, A {});
1272 }
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282 template <class To, class A = default_arch, class From>
1283 XSIMD_INLINE simd_return_type<From, To, A> load_as(From const* ptr, aligned_mode) noexcept
1284 {
1285 using batch_value_type = typename simd_return_type<From, To, A>::value_type;
1286 detail::static_check_supported_config<From, A>();
1287 detail::static_check_supported_config<To, A>();
1288 return kernel::load_aligned<A>(ptr, kernel::convert<batch_value_type> {}, A {});
1289 }
1290
1291 template <class To, class A = default_arch>
1292 XSIMD_INLINE simd_return_type<bool, To, A> load_as(bool const* ptr, aligned_mode) noexcept
1293 {
1294 detail::static_check_supported_config<To, A>();
1295 return simd_return_type<bool, To, A>::load_aligned(ptr);
1296 }
1297
1298 template <class To, class A = default_arch, class From>
1299 XSIMD_INLINE simd_return_type<std::complex<From>, To, A> load_as(std::complex<From> const* ptr, aligned_mode) noexcept
1300 {
1301 detail::static_check_supported_config<To, A>();
1302 using batch_value_type = typename simd_return_type<std::complex<From>, To, A>::value_type;
1303 return kernel::load_complex_aligned<A>(ptr, kernel::convert<batch_value_type> {}, A {});
1304 }
1305
1306 #ifdef XSIMD_ENABLE_XTL_COMPLEX
1307 template <class To, class A = default_arch, class From, bool i3ec>
1308 XSIMD_INLINE simd_return_type<xtl::xcomplex<From, From, i3ec>, To, A> load_as(xtl::xcomplex<From, From, i3ec> const* ptr, aligned_mode) noexcept
1309 {
1310 detail::static_check_supported_config<To, A>();
1311 detail::static_check_supported_config<From, A>();
1312 return load_as<To>(reinterpret_cast<std::complex<From> const*>(ptr), aligned_mode());
1313 }
1314 #endif
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 template <class To, class A = default_arch, class From>
1325 XSIMD_INLINE simd_return_type<From, To, A> load_as(From const* ptr, unaligned_mode) noexcept
1326 {
1327 using batch_value_type = typename simd_return_type<From, To, A>::value_type;
1328 detail::static_check_supported_config<To, A>();
1329 detail::static_check_supported_config<From, A>();
1330 return kernel::load_unaligned<A>(ptr, kernel::convert<batch_value_type> {}, A {});
1331 }
1332
1333 template <class To, class A = default_arch>
1334 XSIMD_INLINE simd_return_type<bool, To, A> load_as(bool const* ptr, unaligned_mode) noexcept
1335 {
1336 return simd_return_type<bool, To, A>::load_unaligned(ptr);
1337 }
1338
1339 template <class To, class A = default_arch, class From>
1340 XSIMD_INLINE simd_return_type<std::complex<From>, To, A> load_as(std::complex<From> const* ptr, unaligned_mode) noexcept
1341 {
1342 detail::static_check_supported_config<To, A>();
1343 detail::static_check_supported_config<From, A>();
1344 using batch_value_type = typename simd_return_type<std::complex<From>, To, A>::value_type;
1345 return kernel::load_complex_unaligned<A>(ptr, kernel::convert<batch_value_type> {}, A {});
1346 }
1347
1348 #ifdef XSIMD_ENABLE_XTL_COMPLEX
1349 template <class To, class A = default_arch, class From, bool i3ec>
1350 XSIMD_INLINE simd_return_type<xtl::xcomplex<From, From, i3ec>, To, A> load_as(xtl::xcomplex<From, From, i3ec> const* ptr, unaligned_mode) noexcept
1351 {
1352 detail::static_check_supported_config<To, A>();
1353 detail::static_check_supported_config<From, A>();
1354 return load_as<To>(reinterpret_cast<std::complex<From> const*>(ptr), unaligned_mode());
1355 }
1356 #endif
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366 template <class A = default_arch, class From>
1367 XSIMD_INLINE batch<From, A> load(From const* ptr, aligned_mode = {}) noexcept
1368 {
1369 detail::static_check_supported_config<From, A>();
1370 return load_as<From, A>(ptr, aligned_mode {});
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381 template <class A = default_arch, class From>
1382 XSIMD_INLINE batch<From, A> load(From const* ptr, unaligned_mode) noexcept
1383 {
1384 detail::static_check_supported_config<From, A>();
1385 return load_as<From, A>(ptr, unaligned_mode {});
1386 }
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396 template <class A = default_arch, class From>
1397 XSIMD_INLINE batch<From, A> load_aligned(From const* ptr) noexcept
1398 {
1399 detail::static_check_supported_config<From, A>();
1400 return load_as<From, A>(ptr, aligned_mode {});
1401 }
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411 template <class A = default_arch, class From>
1412 XSIMD_INLINE batch<From, A> load_unaligned(From const* ptr) noexcept
1413 {
1414 detail::static_check_supported_config<From, A>();
1415 return load_as<From, A>(ptr, unaligned_mode {});
1416 }
1417
1418
1419
1420
1421
1422
1423
1424
1425 template <class T, class A>
1426 XSIMD_INLINE batch<T, A> log(batch<T, A> const& x) noexcept
1427 {
1428 detail::static_check_supported_config<T, A>();
1429 return kernel::log<A>(x, A {});
1430 }
1431
1432
1433
1434
1435
1436
1437
1438 template <class T, class A>
1439 XSIMD_INLINE batch<T, A> log2(batch<T, A> const& x) noexcept
1440 {
1441 detail::static_check_supported_config<T, A>();
1442 return kernel::log2<A>(x, A {});
1443 }
1444
1445
1446
1447
1448
1449
1450
1451 template <class T, class A>
1452 XSIMD_INLINE batch<T, A> log10(batch<T, A> const& x) noexcept
1453 {
1454 detail::static_check_supported_config<T, A>();
1455 return kernel::log10<A>(x, A {});
1456 }
1457
1458
1459
1460
1461
1462
1463
1464 template <class T, class A>
1465 XSIMD_INLINE batch<T, A> log1p(batch<T, A> const& x) noexcept
1466 {
1467 detail::static_check_supported_config<T, A>();
1468 return kernel::log1p<A>(x, A {});
1469 }
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479 template <class T, class A>
1480 XSIMD_INLINE batch_bool<T, A> lt(batch<T, A> const& x, batch<T, A> const& y) noexcept
1481 {
1482 detail::static_check_supported_config<T, A>();
1483 return x < y;
1484 }
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494 template <class T, class A>
1495 XSIMD_INLINE batch<T, A> max(batch<T, A> const& x, batch<T, A> const& y) noexcept
1496 {
1497 detail::static_check_supported_config<T, A>();
1498 return kernel::max<A>(x, y, A {});
1499 }
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509 template <class T, class A>
1510 XSIMD_INLINE batch<T, A> min(batch<T, A> const& x, batch<T, A> const& y) noexcept
1511 {
1512 detail::static_check_supported_config<T, A>();
1513 return kernel::min<A>(x, y, A {});
1514 }
1515
1516
1517
1518
1519
1520
1521
1522 template <class B>
1523 XSIMD_INLINE B minusinfinity() noexcept
1524 {
1525 using T = typename B::value_type;
1526 using A = typename B::arch_type;
1527 detail::static_check_supported_config<T, A>();
1528 return B(-std::numeric_limits<T>::infinity());
1529 }
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539 template <class T, class A>
1540 XSIMD_INLINE auto mod(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x % y)
1541 {
1542 detail::static_check_supported_config<T, A>();
1543 return x % y;
1544 }
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555 template <class T, class A>
1556 XSIMD_INLINE auto mul(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x * y)
1557 {
1558 detail::static_check_supported_config<T, A>();
1559 return x * y;
1560 }
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570 template <class T, class A>
1571 XSIMD_INLINE batch<T, A> nearbyint(batch<T, A> const& x) noexcept
1572 {
1573 detail::static_check_supported_config<T, A>();
1574 return kernel::nearbyint<A>(x, A {});
1575 }
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587 template <class T, class A>
1588 XSIMD_INLINE batch<as_integer_t<T>, A>
1589 nearbyint_as_int(batch<T, A> const& x) noexcept
1590 {
1591 detail::static_check_supported_config<T, A>();
1592 return kernel::nearbyint_as_int(x, A {});
1593 }
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603 template <class T, class A>
1604 XSIMD_INLINE auto neq(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x != y)
1605 {
1606 detail::static_check_supported_config<T, A>();
1607 return x != y;
1608 }
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618 template <class T, class A>
1619 XSIMD_INLINE auto neq(batch_bool<T, A> const& x, batch_bool<T, A> const& y) noexcept -> decltype(x != y)
1620 {
1621 detail::static_check_supported_config<T, A>();
1622 return x != y;
1623 }
1624
1625
1626
1627
1628
1629
1630
1631
1632 template <class T, class A>
1633 XSIMD_INLINE batch<T, A> neg(batch<T, A> const& x) noexcept
1634 {
1635 detail::static_check_supported_config<T, A>();
1636 return -x;
1637 }
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648 template <class T, class A>
1649 XSIMD_INLINE batch<T, A> nextafter(batch<T, A> const& x, batch<T, A> const& y) noexcept
1650 {
1651 detail::static_check_supported_config<T, A>();
1652 return kernel::nextafter<A>(x, y, A {});
1653 }
1654
1655
1656
1657
1658
1659
1660
1661
1662 template <class T, class A>
1663 XSIMD_INLINE real_batch_type_t<batch<T, A>> norm(batch<T, A> const& x) noexcept
1664 {
1665 detail::static_check_supported_config<T, A>();
1666 return kernel::norm(x, A {});
1667 }
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677 template <class T, class A>
1678 XSIMD_INLINE complex_batch_type_t<batch<T, A>> polar(batch<T, A> const& r, batch<T, A> const& theta = batch<T, A> {}) noexcept
1679 {
1680 detail::static_check_supported_config<T, A>();
1681 return kernel::polar<A>(r, theta, A {});
1682 }
1683
1684
1685
1686
1687
1688
1689
1690
1691 template <class T, class A>
1692 XSIMD_INLINE batch<T, A> pos(batch<T, A> const& x) noexcept
1693 {
1694 detail::static_check_supported_config<T, A>();
1695 return +x;
1696 }
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707 template <class T, class A>
1708 XSIMD_INLINE batch<T, A> pow(batch<T, A> const& x, batch<T, A> const& y) noexcept
1709 {
1710 detail::static_check_supported_config<T, A>();
1711 return kernel::pow<A>(x, y, A {});
1712 }
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723 template <class T, class A>
1724 XSIMD_INLINE batch<std::complex<T>, A> pow(batch<std::complex<T>, A> const& x, batch<T, A> const& y) noexcept
1725 {
1726 detail::static_check_supported_config<T, A>();
1727 return kernel::pow<A>(x, y, A {});
1728 }
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739 template <class T, class A>
1740 XSIMD_INLINE batch<std::complex<T>, A> pow(batch<T, A> const& x, batch<std::complex<T>, A> const& y) noexcept
1741 {
1742 detail::static_check_supported_config<T, A>();
1743 return kernel::pow<A>(x, y, A {});
1744 }
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755 template <class T, class ITy, class A, class = typename std::enable_if<std::is_integral<ITy>::value, void>::type>
1756 XSIMD_INLINE batch<T, A> pow(batch<T, A> const& x, ITy y) noexcept
1757 {
1758 detail::static_check_supported_config<T, A>();
1759 return kernel::ipow<A>(x, y, A {});
1760 }
1761
1762
1763
1764
1765
1766
1767
1768
1769 template <class T, class A>
1770 XSIMD_INLINE complex_batch_type_t<batch<T, A>> proj(batch<T, A> const& z) noexcept
1771 {
1772 detail::static_check_supported_config<T, A>();
1773 return kernel::proj(z, A {});
1774 }
1775
1776
1777
1778
1779
1780
1781
1782
1783 template <class T, class A>
1784 XSIMD_INLINE real_batch_type_t<batch<T, A>> real(batch<T, A> const& z) noexcept
1785 {
1786 detail::static_check_supported_config<T, A>();
1787 return kernel::real<A>(z, A {});
1788 }
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799 template <class T, class A, class = typename std::enable_if<std::is_floating_point<T>::value, void>::type>
1800 XSIMD_INLINE batch<T, A> reciprocal(batch<T, A> const& x) noexcept
1801 {
1802 detail::static_check_supported_config<T, A>();
1803 return kernel::reciprocal(x, A {});
1804 }
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814 template <class T, class A, class F>
1815 XSIMD_INLINE T reduce(F&& f, batch<T, A> const& x) noexcept
1816 {
1817 detail::static_check_supported_config<T, A>();
1818 return kernel::detail::reduce(std::forward<F>(f), x, std::integral_constant<unsigned, batch<T, A>::size>());
1819 }
1820
1821
1822
1823
1824
1825
1826
1827
1828 template <class T, class A>
1829 XSIMD_INLINE T reduce_add(batch<T, A> const& x) noexcept
1830 {
1831 detail::static_check_supported_config<T, A>();
1832 return kernel::reduce_add<A>(x, A {});
1833 }
1834
1835
1836
1837
1838
1839
1840
1841
1842 template <class T, class A>
1843 XSIMD_INLINE T reduce_max(batch<T, A> const& x) noexcept
1844 {
1845 detail::static_check_supported_config<T, A>();
1846 return kernel::reduce_max<A>(x, A {});
1847 }
1848
1849
1850
1851
1852
1853
1854
1855
1856 template <class T, class A>
1857 XSIMD_INLINE T reduce_min(batch<T, A> const& x) noexcept
1858 {
1859 detail::static_check_supported_config<T, A>();
1860 return kernel::reduce_min<A>(x, A {});
1861 }
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871 template <class T, class A>
1872 XSIMD_INLINE batch<T, A> remainder(batch<T, A> const& x, batch<T, A> const& y) noexcept
1873 {
1874 detail::static_check_supported_config<T, A>();
1875 return kernel::remainder<A>(x, y, A {});
1876 }
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886 template <class T, class A>
1887 XSIMD_INLINE batch<T, A> rint(batch<T, A> const& x) noexcept
1888 {
1889 detail::static_check_supported_config<T, A>();
1890 return nearbyint(x);
1891 }
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904 template <size_t N, class T, class A>
1905 XSIMD_INLINE batch<T, A> rotate_left(batch<T, A> const& x) noexcept
1906 {
1907 detail::static_check_supported_config<T, A>();
1908 return kernel::rotate_left<N, A>(x, A {});
1909 }
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922 template <size_t N, class T, class A>
1923 XSIMD_INLINE batch<T, A> rotate_right(batch<T, A> const& x) noexcept
1924 {
1925 detail::static_check_supported_config<T, A>();
1926 return kernel::rotate_right<N, A>(x, A {});
1927 }
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938 template <class T, class A>
1939 XSIMD_INLINE batch<T, A> rotl(batch<T, A> const& x, int shift) noexcept
1940 {
1941 detail::static_check_supported_config<T, A>();
1942 return kernel::rotl<A>(x, shift, A {});
1943 }
1944 template <class T, class A>
1945 XSIMD_INLINE batch<T, A> rotl(batch<T, A> const& x, batch<T, A> const& shift) noexcept
1946 {
1947 detail::static_check_supported_config<T, A>();
1948 return kernel::rotl<A>(x, shift, A {});
1949 }
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960 template <class T, class A>
1961 XSIMD_INLINE batch<T, A> rotr(batch<T, A> const& x, int shift) noexcept
1962 {
1963 detail::static_check_supported_config<T, A>();
1964 return kernel::rotr<A>(x, shift, A {});
1965 }
1966 template <class T, class A>
1967 XSIMD_INLINE batch<T, A> rotr(batch<T, A> const& x, batch<T, A> const& shift) noexcept
1968 {
1969 detail::static_check_supported_config<T, A>();
1970 return kernel::rotr<A>(x, shift, A {});
1971 }
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982 template <class T, class A>
1983 XSIMD_INLINE batch<T, A> round(batch<T, A> const& x) noexcept
1984 {
1985 detail::static_check_supported_config<T, A>();
1986 return kernel::round<A>(x, A {});
1987 }
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000 template <class T, class A>
2001 XSIMD_INLINE batch<T, A> rsqrt(batch<T, A> const& x) noexcept
2002 {
2003 detail::static_check_supported_config<T, A>();
2004 return kernel::rsqrt<A>(x, A {});
2005 }
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017 template <class T, class A>
2018 XSIMD_INLINE batch<T, A> sadd(batch<T, A> const& x, batch<T, A> const& y) noexcept
2019 {
2020 detail::static_check_supported_config<T, A>();
2021 return kernel::sadd<A>(x, y, A {});
2022 }
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038 template <class T, class A>
2039 XSIMD_INLINE batch<T, A> select(batch_bool<T, A> const& cond, batch<T, A> const& true_br, batch<T, A> const& false_br) noexcept
2040 {
2041 detail::static_check_supported_config<T, A>();
2042 return kernel::select<A>(cond, true_br, false_br, A {});
2043 }
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059 template <class T, class A>
2060 XSIMD_INLINE batch<std::complex<T>, A> select(batch_bool<T, A> const& cond, batch<std::complex<T>, A> const& true_br, batch<std::complex<T>, A> const& false_br) noexcept
2061 {
2062 detail::static_check_supported_config<T, A>();
2063 return kernel::select<A>(cond, true_br, false_br, A {});
2064 }
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080 template <class T, class A, bool... Values>
2081 XSIMD_INLINE batch<T, A> select(batch_bool_constant<T, A, Values...> const& cond, batch<T, A> const& true_br, batch<T, A> const& false_br) noexcept
2082 {
2083 detail::static_check_supported_config<T, A>();
2084 return kernel::select<A>(cond, true_br, false_br, A {});
2085 }
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103 template <class T, class A, class Vt, Vt... Values>
2104 XSIMD_INLINE typename std::enable_if<std::is_arithmetic<T>::value, batch<T, A>>::type
2105 shuffle(batch<T, A> const& x, batch<T, A> const& y, batch_constant<Vt, A, Values...> mask) noexcept
2106 {
2107 static_assert(sizeof(T) == sizeof(Vt), "consistent mask");
2108 detail::static_check_supported_config<T, A>();
2109 return kernel::shuffle<A>(x, y, mask, A {});
2110 }
2111
2112
2113
2114
2115
2116
2117
2118
2119 template <class T, class A>
2120 XSIMD_INLINE batch<T, A> sign(batch<T, A> const& x) noexcept
2121 {
2122 detail::static_check_supported_config<T, A>();
2123 return kernel::sign<A>(x, A {});
2124 }
2125
2126
2127
2128
2129
2130
2131
2132
2133 template <class T, class A>
2134 XSIMD_INLINE batch<T, A> signnz(batch<T, A> const& x) noexcept
2135 {
2136 detail::static_check_supported_config<T, A>();
2137 return kernel::signnz<A>(x, A {});
2138 }
2139
2140
2141
2142
2143
2144
2145
2146
2147 template <class T, class A>
2148 XSIMD_INLINE batch<T, A> sin(batch<T, A> const& x) noexcept
2149 {
2150 detail::static_check_supported_config<T, A>();
2151 return kernel::sin<A>(x, A {});
2152 }
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162 template <class T, class A>
2163 XSIMD_INLINE std::pair<batch<T, A>, batch<T, A>> sincos(batch<T, A> const& x) noexcept
2164 {
2165 detail::static_check_supported_config<T, A>();
2166 return kernel::sincos<A>(x, A {});
2167 }
2168
2169
2170
2171
2172
2173
2174
2175
2176 template <class T, class A>
2177 XSIMD_INLINE batch<T, A> sinh(batch<T, A> const& x) noexcept
2178 {
2179 detail::static_check_supported_config<T, A>();
2180 return kernel::sinh<A>(x, A {});
2181 }
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193 template <size_t N, class T, class A>
2194 XSIMD_INLINE batch<T, A> slide_left(batch<T, A> const& x) noexcept
2195 {
2196 static_assert(std::is_integral<T>::value, "can only slide batch of integers");
2197 detail::static_check_supported_config<T, A>();
2198 return kernel::slide_left<N, A>(x, A {});
2199 }
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211 template <size_t N, class T, class A>
2212 XSIMD_INLINE batch<T, A> slide_right(batch<T, A> const& x) noexcept
2213 {
2214 static_assert(std::is_integral<T>::value, "can only slide batch of integers");
2215 detail::static_check_supported_config<T, A>();
2216 return kernel::slide_right<N, A>(x, A {});
2217 }
2218
2219
2220
2221
2222
2223
2224
2225
2226 template <class T, class A>
2227 XSIMD_INLINE batch<T, A> sqrt(batch<T, A> const& x) noexcept
2228 {
2229 detail::static_check_supported_config<T, A>();
2230 return kernel::sqrt<A>(x, A {});
2231 }
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242 template <class T, class A>
2243 XSIMD_INLINE batch<T, A> ssub(batch<T, A> const& x, batch<T, A> const& y) noexcept
2244 {
2245 detail::static_check_supported_config<T, A>();
2246 return kernel::ssub<A>(x, y, A {});
2247 }
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257 template <class To, class A = default_arch, class From>
2258 XSIMD_INLINE void store_as(To* dst, batch<From, A> const& src, aligned_mode) noexcept
2259 {
2260 detail::static_check_supported_config<From, A>();
2261 kernel::store_aligned<A>(dst, src, A {});
2262 }
2263
2264 template <class A = default_arch, class From>
2265 XSIMD_INLINE void store_as(bool* dst, batch_bool<From, A> const& src, aligned_mode) noexcept
2266 {
2267 detail::static_check_supported_config<From, A>();
2268 kernel::store<A>(src, dst, A {});
2269 }
2270
2271 template <class To, class A = default_arch, class From>
2272 XSIMD_INLINE void store_as(std::complex<To>* dst, batch<std::complex<From>, A> const& src, aligned_mode) noexcept
2273 {
2274 detail::static_check_supported_config<std::complex<From>, A>();
2275 kernel::store_complex_aligned<A>(dst, src, A {});
2276 }
2277
2278 #ifdef XSIMD_ENABLE_XTL_COMPLEX
2279 template <class To, class A = default_arch, class From, bool i3ec>
2280 XSIMD_INLINE void store_as(xtl::xcomplex<To, To, i3ec>* dst, batch<std::complex<From>, A> const& src, aligned_mode) noexcept
2281 {
2282 store_as(reinterpret_cast<std::complex<To>*>(dst), src, aligned_mode());
2283 }
2284 #endif
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294 template <class To, class A = default_arch, class From>
2295 XSIMD_INLINE void store_as(To* dst, batch<From, A> const& src, unaligned_mode) noexcept
2296 {
2297 detail::static_check_supported_config<From, A>();
2298 kernel::store_unaligned<A>(dst, src, A {});
2299 }
2300
2301 template <class A = default_arch, class From>
2302 XSIMD_INLINE void store_as(bool* dst, batch_bool<From, A> const& src, unaligned_mode) noexcept
2303 {
2304 detail::static_check_supported_config<From, A>();
2305 kernel::store<A>(src, dst, A {});
2306 }
2307
2308 template <class To, class A = default_arch, class From>
2309 XSIMD_INLINE void store_as(std::complex<To>* dst, batch<std::complex<From>, A> const& src, unaligned_mode) noexcept
2310 {
2311 detail::static_check_supported_config<std::complex<From>, A>();
2312 kernel::store_complex_unaligned<A>(dst, src, A {});
2313 }
2314
2315 #ifdef XSIMD_ENABLE_XTL_COMPLEX
2316 template <class To, class A = default_arch, class From, bool i3ec>
2317 XSIMD_INLINE void store_as(xtl::xcomplex<To, To, i3ec>* dst, batch<std::complex<From>, A> const& src, unaligned_mode) noexcept
2318 {
2319 detail::static_check_supported_config<std::complex<From>, A>();
2320 store_as(reinterpret_cast<std::complex<To>*>(dst), src, unaligned_mode());
2321 }
2322 #endif
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332 template <class A, class T>
2333 XSIMD_INLINE void store(T* mem, batch<T, A> const& val, aligned_mode = {}) noexcept
2334 {
2335 store_as<T, A>(mem, val, aligned_mode {});
2336 }
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346 template <class A, class T>
2347 XSIMD_INLINE void store(T* mem, batch<T, A> const& val, unaligned_mode) noexcept
2348 {
2349 store_as<T, A>(mem, val, unaligned_mode {});
2350 }
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360 template <class A, class T>
2361 XSIMD_INLINE void store_aligned(T* mem, batch<T, A> const& val) noexcept
2362 {
2363 store_as<T, A>(mem, val, aligned_mode {});
2364 }
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374 template <class A, class T>
2375 XSIMD_INLINE void store_unaligned(T* mem, batch<T, A> const& val) noexcept
2376 {
2377 store_as<T, A>(mem, val, unaligned_mode {});
2378 }
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389 template <class T, class A>
2390 XSIMD_INLINE auto sub(batch<T, A> const& x, batch<T, A> const& y) noexcept -> decltype(x - y)
2391 {
2392 detail::static_check_supported_config<T, A>();
2393 return x - y;
2394 }
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405 template <class T, class A, class Vt, Vt... Values>
2406 XSIMD_INLINE typename std::enable_if<std::is_arithmetic<T>::value, batch<T, A>>::type
2407 swizzle(batch<T, A> const& x, batch_constant<Vt, A, Values...> mask) noexcept
2408 {
2409 static_assert(sizeof(T) == sizeof(Vt), "consistent mask");
2410 detail::static_check_supported_config<T, A>();
2411 return kernel::swizzle<A>(x, mask, A {});
2412 }
2413 template <class T, class A, class Vt, Vt... Values>
2414 XSIMD_INLINE batch<std::complex<T>, A> swizzle(batch<std::complex<T>, A> const& x, batch_constant<Vt, A, Values...> mask) noexcept
2415 {
2416 static_assert(sizeof(T) == sizeof(Vt), "consistent mask");
2417 detail::static_check_supported_config<T, A>();
2418 return kernel::swizzle<A>(x, mask, A {});
2419 }
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430 template <class T, class A, class Vt>
2431 XSIMD_INLINE typename std::enable_if<std::is_arithmetic<T>::value, batch<T, A>>::type
2432 swizzle(batch<T, A> const& x, batch<Vt, A> mask) noexcept
2433 {
2434 static_assert(sizeof(T) == sizeof(Vt), "consistent mask");
2435 detail::static_check_supported_config<T, A>();
2436 return kernel::swizzle<A>(x, mask, A {});
2437 }
2438
2439 template <class T, class A, class Vt>
2440 XSIMD_INLINE batch<std::complex<T>, A> swizzle(batch<std::complex<T>, A> const& x, batch<Vt, A> mask) noexcept
2441 {
2442 static_assert(sizeof(T) == sizeof(Vt), "consistent mask");
2443 detail::static_check_supported_config<T, A>();
2444 return kernel::swizzle<A>(x, mask, A {});
2445 }
2446
2447
2448
2449
2450
2451
2452
2453
2454 template <class T, class A>
2455 XSIMD_INLINE batch<T, A> tan(batch<T, A> const& x) noexcept
2456 {
2457 detail::static_check_supported_config<T, A>();
2458 return kernel::tan<A>(x, A {});
2459 }
2460
2461
2462
2463
2464
2465
2466
2467
2468 template <class T, class A>
2469 XSIMD_INLINE batch<T, A> tanh(batch<T, A> const& x) noexcept
2470 {
2471 detail::static_check_supported_config<T, A>();
2472 return kernel::tanh<A>(x, A {});
2473 }
2474
2475
2476
2477
2478
2479
2480
2481
2482 template <class T, class A>
2483 XSIMD_INLINE batch<T, A> tgamma(batch<T, A> const& x) noexcept
2484 {
2485 detail::static_check_supported_config<T, A>();
2486 return kernel::tgamma<A>(x, A {});
2487 }
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497 template <class T, class A>
2498 XSIMD_INLINE batch<as_float_t<T>, A> to_float(batch<T, A> const& i) noexcept
2499 {
2500 detail::static_check_supported_config<T, A>();
2501 return batch_cast<as_float_t<T>>(i);
2502 }
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512 template <class T, class A>
2513 XSIMD_INLINE batch<as_integer_t<T>, A> to_int(batch<T, A> const& x) noexcept
2514 {
2515 detail::static_check_supported_config<T, A>();
2516 return batch_cast<as_integer_t<T>>(x);
2517 }
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528 template <class T, class A>
2529 XSIMD_INLINE void transpose(batch<T, A>* matrix_begin, batch<T, A>* matrix_end) noexcept
2530 {
2531 assert((matrix_end - matrix_begin == batch<T, A>::size) && "correctly sized matrix");
2532 detail::static_check_supported_config<T, A>();
2533 return kernel::transpose(matrix_begin, matrix_end, A {});
2534 }
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544 template <class T, class A>
2545 XSIMD_INLINE batch<T, A> trunc(batch<T, A> const& x) noexcept
2546 {
2547 detail::static_check_supported_config<T, A>();
2548 return kernel::trunc<A>(x, A {});
2549 }
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560 template <class T, class A>
2561 XSIMD_INLINE batch<T, A> zip_hi(batch<T, A> const& x, batch<T, A> const& y) noexcept
2562 {
2563 detail::static_check_supported_config<T, A>();
2564 return kernel::zip_hi<A>(x, y, A {});
2565 }
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576 template <class T, class A>
2577 XSIMD_INLINE batch<T, A> zip_lo(batch<T, A> const& x, batch<T, A> const& y) noexcept
2578 {
2579 detail::static_check_supported_config<T, A>();
2580 return kernel::zip_lo<A>(x, y, A {});
2581 }
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593 template <class T, class A, typename std::enable_if<std::is_integral<T>::value, int>::type = 3>
2594 XSIMD_INLINE batch<T, A> bitwise_cast(batch_bool<T, A> const& self) noexcept
2595 {
2596 T z(0);
2597 detail::static_check_supported_config<T, A>();
2598 return select(self, batch<T, A>(T(~z)), batch<T, A>(z));
2599 }
2600
2601 template <class T, class A, typename std::enable_if<std::is_floating_point<T>::value, int>::type = 3>
2602 XSIMD_INLINE batch<T, A> bitwise_cast(batch_bool<T, A> const& self) noexcept
2603 {
2604 T z0(0), z1(0);
2605 using int_type = as_unsigned_integer_t<T>;
2606 int_type value(~int_type(0));
2607 std::memcpy(&z1, &value, sizeof(int_type));
2608 detail::static_check_supported_config<T, A>();
2609 return select(self, batch<T, A>(z1), batch<T, A>(z0));
2610 }
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620 template <class T, class A>
2621 XSIMD_INLINE bool all(batch_bool<T, A> const& x) noexcept
2622 {
2623 detail::static_check_supported_config<T, A>();
2624 return kernel::all<A>(x, A {});
2625 }
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635 template <class T, class A>
2636 XSIMD_INLINE bool any(batch_bool<T, A> const& x) noexcept
2637 {
2638 detail::static_check_supported_config<T, A>();
2639 return kernel::any<A>(x, A {});
2640 }
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650 template <class T, class A>
2651 XSIMD_INLINE bool none(batch_bool<T, A> const& x) noexcept
2652 {
2653 detail::static_check_supported_config<T, A>();
2654 return !xsimd::any(x);
2655 }
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665 template <class T, class A>
2666 XSIMD_INLINE std::ostream& operator<<(std::ostream& o, batch<T, A> const& x) noexcept
2667 {
2668 detail::static_check_supported_config<T, A>();
2669 constexpr auto size = batch<T, A>::size;
2670 alignas(A::alignment()) T buffer[size];
2671 x.store_aligned(&buffer[0]);
2672 o << '(';
2673 for (std::size_t i = 0; i < size - 1; ++i)
2674 o << buffer[i] << ", ";
2675 return o << buffer[size - 1] << ')';
2676 }
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686 template <class T, class A>
2687 XSIMD_INLINE std::ostream& operator<<(std::ostream& o, batch_bool<T, A> const& x) noexcept
2688 {
2689 detail::static_check_supported_config<T, A>();
2690 constexpr auto size = batch_bool<T, A>::size;
2691 alignas(A::alignment()) bool buffer[size];
2692 x.store_aligned(&buffer[0]);
2693 o << '(';
2694 for (std::size_t i = 0; i < size - 1; ++i)
2695 o << buffer[i] << ", ";
2696 return o << buffer[size - 1] << ')';
2697 }
2698 }
2699
2700 #endif