2010-02-14 16:32:02 +00:00
|
|
|
/** NSNumber - Object encapsulation of numbers
|
2005-02-22 11:22:44 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
Copyright (C) 1993, 1994, 1996, 2000 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
Written by: Adam Fedor <fedor@boulder.colorado.edu>
|
|
|
|
Created: Mar 1995
|
|
|
|
Rewrite: Richard Frith-Macdonald <rfm@gnu.org>
|
|
|
|
Date: Mar 2000
|
1995-04-03 20:49:14 +00:00
|
|
|
|
1996-05-12 00:56:10 +00:00
|
|
|
This file is part of the GNUstep Base Library.
|
1995-04-03 20:49:14 +00:00
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
2007-09-14 11:36:11 +00:00
|
|
|
modify it under the terms of the GNU Lesser General Public
|
1995-04-03 20:49:14 +00:00
|
|
|
License as published by the Free Software Foundation; either
|
2008-06-08 10:38:33 +00:00
|
|
|
version 2 of the License, or (at your option) any later version.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
1995-04-03 20:49:14 +00:00
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
2007-09-14 11:36:11 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
1995-04-03 20:49:14 +00:00
|
|
|
License along with this library; if not, write to the Free
|
2006-06-04 06:42:10 +00:00
|
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02111 USA.
|
2001-12-18 16:54:15 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
<title>NSNumber class reference</title>
|
|
|
|
$Date$ $Revision$
|
|
|
|
*/
|
2000-03-18 07:56:43 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
#include <string.h>
|
|
|
|
#import "config.h"
|
|
|
|
#import "GNUstepBase/preface.h"
|
|
|
|
#import "Foundation/NSException.h"
|
|
|
|
#import "Foundation/NSString.h"
|
|
|
|
#import "Foundation/NSNotification.h"
|
|
|
|
#import "Foundation/NSMapTable.h"
|
|
|
|
#import "Foundation/NSThread.h"
|
|
|
|
#import "Foundation/NSCoder.h"
|
|
|
|
#import "Foundation/NSPortCoder.h"
|
|
|
|
#import "Foundation/NSObjCRuntime.h"
|
Rewritten NSNumber implementation. This fixes several OS X-compatibility issues:
The -pointerValue method now returns the value cast to a pointer, not some random value, as the documentation says it should. This is a change from OpenStep, which said:
> It's an error to send this message to an NSValue that doesn't store a pointer.
The OS X docs now say:
> The receiver's value as a pointer to void. If the receiver was not created to hold a pointer-sized data item, the result is undefined.
This means that any NSNumber created with a word-sized integer should return the same value.
Fixed a number of corner-cases in the compare: implementation caused by incorrect type promotion. The OS X docs say:
> The compare: method follows the standard C rules for type conversion.
The OS X implementation does not do this. We now match Apple's conversion rules bug-for-bug: Every value is stored in the smallest signed type that will hold it, unless there is no unsigned type that can hold it, in which case it is stored in an `unsigned long long`, comparisons between integer and floating point values cast both to a double, comparisons between integer types perform a real comparison (so an unsigned long long is always greater than any negative number, at any precision). The Apple implementation is actually quite sane, it is just completely unrelated to the documentation in any way.
We now use the same range of reusable objects. Note that there is an error in Cocoa Design Patterns in the description of how Apple's implementation works. Do not use this as a reference.
We now return `nil` when an NSNumber is sent an -init message. This is consistent with Apple's implementation but breaks some things in the GNUstep test suite (which RFM said he will fix).
There is a small change in NSValue.h so that the locale parameter is now an `id` not an `NSString*`. This is because, under recent OS X, it may also be an `NSLocale` instance. I am not sure how much GNUstep supports `NSLocale`, but this change shouldn't affect anything.
The new (private) GSNumberTypes.h file lets you define macros that are instantiated with each of the names of primitive C types. These might be useful for simplifying other classes that have -intValue, -floatValue, and so on methods, such as the `NSCell` family.
The old NSConcreteNumberTemplate and NSConcreteNumber stuff has been removed. The code is now a bit more than 10% of the size of the old NSNumber code, and is hopefully maintainable now, so the next change won't require a complete rewrite.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29618 72102866-910b-0410-8b05-ffd578937521
2010-02-14 12:57:44 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
#import "NSConcreteNumber.h"
|
|
|
|
#import "GSPrivate.h"
|
|
|
|
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
Rewritten NSNumber implementation. This fixes several OS X-compatibility issues:
The -pointerValue method now returns the value cast to a pointer, not some random value, as the documentation says it should. This is a change from OpenStep, which said:
> It's an error to send this message to an NSValue that doesn't store a pointer.
The OS X docs now say:
> The receiver's value as a pointer to void. If the receiver was not created to hold a pointer-sized data item, the result is undefined.
This means that any NSNumber created with a word-sized integer should return the same value.
Fixed a number of corner-cases in the compare: implementation caused by incorrect type promotion. The OS X docs say:
> The compare: method follows the standard C rules for type conversion.
The OS X implementation does not do this. We now match Apple's conversion rules bug-for-bug: Every value is stored in the smallest signed type that will hold it, unless there is no unsigned type that can hold it, in which case it is stored in an `unsigned long long`, comparisons between integer and floating point values cast both to a double, comparisons between integer types perform a real comparison (so an unsigned long long is always greater than any negative number, at any precision). The Apple implementation is actually quite sane, it is just completely unrelated to the documentation in any way.
We now use the same range of reusable objects. Note that there is an error in Cocoa Design Patterns in the description of how Apple's implementation works. Do not use this as a reference.
We now return `nil` when an NSNumber is sent an -init message. This is consistent with Apple's implementation but breaks some things in the GNUstep test suite (which RFM said he will fix).
There is a small change in NSValue.h so that the locale parameter is now an `id` not an `NSString*`. This is because, under recent OS X, it may also be an `NSLocale` instance. I am not sure how much GNUstep supports `NSLocale`, but this change shouldn't affect anything.
The new (private) GSNumberTypes.h file lets you define macros that are instantiated with each of the names of primitive C types. These might be useful for simplifying other classes that have -intValue, -floatValue, and so on methods, such as the `NSCell` family.
The old NSConcreteNumberTemplate and NSConcreteNumber stuff has been removed. The code is now a bit more than 10% of the size of the old NSNumber code, and is hopefully maintainable now, so the next change won't require a complete rewrite.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29618 72102866-910b-0410-8b05-ffd578937521
2010-02-14 12:57:44 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
@interface GSCachedBool : NSBoolNumber
|
|
|
|
@end
|
|
|
|
@interface GSCachedInt : NSIntNumber
|
|
|
|
@end
|
|
|
|
@implementation GSCachedBool
|
|
|
|
- (id) copyWithZone: (NSZone*)zone
|
2003-11-30 09:05:31 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
return RETAIN(self);
|
2003-11-30 09:05:31 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
- (void) dealloc
|
2003-11-30 09:05:31 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
[NSException raise: NSGenericException
|
|
|
|
format: @"Attempt to deallocate bool number owned by cache"];
|
|
|
|
GSNOSUPERDEALLOC;
|
2003-11-30 09:05:31 +00:00
|
|
|
}
|
Rewritten NSNumber implementation. This fixes several OS X-compatibility issues:
The -pointerValue method now returns the value cast to a pointer, not some random value, as the documentation says it should. This is a change from OpenStep, which said:
> It's an error to send this message to an NSValue that doesn't store a pointer.
The OS X docs now say:
> The receiver's value as a pointer to void. If the receiver was not created to hold a pointer-sized data item, the result is undefined.
This means that any NSNumber created with a word-sized integer should return the same value.
Fixed a number of corner-cases in the compare: implementation caused by incorrect type promotion. The OS X docs say:
> The compare: method follows the standard C rules for type conversion.
The OS X implementation does not do this. We now match Apple's conversion rules bug-for-bug: Every value is stored in the smallest signed type that will hold it, unless there is no unsigned type that can hold it, in which case it is stored in an `unsigned long long`, comparisons between integer and floating point values cast both to a double, comparisons between integer types perform a real comparison (so an unsigned long long is always greater than any negative number, at any precision). The Apple implementation is actually quite sane, it is just completely unrelated to the documentation in any way.
We now use the same range of reusable objects. Note that there is an error in Cocoa Design Patterns in the description of how Apple's implementation works. Do not use this as a reference.
We now return `nil` when an NSNumber is sent an -init message. This is consistent with Apple's implementation but breaks some things in the GNUstep test suite (which RFM said he will fix).
There is a small change in NSValue.h so that the locale parameter is now an `id` not an `NSString*`. This is because, under recent OS X, it may also be an `NSLocale` instance. I am not sure how much GNUstep supports `NSLocale`, but this change shouldn't affect anything.
The new (private) GSNumberTypes.h file lets you define macros that are instantiated with each of the names of primitive C types. These might be useful for simplifying other classes that have -intValue, -floatValue, and so on methods, such as the `NSCell` family.
The old NSConcreteNumberTemplate and NSConcreteNumber stuff has been removed. The code is now a bit more than 10% of the size of the old NSNumber code, and is hopefully maintainable now, so the next change won't require a complete rewrite.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29618 72102866-910b-0410-8b05-ffd578937521
2010-02-14 12:57:44 +00:00
|
|
|
@end
|
2010-02-14 16:32:02 +00:00
|
|
|
@implementation GSCachedInt
|
|
|
|
- (id) copyWithZone: (NSZone*)zone
|
|
|
|
{
|
|
|
|
return RETAIN(self);
|
|
|
|
}
|
|
|
|
- (void) dealloc
|
2003-11-30 09:05:31 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
[NSException raise: NSGenericException
|
|
|
|
format: @"Attempt to deallocate int number owned by cache"];
|
|
|
|
GSNOSUPERDEALLOC;
|
2003-11-30 09:05:31 +00:00
|
|
|
}
|
|
|
|
@end
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
@implementation NSNumber
|
|
|
|
|
|
|
|
static NSMapTable *numberMap;
|
|
|
|
static BOOL multiThreaded = NO;
|
|
|
|
static NSNumber *boolN;
|
|
|
|
static NSNumber *boolY;
|
|
|
|
static NSNumber *smallIntegers[GS_SMALL * 2 + 1];
|
|
|
|
static unsigned int smallHashes[GS_SMALL * 2 + 1];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cache info for each number class.
|
|
|
|
* In a multi-threaded system we may waste some memory in order to get speed.
|
|
|
|
*/
|
|
|
|
GSNumberInfo*
|
|
|
|
GSNumberInfoFromObject(NSNumber *o)
|
|
|
|
{
|
|
|
|
Class c;
|
|
|
|
GSNumberInfo *info;
|
|
|
|
|
|
|
|
if (o == nil)
|
|
|
|
return 0;
|
|
|
|
c = GSObjCClass(o);
|
|
|
|
info = (GSNumberInfo*)NSMapGet (numberMap, (void*)c);
|
|
|
|
if (info == 0)
|
|
|
|
{
|
|
|
|
const char *t = [o objCType];
|
|
|
|
int order = -1;
|
|
|
|
|
|
|
|
if (strlen(t) != 1)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSLog(@"Invalid return value (%s) from [%@ objCType]", t, c);
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (*t)
|
|
|
|
{
|
|
|
|
case 'c': order = 1; break;
|
|
|
|
case 'C': order = 2; break;
|
|
|
|
case 's': order = 3; break;
|
|
|
|
case 'S': order = 4; break;
|
|
|
|
case 'i': order = 5; break;
|
|
|
|
case 'I': order = 6; break;
|
|
|
|
case 'l': order = 7; break;
|
|
|
|
case 'L': order = 8; break;
|
|
|
|
case 'q': order = 9; break;
|
|
|
|
case 'Q': order = 10; break;
|
|
|
|
case 'f': order = 11; break;
|
|
|
|
case 'd': order = 12; break;
|
|
|
|
default:
|
|
|
|
NSLog(@"Invalid return value (%s) from [%@ objCType]", t, c);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
info = (GSNumberInfo*)NSZoneMalloc(NSDefaultMallocZone(),
|
|
|
|
(sizeof(GSNumberInfo)));
|
|
|
|
info->typeLevel = order;
|
|
|
|
|
|
|
|
info->getValue = (void (*)(NSNumber*, SEL, void*))
|
|
|
|
[o methodForSelector: @selector(getValue:)];
|
2000-03-19 20:57:09 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
if (multiThreaded == YES)
|
|
|
|
{
|
|
|
|
NSMapTable *table;
|
2000-03-19 20:57:09 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
/*
|
|
|
|
* Memory leak for efficiency - the old map table is never
|
|
|
|
* deallocated, so we don't have to do any locking.
|
|
|
|
*/
|
|
|
|
table = NSCopyMapTableWithZone(numberMap, NSDefaultMallocZone());
|
|
|
|
NSMapInsert(table, (void*)c, (void*)info);
|
|
|
|
numberMap = table;
|
|
|
|
}
|
|
|
|
else
|
2000-03-19 20:57:09 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSMapInsert(numberMap, (void*)c, (void*)info);
|
2000-03-19 20:57:09 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return info;
|
2000-03-19 20:57:09 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
unsigned int
|
|
|
|
GSPrivateSmallHash(int n)
|
|
|
|
{
|
|
|
|
return smallHashes[n + GS_SMALL];
|
|
|
|
}
|
|
|
|
|
|
|
|
static Class abstractClass;
|
|
|
|
static Class boolNumberClass;
|
|
|
|
static Class charNumberClass;
|
|
|
|
static Class uCharNumberClass;
|
|
|
|
static Class shortNumberClass;
|
|
|
|
static Class uShortNumberClass;
|
|
|
|
static Class intNumberClass;
|
|
|
|
static Class uIntNumberClass;
|
|
|
|
static Class integerNumberClass;
|
|
|
|
static Class uIntegerNumberClass;
|
|
|
|
static Class longNumberClass;
|
|
|
|
static Class uLongNumberClass;
|
|
|
|
static Class longLongNumberClass;
|
|
|
|
static Class uLongLongNumberClass;
|
|
|
|
static Class floatNumberClass;
|
|
|
|
static Class doubleNumberClass;
|
|
|
|
|
|
|
|
+ (void) _becomeThreaded: (NSNotification*)notification
|
1999-06-14 09:07:52 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
multiThreaded = YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (void) initialize
|
|
|
|
{
|
|
|
|
if (self == [NSNumber class])
|
|
|
|
{
|
|
|
|
BOOL boolean;
|
|
|
|
int integer;
|
|
|
|
unsigned (*hasher)(NSNumber*, SEL);
|
|
|
|
GSNumberInfo *info;
|
|
|
|
CREATE_AUTORELEASE_POOL(pool);
|
|
|
|
|
|
|
|
abstractClass = self;
|
|
|
|
hasher = (unsigned (*)(NSNumber*, SEL))
|
|
|
|
[self instanceMethodForSelector: @selector(hash)];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create cache for per-subclass method implementations etc.
|
|
|
|
*/
|
|
|
|
numberMap = NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
|
|
|
|
NSOwnedPointerMapValueCallBacks, 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* cache standard subclass info.
|
|
|
|
*/
|
|
|
|
boolNumberClass = [NSBoolNumber class];
|
|
|
|
info = GSNumberInfoFromObject(AUTORELEASE([boolNumberClass alloc]));
|
|
|
|
/*
|
|
|
|
* Set the typeLevel for a boolean to be '0'
|
|
|
|
*/
|
|
|
|
info->typeLevel = 0;
|
|
|
|
charNumberClass = [NSCharNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([charNumberClass alloc]));
|
|
|
|
uCharNumberClass = [NSUCharNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([uCharNumberClass alloc]));
|
|
|
|
shortNumberClass = [NSShortNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([shortNumberClass alloc]));
|
|
|
|
uShortNumberClass = [NSUShortNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([uShortNumberClass alloc]));
|
|
|
|
intNumberClass = [NSIntNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([intNumberClass alloc]));
|
|
|
|
uIntNumberClass = [NSUIntNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([uIntNumberClass alloc]));
|
|
|
|
longNumberClass = [NSLongNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([longNumberClass alloc]));
|
|
|
|
uLongNumberClass = [NSULongNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([uLongNumberClass alloc]));
|
|
|
|
longLongNumberClass = [NSLongLongNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([longLongNumberClass alloc]));
|
|
|
|
uLongLongNumberClass = [NSULongLongNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([uLongLongNumberClass alloc]));
|
|
|
|
floatNumberClass = [NSFloatNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([floatNumberClass alloc]));
|
|
|
|
doubleNumberClass = [NSDoubleNumber class];
|
|
|
|
GSNumberInfoFromObject(AUTORELEASE([doubleNumberClass alloc]));
|
|
|
|
|
|
|
|
if (sizeof(NSInteger) == sizeof(int))
|
|
|
|
{
|
|
|
|
integerNumberClass = intNumberClass;
|
|
|
|
uIntegerNumberClass = uIntNumberClass;
|
|
|
|
}
|
|
|
|
else if (sizeof(NSInteger) == sizeof(long))
|
|
|
|
{
|
|
|
|
integerNumberClass = longNumberClass;
|
|
|
|
uIntegerNumberClass = uLongNumberClass;
|
|
|
|
}
|
|
|
|
else
|
2009-02-23 20:42:32 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
integerNumberClass = longLongNumberClass;
|
|
|
|
uIntegerNumberClass = uLongLongNumberClass;
|
2009-02-23 20:42:32 +00:00
|
|
|
}
|
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
/*
|
|
|
|
* cache bool values.
|
|
|
|
*/
|
|
|
|
boolN = (NSNumber*)NSAllocateObject([GSCachedBool class], 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
boolean = NO;
|
|
|
|
boolN = [boolN initWithBytes: &boolean objCType: NULL];
|
2000-03-19 20:57:09 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
boolY = (NSNumber*)NSAllocateObject([GSCachedBool class], 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
boolean = YES;
|
|
|
|
boolY = [boolY initWithBytes: &boolean objCType: NULL];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* cache small integer values.
|
|
|
|
*/
|
|
|
|
for (integer = -GS_SMALL; integer <= GS_SMALL; integer++)
|
|
|
|
{
|
|
|
|
NSNumber *num;
|
|
|
|
|
|
|
|
num = (NSNumber*)NSAllocateObject([GSCachedInt class], 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
num = [num initWithBytes: &integer objCType: NULL];
|
|
|
|
smallIntegers[integer + GS_SMALL] = num;
|
|
|
|
smallHashes[integer + GS_SMALL] = (*hasher)(num, @selector(hash));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure we know if we are multi-threaded so that if the caches
|
|
|
|
* need to grow, we do it by copying and replacing without deleting
|
|
|
|
* an old cache that may be in use by another thread.
|
|
|
|
*/
|
|
|
|
if ([NSThread isMultiThreaded])
|
|
|
|
{
|
|
|
|
[self _becomeThreaded: nil];
|
|
|
|
}
|
|
|
|
else
|
2000-03-19 20:57:09 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
[[NSNotificationCenter defaultCenter]
|
|
|
|
addObserver: self
|
|
|
|
selector: @selector(_becomeThreaded:)
|
|
|
|
name: NSWillBecomeMultiThreadedNotification
|
|
|
|
object: nil];
|
2000-03-19 20:57:09 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
RELEASE(pool);
|
|
|
|
}
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
/* Returns the concrete class associated with the type encoding. Note
|
|
|
|
that we don't allow NSNumber to instantiate any class but its own
|
|
|
|
concrete subclasses (see check at end of method) */
|
|
|
|
+ (Class) valueClassWithObjCType: (const char*)type
|
2009-02-23 20:42:32 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
Class theClass = Nil;
|
|
|
|
|
|
|
|
switch (*type)
|
|
|
|
{
|
|
|
|
case _C_CHR: return charNumberClass;
|
|
|
|
case _C_UCHR: return uCharNumberClass;
|
|
|
|
case _C_SHT: return shortNumberClass;
|
|
|
|
case _C_USHT: return uShortNumberClass;
|
|
|
|
case _C_INT: return intNumberClass;
|
|
|
|
case _C_UINT: return uIntNumberClass;
|
|
|
|
case _C_LNG: return longNumberClass;
|
|
|
|
case _C_ULNG: return uLongNumberClass;
|
|
|
|
#ifdef _C_LNGLNG
|
|
|
|
case _C_LNGLNG:
|
|
|
|
#else
|
|
|
|
case 'q':
|
|
|
|
#endif
|
|
|
|
return longLongNumberClass;
|
|
|
|
#ifdef _C_ULNGLNG
|
|
|
|
case _C_ULNGLNG:
|
|
|
|
#else
|
|
|
|
case 'Q':
|
|
|
|
#endif
|
|
|
|
return uLongLongNumberClass;
|
|
|
|
case _C_FLT: return floatNumberClass;
|
|
|
|
case _C_DBL: return doubleNumberClass;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (theClass == Nil && self == abstractClass)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Invalid number type"];
|
|
|
|
/* NOT REACHED */
|
|
|
|
}
|
|
|
|
else if (theClass == Nil)
|
|
|
|
{
|
|
|
|
theClass = [super valueClassWithObjCType: type];
|
|
|
|
}
|
|
|
|
return theClass;
|
2009-02-23 20:42:32 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithBool: (BOOL)value
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value == NO)
|
|
|
|
{
|
|
|
|
return boolN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return boolY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithBool: value]);
|
|
|
|
}
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
+ (NSNumber*) numberWithChar: (signed char)value
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(charNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithChar: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithDouble: (double)value
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(doubleNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithDouble: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
+ (NSNumber*) numberWithFloat: (float)value
|
|
|
|
{
|
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(floatNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithFloat: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithInt: (signed int)value
|
2010-01-24 17:54:31 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(intNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithInt: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
2010-01-24 17:54:31 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithInteger: (NSInteger)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(integerNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithInteger: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithLong: (signed long)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(longNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithLong: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithLongLong: (signed long long)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
1998-02-05 22:06:20 +00:00
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(longLongNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithLongLong: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithShort: (signed short)value
|
2009-02-23 20:42:32 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(shortNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithShort: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
2009-02-23 20:42:32 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithUnsignedChar: (unsigned char)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(uCharNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithUnsignedChar: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithUnsignedInt: (unsigned int)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(uIntNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithUnsignedInt: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithUnsignedInteger: (NSUInteger)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(uIntegerNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithUnsignedInteger: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSNumber*) numberWithUnsignedLong: (unsigned long)value
|
|
|
|
{
|
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(uLongNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithUnsignedLong: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSNumber*) numberWithUnsignedLongLong: (unsigned long long)value
|
|
|
|
{
|
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(uLongLongNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithUnsignedLongLong: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
+ (NSNumber*) numberWithUnsignedShort: (unsigned short)value
|
|
|
|
{
|
|
|
|
NSNumber *theObj = nil;
|
|
|
|
|
|
|
|
// if class is NSNumber, replace by appropriate object
|
|
|
|
if (self == abstractClass)
|
|
|
|
{
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return smallIntegers[value + GS_SMALL];
|
|
|
|
}
|
|
|
|
theObj = (NSNumber*)NSAllocateObject(uShortNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
theObj = [theObj initWithBytes: &value objCType: NULL];
|
|
|
|
}
|
|
|
|
else // alloc class and init with object intWithXX method
|
|
|
|
{
|
|
|
|
theObj = [[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
initWithUnsignedShort: value];
|
|
|
|
}
|
|
|
|
|
|
|
|
return AUTORELEASE(theObj);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
/*
|
|
|
|
* A moderately sane default init method - a zero value integer.
|
Rewritten NSNumber implementation. This fixes several OS X-compatibility issues:
The -pointerValue method now returns the value cast to a pointer, not some random value, as the documentation says it should. This is a change from OpenStep, which said:
> It's an error to send this message to an NSValue that doesn't store a pointer.
The OS X docs now say:
> The receiver's value as a pointer to void. If the receiver was not created to hold a pointer-sized data item, the result is undefined.
This means that any NSNumber created with a word-sized integer should return the same value.
Fixed a number of corner-cases in the compare: implementation caused by incorrect type promotion. The OS X docs say:
> The compare: method follows the standard C rules for type conversion.
The OS X implementation does not do this. We now match Apple's conversion rules bug-for-bug: Every value is stored in the smallest signed type that will hold it, unless there is no unsigned type that can hold it, in which case it is stored in an `unsigned long long`, comparisons between integer and floating point values cast both to a double, comparisons between integer types perform a real comparison (so an unsigned long long is always greater than any negative number, at any precision). The Apple implementation is actually quite sane, it is just completely unrelated to the documentation in any way.
We now use the same range of reusable objects. Note that there is an error in Cocoa Design Patterns in the description of how Apple's implementation works. Do not use this as a reference.
We now return `nil` when an NSNumber is sent an -init message. This is consistent with Apple's implementation but breaks some things in the GNUstep test suite (which RFM said he will fix).
There is a small change in NSValue.h so that the locale parameter is now an `id` not an `NSString*`. This is because, under recent OS X, it may also be an `NSLocale` instance. I am not sure how much GNUstep supports `NSLocale`, but this change shouldn't affect anything.
The new (private) GSNumberTypes.h file lets you define macros that are instantiated with each of the names of primitive C types. These might be useful for simplifying other classes that have -intValue, -floatValue, and so on methods, such as the `NSCell` family.
The old NSConcreteNumberTemplate and NSConcreteNumber stuff has been removed. The code is now a bit more than 10% of the size of the old NSNumber code, and is hopefully maintainable now, so the next change won't require a complete rewrite.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29618 72102866-910b-0410-8b05-ffd578937521
2010-02-14 12:57:44 +00:00
|
|
|
*/
|
2010-02-14 16:32:02 +00:00
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
return [self initWithInt: 0];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithBool: (BOOL)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value == NO)
|
|
|
|
{
|
|
|
|
self = boolN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
self = boolY;
|
|
|
|
}
|
|
|
|
return RETAIN(self);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithBytes: (const void*)data objCType: (const char*)type
|
|
|
|
{
|
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
{
|
|
|
|
Class c = [abstractClass valueClassWithObjCType: type];
|
|
|
|
|
|
|
|
[self release];
|
|
|
|
self = (id)NSAllocateObject(c, 0, GSObjCZone(self));
|
|
|
|
return [self initWithBytes: data objCType: type];
|
|
|
|
}
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithChar: (signed char)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(charNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithDouble: (double)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
self = (NSNumber*)NSAllocateObject(doubleNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithFloat: (float)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
self = (NSNumber*)NSAllocateObject(floatNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithInt: (signed int)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(intNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithInteger: (NSInteger)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(integerNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithLong: (signed long)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(longNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithLongLong: (signed long long)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(longLongNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithShort: (signed short)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL && value >= -GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(shortNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithUnsignedChar: (unsigned char)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(uCharNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithUnsignedInt: (unsigned int)value
|
|
|
|
{
|
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(uIntNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
- (id) initWithUnsignedInteger: (NSUInteger)value
|
2009-02-23 20:42:32 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(uIntegerNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
2009-02-23 20:42:32 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (id) initWithUnsignedLong: (unsigned long)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(uLongNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (id) initWithUnsignedLongLong: (unsigned long long)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(uLongLongNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (id) initWithUnsignedShort: (unsigned short)value
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
RELEASE(self);
|
|
|
|
if (value <= GS_SMALL)
|
|
|
|
{
|
|
|
|
return RETAIN(smallIntegers[value + GS_SMALL]);
|
|
|
|
}
|
|
|
|
self = (NSNumber*)NSAllocateObject(uShortNumberClass, 0,
|
|
|
|
NSDefaultMallocZone());
|
|
|
|
self = [self initWithBytes: &value objCType: NULL];
|
|
|
|
return self;
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (id) copyWithZone: (NSZone*)zone
|
1998-03-12 14:21:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (NSShouldRetainWithZone(self, zone))
|
|
|
|
return RETAIN(self);
|
|
|
|
else
|
|
|
|
return NSCopyObject(self, 0, zone);
|
1998-03-12 14:21:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (NSString*) description
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
return [self descriptionWithLocale: nil];
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
NSString *result = nil;
|
|
|
|
|
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"descriptionWithLocale: for abstract NSNumber"];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
return [self boolValue] ? @"1" : @"0";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%i" locale: locale,
|
|
|
|
(int)[self charValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%u" locale: locale,
|
|
|
|
(unsigned int)[self unsignedCharValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%hi" locale: locale,
|
|
|
|
[self shortValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%hu" locale: locale,
|
|
|
|
[self unsignedShortValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%i" locale: locale,
|
|
|
|
[self intValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%u" locale: locale,
|
|
|
|
[self unsignedIntValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%li" locale: locale,
|
|
|
|
[self longValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%lu" locale: locale,
|
|
|
|
[self unsignedLongValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 9:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%lli" locale: locale,
|
|
|
|
[self longLongValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 10:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%llu" locale: locale,
|
|
|
|
[self unsignedLongLongValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 11:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%0.7g" locale: locale,
|
|
|
|
(double)[self floatValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 12:
|
|
|
|
result = [[NSString alloc] initWithFormat: @"%0.16g" locale: locale,
|
|
|
|
[self doubleValue]];
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for description"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return AUTORELEASE(result);
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
/* All the rest of these methods must be implemented by a subclass */
|
|
|
|
- (BOOL) boolValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get boolValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return (oData == 0) ? NO : YES;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NO;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (signed char) charValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get charValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (double) doubleValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get doubleValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (float) floatValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get floatValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (signed int) intValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get intValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (NSInteger) integerValue
|
2009-02-23 20:42:32 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get integerValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
2009-02-23 20:42:32 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (signed long long) longLongValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get longLongValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (signed long) longValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get longValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (signed short) shortValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get shortValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
- (NSString*) stringValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
return [self descriptionWithLocale: nil];
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
|
|
|
|
2010-02-14 16:32:02 +00:00
|
|
|
- (unsigned char) unsignedCharValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get unsignedCharrValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (unsigned int) unsignedIntValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get unsignedIntValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
2009-02-23 20:42:32 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (NSUInteger) unsignedIntegerValue
|
2009-02-23 20:42:32 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get unsignedIntegerValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (unsigned long long) unsignedLongLongValue
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get unsignedLongLongValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (unsigned long) unsignedLongValue
|
|
|
|
{
|
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get unsignedLongValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (unsigned short) unsignedShortValue
|
|
|
|
{
|
|
|
|
if (GSObjCClass(self) == abstractClass)
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"get unsignedShortValue from abstract NSNumber"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GSNumberInfo *info = GSNumberInfoFromObject(self);
|
|
|
|
|
|
|
|
switch (info->typeLevel)
|
2000-03-23 18:57:43 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
BOOL oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
signed char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
unsigned char oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
signed short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
unsigned short oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
signed int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
unsigned int oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
{
|
|
|
|
signed long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
{
|
|
|
|
unsigned long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
{
|
|
|
|
signed long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 10:
|
|
|
|
{
|
|
|
|
unsigned long long oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 11:
|
|
|
|
{
|
|
|
|
float oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
case 12:
|
|
|
|
{
|
|
|
|
double oData;
|
|
|
|
|
|
|
|
(*(info->getValue))(self, @selector(getValue:), &oData);
|
|
|
|
return oData;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"unknown number type value for get"];
|
2000-03-23 18:57:43 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (NSComparisonResult) compare: (NSNumber*)other
|
1995-04-03 20:49:14 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
double otherValue;
|
|
|
|
double myValue;
|
|
|
|
|
|
|
|
if (other == self)
|
|
|
|
{
|
|
|
|
return NSOrderedSame;
|
|
|
|
}
|
|
|
|
else if (other == nil)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"nil argument for compare:"];
|
|
|
|
}
|
|
|
|
|
|
|
|
myValue = [self doubleValue];
|
|
|
|
otherValue = [other doubleValue];
|
|
|
|
|
|
|
|
if (myValue == otherValue)
|
|
|
|
{
|
|
|
|
return NSOrderedSame;
|
|
|
|
}
|
|
|
|
else if (myValue < otherValue)
|
|
|
|
{
|
|
|
|
return NSOrderedAscending;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return NSOrderedDescending;
|
|
|
|
}
|
1995-04-03 20:49:14 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Because of the rule that two numbers which are the same according to
|
|
|
|
* [-isEqual: ] must generate the same hash, we must generate the hash
|
|
|
|
* from the most general representation of the number.
|
|
|
|
* NB. Don't change this without changing the matching function in
|
|
|
|
* NSConcreteNumber.m
|
|
|
|
*/
|
|
|
|
- (unsigned) hash
|
1998-02-05 22:06:20 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
union {
|
|
|
|
double d;
|
|
|
|
unsigned char c[sizeof(double)];
|
|
|
|
} val;
|
|
|
|
unsigned hash = 0;
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
val.d = [self doubleValue];
|
|
|
|
for (i = 0; i < sizeof(double); i++)
|
|
|
|
{
|
|
|
|
hash = (hash << 5) + hash + val.c[i];
|
|
|
|
}
|
|
|
|
return hash;
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (BOOL) isEqual: (id)o
|
1999-06-14 09:59:59 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (o == self)
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
else if (o == nil)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
else if (GSObjCIsInstance(o) == YES
|
|
|
|
&& GSObjCIsKindOf(GSObjCClass(o), abstractClass))
|
|
|
|
{
|
|
|
|
return [self isEqualToNumber: (NSNumber*)o];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return [super isEqual: o];
|
|
|
|
}
|
1999-06-14 09:59:59 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (BOOL) isEqualToNumber: (NSNumber*)o
|
|
|
|
{
|
|
|
|
if (o == self)
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
else if (o == nil)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
else if ([self compare: o] == NSOrderedSame)
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
return NO;
|
1998-02-05 22:06:20 +00:00
|
|
|
}
|
2010-02-14 16:32:02 +00:00
|
|
|
|
|
|
|
- (BOOL) isEqualToValue: (NSValue*)o
|
2007-06-14 05:03:35 +00:00
|
|
|
{
|
2010-02-14 16:32:02 +00:00
|
|
|
if (o == self)
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
else if (o == nil)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
else if (GSObjCIsInstance(o) == YES
|
|
|
|
&& GSObjCIsKindOf(GSObjCClass(o), abstractClass))
|
|
|
|
{
|
|
|
|
return [self isEqualToNumber: (NSNumber*)o];
|
|
|
|
}
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NSCoding
|
|
|
|
*/
|
|
|
|
|
|
|
|
- (Class) classForCoder
|
|
|
|
{
|
|
|
|
return abstractClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
|
|
|
|
{
|
|
|
|
if ([aCoder isByref] == NO)
|
|
|
|
return self;
|
|
|
|
return [super replacementObjectForPortCoder: aCoder];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) encodeWithCoder: (NSCoder*)coder
|
|
|
|
{
|
|
|
|
const char *t = [self objCType];
|
|
|
|
|
|
|
|
[coder encodeValueOfObjCType: @encode(signed char) at: t];
|
|
|
|
[coder encodeValueOfObjCType: t at: [self pointerValue]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithCoder: (NSCoder*)coder
|
|
|
|
{
|
|
|
|
char t[2];
|
|
|
|
union {
|
|
|
|
signed char c;
|
|
|
|
unsigned char C;
|
|
|
|
signed short s;
|
|
|
|
unsigned short S;
|
|
|
|
signed int i;
|
|
|
|
unsigned int I;
|
|
|
|
signed long l;
|
|
|
|
unsigned long L;
|
|
|
|
signed long long q;
|
|
|
|
unsigned long long Q;
|
|
|
|
float f;
|
|
|
|
double d;
|
|
|
|
} data;
|
|
|
|
|
|
|
|
[coder decodeValueOfObjCType: @encode(signed char) at: t];
|
|
|
|
t[1] = '\0';
|
|
|
|
[coder decodeValueOfObjCType: t at: &data];
|
|
|
|
switch (*t)
|
|
|
|
{
|
|
|
|
case 'c': self = [self initWithChar: data.c]; break;
|
|
|
|
case 'C': self = [self initWithUnsignedChar: data.C]; break;
|
|
|
|
case 's': self = [self initWithShort: data.s]; break;
|
|
|
|
case 'S': self = [self initWithUnsignedShort: data.S]; break;
|
|
|
|
case 'i': self = [self initWithInt: data.i]; break;
|
|
|
|
case 'I': self = [self initWithUnsignedInt: data.I]; break;
|
|
|
|
case 'l': self = [self initWithLong: data.l]; break;
|
|
|
|
case 'L': self = [self initWithUnsignedLong: data.L]; break;
|
|
|
|
case 'q': self = [self initWithLongLong: data.q]; break;
|
|
|
|
case 'Q': self = [self initWithUnsignedLongLong: data.Q]; break;
|
|
|
|
case 'f': self = [self initWithFloat: data.f]; break;
|
|
|
|
case 'd': self = [self initWithDouble: data.d]; break;
|
|
|
|
default:
|
|
|
|
DESTROY(self);
|
|
|
|
NSLog(@"Attempt to decode number with unknown ObjC type");
|
|
|
|
}
|
|
|
|
return self;
|
2000-03-18 07:56:43 +00:00
|
|
|
}
|
1996-02-22 16:02:02 +00:00
|
|
|
@end
|