// Copyright 2014 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code by Matt McCutchen, see the LICENSE file. #ifndef BIGUNSIGNED_H #define BIGUNSIGNED_H #include "NumberlikeArray.hh" /* A BigUnsigned object represents a nonnegative integer of size limited only by * available memory. BigUnsigneds support most mathematical operators and can * be converted to and from most primitive integer types. * * The number is stored as a NumberlikeArray of unsigned longs as if it were * written in base 256^sizeof(unsigned long). The least significant block is * first, and the length is such that the most significant block is nonzero. */ class BigUnsigned : protected NumberlikeArray<unsigned long> { … }; /* Implementing the return-by-value and assignment operators in terms of the * copy-less operations. The copy-less operations are responsible for making * any necessary temporary copies to work around aliasing. */ inline BigUnsigned BigUnsigned::operator +(const BigUnsigned &x) const { … } inline BigUnsigned BigUnsigned::operator -(const BigUnsigned &x) const { … } inline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const { … } inline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const { … } inline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const { … } inline BigUnsigned BigUnsigned::operator &(const BigUnsigned &x) const { … } inline BigUnsigned BigUnsigned::operator |(const BigUnsigned &x) const { … } inline BigUnsigned BigUnsigned::operator ^(const BigUnsigned &x) const { … } inline BigUnsigned BigUnsigned::operator <<(int b) const { … } inline BigUnsigned BigUnsigned::operator >>(int b) const { … } inline BigUnsigned& BigUnsigned::operator +=(const BigUnsigned &x) { … } inline BigUnsigned& BigUnsigned::operator -=(const BigUnsigned &x) { … } inline BigUnsigned& BigUnsigned::operator *=(const BigUnsigned &x) { … } inline BigUnsigned& BigUnsigned::operator /=(const BigUnsigned &x) { … } inline BigUnsigned& BigUnsigned::operator %=(const BigUnsigned &x) { … } inline BigUnsigned& BigUnsigned::operator &=(const BigUnsigned &x) { … } inline BigUnsigned& BigUnsigned::operator |=(const BigUnsigned &x) { … } inline BigUnsigned& BigUnsigned::operator ^=(const BigUnsigned &x) { … } inline BigUnsigned& BigUnsigned::operator <<=(int b) { … } inline BigUnsigned& BigUnsigned::operator >>=(int b) { … } /* Templates for conversions of BigUnsigned to and from primitive integers. * BigInteger.cc needs to instantiate convertToPrimitive, and the uses in * BigUnsigned.cc didn't do the trick; I think g++ inlined convertToPrimitive * instead of generating linkable instantiations. So for consistency, I put * all the templates here. */ // CONSTRUCTION FROM PRIMITIVE INTEGERS /* Initialize this BigUnsigned from the given primitive integer. The same * pattern works for all primitive integer types, so I put it into a template to * reduce code duplication. (Don't worry: this is protected and we instantiate * it only with primitive integer types.) Type X could be signed, but x is * known to be nonnegative. */ template <class X> void BigUnsigned::initFromPrimitive(X x) { … } /* Ditto, but first check that x is nonnegative. I could have put the check in * initFromPrimitive and let the compiler optimize it out for unsigned-type * instantiations, but I wanted to avoid the warning stupidly issued by g++ for * a condition that is constant in *any* instantiation, even if not in all. */ template <class X> void BigUnsigned::initFromSignedPrimitive(X x) { … } // CONVERSION TO PRIMITIVE INTEGERS /* Template with the same idea as initFromPrimitive. This might be slightly * slower than the previous version with the masks, but it's much shorter and * clearer, which is the library's stated goal. */ template <class X> X BigUnsigned::convertToPrimitive() const { … } /* Wrap the above in an x >= 0 test to make sure we got a nonnegative result, * not a negative one that happened to convert back into the correct nonnegative * one. (E.g., catch incorrect conversion of 2^31 to the long -2^31.) Again, * separated to avoid a g++ warning. */ template <class X> X BigUnsigned::convertToSignedPrimitive() const { … } #endif