24
24
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25
25
Boston, MA 02111 USA.
27
<title>NSNumber class reference</title>
28
$Date: 2008-06-08 11:38:33 +0100 (Sun, 08 Jun 2008) $ $Revision: 26606 $
33
#include "GNUstepBase/preface.h"
34
#include "Foundation/NSException.h"
35
#include "Foundation/NSString.h"
36
#include "Foundation/NSNotification.h"
37
#include "Foundation/NSMapTable.h"
38
#include "Foundation/NSThread.h"
39
#include "Foundation/NSCoder.h"
40
#include "Foundation/NSPortCoder.h"
41
#include "Foundation/NSObjCRuntime.h"
43
#include "NSConcreteNumber.h"
44
#include "GSPrivate.h"
46
@interface GSCachedBool : NSBoolNumber
48
@interface GSCachedInt : NSIntNumber
50
@implementation GSCachedBool
51
- (id) copyWithZone: (NSZone*)zone
57
[NSException raise: NSGenericException
58
format: @"Attempt to deallocate bool number owned by cache"];
62
@implementation GSCachedInt
63
- (id) copyWithZone: (NSZone*)zone
69
[NSException raise: NSGenericException
70
format: @"Attempt to deallocate int number owned by cache"];
32
#if !defined(LLONG_MAX)
33
# if defined(__LONG_LONG_MAX__)
34
# define LLONG_MAX __LONG_LONG_MAX__
35
# define LLONG_MIN (-LLONG_MAX-1)
36
# define ULLONG_MAX (LLONG_MAX * 2ULL + 1)
38
# error Neither LLONG_MAX nor __LONG_LONG_MAX__ found
43
#import "Foundation/NSCoder.h"
44
#import "Foundation/NSDecimalNumber.h"
45
#import "Foundation/NSException.h"
46
#import "Foundation/NSValue.h"
47
#import "GNUstepBase/NSObject+GNUstepBase.h"
50
* NSNumber implementation. This matches the behaviour of Apple's
51
* implementation. Values in the range -1 to 12 inclusive are mapped to
52
* singletons. All other values are mapped to the smallest signed value that
53
* will store them, unless they are greater than LLONG_MAX, in which case
54
* they are stored in an unsigned long long.
57
@interface NSSignedIntegerNumber : NSNumber
60
@interface NSIntNumber : NSSignedIntegerNumber
67
@interface NSLongLongNumber : NSSignedIntegerNumber
74
@interface NSUnsignedLongLongNumber : NSNumber
77
unsigned long long int value;
81
// The value ivar in all of the concrete classes contains the real value.
83
#define COMPARE(value, other) \
86
return NSOrderedAscending;\
90
return NSOrderedDescending;\
94
@implementation NSSignedIntegerNumber
95
- (NSComparisonResult) compare: (NSNumber*)aNumber
103
[NSException raise: NSInvalidArgumentException
104
format: @"nil argument for compare:"];
107
switch ([aNumber objCType][0])
109
/* For cases smaller than or equal to an int, we could get the int
122
long long value = [self longLongValue];
123
long long other = [aNumber longLongValue];
125
COMPARE (value, other);
129
unsigned long long other;
130
unsigned long long value;
133
/* According to the C type promotion rules, we should cast this to
134
* an unsigned long long, however Apple's code does not do this.
135
* Instead, it performs a real comparison.
137
v = [self longLongValue];
139
/* If this value is less than 0, then it is less than any value
140
* that can possibly be stored in an unsigned value.
144
return NSOrderedAscending;
147
other = [aNumber unsignedLongLongValue];
148
value = (unsigned long long) v;
149
COMPARE (value, other);
154
double other = [aNumber doubleValue];
155
double value = [self doubleValue];
157
COMPARE (value, other);
160
[NSException raise: NSInvalidArgumentException
161
format: @"unrecognised type for compare:"];
163
return 0; // Not reached.
167
@implementation NSIntNumber
169
#include "NSNumberMethods.h"
172
@implementation NSLongLongNumber
173
#define FORMAT @"%lli"
174
#include "NSNumberMethods.h"
177
@implementation NSUnsignedLongLongNumber
178
#define FORMAT @"%llu"
179
#include "NSNumberMethods.h"
180
- (NSComparisonResult) compare: (NSNumber*)aNumber
184
return NSOrderedSame;
188
[NSException raise: NSInvalidArgumentException
189
format: @"nil argument for compare:"];
192
switch ([aNumber objCType][0])
194
/* For cases smaller than or equal to an int, we could get the int
207
long long other = [aNumber longLongValue];
211
return NSOrderedDescending;
213
COMPARE (value, ((unsigned long long) other));
217
unsigned long long other = [aNumber unsignedLongLongValue];
219
COMPARE (value, other);
224
double other = [aNumber doubleValue];
226
COMPARE (((double) value), other);
229
[NSException raise: NSInvalidArgumentException
230
format: @"unrecognised type for compare:"];
232
return 0; // Not reached.
237
* Abstract superclass for floating point numbers.
239
@interface NSFloatingPointNumber : NSNumber
242
@implementation NSFloatingPointNumber
243
/* For floats, the type promotion rules say that we always promote to a
244
* floating point type, even if the other value is really an integer.
246
- (BOOL) isEqualToNumber: (NSNumber*)aNumber
248
return ([self doubleValue] == [aNumber doubleValue]) ? YES : NO;
251
- (NSComparisonResult) compare: (NSNumber*)aNumber
258
return NSOrderedSame;
262
[NSException raise: NSInvalidArgumentException
263
format: @"nil argument for compare:"];
265
other = [aNumber doubleValue];
266
value = [self doubleValue];
267
COMPARE (value, other);
271
@interface NSFloatNumber : NSFloatingPointNumber
278
@implementation NSFloatNumber
279
#define FORMAT @"%0.7g"
280
#include "NSNumberMethods.h"
283
@interface NSDoubleNumber : NSFloatingPointNumber
290
@implementation NSDoubleNumber
291
#define FORMAT @"%0.16g"
292
#include "NSNumberMethods.h"
75
295
@implementation NSNumber
77
static NSMapTable *numberMap;
78
static BOOL multiThreaded = NO;
79
static NSNumber *boolN;
80
static NSNumber *boolY;
81
static NSNumber *smallIntegers[GS_SMALL * 2 + 1];
82
static unsigned int smallHashes[GS_SMALL * 2 + 1];
85
* Cache info for each number class.
86
* In a multi-threaded system we may waste some memory in order to get speed.
298
* Numbers from -1 to 12 inclusive that are reused.
89
GSNumberInfoFromObject(NSNumber *o)
97
info = (GSNumberInfo*)NSMapGet (numberMap, (void*)c);
100
const char *t = [o objCType];
105
NSLog(@"Invalid return value (%s) from [%@ objCType]", t, c);
111
case 'c': order = 1; break;
112
case 'C': order = 2; break;
113
case 's': order = 3; break;
114
case 'S': order = 4; break;
115
case 'i': order = 5; break;
116
case 'I': order = 6; break;
117
case 'l': order = 7; break;
118
case 'L': order = 8; break;
119
case 'q': order = 9; break;
120
case 'Q': order = 10; break;
121
case 'f': order = 11; break;
122
case 'd': order = 12; break;
124
NSLog(@"Invalid return value (%s) from [%@ objCType]", t, c);
128
info = (GSNumberInfo*)NSZoneMalloc(NSDefaultMallocZone(),
129
(sizeof(GSNumberInfo)));
130
info->typeLevel = order;
132
info->getValue = (void (*)(NSNumber*, SEL, void*))
133
[o methodForSelector: @selector(getValue:)];
135
if (multiThreaded == YES)
140
* Memory leak for efficiency - the old map table is never
141
* deallocated, so we don't have to do any locking.
143
table = NSCopyMapTableWithZone(numberMap, NSDefaultMallocZone());
144
NSMapInsert(table, (void*)c, (void*)info);
149
NSMapInsert(numberMap, (void*)c, (void*)info);
156
GSPrivateSmallHash(int n)
158
return smallHashes[n + GS_SMALL];
161
static Class abstractClass;
162
static Class boolNumberClass;
163
static Class charNumberClass;
164
static Class uCharNumberClass;
165
static Class shortNumberClass;
166
static Class uShortNumberClass;
167
static Class intNumberClass;
168
static Class uIntNumberClass;
169
static Class longNumberClass;
170
static Class uLongNumberClass;
171
static Class longLongNumberClass;
172
static Class uLongLongNumberClass;
173
static Class floatNumberClass;
174
static Class doubleNumberClass;
176
+ (void) _becomeThreaded: (NSNotification*)notification
300
static NSNumber *ReusedInstances[14];
301
static Class NSNumberClass;
302
static Class NSIntNumberClass;
303
static Class NSLongLongNumberClass;
304
static Class NSUnsignedLongLongNumberClass;
305
static Class NSFloatNumberClass;
306
static Class NSDoubleNumberClass;
181
308
+ (void) initialize
183
if (self == [NSNumber class])
187
unsigned (*hasher)(NSNumber*, SEL);
189
CREATE_AUTORELEASE_POOL(pool);
191
abstractClass = self;
192
hasher = (unsigned (*)(NSNumber*, SEL))
193
[self instanceMethodForSelector: @selector(hash)];
196
* Create cache for per-subclass method implementations etc.
198
numberMap = NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
199
NSOwnedPointerMapValueCallBacks, 0);
202
* cache standard subclass info.
204
boolNumberClass = [NSBoolNumber class];
205
info = GSNumberInfoFromObject(AUTORELEASE([boolNumberClass alloc]));
207
* Set the typeLevel for a boolean to be '0'
210
charNumberClass = [NSCharNumber class];
211
GSNumberInfoFromObject(AUTORELEASE([charNumberClass alloc]));
212
uCharNumberClass = [NSUCharNumber class];
213
GSNumberInfoFromObject(AUTORELEASE([uCharNumberClass alloc]));
214
shortNumberClass = [NSShortNumber class];
215
GSNumberInfoFromObject(AUTORELEASE([shortNumberClass alloc]));
216
uShortNumberClass = [NSUShortNumber class];
217
GSNumberInfoFromObject(AUTORELEASE([uShortNumberClass alloc]));
218
intNumberClass = [NSIntNumber class];
219
GSNumberInfoFromObject(AUTORELEASE([intNumberClass alloc]));
220
uIntNumberClass = [NSUIntNumber class];
221
GSNumberInfoFromObject(AUTORELEASE([uIntNumberClass alloc]));
222
longNumberClass = [NSLongNumber class];
223
GSNumberInfoFromObject(AUTORELEASE([longNumberClass alloc]));
224
uLongNumberClass = [NSULongNumber class];
225
GSNumberInfoFromObject(AUTORELEASE([uLongNumberClass alloc]));
226
longLongNumberClass = [NSLongLongNumber class];
227
GSNumberInfoFromObject(AUTORELEASE([longLongNumberClass alloc]));
228
uLongLongNumberClass = [NSULongLongNumber class];
229
GSNumberInfoFromObject(AUTORELEASE([uLongLongNumberClass alloc]));
230
floatNumberClass = [NSFloatNumber class];
231
GSNumberInfoFromObject(AUTORELEASE([floatNumberClass alloc]));
232
doubleNumberClass = [NSDoubleNumber class];
233
GSNumberInfoFromObject(AUTORELEASE([doubleNumberClass alloc]));
238
boolN = (NSNumber*)NSAllocateObject([GSCachedBool class], 0,
239
NSDefaultMallocZone());
241
boolN = [boolN initWithBytes: &boolean objCType: NULL];
243
boolY = (NSNumber*)NSAllocateObject([GSCachedBool class], 0,
244
NSDefaultMallocZone());
246
boolY = [boolY initWithBytes: &boolean objCType: NULL];
249
* cache small integer values.
251
for (integer = -GS_SMALL; integer <= GS_SMALL; integer++)
255
num = (NSNumber*)NSAllocateObject([GSCachedInt class], 0,
256
NSDefaultMallocZone());
257
num = [num initWithBytes: &integer objCType: NULL];
258
smallIntegers[integer + GS_SMALL] = num;
259
smallHashes[integer + GS_SMALL] = (*hasher)(num, @selector(hash));
263
* Make sure we know if we are multi-threaded so that if the caches
264
* need to grow, we do it by copying and replacing without deleting
265
* an old cache that may be in use by another thread.
267
if ([NSThread isMultiThreaded])
269
[self _becomeThreaded: nil];
273
[[NSNotificationCenter defaultCenter]
275
selector: @selector(_becomeThreaded:)
276
name: NSWillBecomeMultiThreadedNotification
283
/* Returns the concrete class associated with the type encoding. Note
284
that we don't allow NSNumber to instantiate any class but its own
285
concrete subclasses (see check at end of method) */
286
+ (Class) valueClassWithObjCType: (const char*)type
288
Class theClass = Nil;
292
case _C_CHR: return charNumberClass;
293
case _C_UCHR: return uCharNumberClass;
294
case _C_SHT: return shortNumberClass;
295
case _C_USHT: return uShortNumberClass;
296
case _C_INT: return intNumberClass;
297
case _C_UINT: return uIntNumberClass;
298
case _C_LNG: return longNumberClass;
299
case _C_ULNG: return uLongNumberClass;
312
if ([NSNumber class] != self)
317
NSNumberClass = self;
318
NSIntNumberClass = [NSIntNumber class];
319
NSLongLongNumberClass = [NSLongLongNumber class];
320
NSUnsignedLongLongNumberClass = [NSUnsignedLongLongNumber class];
321
NSFloatNumberClass = [NSFloatNumber class];
322
NSDoubleNumberClass = [NSDoubleNumber class];
324
for (i = 0; i < 14; i++)
326
NSIntNumber *n = NSAllocateObject (NSIntNumberClass, 0, 0);
329
ReusedInstances[i] = n;
333
- (const char *) objCType
335
/* All concrete NSNumber types must implement this so we know which oen
338
[self subclassResponsibility: _cmd];
339
return NULL; // Not reached
342
- (BOOL) isEqualToNumber: (NSNumber*)aNumber
344
return ([self compare: aNumber] == NSOrderedSame) ? YES : NO;
347
- (BOOL) isEqual: (id)anObject
349
if ([anObject isKindOfClass: NSNumberClass])
351
return [self isEqualToNumber: anObject];
353
return [super isEqual: anObject];
356
- (BOOL) isEqualToValue: (NSValue*)aValue
358
if ([aValue isKindOfClass: NSNumberClass])
360
return [self isEqualToNumber: (NSNumber*)aValue];
367
return (unsigned)[self doubleValue];
370
- (NSString*) stringValue
372
return [self descriptionWithLocale: nil];
375
- (NSString*) descriptionWithLocale: (id)aLocale
377
[self subclassResponsibility: _cmd];
378
return nil; // Not reached
381
- (NSComparisonResult) compare: (NSNumber*)aNumber
383
[self subclassResponsibility: _cmd];
384
return 0; // Not reached
387
#define INTEGER_MACRO(type, ignored, name) \
388
- (id) initWith ## name: (type)aValue \
391
return [[NSNumberClass numberWith ## name: aValue] retain];\
394
#include "GSNumberTypes.h"
396
- (id) initWithBool: (BOOL)aValue
399
return [ReusedInstances[aValue ? 2 : 1] retain];\
403
* Macro for checking whether this value is the same as one of the singleton
406
#define CHECK_SINGLETON(aValue) \
407
if (aValue >= -1 && aValue <= 12)\
409
return ReusedInstances[aValue+1];\
412
+ (NSNumber *) numberWithBool: (BOOL)aValue
414
CHECK_SINGLETON (((signed char) aValue));
415
return [self numberWithInt: aValue];
416
// Not reached (BOOL is always 0 or 1)
419
+ (NSNumber *) numberWithChar: (signed char)aValue
421
return [self numberWithInt: aValue];
424
+ (NSNumber *) numberWithUnsignedChar: (unsigned char)aValue
426
return [self numberWithInt: aValue];
429
+ (NSNumber *) numberWithShort: (short)aValue
431
return [self numberWithInt: aValue];
434
+ (NSNumber *) numberWithUnsignedShort: (unsigned short)aValue
436
return [self numberWithInt: aValue];
439
+ (NSNumber *) numberWithInt: (int)aValue
443
CHECK_SINGLETON (aValue);
444
n = NSAllocateObject (NSIntNumberClass, 0, 0);
446
return AUTORELEASE(n);
449
+ (NSNumber *) numberWithUnsignedInt: (unsigned int)aValue
451
CHECK_SINGLETON (aValue);
453
if (aValue < (unsigned int) INT_MAX)
455
return [self numberWithInt: (int)aValue];
457
return [self numberWithLongLong: aValue];
460
+ (NSNumber *) numberWithLong: (long)aValue
462
return [self numberWithLongLong: aValue];
465
+ (NSNumber *) numberWithUnsignedLong: (unsigned long)aValue
467
return [self numberWithUnsignedLongLong: aValue];
470
+ (NSNumber *) numberWithLongLong: (long long)aValue
474
CHECK_SINGLETON (aValue);
475
if (aValue < (long long)INT_MAX && aValue > (long long)INT_MIN)
477
return [self numberWithInt: (int) aValue];
479
n = NSAllocateObject (NSLongLongNumberClass, 0, 0);
481
return AUTORELEASE(n);
484
+ (NSNumber *) numberWithUnsignedLongLong: (unsigned long long)aValue
486
NSUnsignedLongLongNumber *n;
488
if (aValue < (unsigned long long) LLONG_MAX)
490
return [self numberWithLongLong: (long long) aValue];
492
n = NSAllocateObject (NSUnsignedLongLongNumberClass, 0, 0);
494
return AUTORELEASE(n);
497
+ (NSNumber *) numberWithFloat: (float)aValue
499
NSFloatNumber *n = NSAllocateObject (NSFloatNumberClass, 0, 0);
502
return AUTORELEASE(n);
505
+ (NSNumber *) numberWithDouble: (double)aValue
507
NSDoubleNumber *n = NSAllocateObject (NSDoubleNumberClass, 0, 0);
510
return AUTORELEASE(n);
513
+ (NSNumber *) numberWithInteger: (NSInteger)aValue
515
// Compile time constant; the compiler will remove this conditional
516
if (sizeof (NSInteger) == sizeof (int))
518
return [self numberWithInt: aValue];
520
return [self numberWithLongLong: aValue];
523
+ (NSNumber *) numberWithUnsignedInteger: (NSUInteger)aValue
525
// Compile time constant; the compiler will remove this conditional
526
if (sizeof (NSUInteger) == sizeof (unsigned int))
528
return [self numberWithUnsignedInt: aValue];
530
return [self numberWithUnsignedLongLong: aValue];
533
- (id) initWithBytes: (const void *)
534
value objCType: (const char *)type
539
return [self initWithInteger: *(char *) value];
541
return [self initWithInteger: *(unsigned char *) value];
543
return [self initWithInteger: *(short *) value];
545
return [self initWithInteger: *(unsigned short *) value];
547
return [self initWithInteger: *(int *) value];
549
return [self initWithInteger: *(unsigned int *) value];
551
return [self initWithLong: *(long *) value];
553
return [self initWithUnsignedLong: *(unsigned long *) value];
305
return longLongNumberClass;
555
return [self initWithLongLong: *(long long *) value];
311
return uLongLongNumberClass;
312
case _C_FLT: return floatNumberClass;
313
case _C_DBL: return doubleNumberClass;
318
if (theClass == Nil && self == abstractClass)
320
[NSException raise: NSInvalidArgumentException
321
format: @"Invalid number type"];
324
else if (theClass == Nil)
326
theClass = [super valueClassWithObjCType: type];
331
+ (NSNumber*) numberWithBool: (BOOL)value
333
// if class is NSNumber, replace by appropriate object
334
if (self == abstractClass)
345
else // alloc class and init with object intWithXX method
347
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
348
initWithBool: value]);
352
+ (NSNumber*) numberWithChar: (signed char)value
354
NSNumber *theObj = nil;
356
// if class is NSNumber, replace by appropriate object
357
if (self == abstractClass)
359
if (value <= GS_SMALL && value >= -GS_SMALL)
361
return smallIntegers[value + GS_SMALL];
363
theObj = (NSNumber*)NSAllocateObject(charNumberClass, 0,
364
NSDefaultMallocZone());
365
theObj = [theObj initWithBytes: &value objCType: NULL];
367
else // alloc class and init with object intWithXX method
369
theObj = [[self allocWithZone: NSDefaultMallocZone()]
370
initWithChar: value];
373
return AUTORELEASE(theObj);
376
+ (NSNumber*) numberWithDouble: (double)value
378
NSNumber *theObj = nil;
380
// if class is NSNumber, replace by appropriate object
381
if (self == abstractClass)
383
theObj = (NSNumber*)NSAllocateObject(doubleNumberClass, 0,
384
NSDefaultMallocZone());
385
theObj = [theObj initWithBytes: &value objCType: NULL];
387
else // alloc class and init with object intWithXX method
389
theObj = [[self allocWithZone: NSDefaultMallocZone()]
390
initWithDouble: value];
393
return AUTORELEASE(theObj);
396
+ (NSNumber*) numberWithFloat: (float)value
398
NSNumber *theObj = nil;
400
// if class is NSNumber, replace by appropriate object
401
if (self == abstractClass)
403
theObj = (NSNumber*)NSAllocateObject(floatNumberClass, 0,
404
NSDefaultMallocZone());
405
theObj = [theObj initWithBytes: &value objCType: NULL];
407
else // alloc class and init with object intWithXX method
409
theObj = [[self allocWithZone: NSDefaultMallocZone()]
410
initWithFloat: value];
413
return AUTORELEASE(theObj);
416
+ (NSNumber*) numberWithInt: (signed int)value
418
NSNumber *theObj = nil;
420
// if class is NSNumber, replace by appropriate object
421
if (self == abstractClass)
423
if (value <= GS_SMALL && value >= -GS_SMALL)
425
return smallIntegers[value + GS_SMALL];
427
theObj = (NSNumber*)NSAllocateObject(intNumberClass, 0,
428
NSDefaultMallocZone());
429
theObj = [theObj initWithBytes: &value objCType: NULL];
431
else // alloc class and init with object intWithXX method
433
theObj = [[self allocWithZone: NSDefaultMallocZone()]
437
return AUTORELEASE(theObj);
440
+ (NSNumber*) numberWithLong: (signed long)value
442
NSNumber *theObj = nil;
444
// if class is NSNumber, replace by appropriate object
445
if (self == abstractClass)
447
if (value <= GS_SMALL && value >= -GS_SMALL)
449
return smallIntegers[value + GS_SMALL];
451
theObj = (NSNumber*)NSAllocateObject(longNumberClass, 0,
452
NSDefaultMallocZone());
453
theObj = [theObj initWithBytes: &value objCType: NULL];
455
else // alloc class and init with object intWithXX method
457
theObj = [[self allocWithZone: NSDefaultMallocZone()]
458
initWithLong: value];
461
return AUTORELEASE(theObj);
464
+ (NSNumber*) numberWithLongLong: (signed long long)value
466
NSNumber *theObj = nil;
468
// if class is NSNumber, replace by appropriate object
469
if (self == abstractClass)
471
if (value <= GS_SMALL && value >= -GS_SMALL)
473
return smallIntegers[value + GS_SMALL];
475
theObj = (NSNumber*)NSAllocateObject(longLongNumberClass, 0,
476
NSDefaultMallocZone());
477
theObj = [theObj initWithBytes: &value objCType: NULL];
479
else // alloc class and init with object intWithXX method
481
theObj = [[self allocWithZone: NSDefaultMallocZone()]
482
initWithLongLong: value];
485
return AUTORELEASE(theObj);
488
+ (NSNumber*) numberWithShort: (signed short)value
490
NSNumber *theObj = nil;
492
// if class is NSNumber, replace by appropriate object
493
if (self == abstractClass)
495
if (value <= GS_SMALL && value >= -GS_SMALL)
497
return smallIntegers[value + GS_SMALL];
499
theObj = (NSNumber*)NSAllocateObject(shortNumberClass, 0,
500
NSDefaultMallocZone());
501
theObj = [theObj initWithBytes: &value objCType: NULL];
503
else // alloc class and init with object intWithXX method
505
theObj = [[self allocWithZone: NSDefaultMallocZone()]
506
initWithShort: value];
509
return AUTORELEASE(theObj);
512
+ (NSNumber*) numberWithUnsignedChar: (unsigned char)value
514
NSNumber *theObj = nil;
516
// if class is NSNumber, replace by appropriate object
517
if (self == abstractClass)
519
if (value <= GS_SMALL)
521
return smallIntegers[value + GS_SMALL];
523
theObj = (NSNumber*)NSAllocateObject(uCharNumberClass, 0,
524
NSDefaultMallocZone());
525
theObj = [theObj initWithBytes: &value objCType: NULL];
527
else // alloc class and init with object intWithXX method
529
theObj = [[self allocWithZone: NSDefaultMallocZone()]
530
initWithUnsignedChar: value];
533
return AUTORELEASE(theObj);
536
+ (NSNumber*) numberWithUnsignedInt: (unsigned int)value
538
NSNumber *theObj = nil;
540
// if class is NSNumber, replace by appropriate object
541
if (self == abstractClass)
543
if (value <= GS_SMALL)
545
return smallIntegers[value + GS_SMALL];
547
theObj = (NSNumber*)NSAllocateObject(uIntNumberClass, 0,
548
NSDefaultMallocZone());
549
theObj = [theObj initWithBytes: &value objCType: NULL];
551
else // alloc class and init with object intWithXX method
553
theObj = [[self allocWithZone: NSDefaultMallocZone()]
554
initWithUnsignedInt: value];
557
return AUTORELEASE(theObj);
560
+ (NSNumber*) numberWithUnsignedLong: (unsigned long)value
562
NSNumber *theObj = nil;
564
// if class is NSNumber, replace by appropriate object
565
if (self == abstractClass)
567
if (value <= GS_SMALL)
569
return smallIntegers[value + GS_SMALL];
571
theObj = (NSNumber*)NSAllocateObject(uLongNumberClass, 0,
572
NSDefaultMallocZone());
573
theObj = [theObj initWithBytes: &value objCType: NULL];
575
else // alloc class and init with object intWithXX method
577
theObj = [[self allocWithZone: NSDefaultMallocZone()]
578
initWithUnsignedLong: value];
581
return AUTORELEASE(theObj);
584
+ (NSNumber*) numberWithUnsignedLongLong: (unsigned long long)value
586
NSNumber *theObj = nil;
588
// if class is NSNumber, replace by appropriate object
589
if (self == abstractClass)
591
if (value <= GS_SMALL)
593
return smallIntegers[value + GS_SMALL];
595
theObj = (NSNumber*)NSAllocateObject(uLongLongNumberClass, 0,
596
NSDefaultMallocZone());
597
theObj = [theObj initWithBytes: &value objCType: NULL];
599
else // alloc class and init with object intWithXX method
601
theObj = [[self allocWithZone: NSDefaultMallocZone()]
602
initWithUnsignedLongLong: value];
605
return AUTORELEASE(theObj);
608
+ (NSNumber*) numberWithUnsignedShort: (unsigned short)value
610
NSNumber *theObj = nil;
612
// if class is NSNumber, replace by appropriate object
613
if (self == abstractClass)
615
if (value <= GS_SMALL)
617
return smallIntegers[value + GS_SMALL];
619
theObj = (NSNumber*)NSAllocateObject(uShortNumberClass, 0,
620
NSDefaultMallocZone());
621
theObj = [theObj initWithBytes: &value objCType: NULL];
623
else // alloc class and init with object intWithXX method
625
theObj = [[self allocWithZone: NSDefaultMallocZone()]
626
initWithUnsignedShort: value];
629
return AUTORELEASE(theObj);
633
* A moderately sane default init method - a zero value integer.
557
return [self initWithUnsignedLongLong: *(unsigned long long *) value];
559
return [self initWithFloat: *(float *) value];
561
return [self initWithDouble: *(double *) value];
563
return [super initWithBytes: value objCType: type];
566
- (void *) pointerValue
568
return (void *)[self unsignedIntegerValue];
571
- (id) replacementObjectForPortCoder: (NSPortCoder *) encoder
576
- (Class) classForCoder
578
return NSNumberClass;
581
- (void) encodeWithCoder: (NSCoder *) coder
583
const char *type = [self objCType];
586
[coder encodeValueOfObjCType: @encode (char) at: type];
587
/* The most we currently store in an NSNumber is 8 bytes (double or long
588
* long), but we may add support for vectors or long doubles in future, so
589
* make this 16 bytes now so stuff doesn't break in fun and exciting ways
592
[self getValue: buffer];
593
[coder encodeValueOfObjCType: type at: buffer];
596
- (id) copyWithZone: (NSZone *) aZone
598
// OSX just returns the receive with no copy.
599
return RETAIN (self);
602
- (id) initWithCoder: (NSCoder *) coder
604
char type[2] = { 0 };
607
[coder decodeValueOfObjCType: @encode (char) at: type];
608
[coder decodeValueOfObjCType: type at: buffer];
609
return [self initWithBytes: buffer objCType: type];
612
- (NSString *) description
614
return [self stringValue];
617
/* Return nil for an NSNumber that is allocated and initalized without
618
* providing a real value. Yes, this seems weird, but it is actually what
637
return [self initWithInt: 0];
640
- (id) initWithBool: (BOOL)value
654
- (id) initWithChar: (signed char)value
657
if (value <= GS_SMALL && value >= -GS_SMALL)
659
return RETAIN(smallIntegers[value + GS_SMALL]);
661
self = (NSNumber*)NSAllocateObject(charNumberClass, 0,
662
NSDefaultMallocZone());
663
self = [self initWithBytes: &value objCType: NULL];
667
- (id) initWithDouble: (double)value
670
self = (NSNumber*)NSAllocateObject(doubleNumberClass, 0,
671
NSDefaultMallocZone());
672
self = [self initWithBytes: &value objCType: NULL];
676
- (id) initWithFloat: (float)value
679
self = (NSNumber*)NSAllocateObject(floatNumberClass, 0,
680
NSDefaultMallocZone());
681
self = [self initWithBytes: &value objCType: NULL];
685
- (id) initWithInt: (signed int)value
688
if (value <= GS_SMALL && value >= -GS_SMALL)
690
return RETAIN(smallIntegers[value + GS_SMALL]);
692
self = (NSNumber*)NSAllocateObject(intNumberClass, 0,
693
NSDefaultMallocZone());
694
self = [self initWithBytes: &value objCType: NULL];
698
- (id) initWithLong: (signed long)value
701
if (value <= GS_SMALL && value >= -GS_SMALL)
703
return RETAIN(smallIntegers[value + GS_SMALL]);
705
self = (NSNumber*)NSAllocateObject(longNumberClass, 0,
706
NSDefaultMallocZone());
707
self = [self initWithBytes: &value objCType: NULL];
711
- (id) initWithLongLong: (signed long long)value
714
if (value <= GS_SMALL && value >= -GS_SMALL)
716
return RETAIN(smallIntegers[value + GS_SMALL]);
718
self = (NSNumber*)NSAllocateObject(longLongNumberClass, 0,
719
NSDefaultMallocZone());
720
self = [self initWithBytes: &value objCType: NULL];
724
- (id) initWithShort: (signed short)value
727
if (value <= GS_SMALL && value >= -GS_SMALL)
729
return RETAIN(smallIntegers[value + GS_SMALL]);
731
self = (NSNumber*)NSAllocateObject(shortNumberClass, 0,
732
NSDefaultMallocZone());
733
self = [self initWithBytes: &value objCType: NULL];
737
- (id) initWithUnsignedChar: (unsigned char)value
740
if (value <= GS_SMALL)
742
return RETAIN(smallIntegers[value + GS_SMALL]);
744
self = (NSNumber*)NSAllocateObject(uCharNumberClass, 0,
745
NSDefaultMallocZone());
746
self = [self initWithBytes: &value objCType: NULL];
750
- (id) initWithUnsignedInt: (unsigned int)value
753
if (value <= GS_SMALL)
755
return RETAIN(smallIntegers[value + GS_SMALL]);
757
self = (NSNumber*)NSAllocateObject(uIntNumberClass, 0,
758
NSDefaultMallocZone());
759
self = [self initWithBytes: &value objCType: NULL];
763
- (id) initWithUnsignedLong: (unsigned long)value
766
if (value <= GS_SMALL)
768
return RETAIN(smallIntegers[value + GS_SMALL]);
770
self = (NSNumber*)NSAllocateObject(uLongNumberClass, 0,
771
NSDefaultMallocZone());
772
self = [self initWithBytes: &value objCType: NULL];
776
- (id) initWithUnsignedLongLong: (unsigned long long)value
779
if (value <= GS_SMALL)
781
return RETAIN(smallIntegers[value + GS_SMALL]);
783
self = (NSNumber*)NSAllocateObject(uLongLongNumberClass, 0,
784
NSDefaultMallocZone());
785
self = [self initWithBytes: &value objCType: NULL];
789
- (id) initWithUnsignedShort: (unsigned short)value
792
if (value <= GS_SMALL)
794
return RETAIN(smallIntegers[value + GS_SMALL]);
796
self = (NSNumber*)NSAllocateObject(uShortNumberClass, 0,
797
NSDefaultMallocZone());
798
self = [self initWithBytes: &value objCType: NULL];
802
- (id) copyWithZone: (NSZone*)zone
804
if (NSShouldRetainWithZone(self, zone))
807
return NSCopyObject(self, 0, zone);
810
- (NSString*) description
812
return [self descriptionWithLocale: nil];
815
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
817
NSString *result = nil;
819
if (GSObjCClass(self) == abstractClass)
821
[NSException raise: NSInternalInconsistencyException
822
format: @"descriptionWithLocale: for abstract NSNumber"];
826
GSNumberInfo *info = GSNumberInfoFromObject(self);
828
switch (info->typeLevel)
831
return [self boolValue] ? @"1" : @"0";
835
result = [[NSString alloc] initWithFormat: @"%i" locale: locale,
836
(int)[self charValue]];
840
result = [[NSString alloc] initWithFormat: @"%u" locale: locale,
841
(unsigned int)[self unsignedCharValue]];
845
result = [[NSString alloc] initWithFormat: @"%hi" locale: locale,
850
result = [[NSString alloc] initWithFormat: @"%hu" locale: locale,
851
[self unsignedShortValue]];
855
result = [[NSString alloc] initWithFormat: @"%i" locale: locale,
860
result = [[NSString alloc] initWithFormat: @"%u" locale: locale,
861
[self unsignedIntValue]];
865
result = [[NSString alloc] initWithFormat: @"%li" locale: locale,
870
result = [[NSString alloc] initWithFormat: @"%lu" locale: locale,
871
[self unsignedLongValue]];
875
result = [[NSString alloc] initWithFormat: @"%lli" locale: locale,
876
[self longLongValue]];
880
result = [[NSString alloc] initWithFormat: @"%llu" locale: locale,
881
[self unsignedLongLongValue]];
885
result = [[NSString alloc] initWithFormat: @"%0.7g" locale: locale,
886
(double)[self floatValue]];
890
result = [[NSString alloc] initWithFormat: @"%0.16g" locale: locale,
895
[NSException raise: NSInvalidArgumentException
896
format: @"unknown number type value for description"];
899
return AUTORELEASE(result);
902
/* All the rest of these methods must be implemented by a subclass */
627
/* Stop the compiler complaining about unimplemented methods. Throwing an
628
* exception here matches OS X behaviour, although they throw an invalid
629
* argument exception.
631
#define INTEGER_MACRO(type, name, ignored) \
632
- (type) name ## Value\
634
[self subclassResponsibility: _cmd];\
638
#include "GSNumberTypes.h"
903
640
- (BOOL) boolValue
905
if (GSObjCClass(self) == abstractClass)
906
[NSException raise: NSInternalInconsistencyException
907
format: @"get boolValue from abstract NSNumber"];
910
GSNumberInfo *info = GSNumberInfoFromObject(self);
912
switch (info->typeLevel)
918
(*(info->getValue))(self, @selector(getValue:), &oData);
919
return (oData == 0) ? NO : YES;
925
(*(info->getValue))(self, @selector(getValue:), &oData);
926
return (oData == 0) ? NO : YES;
932
(*(info->getValue))(self, @selector(getValue:), &oData);
933
return (oData == 0) ? NO : YES;
939
(*(info->getValue))(self, @selector(getValue:), &oData);
940
return (oData == 0) ? NO : YES;
944
unsigned short oData;
946
(*(info->getValue))(self, @selector(getValue:), &oData);
947
return (oData == 0) ? NO : YES;
953
(*(info->getValue))(self, @selector(getValue:), &oData);
954
return (oData == 0) ? NO : YES;
960
(*(info->getValue))(self, @selector(getValue:), &oData);
961
return (oData == 0) ? NO : YES;
967
(*(info->getValue))(self, @selector(getValue:), &oData);
968
return (oData == 0) ? NO : YES;
974
(*(info->getValue))(self, @selector(getValue:), &oData);
975
return (oData == 0) ? NO : YES;
979
signed long long oData;
981
(*(info->getValue))(self, @selector(getValue:), &oData);
982
return (oData == 0) ? NO : YES;
986
unsigned long long oData;
988
(*(info->getValue))(self, @selector(getValue:), &oData);
989
return (oData == 0) ? NO : YES;
995
(*(info->getValue))(self, @selector(getValue:), &oData);
996
return (oData == 0) ? NO : YES;
1002
(*(info->getValue))(self, @selector(getValue:), &oData);
1003
return (oData == 0) ? NO : YES;
1006
[NSException raise: NSInvalidArgumentException
1007
format: @"unknown number type value for get"];
1013
- (signed char) charValue
1015
if (GSObjCClass(self) == abstractClass)
1016
[NSException raise: NSInternalInconsistencyException
1017
format: @"get charValue from abstract NSNumber"];
1020
GSNumberInfo *info = GSNumberInfoFromObject(self);
1022
switch (info->typeLevel)
1028
(*(info->getValue))(self, @selector(getValue:), &oData);
1035
(*(info->getValue))(self, @selector(getValue:), &oData);
1040
unsigned char oData;
1042
(*(info->getValue))(self, @selector(getValue:), &oData);
1049
(*(info->getValue))(self, @selector(getValue:), &oData);
1054
unsigned short oData;
1056
(*(info->getValue))(self, @selector(getValue:), &oData);
1063
(*(info->getValue))(self, @selector(getValue:), &oData);
1070
(*(info->getValue))(self, @selector(getValue:), &oData);
1077
(*(info->getValue))(self, @selector(getValue:), &oData);
1082
unsigned long oData;
1084
(*(info->getValue))(self, @selector(getValue:), &oData);
1089
signed long long oData;
1091
(*(info->getValue))(self, @selector(getValue:), &oData);
1096
unsigned long long oData;
1098
(*(info->getValue))(self, @selector(getValue:), &oData);
1105
(*(info->getValue))(self, @selector(getValue:), &oData);
1112
(*(info->getValue))(self, @selector(getValue:), &oData);
1116
[NSException raise: NSInvalidArgumentException
1117
format: @"unknown number type value for get"];
1123
- (double) doubleValue
1125
if (GSObjCClass(self) == abstractClass)
1126
[NSException raise: NSInternalInconsistencyException
1127
format: @"get doubleValue from abstract NSNumber"];
1130
GSNumberInfo *info = GSNumberInfoFromObject(self);
1132
switch (info->typeLevel)
1138
(*(info->getValue))(self, @selector(getValue:), &oData);
1145
(*(info->getValue))(self, @selector(getValue:), &oData);
1150
unsigned char oData;
1152
(*(info->getValue))(self, @selector(getValue:), &oData);
1159
(*(info->getValue))(self, @selector(getValue:), &oData);
1164
unsigned short oData;
1166
(*(info->getValue))(self, @selector(getValue:), &oData);
1173
(*(info->getValue))(self, @selector(getValue:), &oData);
1180
(*(info->getValue))(self, @selector(getValue:), &oData);
1187
(*(info->getValue))(self, @selector(getValue:), &oData);
1192
unsigned long oData;
1194
(*(info->getValue))(self, @selector(getValue:), &oData);
1199
signed long long oData;
1201
(*(info->getValue))(self, @selector(getValue:), &oData);
1206
unsigned long long oData;
1208
(*(info->getValue))(self, @selector(getValue:), &oData);
1215
(*(info->getValue))(self, @selector(getValue:), &oData);
1222
(*(info->getValue))(self, @selector(getValue:), &oData);
1226
[NSException raise: NSInvalidArgumentException
1227
format: @"unknown number type value for get"];
1233
- (float) floatValue
1235
if (GSObjCClass(self) == abstractClass)
1236
[NSException raise: NSInternalInconsistencyException
1237
format: @"get floatValue from abstract NSNumber"];
1240
GSNumberInfo *info = GSNumberInfoFromObject(self);
1242
switch (info->typeLevel)
1248
(*(info->getValue))(self, @selector(getValue:), &oData);
1255
(*(info->getValue))(self, @selector(getValue:), &oData);
1260
unsigned char oData;
1262
(*(info->getValue))(self, @selector(getValue:), &oData);
1269
(*(info->getValue))(self, @selector(getValue:), &oData);
1274
unsigned short oData;
1276
(*(info->getValue))(self, @selector(getValue:), &oData);
1283
(*(info->getValue))(self, @selector(getValue:), &oData);
1290
(*(info->getValue))(self, @selector(getValue:), &oData);
1297
(*(info->getValue))(self, @selector(getValue:), &oData);
1302
unsigned long oData;
1304
(*(info->getValue))(self, @selector(getValue:), &oData);
1309
signed long long oData;
1311
(*(info->getValue))(self, @selector(getValue:), &oData);
1316
unsigned long long oData;
1318
(*(info->getValue))(self, @selector(getValue:), &oData);
1325
(*(info->getValue))(self, @selector(getValue:), &oData);
1332
(*(info->getValue))(self, @selector(getValue:), &oData);
1336
[NSException raise: NSInvalidArgumentException
1337
format: @"unknown number type value for get"];
1343
- (signed int) intValue
1345
if (GSObjCClass(self) == abstractClass)
1346
[NSException raise: NSInternalInconsistencyException
1347
format: @"get intValue from abstract NSNumber"];
1350
GSNumberInfo *info = GSNumberInfoFromObject(self);
1352
switch (info->typeLevel)
1358
(*(info->getValue))(self, @selector(getValue:), &oData);
1365
(*(info->getValue))(self, @selector(getValue:), &oData);
1370
unsigned char oData;
1372
(*(info->getValue))(self, @selector(getValue:), &oData);
1379
(*(info->getValue))(self, @selector(getValue:), &oData);
1384
unsigned short oData;
1386
(*(info->getValue))(self, @selector(getValue:), &oData);
1393
(*(info->getValue))(self, @selector(getValue:), &oData);
1400
(*(info->getValue))(self, @selector(getValue:), &oData);
1407
(*(info->getValue))(self, @selector(getValue:), &oData);
1412
unsigned long oData;
1414
(*(info->getValue))(self, @selector(getValue:), &oData);
1419
signed long long oData;
1421
(*(info->getValue))(self, @selector(getValue:), &oData);
1426
unsigned long long oData;
1428
(*(info->getValue))(self, @selector(getValue:), &oData);
1435
(*(info->getValue))(self, @selector(getValue:), &oData);
1442
(*(info->getValue))(self, @selector(getValue:), &oData);
1446
[NSException raise: NSInvalidArgumentException
1447
format: @"unknown number type value for get"];
1453
- (signed long long) longLongValue
1455
if (GSObjCClass(self) == abstractClass)
1456
[NSException raise: NSInternalInconsistencyException
1457
format: @"get longLongValue from abstract NSNumber"];
1460
GSNumberInfo *info = GSNumberInfoFromObject(self);
1462
switch (info->typeLevel)
1468
(*(info->getValue))(self, @selector(getValue:), &oData);
1475
(*(info->getValue))(self, @selector(getValue:), &oData);
1480
unsigned char oData;
1482
(*(info->getValue))(self, @selector(getValue:), &oData);
1489
(*(info->getValue))(self, @selector(getValue:), &oData);
1494
unsigned short oData;
1496
(*(info->getValue))(self, @selector(getValue:), &oData);
1503
(*(info->getValue))(self, @selector(getValue:), &oData);
1510
(*(info->getValue))(self, @selector(getValue:), &oData);
1517
(*(info->getValue))(self, @selector(getValue:), &oData);
1522
unsigned long oData;
1524
(*(info->getValue))(self, @selector(getValue:), &oData);
1529
signed long long oData;
1531
(*(info->getValue))(self, @selector(getValue:), &oData);
1536
unsigned long long oData;
1538
(*(info->getValue))(self, @selector(getValue:), &oData);
1545
(*(info->getValue))(self, @selector(getValue:), &oData);
1552
(*(info->getValue))(self, @selector(getValue:), &oData);
1556
[NSException raise: NSInvalidArgumentException
1557
format: @"unknown number type value for get"];
1563
- (signed long) longValue
1565
if (GSObjCClass(self) == abstractClass)
1566
[NSException raise: NSInternalInconsistencyException
1567
format: @"get longValue from abstract NSNumber"];
1570
GSNumberInfo *info = GSNumberInfoFromObject(self);
1572
switch (info->typeLevel)
1578
(*(info->getValue))(self, @selector(getValue:), &oData);
1585
(*(info->getValue))(self, @selector(getValue:), &oData);
1590
unsigned char oData;
1592
(*(info->getValue))(self, @selector(getValue:), &oData);
1599
(*(info->getValue))(self, @selector(getValue:), &oData);
1604
unsigned short oData;
1606
(*(info->getValue))(self, @selector(getValue:), &oData);
1613
(*(info->getValue))(self, @selector(getValue:), &oData);
1620
(*(info->getValue))(self, @selector(getValue:), &oData);
1627
(*(info->getValue))(self, @selector(getValue:), &oData);
1632
unsigned long oData;
1634
(*(info->getValue))(self, @selector(getValue:), &oData);
1639
signed long long oData;
1641
(*(info->getValue))(self, @selector(getValue:), &oData);
1646
unsigned long long oData;
1648
(*(info->getValue))(self, @selector(getValue:), &oData);
1655
(*(info->getValue))(self, @selector(getValue:), &oData);
1662
(*(info->getValue))(self, @selector(getValue:), &oData);
1666
[NSException raise: NSInvalidArgumentException
1667
format: @"unknown number type value for get"];
1673
- (signed short) shortValue
1675
if (GSObjCClass(self) == abstractClass)
1676
[NSException raise: NSInternalInconsistencyException
1677
format: @"get shortValue from abstract NSNumber"];
1680
GSNumberInfo *info = GSNumberInfoFromObject(self);
1682
switch (info->typeLevel)
1688
(*(info->getValue))(self, @selector(getValue:), &oData);
1695
(*(info->getValue))(self, @selector(getValue:), &oData);
1700
unsigned char oData;
1702
(*(info->getValue))(self, @selector(getValue:), &oData);
1709
(*(info->getValue))(self, @selector(getValue:), &oData);
1714
unsigned short oData;
1716
(*(info->getValue))(self, @selector(getValue:), &oData);
1723
(*(info->getValue))(self, @selector(getValue:), &oData);
1730
(*(info->getValue))(self, @selector(getValue:), &oData);
1737
(*(info->getValue))(self, @selector(getValue:), &oData);
1742
unsigned long oData;
1744
(*(info->getValue))(self, @selector(getValue:), &oData);
1749
signed long long oData;
1751
(*(info->getValue))(self, @selector(getValue:), &oData);
1756
unsigned long long oData;
1758
(*(info->getValue))(self, @selector(getValue:), &oData);
1765
(*(info->getValue))(self, @selector(getValue:), &oData);
1772
(*(info->getValue))(self, @selector(getValue:), &oData);
1776
[NSException raise: NSInvalidArgumentException
1777
format: @"unknown number type value for get"];
1783
- (NSString*) stringValue
1785
return [self descriptionWithLocale: nil];
1788
- (unsigned char) unsignedCharValue
1790
if (GSObjCClass(self) == abstractClass)
1791
[NSException raise: NSInternalInconsistencyException
1792
format: @"get unsignedCharrValue from abstract NSNumber"];
1795
GSNumberInfo *info = GSNumberInfoFromObject(self);
1797
switch (info->typeLevel)
1803
(*(info->getValue))(self, @selector(getValue:), &oData);
1810
(*(info->getValue))(self, @selector(getValue:), &oData);
1815
unsigned char oData;
1817
(*(info->getValue))(self, @selector(getValue:), &oData);
1824
(*(info->getValue))(self, @selector(getValue:), &oData);
1829
unsigned short oData;
1831
(*(info->getValue))(self, @selector(getValue:), &oData);
1838
(*(info->getValue))(self, @selector(getValue:), &oData);
1845
(*(info->getValue))(self, @selector(getValue:), &oData);
1852
(*(info->getValue))(self, @selector(getValue:), &oData);
1857
unsigned long oData;
1859
(*(info->getValue))(self, @selector(getValue:), &oData);
1864
signed long long oData;
1866
(*(info->getValue))(self, @selector(getValue:), &oData);
1871
unsigned long long oData;
1873
(*(info->getValue))(self, @selector(getValue:), &oData);
1880
(*(info->getValue))(self, @selector(getValue:), &oData);
1887
(*(info->getValue))(self, @selector(getValue:), &oData);
1891
[NSException raise: NSInvalidArgumentException
1892
format: @"unknown number type value for get"];
1898
- (unsigned int) unsignedIntValue
1900
if (GSObjCClass(self) == abstractClass)
1901
[NSException raise: NSInternalInconsistencyException
1902
format: @"get unsignedIntValue from abstract NSNumber"];
1905
GSNumberInfo *info = GSNumberInfoFromObject(self);
1907
switch (info->typeLevel)
1913
(*(info->getValue))(self, @selector(getValue:), &oData);
1920
(*(info->getValue))(self, @selector(getValue:), &oData);
1925
unsigned char oData;
1927
(*(info->getValue))(self, @selector(getValue:), &oData);
1934
(*(info->getValue))(self, @selector(getValue:), &oData);
1939
unsigned short oData;
1941
(*(info->getValue))(self, @selector(getValue:), &oData);
1948
(*(info->getValue))(self, @selector(getValue:), &oData);
1955
(*(info->getValue))(self, @selector(getValue:), &oData);
1962
(*(info->getValue))(self, @selector(getValue:), &oData);
1967
unsigned long oData;
1969
(*(info->getValue))(self, @selector(getValue:), &oData);
1974
signed long long oData;
1976
(*(info->getValue))(self, @selector(getValue:), &oData);
1981
unsigned long long oData;
1983
(*(info->getValue))(self, @selector(getValue:), &oData);
1990
(*(info->getValue))(self, @selector(getValue:), &oData);
1997
(*(info->getValue))(self, @selector(getValue:), &oData);
2001
[NSException raise: NSInvalidArgumentException
2002
format: @"unknown number type value for get"];
2008
- (unsigned long long) unsignedLongLongValue
2010
if (GSObjCClass(self) == abstractClass)
2011
[NSException raise: NSInternalInconsistencyException
2012
format: @"get unsignedLongLongValue from abstract NSNumber"];
2015
GSNumberInfo *info = GSNumberInfoFromObject(self);
2017
switch (info->typeLevel)
2023
(*(info->getValue))(self, @selector(getValue:), &oData);
2030
(*(info->getValue))(self, @selector(getValue:), &oData);
2035
unsigned char oData;
2037
(*(info->getValue))(self, @selector(getValue:), &oData);
2044
(*(info->getValue))(self, @selector(getValue:), &oData);
2049
unsigned short oData;
2051
(*(info->getValue))(self, @selector(getValue:), &oData);
2058
(*(info->getValue))(self, @selector(getValue:), &oData);
2065
(*(info->getValue))(self, @selector(getValue:), &oData);
2072
(*(info->getValue))(self, @selector(getValue:), &oData);
2077
unsigned long oData;
2079
(*(info->getValue))(self, @selector(getValue:), &oData);
2084
signed long long oData;
2086
(*(info->getValue))(self, @selector(getValue:), &oData);
2091
unsigned long long oData;
2093
(*(info->getValue))(self, @selector(getValue:), &oData);
2100
(*(info->getValue))(self, @selector(getValue:), &oData);
2107
(*(info->getValue))(self, @selector(getValue:), &oData);
2111
[NSException raise: NSInvalidArgumentException
2112
format: @"unknown number type value for get"];
2118
- (unsigned long) unsignedLongValue
2120
if (GSObjCClass(self) == abstractClass)
2121
[NSException raise: NSInternalInconsistencyException
2122
format: @"get unsignedLongValue from abstract NSNumber"];
2125
GSNumberInfo *info = GSNumberInfoFromObject(self);
2127
switch (info->typeLevel)
2133
(*(info->getValue))(self, @selector(getValue:), &oData);
2140
(*(info->getValue))(self, @selector(getValue:), &oData);
2145
unsigned char oData;
2147
(*(info->getValue))(self, @selector(getValue:), &oData);
2154
(*(info->getValue))(self, @selector(getValue:), &oData);
2159
unsigned short oData;
2161
(*(info->getValue))(self, @selector(getValue:), &oData);
2168
(*(info->getValue))(self, @selector(getValue:), &oData);
2175
(*(info->getValue))(self, @selector(getValue:), &oData);
2182
(*(info->getValue))(self, @selector(getValue:), &oData);
2187
unsigned long oData;
2189
(*(info->getValue))(self, @selector(getValue:), &oData);
2194
signed long long oData;
2196
(*(info->getValue))(self, @selector(getValue:), &oData);
2201
unsigned long long oData;
2203
(*(info->getValue))(self, @selector(getValue:), &oData);
2210
(*(info->getValue))(self, @selector(getValue:), &oData);
2217
(*(info->getValue))(self, @selector(getValue:), &oData);
2221
[NSException raise: NSInvalidArgumentException
2222
format: @"unknown number type value for get"];
2228
- (unsigned short) unsignedShortValue
2230
if (GSObjCClass(self) == abstractClass)
2231
[NSException raise: NSInternalInconsistencyException
2232
format: @"get unsignedShortValue from abstract NSNumber"];
2235
GSNumberInfo *info = GSNumberInfoFromObject(self);
2237
switch (info->typeLevel)
2243
(*(info->getValue))(self, @selector(getValue:), &oData);
2250
(*(info->getValue))(self, @selector(getValue:), &oData);
2255
unsigned char oData;
2257
(*(info->getValue))(self, @selector(getValue:), &oData);
2264
(*(info->getValue))(self, @selector(getValue:), &oData);
2269
unsigned short oData;
2271
(*(info->getValue))(self, @selector(getValue:), &oData);
2278
(*(info->getValue))(self, @selector(getValue:), &oData);
2285
(*(info->getValue))(self, @selector(getValue:), &oData);
2292
(*(info->getValue))(self, @selector(getValue:), &oData);
2297
unsigned long oData;
2299
(*(info->getValue))(self, @selector(getValue:), &oData);
2304
signed long long oData;
2306
(*(info->getValue))(self, @selector(getValue:), &oData);
2311
unsigned long long oData;
2313
(*(info->getValue))(self, @selector(getValue:), &oData);
2320
(*(info->getValue))(self, @selector(getValue:), &oData);
2327
(*(info->getValue))(self, @selector(getValue:), &oData);
2331
[NSException raise: NSInvalidArgumentException
2332
format: @"unknown number type value for get"];
2338
- (NSComparisonResult) compare: (NSNumber*)other
2345
return NSOrderedSame;
2347
else if (other == nil)
2349
[NSException raise: NSInvalidArgumentException
2350
format: @"nil argument for compare:"];
2353
myValue = [self doubleValue];
2354
otherValue = [other doubleValue];
2356
if (myValue == otherValue)
2358
return NSOrderedSame;
2360
else if (myValue < otherValue)
2362
return NSOrderedAscending;
2366
return NSOrderedDescending;
2371
* Because of the rule that two numbers which are the same according to
2372
* [-isEqual: ] must generate the same hash, we must generate the hash
2373
* from the most general representation of the number.
2374
* NB. Don't change this without changing the matching function in
2375
* NSConcreteNumber.m
2381
unsigned char c[sizeof(double)];
2386
val.d = [self doubleValue];
2387
for (i = 0; i < sizeof(double); i++)
2389
hash = (hash << 5) + hash + val.c[i];
2394
- (BOOL) isEqual: (id)o
2404
else if (GSObjCIsInstance(o) == YES
2405
&& GSObjCIsKindOf(GSObjCClass(o), abstractClass))
2407
return [self isEqualToNumber: (NSNumber*)o];
2411
return [super isEqual: o];
2415
- (BOOL) isEqualToNumber: (NSNumber*)o
2425
else if ([self compare: o] == NSOrderedSame)
2432
- (BOOL) isEqualToValue: (NSValue*)o
2442
else if (GSObjCIsInstance(o) == YES
2443
&& GSObjCIsKindOf(GSObjCClass(o), abstractClass))
2445
return [self isEqualToNumber: (NSNumber*)o];
2454
- (Class) classForCoder
2456
return abstractClass;
2459
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
2461
if ([aCoder isByref] == NO)
2463
return [super replacementObjectForPortCoder: aCoder];
2466
- (void) encodeWithCoder: (NSCoder*)coder
2468
const char *t = [self objCType];
2470
[coder encodeValueOfObjCType: @encode(signed char) at: t];
2471
[coder encodeValueOfObjCType: t at: [self pointerValue]];
2474
- (id) initWithCoder: (NSCoder*)coder
2487
unsigned long long Q;
2492
[coder decodeValueOfObjCType: @encode(signed char) at: t];
2494
[coder decodeValueOfObjCType: t at: &data];
2497
case 'c': self = [self initWithChar: data.c]; break;
2498
case 'C': self = [self initWithUnsignedChar: data.C]; break;
2499
case 's': self = [self initWithShort: data.s]; break;
2500
case 'S': self = [self initWithUnsignedShort: data.S]; break;
2501
case 'i': self = [self initWithInt: data.i]; break;
2502
case 'I': self = [self initWithUnsignedInt: data.I]; break;
2503
case 'l': self = [self initWithLong: data.l]; break;
2504
case 'L': self = [self initWithUnsignedLong: data.L]; break;
2505
case 'q': self = [self initWithLongLong: data.q]; break;
2506
case 'Q': self = [self initWithUnsignedLongLong: data.Q]; break;
2507
case 'f': self = [self initWithFloat: data.f]; break;
2508
case 'd': self = [self initWithDouble: data.d]; break;
2511
NSLog(@"Attempt to decode number with unknown ObjC type");
642
[self subclassResponsibility: _cmd];
646
- (NSDecimal) decimalValue
651
dn = [[NSDecimalNumber alloc] initWithString: [self stringValue]];
652
decimal = [dn decimalValue];