-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvector.cpp.html
476 lines (330 loc) · 26.6 KB
/
vector.cpp.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>/Volumes/Unix/unix-files.noindex/ntl-new/ntl-9.6.0/doc/vector.cpp.html</title>
<meta name="Generator" content="Vim/7.3">
<meta name="plugin-version" content="vim7.3_v6">
<meta name="syntax" content="cpp">
<meta name="settings" content="use_css">
<style type="text/css">
<!--
pre { font-family: monospace; color: #000000; background-color: #ffffff; }
body { font-family: monospace; color: #000000; background-color: #ffffff; }
.Statement { color: #b03060; font-weight: bold; }
.Type { color: #008b00; font-weight: bold; }
.Comment { color: #0000ee; font-style: italic; }
-->
</style>
</head>
<body>
<pre>
<span class="Comment">/*</span><span class="Comment">*************************************************************************\</span>
<span class="Comment">MODULE: vector</span>
<span class="Comment">SUMMARY:</span>
<span class="Comment">Template class for dynamic-sized vectors.</span>
<span class="Comment">The declaration</span>
<span class="Comment"> Vec<T> v;</span>
<span class="Comment">creates a zero-length vector. To grow this vector to length n,</span>
<span class="Comment">execute</span>
<span class="Comment"> v.SetLength(n)</span>
<span class="Comment">This causes space to be allocated for (at least) n elements, and also</span>
<span class="Comment">causes the delault constructor for T to be called to initialize these</span>
<span class="Comment">elements.</span>
<span class="Comment">The current length of a vector is available as v.length().</span>
<span class="Comment">The i-th vector element (counting from 0) is accessed as v[i]. If the</span>
<span class="Comment">macro NTL_RANGE_CHECK is defined, code is emitted to test if 0 <= i <</span>
<span class="Comment">v.length(). This check is not performed by default.</span>
<span class="Comment">For old-time FORTRAN programmers, the i-th vector element (counting</span>
<span class="Comment">from 1) is accessed as v(i).</span>
<span class="Comment">Let n = v.length(). Calling v.SetLength(m) with m <= n sets the</span>
<span class="Comment">current length of v to m (but does not call any destructors or free</span>
<span class="Comment">any space). Calling v.SetLength(m) with m > n will allocate space and</span>
<span class="Comment">initialize as necessary, but will leave the values of the already</span>
<span class="Comment">allocated elements unchanged (although their addresses may change).</span>
<span class="Comment">If T has a user-defined default constructor, that is invoked.</span>
<span class="Comment">Otherwise, the new memory locations are "default initialized".</span>
<span class="Comment">In particular, this means that POD types may be uninitialized.</span>
<span class="Comment">v.MaxLength() is the largest value of n for which v.SetLength(n) was invoked,</span>
<span class="Comment">and is equal to the number of entries that have been initialized.</span>
<span class="Comment">v.SetMaxLength(n) will allocate space for and initialize up to n elements,</span>
<span class="Comment">without changing v.length().</span>
<span class="Comment">When v's destructor is called, all constructed elements will be</span>
<span class="Comment">destructed, and all space will be relinquished.</span>
<span class="Comment">Space is managed using malloc, realloc, and free. When a vector is</span>
<span class="Comment">grown, a bit more space may be allocated than was requested for</span>
<span class="Comment">efficiency reasons.</span>
<span class="Comment">Note that when a vector is grown, the space is reallocated using</span>
<span class="Comment">realloc, and thus the addresses of vector elements may change,</span>
<span class="Comment">possibly creating dangling references to vector elements. One has to</span>
<span class="Comment">be especially careful of this when using vectors passed as reference</span>
<span class="Comment">parameters that may alias one another.</span>
<span class="Comment">Because realloc is used to grow a vector, the objects stored</span>
<span class="Comment">in a vector should be "relocatable"---that is, they shouldn't care</span>
<span class="Comment">what their actual address is, which may change over time.</span>
<span class="Comment">Most reasonable objects satisfy this constraint.</span>
<span class="Comment">v.allocated() is the number of elements which have been allocated,</span>
<span class="Comment">which may be more than the number elements initialized.</span>
<span class="Comment">Note that if n <= v.allocated(), then v.SetLength(n) is guaranteed</span>
<span class="Comment">not to cause any memory allocation, or movement of objects.</span>
<span class="Comment">IMPLEMENTATION DETAILS:</span>
<span class="Comment">A Vec<T> object is just a pointer to the first element of the array.</span>
<span class="Comment">There is a control block immediately before the first element that</span>
<span class="Comment">keeps track of several parameters: </span>
<span class="Comment"> len -- the logical length of the array (returned by length())</span>
<span class="Comment"> init -- the number of elements constructed (returned ny MaxLength())</span>
<span class="Comment"> alloc -- the number of elements for which space has been allocated</span>
<span class="Comment"> (returned by allocated())</span>
<span class="Comment"> fixed -- flag that indicates that the length is fixed </span>
<span class="Comment"> (returned by fixed())</span>
<span class="Comment">Note that 0 <= len <= init <- alloc</span>
<span class="Comment">COMPARISON TO STL VECTORS:</span>
<span class="Comment">When the length of an NTL vector is reduced, no objects are destroyed.</span>
<span class="Comment">In contrast, when the length of an STL vector is reduced, objects are</span>
<span class="Comment">destroyed (effectively, maintaining the invariant len == init).</span>
<span class="Comment">When the length of an NTL vector is increased, and the new value of len</span>
<span class="Comment">exceeds the current value of alloc, the underying array of objects is</span>
<span class="Comment">resized using malloc. This implies that existing objects are moved using</span>
<span class="Comment">a bit-wise copy. As mentioned above, this means that objects should</span>
<span class="Comment">be "relocatable", in the sense that they do not care what their actual</span>
<span class="Comment">address is. Most reasonable objects satisfy this constraint. An example</span>
<span class="Comment">of an object that does not is one that stores in one data member a pointer</span>
<span class="Comment">to another data member within the same object.</span>
<span class="Comment">In contrast, when the length of an STL vector is increased, an new array</span>
<span class="Comment">is allocated, and objects from the old array are copied to the new array,</span>
<span class="Comment">and then destroyed in the old array. This obviously is much more expensive</span>
<span class="Comment">that NTL's strategy. However, the new "move semantics", introduced in C++11,</span>
<span class="Comment">mitigate this issue somewhat.</span>
<span class="Comment">Because of NTL's relocatability requirement, it is not recommended to use NTL</span>
<span class="Comment">vectors over classes coming from the standard library, which may not satisfy</span>
<span class="Comment">the requirement. In those cases, you could either use an STL vector, or use an</span>
<span class="Comment">NTL vector and wrap the suspect classes in an NTL smart pointer of some kind</span>
<span class="Comment">(SmartPtr or OptionalVal).</span>
<span class="Comment">Note also that Facebook's open source "folly" library also provides</span>
<span class="Comment">a vector class that uses realloc in a manner very similar to NTL's vector class.</span>
<span class="Comment">See <a href="https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md">https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md</a></span>
<span class="Comment">\*************************************************************************</span><span class="Comment">*/</span>
<span class="Comment">// EXCEPTIONS: all functions below do not throw any exceptions,</span>
<span class="Comment">// except as noted</span>
<span class="Type">template</span><<span class="Type">class</span> T>
<span class="Type">class</span> Vec {
<span class="Statement">public</span>:
Vec(); <span class="Comment">// initially length 0</span>
Vec(<span class="Type">const</span> Vec<T>& a);
<span class="Comment">// copy constructor; uses the assignment operator of T</span>
<span class="Comment">// for copying into locations that have already been initialized,</span>
<span class="Comment">// and uses the copy constructor for T for initializing new locations.</span>
<span class="Comment">// EXCEPTIONS: may throw</span>
Vec& <span class="Statement">operator</span>=(<span class="Type">const</span> Vec<T>& a);
<span class="Comment">// assignment; uses the assignment operator of T</span>
<span class="Comment">// for copying into locations that have already been initialized,</span>
<span class="Comment">// and uses the copy constructor for T for initializing new locations.</span>
<span class="Comment">// EXCEPTIONS: weak ES (but if it throws, neither length nor MaxLength</span>
<span class="Comment">// will change, although some previously initialized elements</span>
<span class="Comment">// may have been assigned new values).</span>
~Vec();
<span class="Comment">// destructor: calls T's destructor for all initialized</span>
<span class="Comment">// elements in the vector, and then frees the vector itself</span>
<span class="Type">void</span> SetLength(<span class="Type">long</span> n);
<span class="Comment">// set current length to n, growing vector if necessary</span>
<span class="Comment">// new objects are initialized using the default contructor for T</span>
<span class="Comment">// EXCEPTIONS: strong ES (but the vector may have been</span>
<span class="Comment">// reallocated)</span>
<span class="Type">void</span> SetLength(<span class="Type">long</span> n, <span class="Type">const</span> T& a);
<span class="Comment">// set current length to n, growing vector if necessary</span>
<span class="Comment">// new objects are initialized using the copy contructor for T</span>
<span class="Comment">// EXCEPTIONS: strong ES (but the vector may have been</span>
<span class="Comment">// reallocated)</span>
<span class="Type">template</span><<span class="Type">class</span> F>
<span class="Type">void</span> SetLengthAndApply(<span class="Type">long</span> n, F f);
<span class="Comment">// set current length to n, growing vector if necessary</span>
<span class="Comment">// any new objects are initialized using defauly constructor</span>
<span class="Comment">// for T, and after that, f is applied to each new object x</span>
<span class="Comment">// as f(x).</span>
<span class="Comment">// EXCEPTIONS: strong ES (but the vector may have been</span>
<span class="Comment">// reallocated)</span>
<span class="Type">long</span> length() <span class="Type">const</span>;
<span class="Comment">// current length</span>
T& <span class="Statement">operator</span>[](<span class="Type">long</span> i);
<span class="Type">const</span> T& <span class="Statement">operator</span>[](<span class="Type">long</span> i) <span class="Type">const</span>;
<span class="Comment">// indexing operation, starting from 0.</span>
<span class="Comment">// The first version is applied to non-const Vec<T>,</span>
<span class="Comment">// and returns a non-const reference to a T, while the second version</span>
<span class="Comment">// is applied to a const Vec<T> and returns a const reference to a T.</span>
<span class="Comment">// EXCEPTIONS: may throw if range checking turned on, strong ES</span>
T& <span class="Statement">operator</span>()(<span class="Type">long</span> i);
<span class="Type">const</span> T& <span class="Statement">operator</span>()(<span class="Type">long</span> i) <span class="Type">const</span>;
<span class="Comment">// indexing operation, starting from 1</span>
<span class="Comment">// The first version is applied to non-const Vec<T>,</span>
<span class="Comment">// and returns a non-const reference to a T, while the second version</span>
<span class="Comment">// is applied to a const Vec<T> and returns a const reference to a T.</span>
<span class="Comment">// EXCEPTIONS: may throw if range checking turned on, strong ES</span>
T* elts();
<span class="Type">const</span> T* elts() <span class="Type">const</span>;
<span class="Comment">// returns address of first vector element (or 0 if no space has</span>
<span class="Comment">// been allocated for this vector). If a vector potentially has</span>
<span class="Comment">// length 0, it is safer to write v.elts() instead of &v[0].</span>
<span class="Comment">// The first version is applied to non-const Vec<T>,</span>
<span class="Comment">// and returns a non-const pointer to a T, while the second version</span>
<span class="Comment">// is applied to a const Vec<T> and returns a const reference to a T.</span>
<span class="Type">void</span> swap(Vec<T>& y);
<span class="Comment">// swap with y (fast: just swaps pointers)</span>
<span class="Comment">// EXCEPTIONS: throws if vectors are fixed and lengths do not match, strong ES</span>
<span class="Type">void</span> append(<span class="Type">const</span> T& a);
<span class="Comment">// append a to end of vector; uses the assignment operator of T</span>
<span class="Comment">// for copying into locations that have already been initialized,</span>
<span class="Comment">// and uses the copy constructor for T for initializing new locations.</span>
<span class="Comment">// EXCEPTIONS: strong ES if initializing a new element (and in any </span>
<span class="Comment">// case, if an exception throws, length and MaxLength remain </span>
<span class="Comment">// unchanged).</span>
<span class="Type">void</span> append(<span class="Type">const</span> Vec<T>& w);
<span class="Comment">// append w to end of vector; uses the assignment operator of T</span>
<span class="Comment">// for copying into locations that have already been initialized,</span>
<span class="Comment">// and uses the copy constructor for T for initializing new locations.</span>
<span class="Comment">// EXCEPTIONS: strong ES if initializing new elements (and in any </span>
<span class="Comment">// case, if an exception throws, length and MaxLength remain </span>
<span class="Comment">// unchanged).</span>
<span class="Comment">// Alternative access interface </span>
<span class="Type">const</span> T& get(<span class="Type">long</span> i) <span class="Type">const</span>;
<span class="Comment">// v.get(i) returns v[i]</span>
<span class="Type">void</span> put(<span class="Type">long</span> i, <span class="Type">const</span> T& a);
<span class="Comment">// v.put(i, a) equivalent to v[i] = q</span>
<span class="Comment">// Some STL compatibility</span>
<span class="Type">typedef</span> T value_type;
<span class="Type">typedef</span> value_type& reference;
<span class="Type">typedef</span> <span class="Type">const</span> value_type& const_reference;
<span class="Type">typedef</span> value_type *iterator;
<span class="Type">typedef</span> <span class="Type">const</span> value_type *const_iterator;
T* data();
<span class="Type">const</span> T* data() <span class="Type">const</span>;
<span class="Comment">// v.data() same as v.elts()</span>
T* begin();
<span class="Type">const</span> T* begin() <span class="Type">const</span>;
<span class="Comment">// v.begin() same as v.elts()</span>
T* end();
<span class="Type">const</span> T* end() <span class="Type">const</span>;
<span class="Comment">// pointer to last element (or NULL)</span>
T& at(<span class="Type">long</span> i);
<span class="Type">const</span> T& at(<span class="Type">long</span> i) <span class="Type">const</span>;
<span class="Comment">// indexing with range checking</span>
<span class="Comment">// the remaining member functions are a bit esoteric (skip on first</span>
<span class="Comment">// reading)</span>
Vec(INIT_SIZE_TYPE, <span class="Type">long</span> n);
<span class="Comment">// Vec(INIT_SIZE, n) initializes vector with an intial length of n.</span>
<span class="Comment">// new objects are initialized using the default contructor for T</span>
<span class="Comment">// EXCEPTIONS: may throw</span>
Vec(INIT_SIZE_TYPE, <span class="Type">long</span> n, <span class="Type">const</span> T& a);
<span class="Comment">// Vec(INIT_SIZE, n, a) initializes vector with an intial length of n.</span>
<span class="Comment">// new objects are initialized using the copy contructor for T</span>
<span class="Comment">// EXCEPTIONS: may throw</span>
<span class="Type">void</span> kill();
<span class="Comment">// release space and set to length 0</span>
<span class="Type">void</span> SetMaxLength(<span class="Type">long</span> n);
<span class="Comment">// allocates space and initializes up to n elements. Does not change</span>
<span class="Comment">// current length</span>
<span class="Comment">// EXCEPTIONS: may throw, strong ES</span>
<span class="Type">void</span> FixLength(<span class="Type">long</span> n);
<span class="Comment">// sets length to n and prohibits all future length changes.</span>
<span class="Comment">// FixLength may only be invoked immediately after the default</span>
<span class="Comment">// construction or kill.</span>
<span class="Comment">// The kill operation is also subsequently prohibited, and swap is</span>
<span class="Comment">// allowed on fixed length vectors of the same length.</span>
<span class="Comment">// FixLength is provided mainly to implement Mat<T>, to enforce</span>
<span class="Comment">// the restriction that all rows have the same length.</span>
<span class="Comment">// EXCEPTIONS: may throw, strong ES</span>
<span class="Type">void</span> FixAtCurrentLength();
<span class="Comment">// fixes the length at the cuurent length and prohibits</span>
<span class="Comment">// all future length changes. </span>
<span class="Comment">// It is required that length() == MaxLength() when called.</span>
<span class="Comment">// EXCEPTIONS: if length() != MaxLength() and error is raised;</span>
<span class="Comment">// if length() == 0, a memory allocation error may be raised.</span>
<span class="Comment">// Strong ES.</span>
<span class="Type">long</span> fixed() <span class="Type">const</span>;
<span class="Comment">// test if length has been fixed by FixLength() or FixAtCurrentLength()</span>
<span class="Type">long</span> MaxLength() <span class="Type">const</span>;
<span class="Comment">// maximum length, i.e., number of allocated and initialized elements</span>
<span class="Type">long</span> allocated() <span class="Type">const</span>;
<span class="Comment">// the number of objects for which space has been allocated, but not</span>
<span class="Comment">// necessarily initialized; this may be larger than MaxLength().</span>
T& RawGet(<span class="Type">long</span> i);
<span class="Type">const</span> T& RawGet(<span class="Type">long</span> i) <span class="Type">const</span>;
<span class="Comment">// indexing with no range checking</span>
<span class="Type">long</span> position(<span class="Type">const</span> T& a) <span class="Type">const</span>;
<span class="Comment">// returns position of a in the vector, or -1 if it is not there.</span>
<span class="Comment">// The search is conducted from position 0 to allocated()-1 the vector, </span>
<span class="Comment">// and an error is raised if the object is found at position MaxLength()</span>
<span class="Comment">// or higher (in which case a references an uninitialized object).</span>
<span class="Comment">// Note that if NTL_CLEAN_PTR flag is set, this routine takes</span>
<span class="Comment">// linear time, and otherwise, it takes constant time.</span>
<span class="Comment">// EXCEPTIONS: may throw (as indicated above)</span>
<span class="Type">long</span> position1(<span class="Type">const</span> T& a) <span class="Type">const</span>;
<span class="Comment">// returns position of a in the vector, or -1 if it is not there.</span>
<span class="Comment">// The search is conducted from position 0 to length()-1 of the vector.</span>
<span class="Comment">// Note that if NTL_CLEAN_PTR flag is set, this routine takes</span>
<span class="Comment">// linear time, and otherwise, it takes constant time.</span>
};
<span class="Comment">/*</span><span class="Comment">*************************************************************************\</span>
<span class="Comment"> Some utility routines</span>
<span class="Comment">\*************************************************************************</span><span class="Comment">*/</span>
<span class="Type">template</span><<span class="Type">class</span> T>
<span class="Type">void</span> swap(Vec<T>& x, Vec<T>& y);
<span class="Comment">// swaps x & y; same as x.swap(y)</span>
<span class="Comment">// EXCEPTIONS: same as for swap member function</span>
<span class="Type">template</span><<span class="Type">class</span> T>
<span class="Type">void</span> append(Vec<T>& v, <span class="Type">const</span> T& a);
<span class="Comment">// appends a to the end of v; same as v.append(a)</span>
<span class="Comment">// EXCEPTIONS: same as for append member function</span>
<span class="Type">template</span><<span class="Type">class</span> T>
<span class="Type">void</span> append(Vec<T>& v, <span class="Type">const</span> Vec<T>& w);
<span class="Comment">// appends w to the end of v; same as v.append(w)</span>
<span class="Comment">// EXCEPTIONS: same as for append member function</span>
<span class="Comment">/*</span><span class="Comment">*************************************************************************\</span>
<span class="Comment"> Input/Output</span>
<span class="Comment">The I/O format for a vector v with n elements is:</span>
<span class="Comment"> [v[0] v[1] ... v[n-1]]</span>
<span class="Comment">Uses corresponding I/O operators for T</span>
<span class="Comment">\*************************************************************************</span><span class="Comment">*/</span>
<span class="Type">template</span><<span class="Type">class</span> T>
istream& <span class="Statement">operator</span>>>(istream&, Vec<T>&);
<span class="Comment">// EXCEPTIONS: may throw, weak ES</span>
<span class="Type">template</span><<span class="Type">class</span> T>
ostream& <span class="Statement">operator</span><<(ostream&, <span class="Type">const</span> Vec<T>&);
<span class="Comment">// EXCEPTIONS: may throw, weak ES</span>
<span class="Comment">/*</span><span class="Comment">*************************************************************************\</span>
<span class="Comment"> Equality Testing</span>
<span class="Comment">\*************************************************************************</span><span class="Comment">*/</span>
<span class="Type">template</span><<span class="Type">class</span> T>
<span class="Type">long</span> <span class="Statement">operator</span>==(<span class="Type">const</span> Vec<T>& a, <span class="Type">const</span> Vec<T>& b);
<span class="Type">template</span><<span class="Type">class</span> T>
<span class="Type">long</span> <span class="Statement">operator</span>!=(<span class="Type">const</span> Vec<T>& a, <span class="Type">const</span> Vec<T>& b);
<span class="Comment">/*</span><span class="Comment">*************************************************************************\</span>
<span class="Comment"> Customized Constructors and Destructors</span>
<span class="Comment"> </span>
<span class="Comment">Esoteric: skip on first reading...also these interfaces are subject to change</span>
<span class="Comment">When new elements in a vector need to be constructed, one of the</span>
<span class="Comment">following routines is called:</span>
<span class="Comment"> void BlockConstruct(T* p, long n); </span>
<span class="Comment"> // invokes T() to initialize p[i] for i = 0..n-1</span>
<span class="Comment"> void BlockConstructFromVec(T* p, long n, const T* q);</span>
<span class="Comment"> // invokes T(q[i]) to initialize p[i] for i = 0..n-1;</span>
<span class="Comment"> // q points to elements from a Vec<T></span>
<span class="Comment"> void BlockConstructFromObj(T* p, long n, const T& q);</span>
<span class="Comment"> // invokes T(q) to initialize p[i] for i = 0..n-1</span>
<span class="Comment">When a vector is destroyed, the following routine is called:</span>
<span class="Comment"> void BlockDestroy(T* p, long n);</span>
<span class="Comment"> // invokes ~T() on p[i] for i = 0..n-1</span>
<span class="Comment">The default behavior of these routines may be modified by </span>
<span class="Comment">overloading these functions with a custom implementation.</span>
<span class="Comment">EXCEPTIONS:</span>
<span class="Comment">In order to provide exception safe code, the Construct routines</span>
<span class="Comment">should provide strong ES; in particular, if any constructor</span>
<span class="Comment">throws, all newly constructed objects should be destroyed.</span>
<span class="Comment">Moreover, the BlockDestroy routine should not throw at all.</span>
<span class="Comment">In NTL, these routines are overridden for the ZZ_p and GF2E classes,</span>
<span class="Comment">so that many vector entries will be packed into contiguous storage</span>
<span class="Comment">locations. This reduces the number of invocations of malloc, and</span>
<span class="Comment">increases locality of reference.</span>
<span class="Comment">\*************************************************************************</span><span class="Comment">*/</span>
</pre>
</body>
</html>