| Index: third_party/bigint/NumberlikeArray.hh
|
| diff --git a/third_party/bigint/NumberlikeArray.hh b/third_party/bigint/NumberlikeArray.hh
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..53c8e5be8f53b88905e234a31185599de774e742
|
| --- /dev/null
|
| +++ b/third_party/bigint/NumberlikeArray.hh
|
| @@ -0,0 +1,177 @@
|
| +#ifndef NUMBERLIKEARRAY_H
|
| +#define NUMBERLIKEARRAY_H
|
| +
|
| +// Make sure we have NULL.
|
| +#ifndef NULL
|
| +#define NULL 0
|
| +#endif
|
| +
|
| +/* A NumberlikeArray<Blk> object holds a heap-allocated array of Blk with a
|
| + * length and a capacity and provides basic memory management features.
|
| + * BigUnsigned and BigUnsignedInABase both subclass it.
|
| + *
|
| + * NumberlikeArray provides no information hiding. Subclasses should use
|
| + * nonpublic inheritance and manually expose members as desired using
|
| + * declarations like this:
|
| + *
|
| + * public:
|
| + * NumberlikeArray< the-type-argument >::getLength;
|
| + */
|
| +template <class Blk>
|
| +class NumberlikeArray {
|
| +public:
|
| +
|
| + // Type for the index of a block in the array
|
| + typedef unsigned int Index;
|
| + // The number of bits in a block, defined below.
|
| + static const unsigned int N;
|
| +
|
| + // The current allocated capacity of this NumberlikeArray (in blocks)
|
| + Index cap;
|
| + // The actual length of the value stored in this NumberlikeArray (in blocks)
|
| + Index len;
|
| + // Heap-allocated array of the blocks (can be NULL if len == 0)
|
| + Blk *blk;
|
| +
|
| + // Constructs a ``zero'' NumberlikeArray with the given capacity.
|
| + NumberlikeArray(Index c) : cap(c), len(0) {
|
| + blk = (cap > 0) ? (new Blk[cap]) : NULL;
|
| + }
|
| +
|
| + /* Constructs a zero NumberlikeArray without allocating a backing array.
|
| + * A subclass that doesn't know the needed capacity at initialization
|
| + * time can use this constructor and then overwrite blk without first
|
| + * deleting it. */
|
| + NumberlikeArray() : cap(0), len(0) {
|
| + blk = NULL;
|
| + }
|
| +
|
| + // Destructor. Note that `delete NULL' is a no-op.
|
| + ~NumberlikeArray() {
|
| + delete [] blk;
|
| + }
|
| +
|
| + /* Ensures that the array has at least the requested capacity; may
|
| + * destroy the contents. */
|
| + void allocate(Index c);
|
| +
|
| + /* Ensures that the array has at least the requested capacity; does not
|
| + * destroy the contents. */
|
| + void allocateAndCopy(Index c);
|
| +
|
| + // Copy constructor
|
| + NumberlikeArray(const NumberlikeArray<Blk> &x);
|
| +
|
| + // Assignment operator
|
| + void operator=(const NumberlikeArray<Blk> &x);
|
| +
|
| + // Constructor that copies from a given array of blocks
|
| + NumberlikeArray(const Blk *b, Index blen);
|
| +
|
| + // ACCESSORS
|
| + Index getCapacity() const { return cap; }
|
| + Index getLength() const { return len; }
|
| + Blk getBlock(Index i) const { return blk[i]; }
|
| + bool isEmpty() const { return len == 0; }
|
| +
|
| + /* Equality comparison: checks if both objects have the same length and
|
| + * equal (==) array elements to that length. Subclasses may wish to
|
| + * override. */
|
| + bool operator ==(const NumberlikeArray<Blk> &x) const;
|
| +
|
| + bool operator !=(const NumberlikeArray<Blk> &x) const {
|
| + return !operator ==(x);
|
| + }
|
| +};
|
| +
|
| +/* BEGIN TEMPLATE DEFINITIONS. They are present here so that source files that
|
| + * include this header file can generate the necessary real definitions. */
|
| +
|
| +template <class Blk>
|
| +const unsigned int NumberlikeArray<Blk>::N = 8 * sizeof(Blk);
|
| +
|
| +template <class Blk>
|
| +void NumberlikeArray<Blk>::allocate(Index c) {
|
| + // If the requested capacity is more than the current capacity...
|
| + if (c > cap) {
|
| + // Delete the old number array
|
| + delete [] blk;
|
| + // Allocate the new array
|
| + cap = c;
|
| + blk = new Blk[cap];
|
| + }
|
| +}
|
| +
|
| +template <class Blk>
|
| +void NumberlikeArray<Blk>::allocateAndCopy(Index c) {
|
| + // If the requested capacity is more than the current capacity...
|
| + if (c > cap) {
|
| + Blk *oldBlk = blk;
|
| + // Allocate the new number array
|
| + cap = c;
|
| + blk = new Blk[cap];
|
| + // Copy number blocks
|
| + Index i;
|
| + for (i = 0; i < len; i++)
|
| + blk[i] = oldBlk[i];
|
| + // Delete the old array
|
| + delete [] oldBlk;
|
| + }
|
| +}
|
| +
|
| +template <class Blk>
|
| +NumberlikeArray<Blk>::NumberlikeArray(const NumberlikeArray<Blk> &x)
|
| + : len(x.len) {
|
| + // Create array
|
| + cap = len;
|
| + blk = new Blk[cap];
|
| + // Copy blocks
|
| + Index i;
|
| + for (i = 0; i < len; i++)
|
| + blk[i] = x.blk[i];
|
| +}
|
| +
|
| +template <class Blk>
|
| +void NumberlikeArray<Blk>::operator=(const NumberlikeArray<Blk> &x) {
|
| + /* Calls like a = a have no effect; catch them before the aliasing
|
| + * causes a problem */
|
| + if (this == &x)
|
| + return;
|
| + // Copy length
|
| + len = x.len;
|
| + // Expand array if necessary
|
| + allocate(len);
|
| + // Copy number blocks
|
| + Index i;
|
| + for (i = 0; i < len; i++)
|
| + blk[i] = x.blk[i];
|
| +}
|
| +
|
| +template <class Blk>
|
| +NumberlikeArray<Blk>::NumberlikeArray(const Blk *b, Index blen)
|
| + : cap(blen), len(blen) {
|
| + // Create array
|
| + blk = new Blk[cap];
|
| + // Copy blocks
|
| + Index i;
|
| + for (i = 0; i < len; i++)
|
| + blk[i] = b[i];
|
| +}
|
| +
|
| +template <class Blk>
|
| +bool NumberlikeArray<Blk>::operator ==(const NumberlikeArray<Blk> &x) const {
|
| + if (len != x.len)
|
| + // Definitely unequal.
|
| + return false;
|
| + else {
|
| + // Compare corresponding blocks one by one.
|
| + Index i;
|
| + for (i = 0; i < len; i++)
|
| + if (blk[i] != x.blk[i])
|
| + return false;
|
| + // No blocks differed, so the objects are equal.
|
| + return true;
|
| + }
|
| +}
|
| +
|
| +#endif
|
|
|