27
27
#include " num/__private/ptr_type.h"
28
28
#include " num/integer_concepts.h"
29
29
#include " option/option.h"
30
- #include " tuple/tuple.h"
31
30
32
31
namespace sus ::containers {
33
32
template <class T , size_t N>
@@ -39,6 +38,11 @@ namespace sus::num {
39
38
struct u8 ;
40
39
}
41
40
41
+ namespace sus ::tuple {
42
+ template <class T , class ... Ts>
43
+ class Tuple ;
44
+ }
45
+
42
46
#define _sus__unsigned_impl (T, PrimitiveT, SignedT ) \
43
47
_sus__unsigned_storage (PrimitiveT); \
44
48
_sus__unsigned_constants (T, PrimitiveT); \
@@ -354,10 +358,12 @@ struct u8;
354
358
* an arithmetic overflow would occur. If an overflow would have occurred \
355
359
* then the wrapped value is returned. \
356
360
*/ \
357
- constexpr Tuple<T, bool > overflowing_add (const T& rhs) const & noexcept { \
361
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
362
+ ::sus::tuple::Tuple<T, bool >> \
363
+ constexpr Tuple overflowing_add (const T& rhs) const & noexcept { \
358
364
const auto out = \
359
365
__private::add_with_overflow (primitive_value, rhs.primitive_value ); \
360
- return Tuple<T, bool > ::with (out.value , out.overflow ); \
366
+ return Tuple::with (out.value , out.overflow ); \
361
367
} \
362
368
\
363
369
/* * Calculates self + rhs with an unsigned rhs \
@@ -366,12 +372,13 @@ struct u8;
366
372
* an arithmetic overflow would occur. If an overflow would have occurred \
367
373
* then the wrapped value is returned. \
368
374
*/ \
369
- template <std::same_as<SignedT> S> \
370
- constexpr Tuple<T, bool > overflowing_add_signed (const S& rhs) \
371
- const & noexcept { \
375
+ template <std::same_as<SignedT> S, \
376
+ std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
377
+ ::sus::tuple::Tuple<T, bool >> \
378
+ constexpr Tuple overflowing_add_signed (const S& rhs) const & noexcept { \
372
379
const auto r = __private::add_with_overflow_signed (primitive_value, \
373
380
rhs.primitive_value ); \
374
- return Tuple<T, bool > ::with (r.value , r.overflow ); \
381
+ return Tuple::with (r.value , r.overflow ); \
375
382
} \
376
383
\
377
384
/* * Saturating integer addition. Computes self + rhs, saturating at the \
@@ -452,10 +459,12 @@ struct u8;
452
459
* #Panics \
453
460
*This function will panic if rhs is 0. \
454
461
*/ \
455
- constexpr Tuple<T, bool > overflowing_div (const T& rhs) const & noexcept { \
462
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
463
+ ::sus::tuple::Tuple<T, bool >> \
464
+ constexpr Tuple overflowing_div (const T& rhs) const & noexcept { \
456
465
/* TODO: Allow opting out of all overflow checks? */ \
457
466
::sus::check (rhs.primitive_value != 0u ); \
458
- return Tuple<T, bool > ::with ( \
467
+ return Tuple::with ( \
459
468
__private::unchecked_div (primitive_value, rhs.primitive_value ), \
460
469
false ); \
461
470
} \
@@ -506,10 +515,12 @@ struct u8;
506
515
* whether an arithmetic overflow would occur. If an overflow would have \
507
516
* occurred then the wrapped value is returned. \
508
517
*/ \
509
- constexpr Tuple<T, bool > overflowing_mul (const T& rhs) const & noexcept { \
518
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
519
+ ::sus::tuple::Tuple<T, bool >> \
520
+ constexpr Tuple overflowing_mul (const T& rhs) const & noexcept { \
510
521
const auto out = \
511
522
__private::mul_with_overflow (primitive_value, rhs.primitive_value ); \
512
- return Tuple<T, bool > ::with (out.value , out.overflow ); \
523
+ return Tuple::with (out.value , out.overflow ); \
513
524
} \
514
525
\
515
526
/* * Saturating integer multiplication. Computes self * rhs, saturating at \
@@ -558,9 +569,11 @@ struct u8;
558
569
* represents the negation of this unsigned value. Note that for positive \
559
570
* unsigned values overflow always occurs, but negating 0 does not overflow. \
560
571
*/ \
561
- constexpr Tuple<T, bool > overflowing_neg () const & noexcept { \
562
- return Tuple<T, bool >::with ((~(*this )).wrapping_add (T (PrimitiveT{1u })), \
563
- primitive_value != 0u ); \
572
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
573
+ ::sus::tuple::Tuple<T, bool >> \
574
+ constexpr Tuple overflowing_neg () const & noexcept { \
575
+ return Tuple::with ((~(*this )).wrapping_add (T (PrimitiveT{1u })), \
576
+ primitive_value != 0u ); \
564
577
} \
565
578
\
566
579
/* * Wrapping (modular) negation. Computes `-self`, wrapping around at the \
@@ -600,10 +613,12 @@ struct u8;
600
613
* # Panics \
601
614
* This function will panic if rhs is 0. \
602
615
*/ \
603
- constexpr Tuple<T, bool > overflowing_rem (const T& rhs) const & noexcept { \
616
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
617
+ ::sus::tuple::Tuple<T, bool >> \
618
+ constexpr Tuple overflowing_rem (const T& rhs) const & noexcept { \
604
619
/* TODO: Allow opting out of all overflow checks? */ \
605
620
::sus::check (rhs.primitive_value != 0u ); \
606
- return Tuple<T, bool > ::with ( \
621
+ return Tuple::with ( \
607
622
__private::unchecked_rem (primitive_value, rhs.primitive_value ), \
608
623
false ); \
609
624
} \
@@ -662,11 +677,12 @@ struct u8;
662
677
* # Panics \
663
678
* This function will panic if rhs is 0. \
664
679
*/ \
665
- constexpr Tuple<T, bool > overflowing_div_euclid (const T& rhs) \
666
- const & noexcept { \
680
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
681
+ ::sus::tuple::Tuple<T, bool >> \
682
+ constexpr Tuple overflowing_div_euclid (const T& rhs) const & noexcept { \
667
683
/* TODO: Allow opting out of all overflow checks? */ \
668
684
::sus::check (rhs.primitive_value != 0u ); \
669
- return Tuple<T, bool > ::with ( \
685
+ return Tuple::with ( \
670
686
__private::unchecked_div (primitive_value, rhs.primitive_value ), \
671
687
false ); \
672
688
} \
@@ -727,11 +743,12 @@ struct u8;
727
743
* # Panics \
728
744
* This function will panic if rhs is 0. \
729
745
*/ \
730
- constexpr Tuple<T, bool > overflowing_rem_euclid (const T& rhs) \
731
- const & noexcept { \
746
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
747
+ ::sus::tuple::Tuple<T, bool >> \
748
+ constexpr Tuple overflowing_rem_euclid (const T& rhs) const & noexcept { \
732
749
/* TODO: Allow opting out of all overflow checks? */ \
733
750
::sus::check (rhs.primitive_value != 0u ); \
734
- return Tuple<T, bool > ::with ( \
751
+ return Tuple::with ( \
735
752
__private::unchecked_rem (primitive_value, rhs.primitive_value ), \
736
753
false ); \
737
754
} \
@@ -775,10 +792,12 @@ struct u8;
775
792
* where N is the number of bits, and this value is then used to perform the \
776
793
* shift. \
777
794
*/ \
778
- constexpr Tuple<T, bool > overflowing_shl (const u32 & rhs) const & noexcept { \
795
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
796
+ ::sus::tuple::Tuple<T, bool >> \
797
+ constexpr Tuple overflowing_shl (const u32 & rhs) const & noexcept { \
779
798
const auto out = \
780
799
__private::shl_with_overflow (primitive_value, rhs.primitive_value ); \
781
- return Tuple<T, bool > ::with (out.value , out.overflow ); \
800
+ return Tuple::with (out.value , out.overflow ); \
782
801
} \
783
802
\
784
803
/* * Panic-free bitwise shift-left; yields `*this << mask(rhs)`, where mask \
@@ -816,10 +835,12 @@ struct u8;
816
835
* where N is the number of bits, and this value is then used to perform the \
817
836
* shift. \
818
837
*/ \
819
- constexpr Tuple<T, bool > overflowing_shr (const u32 & rhs) const & noexcept { \
838
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
839
+ ::sus::tuple::Tuple<T, bool >> \
840
+ constexpr Tuple overflowing_shr (const u32 & rhs) const & noexcept { \
820
841
const auto out = \
821
842
__private::shr_with_overflow (primitive_value, rhs.primitive_value ); \
822
- return Tuple<T, bool > ::with (out.value , out.overflow ); \
843
+ return Tuple::with (out.value , out.overflow ); \
823
844
} \
824
845
\
825
846
/* * Panic-free bitwise shift-right; yields `*this >> mask(rhs)`, where mask \
@@ -857,10 +878,12 @@ struct u8;
857
878
* whether an arithmetic overflow would occur. If an overflow would have \
858
879
* occurred then the wrapped value is returned. \
859
880
*/ \
860
- constexpr Tuple<T, bool > overflowing_sub (const T& rhs) const & noexcept { \
881
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
882
+ ::sus::tuple::Tuple<T, bool >> \
883
+ constexpr Tuple overflowing_sub (const T& rhs) const & noexcept { \
861
884
const auto out = \
862
885
__private::sub_with_overflow (primitive_value, rhs.primitive_value ); \
863
- return Tuple<T, bool > ::with (out.value , out.overflow ); \
886
+ return Tuple::with (out.value , out.overflow ); \
864
887
} \
865
888
\
866
889
/* * Saturating integer subtraction. Computes self - rhs, saturating at the \
@@ -995,10 +1018,12 @@ struct u8;
995
1018
* Returns a tuple of the exponentiation along with a bool indicating \
996
1019
* whether an overflow happened. \
997
1020
*/ \
998
- constexpr Tuple<T, bool > overflowing_pow (const u32 & exp) const & noexcept { \
1021
+ template <std::same_as<::sus::tuple::Tuple<T, bool >> Tuple = \
1022
+ ::sus::tuple::Tuple<T, bool >> \
1023
+ constexpr Tuple overflowing_pow (const u32 & exp) const & noexcept { \
999
1024
const auto out = \
1000
1025
__private::pow_with_overflow (primitive_value, exp.primitive_value ); \
1001
- return Tuple<T, bool > ::with (out.value , out.overflow ); \
1026
+ return Tuple::with (out.value , out.overflow ); \
1002
1027
} \
1003
1028
\
1004
1029
/* * Wrapping (modular) exponentiation. Computes self.pow(exp), wrapping \
0 commit comments