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