Fix build broken at ac8fda05418b on windows
[pdfium.git] / third_party / bigint / NumberlikeArray.hh
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code by Matt McCutchen, see the LICENSE file.
6
7 #ifndef NUMBERLIKEARRAY_H
8 #define NUMBERLIKEARRAY_H
9
10 #include <stdlib.h> // abort()
11 // Make sure we have NULL.
12 #ifndef NULL
13 #define NULL 0
14 #endif
15
16 /* A NumberlikeArray<Blk> object holds a heap-allocated array of Blk with a
17  * length and a capacity and provides basic memory management features.
18  * BigUnsigned and BigUnsignedInABase both subclass it.
19  *
20  * NumberlikeArray provides no information hiding.  Subclasses should use
21  * nonpublic inheritance and manually expose members as desired using
22  * declarations like this:
23  *
24  * public:
25  *     NumberlikeArray< the-type-argument >::getLength;
26  */
27 template <class Blk>
28 class NumberlikeArray {
29 public:
30
31         // Type for the index of a block in the array
32         typedef unsigned int Index;
33         // The number of bits in a block, defined below.
34         static const unsigned int N;
35
36         // The current allocated capacity of this NumberlikeArray (in blocks)
37         Index cap;
38         // The actual length of the value stored in this NumberlikeArray (in blocks)
39         Index len;
40         // Heap-allocated array of the blocks (can be NULL if len == 0)
41         Blk *blk;
42
43         // Constructs a ``zero'' NumberlikeArray with the given capacity.
44         NumberlikeArray(Index c) : cap(c), len(0) { 
45                 blk = (cap > 0) ? (new Blk[cap]) : NULL;
46         }
47
48         /* Constructs a zero NumberlikeArray without allocating a backing array.
49          * A subclass that doesn't know the needed capacity at initialization
50          * time can use this constructor and then overwrite blk without first
51          * deleting it. */
52         NumberlikeArray() : cap(0), len(0) {
53                 blk = NULL;
54         }
55
56         // Destructor.  Note that `delete NULL' is a no-op.
57         ~NumberlikeArray() {
58                 delete [] blk;
59         }
60
61         /* Ensures that the array has at least the requested capacity; may
62          * destroy the contents. */
63         void allocate(Index c);
64
65         /* Ensures that the array has at least the requested capacity; does not
66          * destroy the contents. */
67         void allocateAndCopy(Index c);
68
69         // Copy constructor
70         NumberlikeArray(const NumberlikeArray<Blk> &x);
71
72         // Assignment operator
73         void operator=(const NumberlikeArray<Blk> &x);
74
75         // Constructor that copies from a given array of blocks
76         NumberlikeArray(const Blk *b, Index blen);
77
78         // ACCESSORS
79         Index getCapacity()     const { return cap;      }
80         Index getLength()       const { return len;      }
81         Blk   getBlock(Index i) const { return blk[i];   }
82         bool  isEmpty()         const { return len == 0; }
83
84         /* Equality comparison: checks if both objects have the same length and
85          * equal (==) array elements to that length.  Subclasses may wish to
86          * override. */
87         bool operator ==(const NumberlikeArray<Blk> &x) const;
88
89         bool operator !=(const NumberlikeArray<Blk> &x) const {
90                 return !operator ==(x);
91         }
92 };
93
94 /* BEGIN TEMPLATE DEFINITIONS.  They are present here so that source files that
95  * include this header file can generate the necessary real definitions. */
96
97 template <class Blk>
98 const unsigned int NumberlikeArray<Blk>::N = 8 * sizeof(Blk);
99
100 template <class Blk>
101 void NumberlikeArray<Blk>::allocate(Index c) {
102         // If the requested capacity is more than the current capacity...
103         if (c > cap) {
104                 // Delete the old number array
105                 delete [] blk;
106                 // Allocate the new array
107                 cap = c;
108                 blk = new Blk[cap];
109         }
110 }
111
112 template <class Blk>
113 void NumberlikeArray<Blk>::allocateAndCopy(Index c) {
114         // If the requested capacity is more than the current capacity...
115         if (c > cap) {
116                 Blk *oldBlk = blk;
117                 // Allocate the new number array
118                 cap = c;
119                 blk = new Blk[cap];
120                 // Copy number blocks
121                 Index i;
122                 for (i = 0; i < len; i++)
123                         blk[i] = oldBlk[i];
124                 // Delete the old array
125                 delete [] oldBlk;
126         }
127 }
128
129 template <class Blk>
130 NumberlikeArray<Blk>::NumberlikeArray(const NumberlikeArray<Blk> &x)
131                 : len(x.len) {
132         // Create array
133         cap = len;
134         blk = new Blk[cap];
135         // Copy blocks
136         Index i;
137         for (i = 0; i < len; i++)
138                 blk[i] = x.blk[i];
139 }
140
141 template <class Blk>
142 void NumberlikeArray<Blk>::operator=(const NumberlikeArray<Blk> &x) {
143         /* Calls like a = a have no effect; catch them before the aliasing
144          * causes a problem */
145         if (this == &x)
146                 return;
147         // Copy length
148         len = x.len;
149         // Expand array if necessary
150         allocate(len);
151         // Copy number blocks
152         Index i;
153         for (i = 0; i < len; i++)
154                 blk[i] = x.blk[i];
155 }
156
157 template <class Blk>
158 NumberlikeArray<Blk>::NumberlikeArray(const Blk *b, Index blen)
159                 : cap(blen), len(blen) {
160         // Create array
161         blk = new Blk[cap];
162         // Copy blocks
163         Index i;
164         for (i = 0; i < len; i++)
165                 blk[i] = b[i];
166 }
167
168 template <class Blk>
169 bool NumberlikeArray<Blk>::operator ==(const NumberlikeArray<Blk> &x) const {
170         if (len != x.len)
171                 // Definitely unequal.
172                 return false;
173         else {
174                 // Compare corresponding blocks one by one.
175                 Index i;
176                 for (i = 0; i < len; i++)
177                         if (blk[i] != x.blk[i])
178                                 return false;
179                 // No blocks differed, so the objects are equal.
180                 return true;
181         }
182 }
183
184 #endif