1// Protocol Buffers - Google's data interchange format
2// Copyright 2015 Google Inc.  All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#import "GPBArray_PackagePrivate.h"
32
33#import "GPBMessage_PackagePrivate.h"
34
35// Direct access is use for speed, to avoid even internally declaring things
36// read/write, etc. The warning is enabled in the project to ensure code calling
37// protos can turn on -Wdirect-ivar-access without issues.
38#pragma clang diagnostic push
39#pragma clang diagnostic ignored "-Wdirect-ivar-access"
40
41// Mutable arrays use an internal buffer that can always hold a multiple of this elements.
42#define kChunkSize 16
43#define CapacityFromCount(x) (((x / kChunkSize) + 1) * kChunkSize)
44
45static BOOL ArrayDefault_IsValidValue(int32_t value) {
46  // Anything but the bad value marker is allowed.
47  return (value != kGPBUnrecognizedEnumeratorValue);
48}
49
50//%PDDM-DEFINE VALIDATE_RANGE(INDEX, COUNT)
51//%  if (INDEX >= COUNT) {
52//%    [NSException raise:NSRangeException
53//%                format:@"Index (%lu) beyond bounds (%lu)",
54//%                       (unsigned long)INDEX, (unsigned long)COUNT];
55//%  }
56//%PDDM-DEFINE MAYBE_GROW_TO_SET_COUNT(NEW_COUNT)
57//%  if (NEW_COUNT > _capacity) {
58//%    [self internalResizeToCapacity:CapacityFromCount(NEW_COUNT)];
59//%  }
60//%  _count = NEW_COUNT;
61//%PDDM-DEFINE SET_COUNT_AND_MAYBE_SHRINK(NEW_COUNT)
62//%  _count = NEW_COUNT;
63//%  if ((NEW_COUNT + (2 * kChunkSize)) < _capacity) {
64//%    [self internalResizeToCapacity:CapacityFromCount(NEW_COUNT)];
65//%  }
66
67//
68// Macros for the common basic cases.
69//
70
71//%PDDM-DEFINE ARRAY_INTERFACE_SIMPLE(NAME, TYPE, FORMAT)
72//%#pragma mark - NAME
73//%
74//%@implementation GPB##NAME##Array {
75//% @package
76//%  TYPE *_values;
77//%  NSUInteger _count;
78//%  NSUInteger _capacity;
79//%}
80//%
81//%@synthesize count = _count;
82//%
83//%+ (instancetype)array {
84//%  return [[[self alloc] init] autorelease];
85//%}
86//%
87//%+ (instancetype)arrayWithValue:(TYPE)value {
88//%  // Cast is needed so the compiler knows what class we are invoking initWithValues: on to get
89//%  // the type correct.
90//%  return [[(GPB##NAME##Array*)[self alloc] initWithValues:&value count:1] autorelease];
91//%}
92//%
93//%+ (instancetype)arrayWithValueArray:(GPB##NAME##Array *)array {
94//%  return [[(GPB##NAME##Array*)[self alloc] initWithValueArray:array] autorelease];
95//%}
96//%
97//%+ (instancetype)arrayWithCapacity:(NSUInteger)count {
98//%  return [[[self alloc] initWithCapacity:count] autorelease];
99//%}
100//%
101//%- (instancetype)init {
102//%  self = [super init];
103//%  // No work needed;
104//%  return self;
105//%}
106//%
107//%- (instancetype)initWithValueArray:(GPB##NAME##Array *)array {
108//%  return [self initWithValues:array->_values count:array->_count];
109//%}
110//%
111//%- (instancetype)initWithValues:(const TYPE [])values count:(NSUInteger)count {
112//%  self = [self init];
113//%  if (self) {
114//%    if (count && values) {
115//%      _values = reallocf(_values, count * sizeof(TYPE));
116//%      if (_values != NULL) {
117//%        _capacity = count;
118//%        memcpy(_values, values, count * sizeof(TYPE));
119//%        _count = count;
120//%      } else {
121//%        [self release];
122//%        [NSException raise:NSMallocException
123//%                    format:@"Failed to allocate %lu bytes",
124//%                           (unsigned long)(count * sizeof(TYPE))];
125//%      }
126//%    }
127//%  }
128//%  return self;
129//%}
130//%
131//%- (instancetype)initWithCapacity:(NSUInteger)count {
132//%  self = [self initWithValues:NULL count:0];
133//%  if (self && count) {
134//%    [self internalResizeToCapacity:count];
135//%  }
136//%  return self;
137//%}
138//%
139//%- (instancetype)copyWithZone:(NSZone *)zone {
140//%  return [[GPB##NAME##Array allocWithZone:zone] initWithValues:_values count:_count];
141//%}
142//%
143//%ARRAY_IMMUTABLE_CORE(NAME, TYPE, , FORMAT)
144//%
145//%- (TYPE)valueAtIndex:(NSUInteger)index {
146//%VALIDATE_RANGE(index, _count)
147//%  return _values[index];
148//%}
149//%
150//%ARRAY_MUTABLE_CORE(NAME, TYPE, , FORMAT)
151//%@end
152//%
153
154//
155// Some core macros used for both the simple types and Enums.
156//
157
158//%PDDM-DEFINE ARRAY_IMMUTABLE_CORE(NAME, TYPE, ACCESSOR_NAME, FORMAT)
159//%- (void)dealloc {
160//%  NSAssert(!_autocreator,
161//%           @"%@: Autocreator must be cleared before release, autocreator: %@",
162//%           [self class], _autocreator);
163//%  free(_values);
164//%  [super dealloc];
165//%}
166//%
167//%- (BOOL)isEqual:(id)other {
168//%  if (self == other) {
169//%    return YES;
170//%  }
171//%  if (![other isKindOfClass:[GPB##NAME##Array class]]) {
172//%    return NO;
173//%  }
174//%  GPB##NAME##Array *otherArray = other;
175//%  return (_count == otherArray->_count
176//%          && memcmp(_values, otherArray->_values, (_count * sizeof(TYPE))) == 0);
177//%}
178//%
179//%- (NSUInteger)hash {
180//%  // Follow NSArray's lead, and use the count as the hash.
181//%  return _count;
182//%}
183//%
184//%- (NSString *)description {
185//%  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
186//%  for (NSUInteger i = 0, count = _count; i < count; ++i) {
187//%    if (i == 0) {
188//%      [result appendFormat:@"##FORMAT##", _values[i]];
189//%    } else {
190//%      [result appendFormat:@", ##FORMAT##", _values[i]];
191//%    }
192//%  }
193//%  [result appendFormat:@" }"];
194//%  return result;
195//%}
196//%
197//%- (void)enumerate##ACCESSOR_NAME##ValuesWithBlock:(void (NS_NOESCAPE ^)(TYPE value, NSUInteger idx, BOOL *stop))block {
198//%  [self enumerate##ACCESSOR_NAME##ValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
199//%}
200//%
201//%- (void)enumerate##ACCESSOR_NAME##ValuesWithOptions:(NSEnumerationOptions)opts
202//%                  ACCESSOR_NAME$S      usingBlock:(void (NS_NOESCAPE ^)(TYPE value, NSUInteger idx, BOOL *stop))block {
203//%  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
204//%  BOOL stop = NO;
205//%  if ((opts & NSEnumerationReverse) == 0) {
206//%    for (NSUInteger i = 0, count = _count; i < count; ++i) {
207//%      block(_values[i], i, &stop);
208//%      if (stop) break;
209//%    }
210//%  } else if (_count > 0) {
211//%    for (NSUInteger i = _count; i > 0; --i) {
212//%      block(_values[i - 1], (i - 1), &stop);
213//%      if (stop) break;
214//%    }
215//%  }
216//%}
217
218//%PDDM-DEFINE MUTATION_HOOK_None()
219//%PDDM-DEFINE MUTATION_METHODS(NAME, TYPE, ACCESSOR_NAME, HOOK_1, HOOK_2)
220//%- (void)add##ACCESSOR_NAME##Value:(TYPE)value {
221//%  [self add##ACCESSOR_NAME##Values:&value count:1];
222//%}
223//%
224//%- (void)add##ACCESSOR_NAME##Values:(const TYPE [])values count:(NSUInteger)count {
225//%  if (values == NULL || count == 0) return;
226//%MUTATION_HOOK_##HOOK_1()  NSUInteger initialCount = _count;
227//%  NSUInteger newCount = initialCount + count;
228//%MAYBE_GROW_TO_SET_COUNT(newCount)
229//%  memcpy(&_values[initialCount], values, count * sizeof(TYPE));
230//%  if (_autocreator) {
231//%    GPBAutocreatedArrayModified(_autocreator, self);
232//%  }
233//%}
234//%
235//%- (void)insert##ACCESSOR_NAME##Value:(TYPE)value atIndex:(NSUInteger)index {
236//%VALIDATE_RANGE(index, _count + 1)
237//%MUTATION_HOOK_##HOOK_2()  NSUInteger initialCount = _count;
238//%  NSUInteger newCount = initialCount + 1;
239//%MAYBE_GROW_TO_SET_COUNT(newCount)
240//%  if (index != initialCount) {
241//%    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(TYPE));
242//%  }
243//%  _values[index] = value;
244//%  if (_autocreator) {
245//%    GPBAutocreatedArrayModified(_autocreator, self);
246//%  }
247//%}
248//%
249//%- (void)replaceValueAtIndex:(NSUInteger)index with##ACCESSOR_NAME##Value:(TYPE)value {
250//%VALIDATE_RANGE(index, _count)
251//%MUTATION_HOOK_##HOOK_2()  _values[index] = value;
252//%}
253
254//%PDDM-DEFINE ARRAY_MUTABLE_CORE(NAME, TYPE, ACCESSOR_NAME, FORMAT)
255//%- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
256//%  _values = reallocf(_values, newCapacity * sizeof(TYPE));
257//%  if (_values == NULL) {
258//%    _capacity = 0;
259//%    _count = 0;
260//%    [NSException raise:NSMallocException
261//%                format:@"Failed to allocate %lu bytes",
262//%                       (unsigned long)(newCapacity * sizeof(TYPE))];
263//%  }
264//%  _capacity = newCapacity;
265//%}
266//%
267//%MUTATION_METHODS(NAME, TYPE, ACCESSOR_NAME, None, None)
268//%
269//%- (void)add##ACCESSOR_NAME##ValuesFromArray:(GPB##NAME##Array *)array {
270//%  [self add##ACCESSOR_NAME##Values:array->_values count:array->_count];
271//%}
272//%
273//%- (void)removeValueAtIndex:(NSUInteger)index {
274//%VALIDATE_RANGE(index, _count)
275//%  NSUInteger newCount = _count - 1;
276//%  if (index != newCount) {
277//%    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(TYPE));
278//%  }
279//%SET_COUNT_AND_MAYBE_SHRINK(newCount)
280//%}
281//%
282//%- (void)removeAll {
283//%SET_COUNT_AND_MAYBE_SHRINK(0)
284//%}
285//%
286//%- (void)exchangeValueAtIndex:(NSUInteger)idx1
287//%            withValueAtIndex:(NSUInteger)idx2 {
288//%VALIDATE_RANGE(idx1, _count)
289//%VALIDATE_RANGE(idx2, _count)
290//%  TYPE temp = _values[idx1];
291//%  _values[idx1] = _values[idx2];
292//%  _values[idx2] = temp;
293//%}
294//%
295
296//%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Int32, int32_t, %d)
297// This block of code is generated, do not edit it directly.
298
299#pragma mark - Int32
300
301@implementation GPBInt32Array {
302 @package
303  int32_t *_values;
304  NSUInteger _count;
305  NSUInteger _capacity;
306}
307
308@synthesize count = _count;
309
310+ (instancetype)array {
311  return [[[self alloc] init] autorelease];
312}
313
314+ (instancetype)arrayWithValue:(int32_t)value {
315  // Cast is needed so the compiler knows what class we are invoking initWithValues: on to get
316  // the type correct.
317  return [[(GPBInt32Array*)[self alloc] initWithValues:&value count:1] autorelease];
318}
319
320+ (instancetype)arrayWithValueArray:(GPBInt32Array *)array {
321  return [[(GPBInt32Array*)[self alloc] initWithValueArray:array] autorelease];
322}
323
324+ (instancetype)arrayWithCapacity:(NSUInteger)count {
325  return [[[self alloc] initWithCapacity:count] autorelease];
326}
327
328- (instancetype)init {
329  self = [super init];
330  // No work needed;
331  return self;
332}
333
334- (instancetype)initWithValueArray:(GPBInt32Array *)array {
335  return [self initWithValues:array->_values count:array->_count];
336}
337
338- (instancetype)initWithValues:(const int32_t [])values count:(NSUInteger)count {
339  self = [self init];
340  if (self) {
341    if (count && values) {
342      _values = reallocf(_values, count * sizeof(int32_t));
343      if (_values != NULL) {
344        _capacity = count;
345        memcpy(_values, values, count * sizeof(int32_t));
346        _count = count;
347      } else {
348        [self release];
349        [NSException raise:NSMallocException
350                    format:@"Failed to allocate %lu bytes",
351                           (unsigned long)(count * sizeof(int32_t))];
352      }
353    }
354  }
355  return self;
356}
357
358- (instancetype)initWithCapacity:(NSUInteger)count {
359  self = [self initWithValues:NULL count:0];
360  if (self && count) {
361    [self internalResizeToCapacity:count];
362  }
363  return self;
364}
365
366- (instancetype)copyWithZone:(NSZone *)zone {
367  return [[GPBInt32Array allocWithZone:zone] initWithValues:_values count:_count];
368}
369
370- (void)dealloc {
371  NSAssert(!_autocreator,
372           @"%@: Autocreator must be cleared before release, autocreator: %@",
373           [self class], _autocreator);
374  free(_values);
375  [super dealloc];
376}
377
378- (BOOL)isEqual:(id)other {
379  if (self == other) {
380    return YES;
381  }
382  if (![other isKindOfClass:[GPBInt32Array class]]) {
383    return NO;
384  }
385  GPBInt32Array *otherArray = other;
386  return (_count == otherArray->_count
387          && memcmp(_values, otherArray->_values, (_count * sizeof(int32_t))) == 0);
388}
389
390- (NSUInteger)hash {
391  // Follow NSArray's lead, and use the count as the hash.
392  return _count;
393}
394
395- (NSString *)description {
396  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
397  for (NSUInteger i = 0, count = _count; i < count; ++i) {
398    if (i == 0) {
399      [result appendFormat:@"%d", _values[i]];
400    } else {
401      [result appendFormat:@", %d", _values[i]];
402    }
403  }
404  [result appendFormat:@" }"];
405  return result;
406}
407
408- (void)enumerateValuesWithBlock:(void (NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))block {
409  [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
410}
411
412- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
413                        usingBlock:(void (NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))block {
414  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
415  BOOL stop = NO;
416  if ((opts & NSEnumerationReverse) == 0) {
417    for (NSUInteger i = 0, count = _count; i < count; ++i) {
418      block(_values[i], i, &stop);
419      if (stop) break;
420    }
421  } else if (_count > 0) {
422    for (NSUInteger i = _count; i > 0; --i) {
423      block(_values[i - 1], (i - 1), &stop);
424      if (stop) break;
425    }
426  }
427}
428
429- (int32_t)valueAtIndex:(NSUInteger)index {
430  if (index >= _count) {
431    [NSException raise:NSRangeException
432                format:@"Index (%lu) beyond bounds (%lu)",
433                       (unsigned long)index, (unsigned long)_count];
434  }
435  return _values[index];
436}
437
438- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
439  _values = reallocf(_values, newCapacity * sizeof(int32_t));
440  if (_values == NULL) {
441    _capacity = 0;
442    _count = 0;
443    [NSException raise:NSMallocException
444                format:@"Failed to allocate %lu bytes",
445                       (unsigned long)(newCapacity * sizeof(int32_t))];
446  }
447  _capacity = newCapacity;
448}
449
450- (void)addValue:(int32_t)value {
451  [self addValues:&value count:1];
452}
453
454- (void)addValues:(const int32_t [])values count:(NSUInteger)count {
455  if (values == NULL || count == 0) return;
456  NSUInteger initialCount = _count;
457  NSUInteger newCount = initialCount + count;
458  if (newCount > _capacity) {
459    [self internalResizeToCapacity:CapacityFromCount(newCount)];
460  }
461  _count = newCount;
462  memcpy(&_values[initialCount], values, count * sizeof(int32_t));
463  if (_autocreator) {
464    GPBAutocreatedArrayModified(_autocreator, self);
465  }
466}
467
468- (void)insertValue:(int32_t)value atIndex:(NSUInteger)index {
469  if (index >= _count + 1) {
470    [NSException raise:NSRangeException
471                format:@"Index (%lu) beyond bounds (%lu)",
472                       (unsigned long)index, (unsigned long)_count + 1];
473  }
474  NSUInteger initialCount = _count;
475  NSUInteger newCount = initialCount + 1;
476  if (newCount > _capacity) {
477    [self internalResizeToCapacity:CapacityFromCount(newCount)];
478  }
479  _count = newCount;
480  if (index != initialCount) {
481    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(int32_t));
482  }
483  _values[index] = value;
484  if (_autocreator) {
485    GPBAutocreatedArrayModified(_autocreator, self);
486  }
487}
488
489- (void)replaceValueAtIndex:(NSUInteger)index withValue:(int32_t)value {
490  if (index >= _count) {
491    [NSException raise:NSRangeException
492                format:@"Index (%lu) beyond bounds (%lu)",
493                       (unsigned long)index, (unsigned long)_count];
494  }
495  _values[index] = value;
496}
497
498- (void)addValuesFromArray:(GPBInt32Array *)array {
499  [self addValues:array->_values count:array->_count];
500}
501
502- (void)removeValueAtIndex:(NSUInteger)index {
503  if (index >= _count) {
504    [NSException raise:NSRangeException
505                format:@"Index (%lu) beyond bounds (%lu)",
506                       (unsigned long)index, (unsigned long)_count];
507  }
508  NSUInteger newCount = _count - 1;
509  if (index != newCount) {
510    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(int32_t));
511  }
512  _count = newCount;
513  if ((newCount + (2 * kChunkSize)) < _capacity) {
514    [self internalResizeToCapacity:CapacityFromCount(newCount)];
515  }
516}
517
518- (void)removeAll {
519  _count = 0;
520  if ((0 + (2 * kChunkSize)) < _capacity) {
521    [self internalResizeToCapacity:CapacityFromCount(0)];
522  }
523}
524
525- (void)exchangeValueAtIndex:(NSUInteger)idx1
526            withValueAtIndex:(NSUInteger)idx2 {
527  if (idx1 >= _count) {
528    [NSException raise:NSRangeException
529                format:@"Index (%lu) beyond bounds (%lu)",
530                       (unsigned long)idx1, (unsigned long)_count];
531  }
532  if (idx2 >= _count) {
533    [NSException raise:NSRangeException
534                format:@"Index (%lu) beyond bounds (%lu)",
535                       (unsigned long)idx2, (unsigned long)_count];
536  }
537  int32_t temp = _values[idx1];
538  _values[idx1] = _values[idx2];
539  _values[idx2] = temp;
540}
541
542@end
543
544//%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(UInt32, uint32_t, %u)
545// This block of code is generated, do not edit it directly.
546
547#pragma mark - UInt32
548
549@implementation GPBUInt32Array {
550 @package
551  uint32_t *_values;
552  NSUInteger _count;
553  NSUInteger _capacity;
554}
555
556@synthesize count = _count;
557
558+ (instancetype)array {
559  return [[[self alloc] init] autorelease];
560}
561
562+ (instancetype)arrayWithValue:(uint32_t)value {
563  // Cast is needed so the compiler knows what class we are invoking initWithValues: on to get
564  // the type correct.
565  return [[(GPBUInt32Array*)[self alloc] initWithValues:&value count:1] autorelease];
566}
567
568+ (instancetype)arrayWithValueArray:(GPBUInt32Array *)array {
569  return [[(GPBUInt32Array*)[self alloc] initWithValueArray:array] autorelease];
570}
571
572+ (instancetype)arrayWithCapacity:(NSUInteger)count {
573  return [[[self alloc] initWithCapacity:count] autorelease];
574}
575
576- (instancetype)init {
577  self = [super init];
578  // No work needed;
579  return self;
580}
581
582- (instancetype)initWithValueArray:(GPBUInt32Array *)array {
583  return [self initWithValues:array->_values count:array->_count];
584}
585
586- (instancetype)initWithValues:(const uint32_t [])values count:(NSUInteger)count {
587  self = [self init];
588  if (self) {
589    if (count && values) {
590      _values = reallocf(_values, count * sizeof(uint32_t));
591      if (_values != NULL) {
592        _capacity = count;
593        memcpy(_values, values, count * sizeof(uint32_t));
594        _count = count;
595      } else {
596        [self release];
597        [NSException raise:NSMallocException
598                    format:@"Failed to allocate %lu bytes",
599                           (unsigned long)(count * sizeof(uint32_t))];
600      }
601    }
602  }
603  return self;
604}
605
606- (instancetype)initWithCapacity:(NSUInteger)count {
607  self = [self initWithValues:NULL count:0];
608  if (self && count) {
609    [self internalResizeToCapacity:count];
610  }
611  return self;
612}
613
614- (instancetype)copyWithZone:(NSZone *)zone {
615  return [[GPBUInt32Array allocWithZone:zone] initWithValues:_values count:_count];
616}
617
618- (void)dealloc {
619  NSAssert(!_autocreator,
620           @"%@: Autocreator must be cleared before release, autocreator: %@",
621           [self class], _autocreator);
622  free(_values);
623  [super dealloc];
624}
625
626- (BOOL)isEqual:(id)other {
627  if (self == other) {
628    return YES;
629  }
630  if (![other isKindOfClass:[GPBUInt32Array class]]) {
631    return NO;
632  }
633  GPBUInt32Array *otherArray = other;
634  return (_count == otherArray->_count
635          && memcmp(_values, otherArray->_values, (_count * sizeof(uint32_t))) == 0);
636}
637
638- (NSUInteger)hash {
639  // Follow NSArray's lead, and use the count as the hash.
640  return _count;
641}
642
643- (NSString *)description {
644  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
645  for (NSUInteger i = 0, count = _count; i < count; ++i) {
646    if (i == 0) {
647      [result appendFormat:@"%u", _values[i]];
648    } else {
649      [result appendFormat:@", %u", _values[i]];
650    }
651  }
652  [result appendFormat:@" }"];
653  return result;
654}
655
656- (void)enumerateValuesWithBlock:(void (NS_NOESCAPE ^)(uint32_t value, NSUInteger idx, BOOL *stop))block {
657  [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
658}
659
660- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
661                        usingBlock:(void (NS_NOESCAPE ^)(uint32_t value, NSUInteger idx, BOOL *stop))block {
662  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
663  BOOL stop = NO;
664  if ((opts & NSEnumerationReverse) == 0) {
665    for (NSUInteger i = 0, count = _count; i < count; ++i) {
666      block(_values[i], i, &stop);
667      if (stop) break;
668    }
669  } else if (_count > 0) {
670    for (NSUInteger i = _count; i > 0; --i) {
671      block(_values[i - 1], (i - 1), &stop);
672      if (stop) break;
673    }
674  }
675}
676
677- (uint32_t)valueAtIndex:(NSUInteger)index {
678  if (index >= _count) {
679    [NSException raise:NSRangeException
680                format:@"Index (%lu) beyond bounds (%lu)",
681                       (unsigned long)index, (unsigned long)_count];
682  }
683  return _values[index];
684}
685
686- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
687  _values = reallocf(_values, newCapacity * sizeof(uint32_t));
688  if (_values == NULL) {
689    _capacity = 0;
690    _count = 0;
691    [NSException raise:NSMallocException
692                format:@"Failed to allocate %lu bytes",
693                       (unsigned long)(newCapacity * sizeof(uint32_t))];
694  }
695  _capacity = newCapacity;
696}
697
698- (void)addValue:(uint32_t)value {
699  [self addValues:&value count:1];
700}
701
702- (void)addValues:(const uint32_t [])values count:(NSUInteger)count {
703  if (values == NULL || count == 0) return;
704  NSUInteger initialCount = _count;
705  NSUInteger newCount = initialCount + count;
706  if (newCount > _capacity) {
707    [self internalResizeToCapacity:CapacityFromCount(newCount)];
708  }
709  _count = newCount;
710  memcpy(&_values[initialCount], values, count * sizeof(uint32_t));
711  if (_autocreator) {
712    GPBAutocreatedArrayModified(_autocreator, self);
713  }
714}
715
716- (void)insertValue:(uint32_t)value atIndex:(NSUInteger)index {
717  if (index >= _count + 1) {
718    [NSException raise:NSRangeException
719                format:@"Index (%lu) beyond bounds (%lu)",
720                       (unsigned long)index, (unsigned long)_count + 1];
721  }
722  NSUInteger initialCount = _count;
723  NSUInteger newCount = initialCount + 1;
724  if (newCount > _capacity) {
725    [self internalResizeToCapacity:CapacityFromCount(newCount)];
726  }
727  _count = newCount;
728  if (index != initialCount) {
729    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(uint32_t));
730  }
731  _values[index] = value;
732  if (_autocreator) {
733    GPBAutocreatedArrayModified(_autocreator, self);
734  }
735}
736
737- (void)replaceValueAtIndex:(NSUInteger)index withValue:(uint32_t)value {
738  if (index >= _count) {
739    [NSException raise:NSRangeException
740                format:@"Index (%lu) beyond bounds (%lu)",
741                       (unsigned long)index, (unsigned long)_count];
742  }
743  _values[index] = value;
744}
745
746- (void)addValuesFromArray:(GPBUInt32Array *)array {
747  [self addValues:array->_values count:array->_count];
748}
749
750- (void)removeValueAtIndex:(NSUInteger)index {
751  if (index >= _count) {
752    [NSException raise:NSRangeException
753                format:@"Index (%lu) beyond bounds (%lu)",
754                       (unsigned long)index, (unsigned long)_count];
755  }
756  NSUInteger newCount = _count - 1;
757  if (index != newCount) {
758    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(uint32_t));
759  }
760  _count = newCount;
761  if ((newCount + (2 * kChunkSize)) < _capacity) {
762    [self internalResizeToCapacity:CapacityFromCount(newCount)];
763  }
764}
765
766- (void)removeAll {
767  _count = 0;
768  if ((0 + (2 * kChunkSize)) < _capacity) {
769    [self internalResizeToCapacity:CapacityFromCount(0)];
770  }
771}
772
773- (void)exchangeValueAtIndex:(NSUInteger)idx1
774            withValueAtIndex:(NSUInteger)idx2 {
775  if (idx1 >= _count) {
776    [NSException raise:NSRangeException
777                format:@"Index (%lu) beyond bounds (%lu)",
778                       (unsigned long)idx1, (unsigned long)_count];
779  }
780  if (idx2 >= _count) {
781    [NSException raise:NSRangeException
782                format:@"Index (%lu) beyond bounds (%lu)",
783                       (unsigned long)idx2, (unsigned long)_count];
784  }
785  uint32_t temp = _values[idx1];
786  _values[idx1] = _values[idx2];
787  _values[idx2] = temp;
788}
789
790@end
791
792//%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Int64, int64_t, %lld)
793// This block of code is generated, do not edit it directly.
794
795#pragma mark - Int64
796
797@implementation GPBInt64Array {
798 @package
799  int64_t *_values;
800  NSUInteger _count;
801  NSUInteger _capacity;
802}
803
804@synthesize count = _count;
805
806+ (instancetype)array {
807  return [[[self alloc] init] autorelease];
808}
809
810+ (instancetype)arrayWithValue:(int64_t)value {
811  // Cast is needed so the compiler knows what class we are invoking initWithValues: on to get
812  // the type correct.
813  return [[(GPBInt64Array*)[self alloc] initWithValues:&value count:1] autorelease];
814}
815
816+ (instancetype)arrayWithValueArray:(GPBInt64Array *)array {
817  return [[(GPBInt64Array*)[self alloc] initWithValueArray:array] autorelease];
818}
819
820+ (instancetype)arrayWithCapacity:(NSUInteger)count {
821  return [[[self alloc] initWithCapacity:count] autorelease];
822}
823
824- (instancetype)init {
825  self = [super init];
826  // No work needed;
827  return self;
828}
829
830- (instancetype)initWithValueArray:(GPBInt64Array *)array {
831  return [self initWithValues:array->_values count:array->_count];
832}
833
834- (instancetype)initWithValues:(const int64_t [])values count:(NSUInteger)count {
835  self = [self init];
836  if (self) {
837    if (count && values) {
838      _values = reallocf(_values, count * sizeof(int64_t));
839      if (_values != NULL) {
840        _capacity = count;
841        memcpy(_values, values, count * sizeof(int64_t));
842        _count = count;
843      } else {
844        [self release];
845        [NSException raise:NSMallocException
846                    format:@"Failed to allocate %lu bytes",
847                           (unsigned long)(count * sizeof(int64_t))];
848      }
849    }
850  }
851  return self;
852}
853
854- (instancetype)initWithCapacity:(NSUInteger)count {
855  self = [self initWithValues:NULL count:0];
856  if (self && count) {
857    [self internalResizeToCapacity:count];
858  }
859  return self;
860}
861
862- (instancetype)copyWithZone:(NSZone *)zone {
863  return [[GPBInt64Array allocWithZone:zone] initWithValues:_values count:_count];
864}
865
866- (void)dealloc {
867  NSAssert(!_autocreator,
868           @"%@: Autocreator must be cleared before release, autocreator: %@",
869           [self class], _autocreator);
870  free(_values);
871  [super dealloc];
872}
873
874- (BOOL)isEqual:(id)other {
875  if (self == other) {
876    return YES;
877  }
878  if (![other isKindOfClass:[GPBInt64Array class]]) {
879    return NO;
880  }
881  GPBInt64Array *otherArray = other;
882  return (_count == otherArray->_count
883          && memcmp(_values, otherArray->_values, (_count * sizeof(int64_t))) == 0);
884}
885
886- (NSUInteger)hash {
887  // Follow NSArray's lead, and use the count as the hash.
888  return _count;
889}
890
891- (NSString *)description {
892  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
893  for (NSUInteger i = 0, count = _count; i < count; ++i) {
894    if (i == 0) {
895      [result appendFormat:@"%lld", _values[i]];
896    } else {
897      [result appendFormat:@", %lld", _values[i]];
898    }
899  }
900  [result appendFormat:@" }"];
901  return result;
902}
903
904- (void)enumerateValuesWithBlock:(void (NS_NOESCAPE ^)(int64_t value, NSUInteger idx, BOOL *stop))block {
905  [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
906}
907
908- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
909                        usingBlock:(void (NS_NOESCAPE ^)(int64_t value, NSUInteger idx, BOOL *stop))block {
910  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
911  BOOL stop = NO;
912  if ((opts & NSEnumerationReverse) == 0) {
913    for (NSUInteger i = 0, count = _count; i < count; ++i) {
914      block(_values[i], i, &stop);
915      if (stop) break;
916    }
917  } else if (_count > 0) {
918    for (NSUInteger i = _count; i > 0; --i) {
919      block(_values[i - 1], (i - 1), &stop);
920      if (stop) break;
921    }
922  }
923}
924
925- (int64_t)valueAtIndex:(NSUInteger)index {
926  if (index >= _count) {
927    [NSException raise:NSRangeException
928                format:@"Index (%lu) beyond bounds (%lu)",
929                       (unsigned long)index, (unsigned long)_count];
930  }
931  return _values[index];
932}
933
934- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
935  _values = reallocf(_values, newCapacity * sizeof(int64_t));
936  if (_values == NULL) {
937    _capacity = 0;
938    _count = 0;
939    [NSException raise:NSMallocException
940                format:@"Failed to allocate %lu bytes",
941                       (unsigned long)(newCapacity * sizeof(int64_t))];
942  }
943  _capacity = newCapacity;
944}
945
946- (void)addValue:(int64_t)value {
947  [self addValues:&value count:1];
948}
949
950- (void)addValues:(const int64_t [])values count:(NSUInteger)count {
951  if (values == NULL || count == 0) return;
952  NSUInteger initialCount = _count;
953  NSUInteger newCount = initialCount + count;
954  if (newCount > _capacity) {
955    [self internalResizeToCapacity:CapacityFromCount(newCount)];
956  }
957  _count = newCount;
958  memcpy(&_values[initialCount], values, count * sizeof(int64_t));
959  if (_autocreator) {
960    GPBAutocreatedArrayModified(_autocreator, self);
961  }
962}
963
964- (void)insertValue:(int64_t)value atIndex:(NSUInteger)index {
965  if (index >= _count + 1) {
966    [NSException raise:NSRangeException
967                format:@"Index (%lu) beyond bounds (%lu)",
968                       (unsigned long)index, (unsigned long)_count + 1];
969  }
970  NSUInteger initialCount = _count;
971  NSUInteger newCount = initialCount + 1;
972  if (newCount > _capacity) {
973    [self internalResizeToCapacity:CapacityFromCount(newCount)];
974  }
975  _count = newCount;
976  if (index != initialCount) {
977    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(int64_t));
978  }
979  _values[index] = value;
980  if (_autocreator) {
981    GPBAutocreatedArrayModified(_autocreator, self);
982  }
983}
984
985- (void)replaceValueAtIndex:(NSUInteger)index withValue:(int64_t)value {
986  if (index >= _count) {
987    [NSException raise:NSRangeException
988                format:@"Index (%lu) beyond bounds (%lu)",
989                       (unsigned long)index, (unsigned long)_count];
990  }
991  _values[index] = value;
992}
993
994- (void)addValuesFromArray:(GPBInt64Array *)array {
995  [self addValues:array->_values count:array->_count];
996}
997
998- (void)removeValueAtIndex:(NSUInteger)index {
999  if (index >= _count) {
1000    [NSException raise:NSRangeException
1001                format:@"Index (%lu) beyond bounds (%lu)",
1002                       (unsigned long)index, (unsigned long)_count];
1003  }
1004  NSUInteger newCount = _count - 1;
1005  if (index != newCount) {
1006    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(int64_t));
1007  }
1008  _count = newCount;
1009  if ((newCount + (2 * kChunkSize)) < _capacity) {
1010    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1011  }
1012}
1013
1014- (void)removeAll {
1015  _count = 0;
1016  if ((0 + (2 * kChunkSize)) < _capacity) {
1017    [self internalResizeToCapacity:CapacityFromCount(0)];
1018  }
1019}
1020
1021- (void)exchangeValueAtIndex:(NSUInteger)idx1
1022            withValueAtIndex:(NSUInteger)idx2 {
1023  if (idx1 >= _count) {
1024    [NSException raise:NSRangeException
1025                format:@"Index (%lu) beyond bounds (%lu)",
1026                       (unsigned long)idx1, (unsigned long)_count];
1027  }
1028  if (idx2 >= _count) {
1029    [NSException raise:NSRangeException
1030                format:@"Index (%lu) beyond bounds (%lu)",
1031                       (unsigned long)idx2, (unsigned long)_count];
1032  }
1033  int64_t temp = _values[idx1];
1034  _values[idx1] = _values[idx2];
1035  _values[idx2] = temp;
1036}
1037
1038@end
1039
1040//%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(UInt64, uint64_t, %llu)
1041// This block of code is generated, do not edit it directly.
1042
1043#pragma mark - UInt64
1044
1045@implementation GPBUInt64Array {
1046 @package
1047  uint64_t *_values;
1048  NSUInteger _count;
1049  NSUInteger _capacity;
1050}
1051
1052@synthesize count = _count;
1053
1054+ (instancetype)array {
1055  return [[[self alloc] init] autorelease];
1056}
1057
1058+ (instancetype)arrayWithValue:(uint64_t)value {
1059  // Cast is needed so the compiler knows what class we are invoking initWithValues: on to get
1060  // the type correct.
1061  return [[(GPBUInt64Array*)[self alloc] initWithValues:&value count:1] autorelease];
1062}
1063
1064+ (instancetype)arrayWithValueArray:(GPBUInt64Array *)array {
1065  return [[(GPBUInt64Array*)[self alloc] initWithValueArray:array] autorelease];
1066}
1067
1068+ (instancetype)arrayWithCapacity:(NSUInteger)count {
1069  return [[[self alloc] initWithCapacity:count] autorelease];
1070}
1071
1072- (instancetype)init {
1073  self = [super init];
1074  // No work needed;
1075  return self;
1076}
1077
1078- (instancetype)initWithValueArray:(GPBUInt64Array *)array {
1079  return [self initWithValues:array->_values count:array->_count];
1080}
1081
1082- (instancetype)initWithValues:(const uint64_t [])values count:(NSUInteger)count {
1083  self = [self init];
1084  if (self) {
1085    if (count && values) {
1086      _values = reallocf(_values, count * sizeof(uint64_t));
1087      if (_values != NULL) {
1088        _capacity = count;
1089        memcpy(_values, values, count * sizeof(uint64_t));
1090        _count = count;
1091      } else {
1092        [self release];
1093        [NSException raise:NSMallocException
1094                    format:@"Failed to allocate %lu bytes",
1095                           (unsigned long)(count * sizeof(uint64_t))];
1096      }
1097    }
1098  }
1099  return self;
1100}
1101
1102- (instancetype)initWithCapacity:(NSUInteger)count {
1103  self = [self initWithValues:NULL count:0];
1104  if (self && count) {
1105    [self internalResizeToCapacity:count];
1106  }
1107  return self;
1108}
1109
1110- (instancetype)copyWithZone:(NSZone *)zone {
1111  return [[GPBUInt64Array allocWithZone:zone] initWithValues:_values count:_count];
1112}
1113
1114- (void)dealloc {
1115  NSAssert(!_autocreator,
1116           @"%@: Autocreator must be cleared before release, autocreator: %@",
1117           [self class], _autocreator);
1118  free(_values);
1119  [super dealloc];
1120}
1121
1122- (BOOL)isEqual:(id)other {
1123  if (self == other) {
1124    return YES;
1125  }
1126  if (![other isKindOfClass:[GPBUInt64Array class]]) {
1127    return NO;
1128  }
1129  GPBUInt64Array *otherArray = other;
1130  return (_count == otherArray->_count
1131          && memcmp(_values, otherArray->_values, (_count * sizeof(uint64_t))) == 0);
1132}
1133
1134- (NSUInteger)hash {
1135  // Follow NSArray's lead, and use the count as the hash.
1136  return _count;
1137}
1138
1139- (NSString *)description {
1140  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
1141  for (NSUInteger i = 0, count = _count; i < count; ++i) {
1142    if (i == 0) {
1143      [result appendFormat:@"%llu", _values[i]];
1144    } else {
1145      [result appendFormat:@", %llu", _values[i]];
1146    }
1147  }
1148  [result appendFormat:@" }"];
1149  return result;
1150}
1151
1152- (void)enumerateValuesWithBlock:(void (NS_NOESCAPE ^)(uint64_t value, NSUInteger idx, BOOL *stop))block {
1153  [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
1154}
1155
1156- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
1157                        usingBlock:(void (NS_NOESCAPE ^)(uint64_t value, NSUInteger idx, BOOL *stop))block {
1158  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
1159  BOOL stop = NO;
1160  if ((opts & NSEnumerationReverse) == 0) {
1161    for (NSUInteger i = 0, count = _count; i < count; ++i) {
1162      block(_values[i], i, &stop);
1163      if (stop) break;
1164    }
1165  } else if (_count > 0) {
1166    for (NSUInteger i = _count; i > 0; --i) {
1167      block(_values[i - 1], (i - 1), &stop);
1168      if (stop) break;
1169    }
1170  }
1171}
1172
1173- (uint64_t)valueAtIndex:(NSUInteger)index {
1174  if (index >= _count) {
1175    [NSException raise:NSRangeException
1176                format:@"Index (%lu) beyond bounds (%lu)",
1177                       (unsigned long)index, (unsigned long)_count];
1178  }
1179  return _values[index];
1180}
1181
1182- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
1183  _values = reallocf(_values, newCapacity * sizeof(uint64_t));
1184  if (_values == NULL) {
1185    _capacity = 0;
1186    _count = 0;
1187    [NSException raise:NSMallocException
1188                format:@"Failed to allocate %lu bytes",
1189                       (unsigned long)(newCapacity * sizeof(uint64_t))];
1190  }
1191  _capacity = newCapacity;
1192}
1193
1194- (void)addValue:(uint64_t)value {
1195  [self addValues:&value count:1];
1196}
1197
1198- (void)addValues:(const uint64_t [])values count:(NSUInteger)count {
1199  if (values == NULL || count == 0) return;
1200  NSUInteger initialCount = _count;
1201  NSUInteger newCount = initialCount + count;
1202  if (newCount > _capacity) {
1203    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1204  }
1205  _count = newCount;
1206  memcpy(&_values[initialCount], values, count * sizeof(uint64_t));
1207  if (_autocreator) {
1208    GPBAutocreatedArrayModified(_autocreator, self);
1209  }
1210}
1211
1212- (void)insertValue:(uint64_t)value atIndex:(NSUInteger)index {
1213  if (index >= _count + 1) {
1214    [NSException raise:NSRangeException
1215                format:@"Index (%lu) beyond bounds (%lu)",
1216                       (unsigned long)index, (unsigned long)_count + 1];
1217  }
1218  NSUInteger initialCount = _count;
1219  NSUInteger newCount = initialCount + 1;
1220  if (newCount > _capacity) {
1221    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1222  }
1223  _count = newCount;
1224  if (index != initialCount) {
1225    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(uint64_t));
1226  }
1227  _values[index] = value;
1228  if (_autocreator) {
1229    GPBAutocreatedArrayModified(_autocreator, self);
1230  }
1231}
1232
1233- (void)replaceValueAtIndex:(NSUInteger)index withValue:(uint64_t)value {
1234  if (index >= _count) {
1235    [NSException raise:NSRangeException
1236                format:@"Index (%lu) beyond bounds (%lu)",
1237                       (unsigned long)index, (unsigned long)_count];
1238  }
1239  _values[index] = value;
1240}
1241
1242- (void)addValuesFromArray:(GPBUInt64Array *)array {
1243  [self addValues:array->_values count:array->_count];
1244}
1245
1246- (void)removeValueAtIndex:(NSUInteger)index {
1247  if (index >= _count) {
1248    [NSException raise:NSRangeException
1249                format:@"Index (%lu) beyond bounds (%lu)",
1250                       (unsigned long)index, (unsigned long)_count];
1251  }
1252  NSUInteger newCount = _count - 1;
1253  if (index != newCount) {
1254    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(uint64_t));
1255  }
1256  _count = newCount;
1257  if ((newCount + (2 * kChunkSize)) < _capacity) {
1258    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1259  }
1260}
1261
1262- (void)removeAll {
1263  _count = 0;
1264  if ((0 + (2 * kChunkSize)) < _capacity) {
1265    [self internalResizeToCapacity:CapacityFromCount(0)];
1266  }
1267}
1268
1269- (void)exchangeValueAtIndex:(NSUInteger)idx1
1270            withValueAtIndex:(NSUInteger)idx2 {
1271  if (idx1 >= _count) {
1272    [NSException raise:NSRangeException
1273                format:@"Index (%lu) beyond bounds (%lu)",
1274                       (unsigned long)idx1, (unsigned long)_count];
1275  }
1276  if (idx2 >= _count) {
1277    [NSException raise:NSRangeException
1278                format:@"Index (%lu) beyond bounds (%lu)",
1279                       (unsigned long)idx2, (unsigned long)_count];
1280  }
1281  uint64_t temp = _values[idx1];
1282  _values[idx1] = _values[idx2];
1283  _values[idx2] = temp;
1284}
1285
1286@end
1287
1288//%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Float, float, %f)
1289// This block of code is generated, do not edit it directly.
1290
1291#pragma mark - Float
1292
1293@implementation GPBFloatArray {
1294 @package
1295  float *_values;
1296  NSUInteger _count;
1297  NSUInteger _capacity;
1298}
1299
1300@synthesize count = _count;
1301
1302+ (instancetype)array {
1303  return [[[self alloc] init] autorelease];
1304}
1305
1306+ (instancetype)arrayWithValue:(float)value {
1307  // Cast is needed so the compiler knows what class we are invoking initWithValues: on to get
1308  // the type correct.
1309  return [[(GPBFloatArray*)[self alloc] initWithValues:&value count:1] autorelease];
1310}
1311
1312+ (instancetype)arrayWithValueArray:(GPBFloatArray *)array {
1313  return [[(GPBFloatArray*)[self alloc] initWithValueArray:array] autorelease];
1314}
1315
1316+ (instancetype)arrayWithCapacity:(NSUInteger)count {
1317  return [[[self alloc] initWithCapacity:count] autorelease];
1318}
1319
1320- (instancetype)init {
1321  self = [super init];
1322  // No work needed;
1323  return self;
1324}
1325
1326- (instancetype)initWithValueArray:(GPBFloatArray *)array {
1327  return [self initWithValues:array->_values count:array->_count];
1328}
1329
1330- (instancetype)initWithValues:(const float [])values count:(NSUInteger)count {
1331  self = [self init];
1332  if (self) {
1333    if (count && values) {
1334      _values = reallocf(_values, count * sizeof(float));
1335      if (_values != NULL) {
1336        _capacity = count;
1337        memcpy(_values, values, count * sizeof(float));
1338        _count = count;
1339      } else {
1340        [self release];
1341        [NSException raise:NSMallocException
1342                    format:@"Failed to allocate %lu bytes",
1343                           (unsigned long)(count * sizeof(float))];
1344      }
1345    }
1346  }
1347  return self;
1348}
1349
1350- (instancetype)initWithCapacity:(NSUInteger)count {
1351  self = [self initWithValues:NULL count:0];
1352  if (self && count) {
1353    [self internalResizeToCapacity:count];
1354  }
1355  return self;
1356}
1357
1358- (instancetype)copyWithZone:(NSZone *)zone {
1359  return [[GPBFloatArray allocWithZone:zone] initWithValues:_values count:_count];
1360}
1361
1362- (void)dealloc {
1363  NSAssert(!_autocreator,
1364           @"%@: Autocreator must be cleared before release, autocreator: %@",
1365           [self class], _autocreator);
1366  free(_values);
1367  [super dealloc];
1368}
1369
1370- (BOOL)isEqual:(id)other {
1371  if (self == other) {
1372    return YES;
1373  }
1374  if (![other isKindOfClass:[GPBFloatArray class]]) {
1375    return NO;
1376  }
1377  GPBFloatArray *otherArray = other;
1378  return (_count == otherArray->_count
1379          && memcmp(_values, otherArray->_values, (_count * sizeof(float))) == 0);
1380}
1381
1382- (NSUInteger)hash {
1383  // Follow NSArray's lead, and use the count as the hash.
1384  return _count;
1385}
1386
1387- (NSString *)description {
1388  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
1389  for (NSUInteger i = 0, count = _count; i < count; ++i) {
1390    if (i == 0) {
1391      [result appendFormat:@"%f", _values[i]];
1392    } else {
1393      [result appendFormat:@", %f", _values[i]];
1394    }
1395  }
1396  [result appendFormat:@" }"];
1397  return result;
1398}
1399
1400- (void)enumerateValuesWithBlock:(void (NS_NOESCAPE ^)(float value, NSUInteger idx, BOOL *stop))block {
1401  [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
1402}
1403
1404- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
1405                        usingBlock:(void (NS_NOESCAPE ^)(float value, NSUInteger idx, BOOL *stop))block {
1406  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
1407  BOOL stop = NO;
1408  if ((opts & NSEnumerationReverse) == 0) {
1409    for (NSUInteger i = 0, count = _count; i < count; ++i) {
1410      block(_values[i], i, &stop);
1411      if (stop) break;
1412    }
1413  } else if (_count > 0) {
1414    for (NSUInteger i = _count; i > 0; --i) {
1415      block(_values[i - 1], (i - 1), &stop);
1416      if (stop) break;
1417    }
1418  }
1419}
1420
1421- (float)valueAtIndex:(NSUInteger)index {
1422  if (index >= _count) {
1423    [NSException raise:NSRangeException
1424                format:@"Index (%lu) beyond bounds (%lu)",
1425                       (unsigned long)index, (unsigned long)_count];
1426  }
1427  return _values[index];
1428}
1429
1430- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
1431  _values = reallocf(_values, newCapacity * sizeof(float));
1432  if (_values == NULL) {
1433    _capacity = 0;
1434    _count = 0;
1435    [NSException raise:NSMallocException
1436                format:@"Failed to allocate %lu bytes",
1437                       (unsigned long)(newCapacity * sizeof(float))];
1438  }
1439  _capacity = newCapacity;
1440}
1441
1442- (void)addValue:(float)value {
1443  [self addValues:&value count:1];
1444}
1445
1446- (void)addValues:(const float [])values count:(NSUInteger)count {
1447  if (values == NULL || count == 0) return;
1448  NSUInteger initialCount = _count;
1449  NSUInteger newCount = initialCount + count;
1450  if (newCount > _capacity) {
1451    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1452  }
1453  _count = newCount;
1454  memcpy(&_values[initialCount], values, count * sizeof(float));
1455  if (_autocreator) {
1456    GPBAutocreatedArrayModified(_autocreator, self);
1457  }
1458}
1459
1460- (void)insertValue:(float)value atIndex:(NSUInteger)index {
1461  if (index >= _count + 1) {
1462    [NSException raise:NSRangeException
1463                format:@"Index (%lu) beyond bounds (%lu)",
1464                       (unsigned long)index, (unsigned long)_count + 1];
1465  }
1466  NSUInteger initialCount = _count;
1467  NSUInteger newCount = initialCount + 1;
1468  if (newCount > _capacity) {
1469    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1470  }
1471  _count = newCount;
1472  if (index != initialCount) {
1473    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(float));
1474  }
1475  _values[index] = value;
1476  if (_autocreator) {
1477    GPBAutocreatedArrayModified(_autocreator, self);
1478  }
1479}
1480
1481- (void)replaceValueAtIndex:(NSUInteger)index withValue:(float)value {
1482  if (index >= _count) {
1483    [NSException raise:NSRangeException
1484                format:@"Index (%lu) beyond bounds (%lu)",
1485                       (unsigned long)index, (unsigned long)_count];
1486  }
1487  _values[index] = value;
1488}
1489
1490- (void)addValuesFromArray:(GPBFloatArray *)array {
1491  [self addValues:array->_values count:array->_count];
1492}
1493
1494- (void)removeValueAtIndex:(NSUInteger)index {
1495  if (index >= _count) {
1496    [NSException raise:NSRangeException
1497                format:@"Index (%lu) beyond bounds (%lu)",
1498                       (unsigned long)index, (unsigned long)_count];
1499  }
1500  NSUInteger newCount = _count - 1;
1501  if (index != newCount) {
1502    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(float));
1503  }
1504  _count = newCount;
1505  if ((newCount + (2 * kChunkSize)) < _capacity) {
1506    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1507  }
1508}
1509
1510- (void)removeAll {
1511  _count = 0;
1512  if ((0 + (2 * kChunkSize)) < _capacity) {
1513    [self internalResizeToCapacity:CapacityFromCount(0)];
1514  }
1515}
1516
1517- (void)exchangeValueAtIndex:(NSUInteger)idx1
1518            withValueAtIndex:(NSUInteger)idx2 {
1519  if (idx1 >= _count) {
1520    [NSException raise:NSRangeException
1521                format:@"Index (%lu) beyond bounds (%lu)",
1522                       (unsigned long)idx1, (unsigned long)_count];
1523  }
1524  if (idx2 >= _count) {
1525    [NSException raise:NSRangeException
1526                format:@"Index (%lu) beyond bounds (%lu)",
1527                       (unsigned long)idx2, (unsigned long)_count];
1528  }
1529  float temp = _values[idx1];
1530  _values[idx1] = _values[idx2];
1531  _values[idx2] = temp;
1532}
1533
1534@end
1535
1536//%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Double, double, %lf)
1537// This block of code is generated, do not edit it directly.
1538
1539#pragma mark - Double
1540
1541@implementation GPBDoubleArray {
1542 @package
1543  double *_values;
1544  NSUInteger _count;
1545  NSUInteger _capacity;
1546}
1547
1548@synthesize count = _count;
1549
1550+ (instancetype)array {
1551  return [[[self alloc] init] autorelease];
1552}
1553
1554+ (instancetype)arrayWithValue:(double)value {
1555  // Cast is needed so the compiler knows what class we are invoking initWithValues: on to get
1556  // the type correct.
1557  return [[(GPBDoubleArray*)[self alloc] initWithValues:&value count:1] autorelease];
1558}
1559
1560+ (instancetype)arrayWithValueArray:(GPBDoubleArray *)array {
1561  return [[(GPBDoubleArray*)[self alloc] initWithValueArray:array] autorelease];
1562}
1563
1564+ (instancetype)arrayWithCapacity:(NSUInteger)count {
1565  return [[[self alloc] initWithCapacity:count] autorelease];
1566}
1567
1568- (instancetype)init {
1569  self = [super init];
1570  // No work needed;
1571  return self;
1572}
1573
1574- (instancetype)initWithValueArray:(GPBDoubleArray *)array {
1575  return [self initWithValues:array->_values count:array->_count];
1576}
1577
1578- (instancetype)initWithValues:(const double [])values count:(NSUInteger)count {
1579  self = [self init];
1580  if (self) {
1581    if (count && values) {
1582      _values = reallocf(_values, count * sizeof(double));
1583      if (_values != NULL) {
1584        _capacity = count;
1585        memcpy(_values, values, count * sizeof(double));
1586        _count = count;
1587      } else {
1588        [self release];
1589        [NSException raise:NSMallocException
1590                    format:@"Failed to allocate %lu bytes",
1591                           (unsigned long)(count * sizeof(double))];
1592      }
1593    }
1594  }
1595  return self;
1596}
1597
1598- (instancetype)initWithCapacity:(NSUInteger)count {
1599  self = [self initWithValues:NULL count:0];
1600  if (self && count) {
1601    [self internalResizeToCapacity:count];
1602  }
1603  return self;
1604}
1605
1606- (instancetype)copyWithZone:(NSZone *)zone {
1607  return [[GPBDoubleArray allocWithZone:zone] initWithValues:_values count:_count];
1608}
1609
1610- (void)dealloc {
1611  NSAssert(!_autocreator,
1612           @"%@: Autocreator must be cleared before release, autocreator: %@",
1613           [self class], _autocreator);
1614  free(_values);
1615  [super dealloc];
1616}
1617
1618- (BOOL)isEqual:(id)other {
1619  if (self == other) {
1620    return YES;
1621  }
1622  if (![other isKindOfClass:[GPBDoubleArray class]]) {
1623    return NO;
1624  }
1625  GPBDoubleArray *otherArray = other;
1626  return (_count == otherArray->_count
1627          && memcmp(_values, otherArray->_values, (_count * sizeof(double))) == 0);
1628}
1629
1630- (NSUInteger)hash {
1631  // Follow NSArray's lead, and use the count as the hash.
1632  return _count;
1633}
1634
1635- (NSString *)description {
1636  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
1637  for (NSUInteger i = 0, count = _count; i < count; ++i) {
1638    if (i == 0) {
1639      [result appendFormat:@"%lf", _values[i]];
1640    } else {
1641      [result appendFormat:@", %lf", _values[i]];
1642    }
1643  }
1644  [result appendFormat:@" }"];
1645  return result;
1646}
1647
1648- (void)enumerateValuesWithBlock:(void (NS_NOESCAPE ^)(double value, NSUInteger idx, BOOL *stop))block {
1649  [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
1650}
1651
1652- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
1653                        usingBlock:(void (NS_NOESCAPE ^)(double value, NSUInteger idx, BOOL *stop))block {
1654  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
1655  BOOL stop = NO;
1656  if ((opts & NSEnumerationReverse) == 0) {
1657    for (NSUInteger i = 0, count = _count; i < count; ++i) {
1658      block(_values[i], i, &stop);
1659      if (stop) break;
1660    }
1661  } else if (_count > 0) {
1662    for (NSUInteger i = _count; i > 0; --i) {
1663      block(_values[i - 1], (i - 1), &stop);
1664      if (stop) break;
1665    }
1666  }
1667}
1668
1669- (double)valueAtIndex:(NSUInteger)index {
1670  if (index >= _count) {
1671    [NSException raise:NSRangeException
1672                format:@"Index (%lu) beyond bounds (%lu)",
1673                       (unsigned long)index, (unsigned long)_count];
1674  }
1675  return _values[index];
1676}
1677
1678- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
1679  _values = reallocf(_values, newCapacity * sizeof(double));
1680  if (_values == NULL) {
1681    _capacity = 0;
1682    _count = 0;
1683    [NSException raise:NSMallocException
1684                format:@"Failed to allocate %lu bytes",
1685                       (unsigned long)(newCapacity * sizeof(double))];
1686  }
1687  _capacity = newCapacity;
1688}
1689
1690- (void)addValue:(double)value {
1691  [self addValues:&value count:1];
1692}
1693
1694- (void)addValues:(const double [])values count:(NSUInteger)count {
1695  if (values == NULL || count == 0) return;
1696  NSUInteger initialCount = _count;
1697  NSUInteger newCount = initialCount + count;
1698  if (newCount > _capacity) {
1699    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1700  }
1701  _count = newCount;
1702  memcpy(&_values[initialCount], values, count * sizeof(double));
1703  if (_autocreator) {
1704    GPBAutocreatedArrayModified(_autocreator, self);
1705  }
1706}
1707
1708- (void)insertValue:(double)value atIndex:(NSUInteger)index {
1709  if (index >= _count + 1) {
1710    [NSException raise:NSRangeException
1711                format:@"Index (%lu) beyond bounds (%lu)",
1712                       (unsigned long)index, (unsigned long)_count + 1];
1713  }
1714  NSUInteger initialCount = _count;
1715  NSUInteger newCount = initialCount + 1;
1716  if (newCount > _capacity) {
1717    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1718  }
1719  _count = newCount;
1720  if (index != initialCount) {
1721    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(double));
1722  }
1723  _values[index] = value;
1724  if (_autocreator) {
1725    GPBAutocreatedArrayModified(_autocreator, self);
1726  }
1727}
1728
1729- (void)replaceValueAtIndex:(NSUInteger)index withValue:(double)value {
1730  if (index >= _count) {
1731    [NSException raise:NSRangeException
1732                format:@"Index (%lu) beyond bounds (%lu)",
1733                       (unsigned long)index, (unsigned long)_count];
1734  }
1735  _values[index] = value;
1736}
1737
1738- (void)addValuesFromArray:(GPBDoubleArray *)array {
1739  [self addValues:array->_values count:array->_count];
1740}
1741
1742- (void)removeValueAtIndex:(NSUInteger)index {
1743  if (index >= _count) {
1744    [NSException raise:NSRangeException
1745                format:@"Index (%lu) beyond bounds (%lu)",
1746                       (unsigned long)index, (unsigned long)_count];
1747  }
1748  NSUInteger newCount = _count - 1;
1749  if (index != newCount) {
1750    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(double));
1751  }
1752  _count = newCount;
1753  if ((newCount + (2 * kChunkSize)) < _capacity) {
1754    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1755  }
1756}
1757
1758- (void)removeAll {
1759  _count = 0;
1760  if ((0 + (2 * kChunkSize)) < _capacity) {
1761    [self internalResizeToCapacity:CapacityFromCount(0)];
1762  }
1763}
1764
1765- (void)exchangeValueAtIndex:(NSUInteger)idx1
1766            withValueAtIndex:(NSUInteger)idx2 {
1767  if (idx1 >= _count) {
1768    [NSException raise:NSRangeException
1769                format:@"Index (%lu) beyond bounds (%lu)",
1770                       (unsigned long)idx1, (unsigned long)_count];
1771  }
1772  if (idx2 >= _count) {
1773    [NSException raise:NSRangeException
1774                format:@"Index (%lu) beyond bounds (%lu)",
1775                       (unsigned long)idx2, (unsigned long)_count];
1776  }
1777  double temp = _values[idx1];
1778  _values[idx1] = _values[idx2];
1779  _values[idx2] = temp;
1780}
1781
1782@end
1783
1784//%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Bool, BOOL, %d)
1785// This block of code is generated, do not edit it directly.
1786
1787#pragma mark - Bool
1788
1789@implementation GPBBoolArray {
1790 @package
1791  BOOL *_values;
1792  NSUInteger _count;
1793  NSUInteger _capacity;
1794}
1795
1796@synthesize count = _count;
1797
1798+ (instancetype)array {
1799  return [[[self alloc] init] autorelease];
1800}
1801
1802+ (instancetype)arrayWithValue:(BOOL)value {
1803  // Cast is needed so the compiler knows what class we are invoking initWithValues: on to get
1804  // the type correct.
1805  return [[(GPBBoolArray*)[self alloc] initWithValues:&value count:1] autorelease];
1806}
1807
1808+ (instancetype)arrayWithValueArray:(GPBBoolArray *)array {
1809  return [[(GPBBoolArray*)[self alloc] initWithValueArray:array] autorelease];
1810}
1811
1812+ (instancetype)arrayWithCapacity:(NSUInteger)count {
1813  return [[[self alloc] initWithCapacity:count] autorelease];
1814}
1815
1816- (instancetype)init {
1817  self = [super init];
1818  // No work needed;
1819  return self;
1820}
1821
1822- (instancetype)initWithValueArray:(GPBBoolArray *)array {
1823  return [self initWithValues:array->_values count:array->_count];
1824}
1825
1826- (instancetype)initWithValues:(const BOOL [])values count:(NSUInteger)count {
1827  self = [self init];
1828  if (self) {
1829    if (count && values) {
1830      _values = reallocf(_values, count * sizeof(BOOL));
1831      if (_values != NULL) {
1832        _capacity = count;
1833        memcpy(_values, values, count * sizeof(BOOL));
1834        _count = count;
1835      } else {
1836        [self release];
1837        [NSException raise:NSMallocException
1838                    format:@"Failed to allocate %lu bytes",
1839                           (unsigned long)(count * sizeof(BOOL))];
1840      }
1841    }
1842  }
1843  return self;
1844}
1845
1846- (instancetype)initWithCapacity:(NSUInteger)count {
1847  self = [self initWithValues:NULL count:0];
1848  if (self && count) {
1849    [self internalResizeToCapacity:count];
1850  }
1851  return self;
1852}
1853
1854- (instancetype)copyWithZone:(NSZone *)zone {
1855  return [[GPBBoolArray allocWithZone:zone] initWithValues:_values count:_count];
1856}
1857
1858- (void)dealloc {
1859  NSAssert(!_autocreator,
1860           @"%@: Autocreator must be cleared before release, autocreator: %@",
1861           [self class], _autocreator);
1862  free(_values);
1863  [super dealloc];
1864}
1865
1866- (BOOL)isEqual:(id)other {
1867  if (self == other) {
1868    return YES;
1869  }
1870  if (![other isKindOfClass:[GPBBoolArray class]]) {
1871    return NO;
1872  }
1873  GPBBoolArray *otherArray = other;
1874  return (_count == otherArray->_count
1875          && memcmp(_values, otherArray->_values, (_count * sizeof(BOOL))) == 0);
1876}
1877
1878- (NSUInteger)hash {
1879  // Follow NSArray's lead, and use the count as the hash.
1880  return _count;
1881}
1882
1883- (NSString *)description {
1884  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
1885  for (NSUInteger i = 0, count = _count; i < count; ++i) {
1886    if (i == 0) {
1887      [result appendFormat:@"%d", _values[i]];
1888    } else {
1889      [result appendFormat:@", %d", _values[i]];
1890    }
1891  }
1892  [result appendFormat:@" }"];
1893  return result;
1894}
1895
1896- (void)enumerateValuesWithBlock:(void (NS_NOESCAPE ^)(BOOL value, NSUInteger idx, BOOL *stop))block {
1897  [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
1898}
1899
1900- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
1901                        usingBlock:(void (NS_NOESCAPE ^)(BOOL value, NSUInteger idx, BOOL *stop))block {
1902  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
1903  BOOL stop = NO;
1904  if ((opts & NSEnumerationReverse) == 0) {
1905    for (NSUInteger i = 0, count = _count; i < count; ++i) {
1906      block(_values[i], i, &stop);
1907      if (stop) break;
1908    }
1909  } else if (_count > 0) {
1910    for (NSUInteger i = _count; i > 0; --i) {
1911      block(_values[i - 1], (i - 1), &stop);
1912      if (stop) break;
1913    }
1914  }
1915}
1916
1917- (BOOL)valueAtIndex:(NSUInteger)index {
1918  if (index >= _count) {
1919    [NSException raise:NSRangeException
1920                format:@"Index (%lu) beyond bounds (%lu)",
1921                       (unsigned long)index, (unsigned long)_count];
1922  }
1923  return _values[index];
1924}
1925
1926- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
1927  _values = reallocf(_values, newCapacity * sizeof(BOOL));
1928  if (_values == NULL) {
1929    _capacity = 0;
1930    _count = 0;
1931    [NSException raise:NSMallocException
1932                format:@"Failed to allocate %lu bytes",
1933                       (unsigned long)(newCapacity * sizeof(BOOL))];
1934  }
1935  _capacity = newCapacity;
1936}
1937
1938- (void)addValue:(BOOL)value {
1939  [self addValues:&value count:1];
1940}
1941
1942- (void)addValues:(const BOOL [])values count:(NSUInteger)count {
1943  if (values == NULL || count == 0) return;
1944  NSUInteger initialCount = _count;
1945  NSUInteger newCount = initialCount + count;
1946  if (newCount > _capacity) {
1947    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1948  }
1949  _count = newCount;
1950  memcpy(&_values[initialCount], values, count * sizeof(BOOL));
1951  if (_autocreator) {
1952    GPBAutocreatedArrayModified(_autocreator, self);
1953  }
1954}
1955
1956- (void)insertValue:(BOOL)value atIndex:(NSUInteger)index {
1957  if (index >= _count + 1) {
1958    [NSException raise:NSRangeException
1959                format:@"Index (%lu) beyond bounds (%lu)",
1960                       (unsigned long)index, (unsigned long)_count + 1];
1961  }
1962  NSUInteger initialCount = _count;
1963  NSUInteger newCount = initialCount + 1;
1964  if (newCount > _capacity) {
1965    [self internalResizeToCapacity:CapacityFromCount(newCount)];
1966  }
1967  _count = newCount;
1968  if (index != initialCount) {
1969    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(BOOL));
1970  }
1971  _values[index] = value;
1972  if (_autocreator) {
1973    GPBAutocreatedArrayModified(_autocreator, self);
1974  }
1975}
1976
1977- (void)replaceValueAtIndex:(NSUInteger)index withValue:(BOOL)value {
1978  if (index >= _count) {
1979    [NSException raise:NSRangeException
1980                format:@"Index (%lu) beyond bounds (%lu)",
1981                       (unsigned long)index, (unsigned long)_count];
1982  }
1983  _values[index] = value;
1984}
1985
1986- (void)addValuesFromArray:(GPBBoolArray *)array {
1987  [self addValues:array->_values count:array->_count];
1988}
1989
1990- (void)removeValueAtIndex:(NSUInteger)index {
1991  if (index >= _count) {
1992    [NSException raise:NSRangeException
1993                format:@"Index (%lu) beyond bounds (%lu)",
1994                       (unsigned long)index, (unsigned long)_count];
1995  }
1996  NSUInteger newCount = _count - 1;
1997  if (index != newCount) {
1998    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(BOOL));
1999  }
2000  _count = newCount;
2001  if ((newCount + (2 * kChunkSize)) < _capacity) {
2002    [self internalResizeToCapacity:CapacityFromCount(newCount)];
2003  }
2004}
2005
2006- (void)removeAll {
2007  _count = 0;
2008  if ((0 + (2 * kChunkSize)) < _capacity) {
2009    [self internalResizeToCapacity:CapacityFromCount(0)];
2010  }
2011}
2012
2013- (void)exchangeValueAtIndex:(NSUInteger)idx1
2014            withValueAtIndex:(NSUInteger)idx2 {
2015  if (idx1 >= _count) {
2016    [NSException raise:NSRangeException
2017                format:@"Index (%lu) beyond bounds (%lu)",
2018                       (unsigned long)idx1, (unsigned long)_count];
2019  }
2020  if (idx2 >= _count) {
2021    [NSException raise:NSRangeException
2022                format:@"Index (%lu) beyond bounds (%lu)",
2023                       (unsigned long)idx2, (unsigned long)_count];
2024  }
2025  BOOL temp = _values[idx1];
2026  _values[idx1] = _values[idx2];
2027  _values[idx2] = temp;
2028}
2029
2030@end
2031
2032//%PDDM-EXPAND-END (7 expansions)
2033
2034#pragma mark - Enum
2035
2036@implementation GPBEnumArray {
2037 @package
2038  GPBEnumValidationFunc _validationFunc;
2039  int32_t *_values;
2040  NSUInteger _count;
2041  NSUInteger _capacity;
2042}
2043
2044@synthesize count = _count;
2045@synthesize validationFunc = _validationFunc;
2046
2047+ (instancetype)array {
2048  return [[[self alloc] initWithValidationFunction:NULL] autorelease];
2049}
2050
2051+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func {
2052  return [[[self alloc] initWithValidationFunction:func] autorelease];
2053}
2054
2055+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func
2056                                   rawValue:(int32_t)value {
2057  return [[[self alloc] initWithValidationFunction:func
2058                                         rawValues:&value
2059                                             count:1] autorelease];
2060}
2061
2062+ (instancetype)arrayWithValueArray:(GPBEnumArray *)array {
2063  return [[(GPBEnumArray*)[self alloc] initWithValueArray:array] autorelease];
2064}
2065
2066+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func
2067                                   capacity:(NSUInteger)count {
2068  return [[[self alloc] initWithValidationFunction:func capacity:count] autorelease];
2069}
2070
2071- (instancetype)init {
2072  return [self initWithValidationFunction:NULL];
2073}
2074
2075- (instancetype)initWithValueArray:(GPBEnumArray *)array {
2076  return [self initWithValidationFunction:array->_validationFunc
2077                                rawValues:array->_values
2078                                    count:array->_count];
2079}
2080
2081- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func {
2082  self = [super init];
2083  if (self) {
2084    _validationFunc = (func != NULL ? func : ArrayDefault_IsValidValue);
2085  }
2086  return self;
2087}
2088
2089- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func
2090                                 rawValues:(const int32_t [])values
2091                                     count:(NSUInteger)count {
2092  self = [self initWithValidationFunction:func];
2093  if (self) {
2094    if (count && values) {
2095      _values = reallocf(_values, count * sizeof(int32_t));
2096      if (_values != NULL) {
2097        _capacity = count;
2098        memcpy(_values, values, count * sizeof(int32_t));
2099        _count = count;
2100      } else {
2101        [self release];
2102        [NSException raise:NSMallocException
2103                    format:@"Failed to allocate %lu bytes",
2104                           (unsigned long)(count * sizeof(int32_t))];
2105      }
2106    }
2107  }
2108  return self;
2109}
2110
2111- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func
2112                                  capacity:(NSUInteger)count {
2113  self = [self initWithValidationFunction:func];
2114  if (self && count) {
2115    [self internalResizeToCapacity:count];
2116  }
2117  return self;
2118}
2119
2120- (instancetype)copyWithZone:(NSZone *)zone {
2121  return [[GPBEnumArray allocWithZone:zone]
2122             initWithValidationFunction:_validationFunc
2123                              rawValues:_values
2124                                  count:_count];
2125}
2126
2127//%PDDM-EXPAND ARRAY_IMMUTABLE_CORE(Enum, int32_t, Raw, %d)
2128// This block of code is generated, do not edit it directly.
2129
2130- (void)dealloc {
2131  NSAssert(!_autocreator,
2132           @"%@: Autocreator must be cleared before release, autocreator: %@",
2133           [self class], _autocreator);
2134  free(_values);
2135  [super dealloc];
2136}
2137
2138- (BOOL)isEqual:(id)other {
2139  if (self == other) {
2140    return YES;
2141  }
2142  if (![other isKindOfClass:[GPBEnumArray class]]) {
2143    return NO;
2144  }
2145  GPBEnumArray *otherArray = other;
2146  return (_count == otherArray->_count
2147          && memcmp(_values, otherArray->_values, (_count * sizeof(int32_t))) == 0);
2148}
2149
2150- (NSUInteger)hash {
2151  // Follow NSArray's lead, and use the count as the hash.
2152  return _count;
2153}
2154
2155- (NSString *)description {
2156  NSMutableString *result = [NSMutableString stringWithFormat:@"<%@ %p> { ", [self class], self];
2157  for (NSUInteger i = 0, count = _count; i < count; ++i) {
2158    if (i == 0) {
2159      [result appendFormat:@"%d", _values[i]];
2160    } else {
2161      [result appendFormat:@", %d", _values[i]];
2162    }
2163  }
2164  [result appendFormat:@" }"];
2165  return result;
2166}
2167
2168- (void)enumerateRawValuesWithBlock:(void (NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))block {
2169  [self enumerateRawValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
2170}
2171
2172- (void)enumerateRawValuesWithOptions:(NSEnumerationOptions)opts
2173                           usingBlock:(void (NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))block {
2174  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
2175  BOOL stop = NO;
2176  if ((opts & NSEnumerationReverse) == 0) {
2177    for (NSUInteger i = 0, count = _count; i < count; ++i) {
2178      block(_values[i], i, &stop);
2179      if (stop) break;
2180    }
2181  } else if (_count > 0) {
2182    for (NSUInteger i = _count; i > 0; --i) {
2183      block(_values[i - 1], (i - 1), &stop);
2184      if (stop) break;
2185    }
2186  }
2187}
2188//%PDDM-EXPAND-END ARRAY_IMMUTABLE_CORE(Enum, int32_t, Raw, %d)
2189
2190- (int32_t)valueAtIndex:(NSUInteger)index {
2191//%PDDM-EXPAND VALIDATE_RANGE(index, _count)
2192// This block of code is generated, do not edit it directly.
2193
2194  if (index >= _count) {
2195    [NSException raise:NSRangeException
2196                format:@"Index (%lu) beyond bounds (%lu)",
2197                       (unsigned long)index, (unsigned long)_count];
2198  }
2199//%PDDM-EXPAND-END VALIDATE_RANGE(index, _count)
2200  int32_t result = _values[index];
2201  if (!_validationFunc(result)) {
2202    result = kGPBUnrecognizedEnumeratorValue;
2203  }
2204  return result;
2205}
2206
2207- (int32_t)rawValueAtIndex:(NSUInteger)index {
2208//%PDDM-EXPAND VALIDATE_RANGE(index, _count)
2209// This block of code is generated, do not edit it directly.
2210
2211  if (index >= _count) {
2212    [NSException raise:NSRangeException
2213                format:@"Index (%lu) beyond bounds (%lu)",
2214                       (unsigned long)index, (unsigned long)_count];
2215  }
2216//%PDDM-EXPAND-END VALIDATE_RANGE(index, _count)
2217  return _values[index];
2218}
2219
2220- (void)enumerateValuesWithBlock:(void (NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))block {
2221  [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
2222}
2223
2224- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
2225                        usingBlock:(void (NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))block {
2226  // NSEnumerationConcurrent isn't currently supported (and Apple's docs say that is ok).
2227  BOOL stop = NO;
2228  GPBEnumValidationFunc func = _validationFunc;
2229  if ((opts & NSEnumerationReverse) == 0) {
2230    int32_t *scan = _values;
2231    int32_t *end = scan + _count;
2232    for (NSUInteger i = 0; scan < end; ++i, ++scan) {
2233      int32_t value = *scan;
2234      if (!func(value)) {
2235        value = kGPBUnrecognizedEnumeratorValue;
2236      }
2237      block(value, i, &stop);
2238      if (stop) break;
2239    }
2240  } else if (_count > 0) {
2241    int32_t *end = _values;
2242    int32_t *scan = end + (_count - 1);
2243    for (NSUInteger i = (_count - 1); scan >= end; --i, --scan) {
2244      int32_t value = *scan;
2245      if (!func(value)) {
2246        value = kGPBUnrecognizedEnumeratorValue;
2247      }
2248      block(value, i, &stop);
2249      if (stop) break;
2250    }
2251  }
2252}
2253
2254//%PDDM-EXPAND ARRAY_MUTABLE_CORE(Enum, int32_t, Raw, %d)
2255// This block of code is generated, do not edit it directly.
2256
2257- (void)internalResizeToCapacity:(NSUInteger)newCapacity {
2258  _values = reallocf(_values, newCapacity * sizeof(int32_t));
2259  if (_values == NULL) {
2260    _capacity = 0;
2261    _count = 0;
2262    [NSException raise:NSMallocException
2263                format:@"Failed to allocate %lu bytes",
2264                       (unsigned long)(newCapacity * sizeof(int32_t))];
2265  }
2266  _capacity = newCapacity;
2267}
2268
2269- (void)addRawValue:(int32_t)value {
2270  [self addRawValues:&value count:1];
2271}
2272
2273- (void)addRawValues:(const int32_t [])values count:(NSUInteger)count {
2274  if (values == NULL || count == 0) return;
2275  NSUInteger initialCount = _count;
2276  NSUInteger newCount = initialCount + count;
2277  if (newCount > _capacity) {
2278    [self internalResizeToCapacity:CapacityFromCount(newCount)];
2279  }
2280  _count = newCount;
2281  memcpy(&_values[initialCount], values, count * sizeof(int32_t));
2282  if (_autocreator) {
2283    GPBAutocreatedArrayModified(_autocreator, self);
2284  }
2285}
2286
2287- (void)insertRawValue:(int32_t)value atIndex:(NSUInteger)index {
2288  if (index >= _count + 1) {
2289    [NSException raise:NSRangeException
2290                format:@"Index (%lu) beyond bounds (%lu)",
2291                       (unsigned long)index, (unsigned long)_count + 1];
2292  }
2293  NSUInteger initialCount = _count;
2294  NSUInteger newCount = initialCount + 1;
2295  if (newCount > _capacity) {
2296    [self internalResizeToCapacity:CapacityFromCount(newCount)];
2297  }
2298  _count = newCount;
2299  if (index != initialCount) {
2300    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(int32_t));
2301  }
2302  _values[index] = value;
2303  if (_autocreator) {
2304    GPBAutocreatedArrayModified(_autocreator, self);
2305  }
2306}
2307
2308- (void)replaceValueAtIndex:(NSUInteger)index withRawValue:(int32_t)value {
2309  if (index >= _count) {
2310    [NSException raise:NSRangeException
2311                format:@"Index (%lu) beyond bounds (%lu)",
2312                       (unsigned long)index, (unsigned long)_count];
2313  }
2314  _values[index] = value;
2315}
2316
2317- (void)addRawValuesFromArray:(GPBEnumArray *)array {
2318  [self addRawValues:array->_values count:array->_count];
2319}
2320
2321- (void)removeValueAtIndex:(NSUInteger)index {
2322  if (index >= _count) {
2323    [NSException raise:NSRangeException
2324                format:@"Index (%lu) beyond bounds (%lu)",
2325                       (unsigned long)index, (unsigned long)_count];
2326  }
2327  NSUInteger newCount = _count - 1;
2328  if (index != newCount) {
2329    memmove(&_values[index], &_values[index + 1], (newCount - index) * sizeof(int32_t));
2330  }
2331  _count = newCount;
2332  if ((newCount + (2 * kChunkSize)) < _capacity) {
2333    [self internalResizeToCapacity:CapacityFromCount(newCount)];
2334  }
2335}
2336
2337- (void)removeAll {
2338  _count = 0;
2339  if ((0 + (2 * kChunkSize)) < _capacity) {
2340    [self internalResizeToCapacity:CapacityFromCount(0)];
2341  }
2342}
2343
2344- (void)exchangeValueAtIndex:(NSUInteger)idx1
2345            withValueAtIndex:(NSUInteger)idx2 {
2346  if (idx1 >= _count) {
2347    [NSException raise:NSRangeException
2348                format:@"Index (%lu) beyond bounds (%lu)",
2349                       (unsigned long)idx1, (unsigned long)_count];
2350  }
2351  if (idx2 >= _count) {
2352    [NSException raise:NSRangeException
2353                format:@"Index (%lu) beyond bounds (%lu)",
2354                       (unsigned long)idx2, (unsigned long)_count];
2355  }
2356  int32_t temp = _values[idx1];
2357  _values[idx1] = _values[idx2];
2358  _values[idx2] = temp;
2359}
2360
2361//%PDDM-EXPAND MUTATION_METHODS(Enum, int32_t, , EnumValidationList, EnumValidationOne)
2362// This block of code is generated, do not edit it directly.
2363
2364- (void)addValue:(int32_t)value {
2365  [self addValues:&value count:1];
2366}
2367
2368- (void)addValues:(const int32_t [])values count:(NSUInteger)count {
2369  if (values == NULL || count == 0) return;
2370  GPBEnumValidationFunc func = _validationFunc;
2371  for (NSUInteger i = 0; i < count; ++i) {
2372    if (!func(values[i])) {
2373      [NSException raise:NSInvalidArgumentException
2374                  format:@"%@: Attempt to set an unknown enum value (%d)",
2375                         [self class], values[i]];
2376    }
2377  }
2378  NSUInteger initialCount = _count;
2379  NSUInteger newCount = initialCount + count;
2380  if (newCount > _capacity) {
2381    [self internalResizeToCapacity:CapacityFromCount(newCount)];
2382  }
2383  _count = newCount;
2384  memcpy(&_values[initialCount], values, count * sizeof(int32_t));
2385  if (_autocreator) {
2386    GPBAutocreatedArrayModified(_autocreator, self);
2387  }
2388}
2389
2390- (void)insertValue:(int32_t)value atIndex:(NSUInteger)index {
2391  if (index >= _count + 1) {
2392    [NSException raise:NSRangeException
2393                format:@"Index (%lu) beyond bounds (%lu)",
2394                       (unsigned long)index, (unsigned long)_count + 1];
2395  }
2396  if (!_validationFunc(value)) {
2397    [NSException raise:NSInvalidArgumentException
2398                format:@"%@: Attempt to set an unknown enum value (%d)",
2399                       [self class], value];
2400  }
2401  NSUInteger initialCount = _count;
2402  NSUInteger newCount = initialCount + 1;
2403  if (newCount > _capacity) {
2404    [self internalResizeToCapacity:CapacityFromCount(newCount)];
2405  }
2406  _count = newCount;
2407  if (index != initialCount) {
2408    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(int32_t));
2409  }
2410  _values[index] = value;
2411  if (_autocreator) {
2412    GPBAutocreatedArrayModified(_autocreator, self);
2413  }
2414}
2415
2416- (void)replaceValueAtIndex:(NSUInteger)index withValue:(int32_t)value {
2417  if (index >= _count) {
2418    [NSException raise:NSRangeException
2419                format:@"Index (%lu) beyond bounds (%lu)",
2420                       (unsigned long)index, (unsigned long)_count];
2421  }
2422  if (!_validationFunc(value)) {
2423    [NSException raise:NSInvalidArgumentException
2424                format:@"%@: Attempt to set an unknown enum value (%d)",
2425                       [self class], value];
2426  }
2427  _values[index] = value;
2428}
2429//%PDDM-EXPAND-END (2 expansions)
2430
2431//%PDDM-DEFINE MUTATION_HOOK_EnumValidationList()
2432//%  GPBEnumValidationFunc func = _validationFunc;
2433//%  for (NSUInteger i = 0; i < count; ++i) {
2434//%    if (!func(values[i])) {
2435//%      [NSException raise:NSInvalidArgumentException
2436//%                  format:@"%@: Attempt to set an unknown enum value (%d)",
2437//%                         [self class], values[i]];
2438//%    }
2439//%  }
2440//%
2441//%PDDM-DEFINE MUTATION_HOOK_EnumValidationOne()
2442//%  if (!_validationFunc(value)) {
2443//%    [NSException raise:NSInvalidArgumentException
2444//%                format:@"%@: Attempt to set an unknown enum value (%d)",
2445//%                       [self class], value];
2446//%  }
2447//%
2448
2449@end
2450
2451#pragma mark - NSArray Subclass
2452
2453@implementation GPBAutocreatedArray {
2454  NSMutableArray *_array;
2455}
2456
2457- (void)dealloc {
2458  NSAssert(!_autocreator,
2459           @"%@: Autocreator must be cleared before release, autocreator: %@",
2460           [self class], _autocreator);
2461  [_array release];
2462  [super dealloc];
2463}
2464
2465#pragma mark Required NSArray overrides
2466
2467- (NSUInteger)count {
2468  return [_array count];
2469}
2470
2471- (id)objectAtIndex:(NSUInteger)idx {
2472  return [_array objectAtIndex:idx];
2473}
2474
2475#pragma mark Required NSMutableArray overrides
2476
2477// Only need to call GPBAutocreatedArrayModified() when adding things since
2478// we only autocreate empty arrays.
2479
2480- (void)insertObject:(id)anObject atIndex:(NSUInteger)idx {
2481  if (_array == nil) {
2482    _array = [[NSMutableArray alloc] init];
2483  }
2484  [_array insertObject:anObject atIndex:idx];
2485
2486  if (_autocreator) {
2487    GPBAutocreatedArrayModified(_autocreator, self);
2488  }
2489}
2490
2491- (void)removeObject:(id)anObject {
2492  [_array removeObject:anObject];
2493}
2494
2495- (void)removeObjectAtIndex:(NSUInteger)idx {
2496  [_array removeObjectAtIndex:idx];
2497}
2498
2499- (void)addObject:(id)anObject {
2500  if (_array == nil) {
2501    _array = [[NSMutableArray alloc] init];
2502  }
2503  [_array addObject:anObject];
2504
2505  if (_autocreator) {
2506    GPBAutocreatedArrayModified(_autocreator, self);
2507  }
2508}
2509
2510- (void)removeLastObject {
2511  [_array removeLastObject];
2512}
2513
2514- (void)replaceObjectAtIndex:(NSUInteger)idx withObject:(id)anObject {
2515  [_array replaceObjectAtIndex:idx withObject:anObject];
2516}
2517
2518#pragma mark Extra things hooked
2519
2520- (id)copyWithZone:(NSZone *)zone {
2521  if (_array == nil) {
2522    return [[NSMutableArray allocWithZone:zone] init];
2523  }
2524  return [_array copyWithZone:zone];
2525}
2526
2527- (id)mutableCopyWithZone:(NSZone *)zone {
2528  if (_array == nil) {
2529    return [[NSMutableArray allocWithZone:zone] init];
2530  }
2531  return [_array mutableCopyWithZone:zone];
2532}
2533
2534- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
2535                                  objects:(id __unsafe_unretained [])buffer
2536                                    count:(NSUInteger)len {
2537  return [_array countByEnumeratingWithState:state objects:buffer count:len];
2538}
2539
2540- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(id obj, NSUInteger idx, BOOL *stop))block {
2541  [_array enumerateObjectsUsingBlock:block];
2542}
2543
2544- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts
2545                         usingBlock:(void (NS_NOESCAPE ^)(id obj, NSUInteger idx, BOOL *stop))block {
2546  [_array enumerateObjectsWithOptions:opts usingBlock:block];
2547}
2548
2549@end
2550
2551#pragma clang diagnostic pop
2552