Avoid recursive call to `Insert` in the flat case.
[google-protobuf.git] / objectivec / GPBArray.m
blob50d07b2379ef9f95ec6bafef6b5696a6d9fe9ce9
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
8 #import "GPBArray.h"
9 #import "GPBArray_PackagePrivate.h"
11 #import "GPBMessage.h"
12 #import "GPBMessage_PackagePrivate.h"
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"
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)
24 static BOOL ArrayDefault_IsValidValue(int32_t value) {
25   // Anything but the bad value marker is allowed.
26   return (value != kGPBUnrecognizedEnumeratorValue);
29 // Disable clang-format for the macros.
30 // clang-format off
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 //%  }
50 // Macros for the common basic cases.
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 //%}
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 //%}
121 //%- (instancetype)copyWithZone:(NSZone *)zone {
122 //%  return [[GPB##NAME##Array allocWithZone:zone] initWithValues:_values count:_count];
123 //%}
125 //%ARRAY_IMMUTABLE_CORE(NAME, TYPE, , FORMAT)
127 //%- (TYPE)valueAtIndex:(NSUInteger)index {
128 //%VALIDATE_RANGE(index, _count)
129 //%  return _values[index];
130 //%}
132 //%ARRAY_MUTABLE_CORE(NAME, TYPE, , FORMAT)
133 //%@end
137 // Some core macros used for both the simple types and Enums.
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 //%}
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 //%}
161 //%- (NSUInteger)hash {
162 //%  // Follow NSArray's lead, and use the count as the hash.
163 //%  return _count;
164 //%}
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 //%}
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 //%}
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 //%}
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 //%}
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 //%}
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 //%}
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 //%}
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 //%}
249 //%MUTATION_METHODS(NAME, TYPE, ACCESSOR_NAME, None, None)
251 //%- (void)add##ACCESSOR_NAME##ValuesFromArray:(GPB##NAME##Array *)array {
252 //%  [self add##ACCESSOR_NAME##Values:array->_values count:array->_count];
253 //%}
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 //%}
264 //%- (void)removeAll {
265 //%SET_COUNT_AND_MAYBE_SHRINK(0)
266 //%}
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 //%}
277 //%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Int32, int32_t, %d)
278 // This block of code is generated, do not edit it directly.
280 #pragma mark - Int32
282 @implementation GPBInt32Array {
283  @package
284   int32_t *_values;
285   NSUInteger _count;
286   NSUInteger _capacity;
289 @synthesize count = _count;
291 + (instancetype)array {
292   return [[[self alloc] init] autorelease];
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];
301 + (instancetype)arrayWithValueArray:(GPBInt32Array *)array {
302   return [[(GPBInt32Array*)[self alloc] initWithValueArray:array] autorelease];
305 + (instancetype)arrayWithCapacity:(NSUInteger)count {
306   return [[[self alloc] initWithCapacity:count] autorelease];
309 - (instancetype)init {
310   self = [super init];
311   // No work needed;
312   return self;
315 - (instancetype)initWithValueArray:(GPBInt32Array *)array {
316   return [self initWithValues:array->_values count:array->_count];
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;
339 - (instancetype)initWithCapacity:(NSUInteger)count {
340   self = [self initWithValues:NULL count:0];
341   if (self && count) {
342     [self internalResizeToCapacity:count];
343   }
344   return self;
347 - (instancetype)copyWithZone:(NSZone *)zone {
348   return [[GPBInt32Array allocWithZone:zone] initWithValues:_values count:_count];
351 - (void)dealloc {
352   NSAssert(!_autocreator,
353            @"%@: Autocreator must be cleared before release, autocreator: %@",
354            [self class], _autocreator);
355   free(_values);
356   [super dealloc];
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);
371 - (NSUInteger)hash {
372   // Follow NSArray's lead, and use the count as the hash.
373   return _count;
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;
389 - (void)enumerateValuesWithBlock:(void(NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))block {
390   [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
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];
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;
431 - (void)addValue:(int32_t)value {
432   [self addValues:&value count:1];
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   }
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   }
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;
479 - (void)addValuesFromArray:(GPBInt32Array *)array {
480   [self addValues:array->_values count:array->_count];
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   }
499 - (void)removeAll {
500   _count = 0;
501   if ((0 + (2 * kChunkSize)) < _capacity) {
502     [self internalResizeToCapacity:CapacityFromCount(0)];
503   }
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;
523 @end
525 //%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(UInt32, uint32_t, %u)
526 // This block of code is generated, do not edit it directly.
528 #pragma mark - UInt32
530 @implementation GPBUInt32Array {
531  @package
532   uint32_t *_values;
533   NSUInteger _count;
534   NSUInteger _capacity;
537 @synthesize count = _count;
539 + (instancetype)array {
540   return [[[self alloc] init] autorelease];
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];
549 + (instancetype)arrayWithValueArray:(GPBUInt32Array *)array {
550   return [[(GPBUInt32Array*)[self alloc] initWithValueArray:array] autorelease];
553 + (instancetype)arrayWithCapacity:(NSUInteger)count {
554   return [[[self alloc] initWithCapacity:count] autorelease];
557 - (instancetype)init {
558   self = [super init];
559   // No work needed;
560   return self;
563 - (instancetype)initWithValueArray:(GPBUInt32Array *)array {
564   return [self initWithValues:array->_values count:array->_count];
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;
587 - (instancetype)initWithCapacity:(NSUInteger)count {
588   self = [self initWithValues:NULL count:0];
589   if (self && count) {
590     [self internalResizeToCapacity:count];
591   }
592   return self;
595 - (instancetype)copyWithZone:(NSZone *)zone {
596   return [[GPBUInt32Array allocWithZone:zone] initWithValues:_values count:_count];
599 - (void)dealloc {
600   NSAssert(!_autocreator,
601            @"%@: Autocreator must be cleared before release, autocreator: %@",
602            [self class], _autocreator);
603   free(_values);
604   [super dealloc];
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);
619 - (NSUInteger)hash {
620   // Follow NSArray's lead, and use the count as the hash.
621   return _count;
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;
637 - (void)enumerateValuesWithBlock:(void(NS_NOESCAPE ^)(uint32_t value, NSUInteger idx, BOOL *stop))block {
638   [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
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];
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;
679 - (void)addValue:(uint32_t)value {
680   [self addValues:&value count:1];
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   }
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   }
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;
727 - (void)addValuesFromArray:(GPBUInt32Array *)array {
728   [self addValues:array->_values count:array->_count];
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   }
747 - (void)removeAll {
748   _count = 0;
749   if ((0 + (2 * kChunkSize)) < _capacity) {
750     [self internalResizeToCapacity:CapacityFromCount(0)];
751   }
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;
771 @end
773 //%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Int64, int64_t, %lld)
774 // This block of code is generated, do not edit it directly.
776 #pragma mark - Int64
778 @implementation GPBInt64Array {
779  @package
780   int64_t *_values;
781   NSUInteger _count;
782   NSUInteger _capacity;
785 @synthesize count = _count;
787 + (instancetype)array {
788   return [[[self alloc] init] autorelease];
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];
797 + (instancetype)arrayWithValueArray:(GPBInt64Array *)array {
798   return [[(GPBInt64Array*)[self alloc] initWithValueArray:array] autorelease];
801 + (instancetype)arrayWithCapacity:(NSUInteger)count {
802   return [[[self alloc] initWithCapacity:count] autorelease];
805 - (instancetype)init {
806   self = [super init];
807   // No work needed;
808   return self;
811 - (instancetype)initWithValueArray:(GPBInt64Array *)array {
812   return [self initWithValues:array->_values count:array->_count];
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;
835 - (instancetype)initWithCapacity:(NSUInteger)count {
836   self = [self initWithValues:NULL count:0];
837   if (self && count) {
838     [self internalResizeToCapacity:count];
839   }
840   return self;
843 - (instancetype)copyWithZone:(NSZone *)zone {
844   return [[GPBInt64Array allocWithZone:zone] initWithValues:_values count:_count];
847 - (void)dealloc {
848   NSAssert(!_autocreator,
849            @"%@: Autocreator must be cleared before release, autocreator: %@",
850            [self class], _autocreator);
851   free(_values);
852   [super dealloc];
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);
867 - (NSUInteger)hash {
868   // Follow NSArray's lead, and use the count as the hash.
869   return _count;
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;
885 - (void)enumerateValuesWithBlock:(void(NS_NOESCAPE ^)(int64_t value, NSUInteger idx, BOOL *stop))block {
886   [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
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];
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;
927 - (void)addValue:(int64_t)value {
928   [self addValues:&value count:1];
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   }
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   }
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;
975 - (void)addValuesFromArray:(GPBInt64Array *)array {
976   [self addValues:array->_values count:array->_count];
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   }
995 - (void)removeAll {
996   _count = 0;
997   if ((0 + (2 * kChunkSize)) < _capacity) {
998     [self internalResizeToCapacity:CapacityFromCount(0)];
999   }
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;
1019 @end
1021 //%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(UInt64, uint64_t, %llu)
1022 // This block of code is generated, do not edit it directly.
1024 #pragma mark - UInt64
1026 @implementation GPBUInt64Array {
1027  @package
1028   uint64_t *_values;
1029   NSUInteger _count;
1030   NSUInteger _capacity;
1033 @synthesize count = _count;
1035 + (instancetype)array {
1036   return [[[self alloc] init] autorelease];
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];
1045 + (instancetype)arrayWithValueArray:(GPBUInt64Array *)array {
1046   return [[(GPBUInt64Array*)[self alloc] initWithValueArray:array] autorelease];
1049 + (instancetype)arrayWithCapacity:(NSUInteger)count {
1050   return [[[self alloc] initWithCapacity:count] autorelease];
1053 - (instancetype)init {
1054   self = [super init];
1055   // No work needed;
1056   return self;
1059 - (instancetype)initWithValueArray:(GPBUInt64Array *)array {
1060   return [self initWithValues:array->_values count:array->_count];
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;
1083 - (instancetype)initWithCapacity:(NSUInteger)count {
1084   self = [self initWithValues:NULL count:0];
1085   if (self && count) {
1086     [self internalResizeToCapacity:count];
1087   }
1088   return self;
1091 - (instancetype)copyWithZone:(NSZone *)zone {
1092   return [[GPBUInt64Array allocWithZone:zone] initWithValues:_values count:_count];
1095 - (void)dealloc {
1096   NSAssert(!_autocreator,
1097            @"%@: Autocreator must be cleared before release, autocreator: %@",
1098            [self class], _autocreator);
1099   free(_values);
1100   [super dealloc];
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);
1115 - (NSUInteger)hash {
1116   // Follow NSArray's lead, and use the count as the hash.
1117   return _count;
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;
1133 - (void)enumerateValuesWithBlock:(void(NS_NOESCAPE ^)(uint64_t value, NSUInteger idx, BOOL *stop))block {
1134   [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
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];
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;
1175 - (void)addValue:(uint64_t)value {
1176   [self addValues:&value count:1];
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   }
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   }
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;
1223 - (void)addValuesFromArray:(GPBUInt64Array *)array {
1224   [self addValues:array->_values count:array->_count];
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   }
1243 - (void)removeAll {
1244   _count = 0;
1245   if ((0 + (2 * kChunkSize)) < _capacity) {
1246     [self internalResizeToCapacity:CapacityFromCount(0)];
1247   }
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;
1267 @end
1269 //%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Float, float, %f)
1270 // This block of code is generated, do not edit it directly.
1272 #pragma mark - Float
1274 @implementation GPBFloatArray {
1275  @package
1276   float *_values;
1277   NSUInteger _count;
1278   NSUInteger _capacity;
1281 @synthesize count = _count;
1283 + (instancetype)array {
1284   return [[[self alloc] init] autorelease];
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];
1293 + (instancetype)arrayWithValueArray:(GPBFloatArray *)array {
1294   return [[(GPBFloatArray*)[self alloc] initWithValueArray:array] autorelease];
1297 + (instancetype)arrayWithCapacity:(NSUInteger)count {
1298   return [[[self alloc] initWithCapacity:count] autorelease];
1301 - (instancetype)init {
1302   self = [super init];
1303   // No work needed;
1304   return self;
1307 - (instancetype)initWithValueArray:(GPBFloatArray *)array {
1308   return [self initWithValues:array->_values count:array->_count];
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;
1331 - (instancetype)initWithCapacity:(NSUInteger)count {
1332   self = [self initWithValues:NULL count:0];
1333   if (self && count) {
1334     [self internalResizeToCapacity:count];
1335   }
1336   return self;
1339 - (instancetype)copyWithZone:(NSZone *)zone {
1340   return [[GPBFloatArray allocWithZone:zone] initWithValues:_values count:_count];
1343 - (void)dealloc {
1344   NSAssert(!_autocreator,
1345            @"%@: Autocreator must be cleared before release, autocreator: %@",
1346            [self class], _autocreator);
1347   free(_values);
1348   [super dealloc];
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);
1363 - (NSUInteger)hash {
1364   // Follow NSArray's lead, and use the count as the hash.
1365   return _count;
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;
1381 - (void)enumerateValuesWithBlock:(void(NS_NOESCAPE ^)(float value, NSUInteger idx, BOOL *stop))block {
1382   [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
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];
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;
1423 - (void)addValue:(float)value {
1424   [self addValues:&value count:1];
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   }
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   }
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;
1471 - (void)addValuesFromArray:(GPBFloatArray *)array {
1472   [self addValues:array->_values count:array->_count];
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   }
1491 - (void)removeAll {
1492   _count = 0;
1493   if ((0 + (2 * kChunkSize)) < _capacity) {
1494     [self internalResizeToCapacity:CapacityFromCount(0)];
1495   }
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;
1515 @end
1517 //%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Double, double, %lf)
1518 // This block of code is generated, do not edit it directly.
1520 #pragma mark - Double
1522 @implementation GPBDoubleArray {
1523  @package
1524   double *_values;
1525   NSUInteger _count;
1526   NSUInteger _capacity;
1529 @synthesize count = _count;
1531 + (instancetype)array {
1532   return [[[self alloc] init] autorelease];
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];
1541 + (instancetype)arrayWithValueArray:(GPBDoubleArray *)array {
1542   return [[(GPBDoubleArray*)[self alloc] initWithValueArray:array] autorelease];
1545 + (instancetype)arrayWithCapacity:(NSUInteger)count {
1546   return [[[self alloc] initWithCapacity:count] autorelease];
1549 - (instancetype)init {
1550   self = [super init];
1551   // No work needed;
1552   return self;
1555 - (instancetype)initWithValueArray:(GPBDoubleArray *)array {
1556   return [self initWithValues:array->_values count:array->_count];
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;
1579 - (instancetype)initWithCapacity:(NSUInteger)count {
1580   self = [self initWithValues:NULL count:0];
1581   if (self && count) {
1582     [self internalResizeToCapacity:count];
1583   }
1584   return self;
1587 - (instancetype)copyWithZone:(NSZone *)zone {
1588   return [[GPBDoubleArray allocWithZone:zone] initWithValues:_values count:_count];
1591 - (void)dealloc {
1592   NSAssert(!_autocreator,
1593            @"%@: Autocreator must be cleared before release, autocreator: %@",
1594            [self class], _autocreator);
1595   free(_values);
1596   [super dealloc];
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);
1611 - (NSUInteger)hash {
1612   // Follow NSArray's lead, and use the count as the hash.
1613   return _count;
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;
1629 - (void)enumerateValuesWithBlock:(void(NS_NOESCAPE ^)(double value, NSUInteger idx, BOOL *stop))block {
1630   [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
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];
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;
1671 - (void)addValue:(double)value {
1672   [self addValues:&value count:1];
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   }
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   }
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;
1719 - (void)addValuesFromArray:(GPBDoubleArray *)array {
1720   [self addValues:array->_values count:array->_count];
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   }
1739 - (void)removeAll {
1740   _count = 0;
1741   if ((0 + (2 * kChunkSize)) < _capacity) {
1742     [self internalResizeToCapacity:CapacityFromCount(0)];
1743   }
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;
1763 @end
1765 //%PDDM-EXPAND ARRAY_INTERFACE_SIMPLE(Bool, BOOL, %d)
1766 // This block of code is generated, do not edit it directly.
1768 #pragma mark - Bool
1770 @implementation GPBBoolArray {
1771  @package
1772   BOOL *_values;
1773   NSUInteger _count;
1774   NSUInteger _capacity;
1777 @synthesize count = _count;
1779 + (instancetype)array {
1780   return [[[self alloc] init] autorelease];
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];
1789 + (instancetype)arrayWithValueArray:(GPBBoolArray *)array {
1790   return [[(GPBBoolArray*)[self alloc] initWithValueArray:array] autorelease];
1793 + (instancetype)arrayWithCapacity:(NSUInteger)count {
1794   return [[[self alloc] initWithCapacity:count] autorelease];
1797 - (instancetype)init {
1798   self = [super init];
1799   // No work needed;
1800   return self;
1803 - (instancetype)initWithValueArray:(GPBBoolArray *)array {
1804   return [self initWithValues:array->_values count:array->_count];
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;
1827 - (instancetype)initWithCapacity:(NSUInteger)count {
1828   self = [self initWithValues:NULL count:0];
1829   if (self && count) {
1830     [self internalResizeToCapacity:count];
1831   }
1832   return self;
1835 - (instancetype)copyWithZone:(NSZone *)zone {
1836   return [[GPBBoolArray allocWithZone:zone] initWithValues:_values count:_count];
1839 - (void)dealloc {
1840   NSAssert(!_autocreator,
1841            @"%@: Autocreator must be cleared before release, autocreator: %@",
1842            [self class], _autocreator);
1843   free(_values);
1844   [super dealloc];
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);
1859 - (NSUInteger)hash {
1860   // Follow NSArray's lead, and use the count as the hash.
1861   return _count;
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;
1877 - (void)enumerateValuesWithBlock:(void(NS_NOESCAPE ^)(BOOL value, NSUInteger idx, BOOL *stop))block {
1878   [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
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];
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;
1919 - (void)addValue:(BOOL)value {
1920   [self addValues:&value count:1];
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   }
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   }
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;
1967 - (void)addValuesFromArray:(GPBBoolArray *)array {
1968   [self addValues:array->_values count:array->_count];
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   }
1987 - (void)removeAll {
1988   _count = 0;
1989   if ((0 + (2 * kChunkSize)) < _capacity) {
1990     [self internalResizeToCapacity:CapacityFromCount(0)];
1991   }
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;
2011 @end
2013 //%PDDM-EXPAND-END (7 expansions)
2015 // clang-format on
2017 #pragma mark - Enum
2019 @implementation GPBEnumArray {
2020  @package
2021   GPBEnumValidationFunc _validationFunc;
2022   int32_t *_values;
2023   NSUInteger _count;
2024   NSUInteger _capacity;
2027 @synthesize count = _count;
2028 @synthesize validationFunc = _validationFunc;
2030 + (instancetype)array {
2031   return [[[self alloc] initWithValidationFunction:NULL] autorelease];
2034 + (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func {
2035   return [[[self alloc] initWithValidationFunction:func] autorelease];
2038 + (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func rawValue:(int32_t)value {
2039   return [[[self alloc] initWithValidationFunction:func rawValues:&value count:1] autorelease];
2042 + (instancetype)arrayWithValueArray:(GPBEnumArray *)array {
2043   return [[(GPBEnumArray *)[self alloc] initWithValueArray:array] autorelease];
2046 + (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func capacity:(NSUInteger)count {
2047   return [[[self alloc] initWithValidationFunction:func capacity:count] autorelease];
2050 - (instancetype)init {
2051   return [self initWithValidationFunction:NULL];
2054 - (instancetype)initWithValueArray:(GPBEnumArray *)array {
2055   return [self initWithValidationFunction:array->_validationFunc
2056                                 rawValues:array->_values
2057                                     count:array->_count];
2060 - (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func {
2061   self = [super init];
2062   if (self) {
2063     _validationFunc = (func != NULL ? func : ArrayDefault_IsValidValue);
2064   }
2065   return self;
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;
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;
2098 - (instancetype)copyWithZone:(NSZone *)zone {
2099   return [[GPBEnumArray allocWithZone:zone] initWithValidationFunction:_validationFunc
2100                                                              rawValues:_values
2101                                                                  count:_count];
2104 // Disable clang-format for the macros.
2105 // clang-format off
2107 //%PDDM-EXPAND ARRAY_IMMUTABLE_CORE(Enum, int32_t, Raw, %d)
2108 // This block of code is generated, do not edit it directly.
2110 - (void)dealloc {
2111   NSAssert(!_autocreator,
2112            @"%@: Autocreator must be cleared before release, autocreator: %@",
2113            [self class], _autocreator);
2114   free(_values);
2115   [super dealloc];
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);
2130 - (NSUInteger)hash {
2131   // Follow NSArray's lead, and use the count as the hash.
2132   return _count;
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;
2148 - (void)enumerateRawValuesWithBlock:(void(NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))block {
2149   [self enumerateRawValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
2168 //%PDDM-EXPAND-END ARRAY_IMMUTABLE_CORE(Enum, int32_t, Raw, %d)
2170 // clang-format on
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.
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;
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.
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];
2206 - (void)enumerateValuesWithBlock:(void(NS_NOESCAPE ^)(int32_t value, NSUInteger idx, BOOL *stop))
2207                                      block {
2208   [self enumerateValuesWithOptions:(NSEnumerationOptions)0 usingBlock:block];
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   }
2242 // clang-format off
2244 //%PDDM-EXPAND ARRAY_MUTABLE_CORE(Enum, int32_t, Raw, %d)
2245 // This block of code is generated, do not edit it directly.
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;
2259 - (void)addRawValue:(int32_t)value {
2260   [self addRawValues:&value count:1];
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   }
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   }
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;
2307 - (void)addRawValuesFromArray:(GPBEnumArray *)array {
2308   [self addRawValues:array->_values count:array->_count];
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   }
2327 - (void)removeAll {
2328   _count = 0;
2329   if ((0 + (2 * kChunkSize)) < _capacity) {
2330     [self internalResizeToCapacity:CapacityFromCount(0)];
2331   }
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;
2351 //%PDDM-EXPAND MUTATION_METHODS(Enum, int32_t, , EnumValidationList, EnumValidationOne)
2352 // This block of code is generated, do not edit it directly.
2354 - (void)addValue:(int32_t)value {
2355   [self addValues:&value count:1];
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   }
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   }
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;
2419 //%PDDM-EXPAND-END (2 expansions)
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 //%  }
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 //%  }
2439 // clang-format on
2441 @end
2443 #pragma mark - NSArray Subclass
2445 @implementation GPBAutocreatedArray {
2446   NSMutableArray *_array;
2449 - (void)dealloc {
2450   NSAssert(!_autocreator, @"%@: Autocreator must be cleared before release, autocreator: %@",
2451            [self class], _autocreator);
2452   [_array release];
2453   [super dealloc];
2456 #pragma mark Required NSArray overrides
2458 - (NSUInteger)count {
2459   return [_array count];
2462 - (id)objectAtIndex:(NSUInteger)idx {
2463   return [_array objectAtIndex:idx];
2466 #pragma mark Required NSMutableArray overrides
2468 // Only need to call GPBAutocreatedArrayModified() when adding things since
2469 // we only autocreate empty arrays.
2471 - (void)insertObject:(id)anObject atIndex:(NSUInteger)idx {
2472   if (_array == nil) {
2473     _array = [[NSMutableArray alloc] init];
2474   }
2475   [_array insertObject:anObject atIndex:idx];
2477   if (_autocreator) {
2478     GPBAutocreatedArrayModified(_autocreator, self);
2479   }
2482 - (void)removeObject:(id)anObject {
2483   [_array removeObject:anObject];
2486 - (void)removeObjectAtIndex:(NSUInteger)idx {
2487   [_array removeObjectAtIndex:idx];
2490 - (void)addObject:(id)anObject {
2491   if (_array == nil) {
2492     _array = [[NSMutableArray alloc] init];
2493   }
2494   [_array addObject:anObject];
2496   if (_autocreator) {
2497     GPBAutocreatedArrayModified(_autocreator, self);
2498   }
2501 - (void)removeLastObject {
2502   [_array removeLastObject];
2505 - (void)replaceObjectAtIndex:(NSUInteger)idx withObject:(id)anObject {
2506   [_array replaceObjectAtIndex:idx withObject:anObject];
2509 #pragma mark Extra things hooked
2511 - (id)copyWithZone:(NSZone *)zone {
2512   if (_array == nil) {
2513     return [[NSMutableArray allocWithZone:zone] init];
2514   }
2515   return [_array copyWithZone:zone];
2518 - (id)mutableCopyWithZone:(NSZone *)zone {
2519   if (_array == nil) {
2520     return [[NSMutableArray allocWithZone:zone] init];
2521   }
2522   return [_array mutableCopyWithZone:zone];
2525 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
2526                                   objects:(id __unsafe_unretained[])buffer
2527                                     count:(NSUInteger)len {
2528   return [_array countByEnumeratingWithState:state objects:buffer count:len];
2531 - (void)enumerateObjectsUsingBlock:(void(NS_NOESCAPE ^)(id obj, NSUInteger idx, BOOL *stop))block {
2532   [_array enumerateObjectsUsingBlock:block];
2535 - (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts
2536                          usingBlock:(void(NS_NOESCAPE ^)(id obj, NSUInteger idx, BOOL *stop))block {
2537   [_array enumerateObjectsWithOptions:opts usingBlock:block];
2540 @end
2542 #pragma clang diagnostic pop