Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -693,10 +693,18 @@ 4B3D23E81337FCB000DD29B8 /* macros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBA36C511406AB700CBA3AC /* macros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23E91337FCB000DD29B8 /* of_asprintf.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB50DCF12F863C700C9393F /* of_asprintf.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23EA1337FCB000DD29B8 /* threading.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B67998B1099E7C50041064A /* threading.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3D23EE1337FFD000DD29B8 /* of_asprintf.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BB50DD012F863C700C9393F /* of_asprintf.m */; }; 4B3D5694139A617D0010A78F /* OFSerializationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3D5693139A617D0010A78F /* OFSerializationTests.m */; }; + 4B3DE1271F5F4F2F0090AA3E /* OFMutablePair.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3DE1231F5F4F2F0090AA3E /* OFMutablePair.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B3DE1281F5F4F2F0090AA3E /* OFMutablePair.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3DE1231F5F4F2F0090AA3E /* OFMutablePair.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B3DE1291F5F4F2F0090AA3E /* OFMutablePair.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3DE1241F5F4F2F0090AA3E /* OFMutablePair.m */; }; + 4B3DE12A1F5F4F2F0090AA3E /* OFMutablePair.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3DE1241F5F4F2F0090AA3E /* OFMutablePair.m */; }; + 4B3DE12B1F5F4F2F0090AA3E /* OFPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3DE1251F5F4F2F0090AA3E /* OFPair.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B3DE12C1F5F4F2F0090AA3E /* OFPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3DE1251F5F4F2F0090AA3E /* OFPair.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B3DE12D1F5F4F2F0090AA3E /* OFPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3DE1261F5F4F2F0090AA3E /* OFPair.m */; }; + 4B3DE12E1F5F4F2F0090AA3E /* OFPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3DE1261F5F4F2F0090AA3E /* OFPair.m */; }; 4B3ED7C21AF62C30004C8FF1 /* OFGetOptionFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3ED7C01AF62C30004C8FF1 /* OFGetOptionFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B3ED7C31AF62C30004C8FF1 /* OFGetOptionFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B3ED7C11AF62C30004C8FF1 /* OFGetOptionFailedException.m */; }; 4B40EC1B189FE2650031E19E /* socket.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B40EC1A189FE2650031E19E /* socket.m */; }; 4B4116D01F21654200E78916 /* OFMutableURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4116CD1F21654200E78916 /* OFMutableURL.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B4116D11F21654200E78916 /* OFMutableURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4116CD1F21654200E78916 /* OFMutableURL.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1326,10 +1334,14 @@ 4B3D236D1337FB5800DD29B8 /* base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base64.h; path = src/base64.h; sourceTree = ""; }; 4B3D236E1337FB5800DD29B8 /* base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = base64.m; path = src/base64.m; sourceTree = ""; }; 4B3D23761337FBC800DD29B8 /* ObjFW.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ObjFW.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B3D23BB1337FC5800DD29B8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = misc/Info.plist; sourceTree = SOURCE_ROOT; }; 4B3D5693139A617D0010A78F /* OFSerializationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSerializationTests.m; path = tests/OFSerializationTests.m; sourceTree = ""; }; + 4B3DE1231F5F4F2F0090AA3E /* OFMutablePair.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutablePair.h; path = src/OFMutablePair.h; sourceTree = ""; }; + 4B3DE1241F5F4F2F0090AA3E /* OFMutablePair.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutablePair.m; path = src/OFMutablePair.m; sourceTree = ""; }; + 4B3DE1251F5F4F2F0090AA3E /* OFPair.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFPair.h; path = src/OFPair.h; sourceTree = ""; }; + 4B3DE1261F5F4F2F0090AA3E /* OFPair.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFPair.m; path = src/OFPair.m; sourceTree = ""; }; 4B3ED7C01AF62C30004C8FF1 /* OFGetOptionFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFGetOptionFailedException.h; path = src/exceptions/OFGetOptionFailedException.h; sourceTree = ""; }; 4B3ED7C11AF62C30004C8FF1 /* OFGetOptionFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFGetOptionFailedException.m; path = src/exceptions/OFGetOptionFailedException.m; sourceTree = ""; }; 4B40EC1A189FE2650031E19E /* socket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = socket.m; path = src/socket.m; sourceTree = ""; }; 4B4116CD1F21654200E78916 /* OFMutableURL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutableURL.h; path = src/OFMutableURL.h; sourceTree = ""; }; 4B4116CE1F21654200E78916 /* OFMutableURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableURL.m; path = src/OFMutableURL.m; sourceTree = ""; }; @@ -2117,10 +2129,12 @@ 4B1223121F23E6B300D9F8FF /* OFMutableData.m */, 4B6799711099E7C50041064A /* OFMutableDictionary.h */, 4B6799721099E7C50041064A /* OFMutableDictionary.m */, 4B2B3E79140D430500EC2F7C /* OFMutableDictionary_hashtable.h */, 4B2B3E7A140D430500EC2F7C /* OFMutableDictionary_hashtable.m */, + 4B3DE1231F5F4F2F0090AA3E /* OFMutablePair.h */, + 4B3DE1241F5F4F2F0090AA3E /* OFMutablePair.m */, 4B39844513D3AFB400E6F825 /* OFMutableSet.h */, 4B39844613D3AFB400E6F825 /* OFMutableSet.m */, 4BA85BC6140ECCE800E91D51 /* OFMutableSet_hashtable.h */, 4BA85BC7140ECCE800E91D51 /* OFMutableSet_hashtable.m */, 4B6799731099E7C50041064A /* OFMutableString.h */, @@ -2145,10 +2159,12 @@ 4BC176251D04963000C32718 /* OFObject+KeyValueCoding.m */, 4BB25E82139C388A00F574EA /* OFObject+Serialization.h */, 4BB25E83139C388A00F574EA /* OFObject+Serialization.m */, 4BAFC166182EAA7800BE5E57 /* OFOptionsParser.h */, 4BAFC167182EAA7800BE5E57 /* OFOptionsParser.m */, + 4B3DE1251F5F4F2F0090AA3E /* OFPair.h */, + 4B3DE1261F5F4F2F0090AA3E /* OFPair.m */, 4B6799791099E7C50041064A /* OFPlugin.h */, 4B67997A1099E7C50041064A /* OFPlugin.m */, 4BB524BF143D1E4E0085FBCC /* OFProcess.h */, 4BB524C0143D1E4E0085FBCC /* OFProcess.m */, 4B6743FC163C395900EB1E59 /* OFRecursiveMutex.h */, @@ -2490,10 +2506,11 @@ 4B2C21FE1DA292BE00735907 /* OFMessagePackExtension.h in Headers */, 4B2C21FF1DA292BE00735907 /* OFMessagePackRepresentation.h in Headers */, 4B2C22001DA292BE00735907 /* OFMutableArray.h in Headers */, 4B1223181F23E6C100D9F8FF /* OFMutableData.h in Headers */, 4B2C22011DA292BE00735907 /* OFMutableDictionary.h in Headers */, + 4B3DE1281F5F4F2F0090AA3E /* OFMutablePair.h in Headers */, 4B2C22021DA292BE00735907 /* OFMutableSet.h in Headers */, 4B2C22031DA292BE00735907 /* OFMutableString.h in Headers */, 4BA842E71F35E53800292FC6 /* OFMutableTarArchiveEntry.h in Headers */, 4B4116D11F21654200E78916 /* OFMutableURL.h in Headers */, 4B92FDE01F35DFB5000D541D /* OFMutableZIPArchiveEntry.h in Headers */, @@ -2502,10 +2519,11 @@ 4B2C22061DA292BE00735907 /* OFNumber.h in Headers */, 4B2C22071DA292BE00735907 /* OFObject.h in Headers */, 4B2C22081DA292BE00735907 /* OFObject+KeyValueCoding.h in Headers */, 4B2C22091DA292BE00735907 /* OFObject+Serialization.h in Headers */, 4B2C220A1DA292BE00735907 /* OFOptionsParser.h in Headers */, + 4B3DE12C1F5F4F2F0090AA3E /* OFPair.h in Headers */, 4B5D70671DA2F7B400B3B2D7 /* OFPlugin.h in Headers */, 4B2C220D1DA292BE00735907 /* OFRecursiveMutex.h in Headers */, 4B2C220E1DA292BE00735907 /* OFRIPEMD160Hash.h in Headers */, 4B2C220F1DA292BE00735907 /* OFRunLoop.h in Headers */, 4B935D131E9A7DC3001F2957 /* OFSandbox.h in Headers */, @@ -2719,10 +2737,11 @@ 4BCAA9AF1772432F003EF859 /* OFMessagePackExtension.h in Headers */, 4B879A8E177231F000EBCEA4 /* OFMessagePackRepresentation.h in Headers */, 4B3D23CD1337FCB000DD29B8 /* OFMutableArray.h in Headers */, 4B1223151F23E6C000D9F8FF /* OFMutableData.h in Headers */, 4B3D23CE1337FCB000DD29B8 /* OFMutableDictionary.h in Headers */, + 4B3DE1271F5F4F2F0090AA3E /* OFMutablePair.h in Headers */, 4B39844713D3AFB400E6F825 /* OFMutableSet.h in Headers */, 4B3D23CF1337FCB000DD29B8 /* OFMutableString.h in Headers */, 4BA842E61F35E53800292FC6 /* OFMutableTarArchiveEntry.h in Headers */, 4B4116D01F21654200E78916 /* OFMutableURL.h in Headers */, 4B92FDDF1F35DFB5000D541D /* OFMutableZIPArchiveEntry.h in Headers */, @@ -2731,10 +2750,11 @@ 4B3D23D01337FCB000DD29B8 /* OFNumber.h in Headers */, 4B3D23D11337FCB000DD29B8 /* OFObject.h in Headers */, 4BC176301D04963000C32718 /* OFObject+KeyValueCoding.h in Headers */, 4BB25E88139C388A00F574EA /* OFObject+Serialization.h in Headers */, 4BAFC168182EAA7800BE5E57 /* OFOptionsParser.h in Headers */, + 4B3DE12B1F5F4F2F0090AA3E /* OFPair.h in Headers */, 4B3D23D21337FCB000DD29B8 /* OFPlugin.h in Headers */, 4BB524C1143D1E4E0085FBCC /* OFProcess.h in Headers */, 4B674405163C395900EB1E59 /* OFRecursiveMutex.h in Headers */, 4BEC83B919B7CB7100E4BB08 /* OFRIPEMD160Hash.h in Headers */, 4B325EDD1605F3A0007836CA /* OFRunLoop.h in Headers */, @@ -3283,10 +3303,11 @@ 4B2C21481DA292BE00735907 /* OFMutableArray.m in Sources */, 4B2C21491DA292BE00735907 /* OFMutableArray_adjacent.m in Sources */, 4B1223191F23E6C100D9F8FF /* OFMutableData.m in Sources */, 4B2C214A1DA292BE00735907 /* OFMutableDictionary.m in Sources */, 4B2C214B1DA292BE00735907 /* OFMutableDictionary_hashtable.m in Sources */, + 4B3DE12A1F5F4F2F0090AA3E /* OFMutablePair.m in Sources */, 4B2C214C1DA292BE00735907 /* OFMutableSet.m in Sources */, 4B2C214D1DA292BE00735907 /* OFMutableSet_hashtable.m in Sources */, 4B2C214E1DA292BE00735907 /* OFMutableString.m in Sources */, 4B2C214F1DA292BE00735907 /* OFMutableString_UTF8.m in Sources */, 4BA842E91F35E53800292FC6 /* OFMutableTarArchiveEntry.m in Sources */, @@ -3296,10 +3317,11 @@ 4B2C21511DA292BE00735907 /* OFNull.m in Sources */, 4B2C21521DA292BE00735907 /* OFNumber.m in Sources */, 4B2C21531DA292BE00735907 /* OFObject.m in Sources */, 4B2C21541DA292BE00735907 /* OFObject+Serialization.m in Sources */, 4B2C21551DA292BE00735907 /* OFOptionsParser.m in Sources */, + 4B3DE12E1F5F4F2F0090AA3E /* OFPair.m in Sources */, 4B5D70681DA2F7B400B3B2D7 /* OFPlugin.m in Sources */, 4B2C21581DA292BE00735907 /* OFRecursiveMutex.m in Sources */, 4B2C21591DA292BE00735907 /* OFRIPEMD160Hash.m in Sources */, 4B2C215A1DA292BE00735907 /* OFRunLoop.m in Sources */, 4B935D151E9A7DC3001F2957 /* OFSandbox.m in Sources */, @@ -3485,10 +3507,11 @@ 4B3D239B1337FC0D00DD29B8 /* OFMutableArray.m in Sources */, 4B2B3E82140D430500EC2F7C /* OFMutableArray_adjacent.m in Sources */, 4B1223161F23E6C000D9F8FF /* OFMutableData.m in Sources */, 4B3D239C1337FC0D00DD29B8 /* OFMutableDictionary.m in Sources */, 4B2B3E84140D430500EC2F7C /* OFMutableDictionary_hashtable.m in Sources */, + 4B3DE1291F5F4F2F0090AA3E /* OFMutablePair.m in Sources */, 4B39844813D3AFB400E6F825 /* OFMutableSet.m in Sources */, 4BA85BCD140ECCE800E91D51 /* OFMutableSet_hashtable.m in Sources */, 4B3D239D1337FC0D00DD29B8 /* OFMutableString.m in Sources */, 4B552553147AA5DB0003BF47 /* OFMutableString_UTF8.m in Sources */, 4BA842E81F35E53800292FC6 /* OFMutableTarArchiveEntry.m in Sources */, @@ -3498,10 +3521,11 @@ 4B511B7D139C0A34003764A5 /* OFNull.m in Sources */, 4B3D239E1337FC0D00DD29B8 /* OFNumber.m in Sources */, 4B3D239F1337FC0D00DD29B8 /* OFObject.m in Sources */, 4BB25E89139C388A00F574EA /* OFObject+Serialization.m in Sources */, 4BAFC169182EAA7800BE5E57 /* OFOptionsParser.m in Sources */, + 4B3DE12D1F5F4F2F0090AA3E /* OFPair.m in Sources */, 4B3D23A01337FC0D00DD29B8 /* OFPlugin.m in Sources */, 4BB524C2143D1E4E0085FBCC /* OFProcess.m in Sources */, 4B674406163C395900EB1E59 /* OFRecursiveMutex.m in Sources */, 4BEC83BA19B7CB7100E4BB08 /* OFRIPEMD160Hash.m in Sources */, 4B325EDE1605F3A0007836CA /* OFRunLoop.m in Sources */, Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -36,10 +36,11 @@ OFMD5Hash.m \ OFMessagePackExtension.m \ OFMutableArray.m \ OFMutableData.m \ OFMutableDictionary.m \ + OFMutablePair.m \ OFMutableSet.m \ OFMutableString.m \ OFMutableTarArchiveEntry.m \ OFMutableURL.m \ OFMutableZIPArchiveEntry.m \ @@ -47,10 +48,11 @@ OFNumber.m \ OFObject.m \ OFObject+KeyValueCoding.m \ OFObject+Serialization.m \ OFOptionsParser.m \ + OFPair.m \ ${OFPROCESS_M} \ OFRIPEMD160Hash.m \ OFRunLoop.m \ OFSandbox.m \ OFSeekableStream.m \ ADDED src/OFMutablePair.h Index: src/OFMutablePair.h ================================================================== --- /dev/null +++ src/OFMutablePair.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFPair.h" + +OF_ASSUME_NONNULL_BEGIN + +/*! + * @class OFMutablePair OFMutablePair.h ObjFW/OFMutablePair.h + * + * @brief A class for storing a pair of two objects. + */ +@interface OFMutablePair OF_GENERIC(FirstType, SecondType): + OFPair OF_GENERIC(FirstType, SecondType) +#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) +# define FirstType id +# define SecondType id +#endif +/*! + * The first object of the pair. + */ +@property (readwrite, nonatomic, retain) FirstType firstObject; + +/*! + * The second object of the pair. + */ +@property (readwrite, nonatomic, retain) SecondType secondObject; + +/*! + * @brief Converts the mutable pair to an immutable pair. + */ +- (void)makeImmutable; +#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) +# undef FirstType +# undef SecondType +#endif +@end + +OF_ASSUME_NONNULL_END ADDED src/OFMutablePair.m Index: src/OFMutablePair.m ================================================================== --- /dev/null +++ src/OFMutablePair.m @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFMutablePair.h" + +@implementation OFMutablePair +@dynamic firstObject, secondObject; + +- (void)setFirstObject: (id)firstObject +{ + id old = _firstObject; + _firstObject = [firstObject retain]; + [old release]; +} + +- (void)setSecondObject: (id)secondObject +{ + id old = _secondObject; + _secondObject = [secondObject retain]; + [old release]; +} + +- copy +{ + OFMutablePair *copy = [self mutableCopy]; + + [copy makeImmutable]; + + return copy; +} + +- (void)makeImmutable +{ + object_setClass(self, [OFPair class]); +} +@end ADDED src/OFPair.h Index: src/OFPair.h ================================================================== --- /dev/null +++ src/OFPair.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFObject.h" + +OF_ASSUME_NONNULL_BEGIN + +/*! + * @class OFPair OFPair.h ObjFW/OFPair.h + * + * @brief A class for storing a pair of two objects. + */ +@interface OFPair OF_GENERIC(FirstType, SecondType): OFObject +#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) +# define FirstType id +# define SecondType id +#endif +{ + FirstType _firstObject; + SecondType _secondObject; +} + +/*! + * The first object of the pair. + */ +@property (readonly, nonatomic, retain) FirstType firstObject; + +/*! + * The second object of the pair. + */ +@property (readonly, nonatomic, retain) SecondType secondObject; + +/*! + * @brief Creates a new OFPair with the specified objects. + * + * @param firstObject The first object for the pair + * @param secondObject The second object for the pair + * @return A new, autoreleased OFPair + */ ++ (instancetype)pairWithFirstObject: (FirstType)firstObject + secondObject: (SecondType)secondObject; + +/*! + * @brief Initializes an already allocated OFPair with the specified objects. + * + * @param firstObject The first object for the pair + * @param secondObject The second object for the pair + * @return An initialized OFPair + */ +- initWithFirstObject: (FirstType)firstObject + secondObject: (SecondType)secondObject; +#if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) +# undef FirstType +# undef SecondType +#endif +@end + +OF_ASSUME_NONNULL_END + +#import "OFMutablePair.h" ADDED src/OFPair.m Index: src/OFPair.m ================================================================== --- /dev/null +++ src/OFPair.m @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFPair.h" +#import "OFString.h" + +@implementation OFPair ++ (instancetype)pairWithFirstObject: (id)firstObject + secondObject: (id)secondObject +{ + return [[[self alloc] initWithFirstObject: firstObject + secondObject: secondObject] autorelease]; +} + +- initWithFirstObject: (id)firstObject + secondObject: (id)secondObject +{ + self = [super init]; + + @try { + _firstObject = [firstObject retain]; + _secondObject = [secondObject retain]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_firstObject release]; + [_secondObject release]; + + [super dealloc]; +} + +- (id)firstObject +{ + return _firstObject; +} + +- (id)secondObject +{ + return _secondObject; +} + +- (bool)isEqual: (id)object +{ + OFPair *pair; + + if (![object isKindOfClass: [OFPair class]]) + return false; + + pair = object; + + if (![pair->_firstObject isEqual: _firstObject]) + return false; + + if (![pair->_secondObject isEqual: _secondObject]) + return false; + + return true; +} + +- (uint32_t)hash +{ + uint32_t hash; + + OF_HASH_INIT(hash); + + OF_HASH_ADD_HASH(hash, [_firstObject hash]); + OF_HASH_ADD_HASH(hash, [_secondObject hash]); + + OF_HASH_FINALIZE(hash); + + return hash; +} + +- copy +{ + return [self retain]; +} + +- mutableCopy +{ + return [OFMutablePair pairWithFirstObject: _firstObject + secondObject: _secondObject]; +} + +- (OFString *)description +{ + return [OFString stringWithFormat: @"<<%@, %@>>", + _firstObject, _secondObject]; +} +@end