@@ -156,12 +156,14 @@ namespace com::saxbophone::arby {
156156 * @brief Defaulted equality operator for Nat objects
157157 * @param rhs other Nat object to compare against
158158 * @returns `true` if objects are equal, otherwise `false`
159+ * @note Worst-case complexity: @f$ \mathcal{O(n)} @f$
159160 */
160161 constexpr bool operator ==(const Nat& rhs) const = default ;
161162 /* *
162163 * @brief three-way-comparison operator defines all relational operators
163164 * @param rhs other Nat object to compare against
164165 * @returns std::strong_ordering object for comparison
166+ * @note Complexity: @f$ \mathcal{O(n)} @f$
165167 */
166168 constexpr auto operator <=>(const Nat& rhs) const {
167169 // use size to indicate ordering if they differ
@@ -297,6 +299,7 @@ namespace com::saxbophone::arby {
297299 /* *
298300 * @brief custom ostream operator that allows class Nat to be printed
299301 * with std::cout and friends
302+ * @note Complexity is @f$ \mathcal{O(terrible)} @f$
300303 */
301304 friend std::ostream& operator <<(std::ostream& os, const Nat& object);
302305 /* *
@@ -306,6 +309,8 @@ namespace com::saxbophone::arby {
306309 /* *
307310 * @brief prefix increment
308311 * @returns new value of Nat object after incrementing
312+ * @note Best-case complexity: @f$ \mathcal{O(1)} @f$
313+ * @note Worst-case complexity: @f$ \mathcal{O(n)} @f$
309314 */
310315 constexpr Nat& operator ++() {
311316 // increment least significant digit then rollover remaining digits as needed
@@ -325,6 +330,8 @@ namespace com::saxbophone::arby {
325330 /* *
326331 * @brief postfix increment
327332 * @returns old value of Nat object before incrementing
333+ * @note Best-case complexity: @f$ \mathcal{O(1)} @f$
334+ * @note Worst-case complexity: @f$ \mathcal{O(n)} @f$
328335 */
329336 constexpr Nat operator ++(int ) {
330337 Nat old = *this ; // copy old value
@@ -335,10 +342,12 @@ namespace com::saxbophone::arby {
335342 * @brief prefix decrement
336343 * @returns new value of Nat object after decrementing
337344 * @throws std::underflow_error when value of Nat is `0`
345+ * @note Best-case complexity: @f$ \mathcal{O(1)} @f$
346+ * @note Worst-case complexity: @f$ \mathcal{O(n)} @f$
338347 */
339348 constexpr Nat& operator --() {
340349 // empty digits vector (means value is zero) is a special case
341- if (_digits.size () == 0 ) {
350+ if (_digits.empty () ) {
342351 throw std::underflow_error (" arithmetic underflow: can't decrement unsigned zero" );
343352 } else {
344353 // decrement least significant digit then borrow from remaining digits as needed
@@ -360,6 +369,8 @@ namespace com::saxbophone::arby {
360369 * @brief postfix decrement
361370 * @returns old value of Nat object before decrementing
362371 * @throws std::underflow_error when value of Nat is `0`
372+ * @note Best-case complexity: @f$ \mathcal{O(1)} @f$
373+ * @note Worst-case complexity: @f$ \mathcal{O(n)} @f$
363374 */
364375 constexpr Nat operator --(int ) {
365376 Nat old = *this ; // copy old value
@@ -371,10 +382,11 @@ namespace com::saxbophone::arby {
371382 * @details Adds other value to this Nat and assigns the result to self
372383 * @param rhs value to add to this Nat
373384 * @returns resulting object after addition-assignment
385+ * @note Complexity: @f$ \mathcal{O(n)} @f$
374386 */
375387 constexpr Nat& operator +=(Nat rhs) {
376- // either arg being a zero is a no-op, guard against this
377- if (_digits.size () != 0 or rhs._digits .size () != 0 ) {
388+ // both args being zero is a no-op, guard against this
389+ if (not ( _digits.empty () and rhs._digits .empty ()) ) {
378390 // make sure this and rhs are the same size, fill with leading zeroes if needed
379391 if (rhs._digits .size () > _digits.size ()) {
380392 _digits.push_front (rhs._digits .size () - _digits.size (), 0 );
@@ -404,6 +416,7 @@ namespace com::saxbophone::arby {
404416 * @brief Addition operator for Nat
405417 * @param lhs,rhs operands for the addition
406418 * @returns sum of lhs + rhs
419+ * @note Complexity: @f$ \mathcal{O(n)} @f$
407420 */
408421 friend constexpr Nat operator +(Nat lhs, const Nat& rhs) {
409422 lhs += rhs; // reuse compound assignment
@@ -415,11 +428,12 @@ namespace com::saxbophone::arby {
415428 * @param rhs value to subtract from this Nat
416429 * @returns resulting object after subtraction-assignment
417430 * @throws std::underflow_error when rhs is bigger than this
431+ * @note Complexity: @f$ \mathcal{O(n)} @f$
418432 */
419433 constexpr Nat& operator -=(Nat rhs) {
420434 // TODO: detect underflow early?
421435 // rhs being a zero is a no-op, guard against this
422- if (rhs._digits .size () != 0 ) {
436+ if (not rhs._digits .empty () ) {
423437 // make sure this and rhs are the same size, fill with leading zeroes if needed
424438 if (rhs._digits .size () > _digits.size ()) {
425439 _digits.push_front (rhs._digits .size () - _digits.size (), 0 );
@@ -444,7 +458,7 @@ namespace com::saxbophone::arby {
444458 }
445459 }
446460 // remove any leading zeroes
447- while (_digits.size () > 0 and _digits.front () == 0 ) {
461+ while (not _digits.empty () and _digits.front () == 0 ) {
448462 _digits.pop_front ();
449463 }
450464 return *this ; // return the result by reference
@@ -454,6 +468,7 @@ namespace com::saxbophone::arby {
454468 * @param lhs,rhs operands for the subtraction
455469 * @returns result of lhs - rhs
456470 * @throws std::underflow_error when rhs is bigger than lhs
471+ * @note Complexity: @f$ \mathcal{O(n)} @f$
457472 */
458473 friend constexpr Nat operator -(Nat lhs, const Nat& rhs) {
459474 lhs -= rhs; // reuse compound assignment
@@ -464,6 +479,7 @@ namespace com::saxbophone::arby {
464479 * @details Multiplies this Nat by other value and assigns the result to self
465480 * @param rhs value to multiply this Nat by
466481 * @returns resulting object after multiplication-assignment
482+ * @note Complexity: @f$ \mathcal{O(n^2)} @f$
467483 */
468484 constexpr Nat& operator *=(const Nat& rhs) {
469485 Nat product = *this * rhs; // uses friend *operator
@@ -475,12 +491,13 @@ namespace com::saxbophone::arby {
475491 * @brief Multiplication operator for Nat
476492 * @param lhs,rhs operands for the multiplication
477493 * @returns product of lhs * rhs
494+ * @note Complexity: @f$ \mathcal{O(n^2)} @f$
478495 */
479496 friend constexpr Nat operator *(const Nat& lhs, const Nat& rhs) {
480497 // init product to zero
481498 Nat product;
482499 // either operand being zero always results in zero, so only run the algorithm if they're both non-zero
483- if (lhs._digits .size () != 0 and rhs._digits .size () != 0 ) {
500+ if (not ( lhs._digits .empty () or rhs._digits .empty ()) ) {
484501 // multiply each digit from lhs with each digit from rhs
485502 std::size_t l = 0 ; // manual indices to track which digit we are on,
486503 std::size_t r = 0 ; // as codlili's iterators are not random-access
@@ -547,10 +564,11 @@ namespace com::saxbophone::arby {
547564 * @param lhs,rhs operands for the division/modulo operation
548565 * @returns pair of {quotient, remainder}
549566 * @throws std::domain_error when rhs is zero
567+ * @todo Work out time-complexity
550568 */
551569 static constexpr std::pair<Nat, Nat> divmod (const Nat& lhs, const Nat& rhs) {
552570 // division by zero is undefined
553- if (rhs._digits .size () == 0 ) {
571+ if (rhs._digits .empty () ) {
554572 throw std::domain_error (" division by zero" );
555573 }
556574 // this will gradually accumulate the calculated quotient
@@ -588,6 +606,7 @@ namespace com::saxbophone::arby {
588606 * @param rhs value to divide this Nat by
589607 * @returns resulting object after division-assignment
590608 * @throws std::domain_error when rhs is zero
609+ * @todo Work out time-complexity
591610 */
592611 constexpr Nat& operator /=(const Nat& rhs) {
593612 Nat quotient = *this / rhs; // uses friend /operator
@@ -600,6 +619,7 @@ namespace com::saxbophone::arby {
600619 * @note This implements floor-division, returning the quotient only
601620 * @param lhs,rhs operands for the division
602621 * @returns quotient of lhs / rhs
622+ * @todo Work out time-complexity
603623 */
604624 friend constexpr Nat operator /(Nat lhs, const Nat& rhs) {
605625 Nat quotient;
@@ -613,6 +633,7 @@ namespace com::saxbophone::arby {
613633 * @param rhs value to modulo-divide this Nat by
614634 * @returns resulting object after modulo-assignment
615635 * @throws std::domain_error when rhs is zero
636+ * @todo Work out time-complexity
616637 */
617638 constexpr Nat& operator %=(const Nat& rhs) {
618639 Nat remainder = *this % rhs; // uses friend %operator
@@ -626,6 +647,7 @@ namespace com::saxbophone::arby {
626647 * @param lhs,rhs operands for the division
627648 * @returns remainder of lhs / rhs
628649 * @throws std::domain_error when rhs is zero
650+ * @todo Work out time-complexity
629651 */
630652 friend constexpr Nat operator %(Nat lhs, const Nat& rhs) {
631653 Nat remainder;
@@ -634,6 +656,7 @@ namespace com::saxbophone::arby {
634656 }
635657 /* *
636658 * @brief bitwise OR-assignment
659+ * @note Complexity: @f$ \mathcal{O(n)} @f$
637660 */
638661 constexpr Nat& operator |=(const Nat& rhs) {
639662 // add additional digits to this if fewer than rhs
@@ -655,22 +678,26 @@ namespace com::saxbophone::arby {
655678 }
656679 /* *
657680 * @brief bitwise OR operator for Nat
681+ * @note Complexity: @f$ \mathcal{O(n)} @f$
658682 */
659683 friend constexpr Nat operator |(Nat lhs, const Nat& rhs) {
660684 lhs |= rhs; // reuse member operator
661685 return lhs;
662686 }
663687 /* *
664688 * @brief bitwise AND-assignment
689+ * @note Complexity: @f$ \mathcal{O(n)} @f$
665690 */
666691 constexpr Nat& operator &=(const Nat& rhs) {
667692 /*
668693 * if rhs has fewer digits than this, we can remove this' leading
669694 * digits because they would be AND'ed with implicit zero which is
670695 * always zero
671696 */
672- if (rhs._digits .size () < _digits.size ()) {
673- while (_digits.size () > rhs._digits .size ()) {
697+ std::size_t lhs_size = _digits.size ();
698+ std::size_t rhs_size = rhs._digits .size ();
699+ if (lhs_size > rhs_size) {
700+ for (std::size_t i = 0 ; i < lhs_size - rhs_size; i++) {
674701 _digits.pop_front ();
675702 }
676703 }
@@ -686,20 +713,22 @@ namespace com::saxbophone::arby {
686713 *it &= *rhs_it;
687714 }
688715 // remove any leading zeroes
689- while (_digits.size () > 0 and _digits.front () == 0 ) {
716+ while (not _digits.empty () and _digits.front () == 0 ) {
690717 _digits.pop_front ();
691718 }
692719 return *this ;
693720 }
694721 /* *
695722 * @brief bitwise AND operator for Nat
723+ * @note Complexity: @f$ \mathcal{O(n)} @f$
696724 */
697725 friend constexpr Nat operator &(Nat lhs, const Nat& rhs) {
698726 lhs &= rhs; // reuse member operator
699727 return lhs;
700728 }
701729 /* *
702730 * @brief bitwise XOR-assignment
731+ * @note Complexity: @f$ \mathcal{O(n)} @f$
703732 */
704733 constexpr Nat& operator ^=(const Nat& rhs) {
705734 Nat result = *this ^ rhs; // reuse friend function
@@ -709,6 +738,7 @@ namespace com::saxbophone::arby {
709738 }
710739 /* *
711740 * @brief bitwise XOR operator for Nat
741+ * @note Complexity: @f$ \mathcal{O(n)} @f$
712742 */
713743 friend constexpr Nat operator ^(Nat lhs, const Nat& rhs) {
714744 Nat result;
@@ -764,6 +794,7 @@ namespace com::saxbophone::arby {
764794 /* *
765795 * @brief contextual conversion to bool (behaves same way as int)
766796 * @returns `false` when value is `0`, otherwise `true`
797+ * @note Complexity is @f$ \mathcal{O(n)} @f$ but should be @f$ \mathcal{O(1)} @f$
767798 */
768799 explicit constexpr operator bool () const {
769800 // zero is false --all other values are true
0 commit comments