Commits

Tuukka Norri  committed 4f8516a

Updated the C++ collection implementation, HOM methods for NSMapTable, NSHashTable

  • Participants
  • Parent commits c4a316b

Comments (0)

Files changed (36)

File Sources/BXAttributeDescription.m

  * \ingroup descriptions
  */
 @implementation BXAttributeDescription
-- (void) finalize
-{
-	if (mRelationshipsUsing)
-		CFRelease (mRelationshipsUsing);
-	[super finalize];
-}
-
 - (void) dealloc
 {
-	if (mRelationshipsUsing)
-		CFRelease (mRelationshipsUsing);
-	
+	[mRelationshipsUsing release];
 	[mDatabaseTypeName release];
 	[super dealloc];
 }

File Sources/BXCollectionFunctions.h

+//
+// BXCollectionFunctions.h
+// BaseTen
+//
+// Copyright (C) 2008-2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+#import <Foundation/Foundation.h>
+
+
+#if defined(__cplusplus)
+namespace BaseTen {
+	
+	namespace CollectionFunctions {
+
+		template <typename T>
+		BOOL ContainsKey (T *container, typename T::key_type key)
+		{
+			BOOL retval = NO;
+			if (container)
+			{
+				typename T::const_iterator it = container->find (key);
+				if (container->end () != it)
+					retval = YES;
+			}
+			return retval;
+		}
+		
+		
+		template <typename T>
+		BOOL ContainsKey (T *container, typename T::key_type::element_type key)
+		{
+			BOOL retval = NO;
+			if (container)
+			{
+				BaseTen::ObjCPtr <typename T::key_type::element_type> keyPtr (key);
+				typename T::const_iterator it = container->find (keyPtr);
+				if (container->end () != it)
+					retval = YES;
+			}
+			return retval;
+		}		
+		
+		
+		template <typename T>
+		BOOL FindElement (T *container, typename T::key_type key, typename T::mapped_type *outVal)
+		{
+			BOOL retval = NO;
+			if (container && outVal)
+			{
+				typename T::const_iterator it = container->find (key);
+				if (container->end () != it)
+				{
+					*outVal = it->second;
+					retval = YES;
+				}
+			}
+			return retval;
+		}
+		
+		
+		template <typename T>
+		BOOL FindElement (T *container, typename T::key_type::element_type key, typename T::mapped_type *outVal)
+		{
+			BOOL retval = NO;
+			if (container && outVal)
+			{
+				BaseTen::ObjCPtr <typename T::key_type::element_type> keyPtr (key);
+				typename T::const_iterator it = container->find (keyPtr);
+				if (container->end () != it)
+				{
+					*outVal = it->second;
+					retval = YES;
+				}
+			}
+			return retval;
+		}		
+		
+		
+		template <typename T>
+		typename T::mapped_type::element_type FindObject (T *container, typename T::key_type key)
+		{
+			typename T::mapped_type::element_type retval = nil;
+			if (container)
+			{
+				typename T::const_iterator it = container->find (key);
+				if (container->end () != it)
+					retval = *it->second;
+			}
+			return retval;
+		}
+		
+		
+		template <typename T>
+		typename T::mapped_type::element_type FindObject (T *container, typename T::key_type::element_type key)
+		{
+			typename T::mapped_type::element_type retval = nil;
+			if (container)
+			{
+				BaseTen::ObjCPtr <typename T::key_type::element_type> keyPtr (key);
+				typename T::const_iterator it = container->find (keyPtr);
+				if (container->end () != it)
+					retval = *it->second;
+			}
+			return retval;
+		}		
+		
+		
+		template <typename T>
+		void Insert (T *container, typename T::key_type key, typename T::mapped_type val)
+		{
+			container->insert (std::make_pair (key, val));
+		}
+		
+		
+		template <typename T>
+		void Insert (T *container, typename T::key_type::element_type key, typename T::mapped_type val)
+		{
+			typename T::key_type keyPtr (key);
+			container->insert (std::make_pair (keyPtr, val));
+		}
+		
+		
+		template <typename T>
+		void Insert (T *container, typename T::key_type key, typename T::mapped_type::element_type val)
+		{
+			typename T::mapped_type valPtr (val);
+			container->insert (std::make_pair (key, valPtr));
+		}
+		
+		
+		template <typename T>
+		void Insert (T *container, typename T::key_type::element_type key, typename T::mapped_type::element_type val)
+		{
+			typename T::key_type keyPtr (key);
+			typename T::mapped_type valPtr (val);
+			container->insert (std::make_pair (keyPtr, valPtr));
+		}		
+		
+		
+		template <typename T>
+		void InsertConditionally (T *container, typename T::key_type key, typename T::mapped_type val)
+		{
+			if (! ContainsKey (container, key))
+				Insert (container, key, val);
+		}
+		
+		
+		template <typename T>
+		void InsertConditionally (T *container, typename T::key_type::element_type key, typename T::mapped_type val)
+		{
+			if (! ContainsKey (container, key))
+				Insert (container, key, val);
+		}		
+		
+		
+		template <typename T>
+		void InsertConditionally (T *container, typename T::key_type key, typename T::mapped_type::element_type val)
+		{
+			if (! ContainsKey (container, key))
+				Insert (container, key, val);
+		}
+		
+		
+		template <typename T>
+		void InsertConditionally (T *container, typename T::key_type::element_type key, typename T::mapped_type::element_type val)
+		{
+			if (! ContainsKey (container, key))
+				Insert (container, key, val);
+		}
+		
+		
+		template <typename T>
+		void PushBack (T *container, typename T::value_type::element_type val)
+		{
+			if (container)
+			{
+				typename T::value_type valPtr (val);
+				container->push_back (valPtr);
+			}
+		}
+	}
+}
+#endif

File Sources/BXCollections.h

+//
+// BXCollections.h
+// BaseTen
+//
+// Copyright (C) 2008-2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+#import <Foundation/Foundation.h>
+
+
+#if defined(__cplusplus)
+#import <BaseTen/BXScannedMemoryAllocator.h>
+#import <BaseTen/BXScannedMemoryObject.h>
+#import <BaseTen/BXObjCPtr.h>
+#import <BaseTen/BXObjCPair.h>
+#import <list>
+#import <tr1/unordered_set>
+#import <tr1/unordered_map>
+namespace BaseTen
+{
+	namespace internal {
+		
+		template <typename T>
+		class list :
+			public std::list <T, BaseTen::ScannedMemoryAllocator <T> >,
+			public BaseTen::ScannedMemoryObject
+		{
+		public:
+			typedef std::list <T, BaseTen::ScannedMemoryAllocator <T> > _Base;
+			
+			explicit list () : _Base () {};
+			explicit list (typename _Base::size_type size) : _Base (size) {};
+		};
+		
+		
+		template <typename T>
+		class unordered_set : 
+			public std::tr1::unordered_set <
+				T,
+				std::tr1::hash <T>,
+				std::equal_to <T>,
+				BaseTen::ScannedMemoryAllocator <T>
+			>,
+			public BaseTen::ScannedMemoryObject
+		{
+		public:
+			typedef std::tr1::unordered_set <
+				T,
+				std::tr1::hash <T>,
+				std::equal_to <T>,
+				BaseTen::ScannedMemoryAllocator <T>
+			> _Base;
+
+			explicit unordered_set (typename _Base::size_type size = 10) : _Base (size) {};
+		};
+		
+		
+		template <typename T, typename U>
+		class unordered_map :
+			public std::tr1::unordered_map <
+				T,
+				U,
+				std::tr1::hash <T>,
+				std::equal_to <T>,
+				BaseTen::ScannedMemoryAllocator <std::pair <
+					const T, U
+				> >
+			>,
+			public BaseTen::ScannedMemoryObject
+		{
+		public:
+			typedef std::tr1::unordered_map <
+				T,
+				U,
+				std::tr1::hash <T>,
+				std::equal_to <T>,
+				BaseTen::ScannedMemoryAllocator <std::pair <
+					const T, U
+				> >
+			> _Base;
+			
+			explicit unordered_map (typename _Base::size_type size = 10) : _Base (size) {};
+		};
+	}
+	
+	
+	typedef ObjCPtr <id> IdPtr;
+	typedef ObjCPair <id, id> IdPair;
+
+	
+	typedef BaseTen::internal::list <IdPtr> IdList;
+	typedef BaseTen::internal::unordered_set <IdPair> IdPairSet;
+	typedef BaseTen::internal::unordered_map <IdPtr, IdPtr> IdMap;
+	typedef BaseTen::internal::unordered_map <NSInteger, IdPtr> IndexMap;
+}
+
+#define BX_IdList    __strong BaseTen::IdList
+#define BX_IdMap     __strong BaseTen::IdMap
+#define BX_IndexMap  __strong BaseTen::IndexMap
+#define BX_IdPairSet __strong BaseTen::IdPairSet
+
+#else
+#define BX_IdList    __strong void
+#define BX_IdMap     __strong void
+#define BX_IndexMap  __strong void
+#define BX_IdPairSet __strong void
+#endif

File Sources/BXDatabaseObjectModelMOMSerialization.mm

 #import <CoreData/CoreData.h>
 #import <tr1/unordered_map>
 #import "BXDatabaseObjectModel.h"
-#import "PGTSCollections.h"
+#import "BXCollections.h"
 #import "BXEnumerate.h"
 #import "BXEntityDescription.h"
 #import "BXAttributeDescription.h"
 #import "BXLogger.h"
 #import "BXForeignKey.h"
 #import "BXHOM.h"
+#import "BXCollectionFunctions.h"
 
 
-typedef std::tr1::unordered_map <id, NSAttributeType,
-	PGTS::ObjectHash, 
-	PGTS::ObjectCompare <id>, 
-	PGTS::scanned_memory_allocator <std::pair <const id, NSAttributeType> > > 
-	IdentifierMap;
+using namespace BaseTen;
+using namespace BaseTen::CollectionFunctions;
+
+
+typedef std::tr1::unordered_map <
+	IdPtr,
+	NSAttributeType,
+	std::tr1::hash <IdPtr>,
+	std::equal_to <IdPtr>,
+	BaseTen::ScannedMemoryAllocator <std::pair <
+		const IdPtr, NSAttributeType
+	> > 
+> IdentifierMap;
 
 
 static IdentifierMap gTypeMapping;
 	{
 		tooLate = YES;
 		
-		gTypeMapping [@"bit"]         = NSStringAttributeType;
-		gTypeMapping [@"bool"]        = NSBooleanAttributeType;
-		gTypeMapping [@"bytea"]       = NSBinaryDataAttributeType;
-		gTypeMapping [@"char"]        = NSStringAttributeType;
-		gTypeMapping [@"date"]        = NSDateAttributeType;
-		gTypeMapping [@"float4"]      = NSFloatAttributeType;
-		gTypeMapping [@"float8"]      = NSDoubleAttributeType;
-		gTypeMapping [@"int2"]        = NSInteger16AttributeType;
-		gTypeMapping [@"int4"]        = NSInteger32AttributeType;
-		gTypeMapping [@"int8"]        = NSInteger64AttributeType;
-		gTypeMapping [@"name"]        = NSStringAttributeType;
-		gTypeMapping [@"numeric"]     = NSDecimalAttributeType;
-		gTypeMapping [@"oid"]         = NSInteger32AttributeType;
-		gTypeMapping [@"text"]        = NSStringAttributeType;
-		gTypeMapping [@"timestamp"]   = NSDateAttributeType;
-		gTypeMapping [@"timestamptz"] = NSDateAttributeType;
-		gTypeMapping [@"time"]        = NSDateAttributeType;
-		gTypeMapping [@"timetz"]      = NSDateAttributeType;
-		gTypeMapping [@"varbit"]      = NSStringAttributeType;
-		gTypeMapping [@"varchar"]     = NSStringAttributeType;
-		gTypeMapping [@"bpchar"]      = NSStringAttributeType;
-		gTypeMapping [@"uuid"]        = NSStringAttributeType;
+		gTypeMapping [IdPtr (@"bit")]         = NSStringAttributeType;
+		gTypeMapping [IdPtr (@"bool")]        = NSBooleanAttributeType;
+		gTypeMapping [IdPtr (@"bytea")]       = NSBinaryDataAttributeType;
+		gTypeMapping [IdPtr (@"char")]        = NSStringAttributeType;
+		gTypeMapping [IdPtr (@"date")]        = NSDateAttributeType;
+		gTypeMapping [IdPtr (@"float4")]      = NSFloatAttributeType;
+		gTypeMapping [IdPtr (@"float8")]      = NSDoubleAttributeType;
+		gTypeMapping [IdPtr (@"int2")]        = NSInteger16AttributeType;
+		gTypeMapping [IdPtr (@"int4")]        = NSInteger32AttributeType;
+		gTypeMapping [IdPtr (@"int8")]        = NSInteger64AttributeType;
+		gTypeMapping [IdPtr (@"name")]        = NSStringAttributeType;
+		gTypeMapping [IdPtr (@"numeric")]     = NSDecimalAttributeType;
+		gTypeMapping [IdPtr (@"oid")]         = NSInteger32AttributeType;
+		gTypeMapping [IdPtr (@"text")]        = NSStringAttributeType;
+		gTypeMapping [IdPtr (@"timestamp")]   = NSDateAttributeType;
+		gTypeMapping [IdPtr (@"timestamptz")] = NSDateAttributeType;
+		gTypeMapping [IdPtr (@"time")]        = NSDateAttributeType;
+		gTypeMapping [IdPtr (@"timetz")]      = NSDateAttributeType;
+		gTypeMapping [IdPtr (@"varbit")]      = NSStringAttributeType;
+		gTypeMapping [IdPtr (@"varchar")]     = NSStringAttributeType;
+		gTypeMapping [IdPtr (@"bpchar")]      = NSStringAttributeType;
+		gTypeMapping [IdPtr (@"uuid")]        = NSStringAttributeType;
 		
 		gNameMapping = [[NSDictionary alloc] initWithObjectsAndKeys:
 						@"modelDescription", @"description",
 				[attr setName: [self sanitizedName: [bxAttr name]]];
 				[attr setOptional: [bxAttr isOptional]];
 				
-				IdentifierMap::const_iterator it = gTypeMapping.find ([bxAttr databaseTypeName]);
-				if (it != gTypeMapping.end ())
-					[attr setAttributeType: it->second];
-				else
-					[attr setAttributeType: NSUndefinedAttributeType];
+				NSAttributeType attributeType = NSUndefinedAttributeType;
+				FindElement (&gTypeMapping, [bxAttr databaseTypeName], &attributeType);
+				[attr setAttributeType: attributeType];
 				
 				NSDictionary* userInfo = [NSDictionary dictionaryWithObject: [bxAttr databaseTypeName] forKey: @"Database type"];
 				[attr setUserInfo: userInfo];

File Sources/BXHOM.h

 
 
 
-@interface NSSet (BXHOM) <BXHOM>
+@protocol BXSetHOM <BXHOM>
 - (id) BX_SelectFunction: (int (*)(id)) fptr;
 - (id) BX_SelectFunction: (int (*)(id, void*)) fptr argument: (void *) arg;
 @end
 
 
 
-@interface NSArray (BXHOM) <BXHOM>
+@protocol BXArrayHOM <BXHOM>
 - (NSArray *) BX_Reverse;
 - (id) BX_SelectFunction: (int (*)(id)) fptr;
 - (id) BX_SelectFunction: (int (*)(id, void*)) fptr argument: (void *) arg;
 
 
 
-@interface NSDictionary (BXHOM) <BXHOM>
+@protocol BXDictionaryHOM <BXHOM>
 /**
  * \internal
  * \brief Make a dictionary of objects collected from keys.
 - (id) BX_ValueSelectFunction: (int (*)(id)) fptr;
 - (id) BX_ValueSelectFunction: (int (*)(id, void*)) fptr argument: (void *) arg;
 @end
+
+
+
+@interface NSSet (BXHOM) <BXSetHOM>
+@end
+
+
+
+@interface NSArray (BXHOM) <BXArrayHOM>
+@end
+
+
+
+@interface NSDictionary (BXHOM) <BXDictionaryHOM>
+@end
+
+
+
+@interface NSHashTable (BXHOM) <BXSetHOM>
+@end
+
+
+
+@interface NSMapTable (BXHOM) <BXDictionaryHOM>
+@end

File Sources/BXHOM.m

 
 
 
+@implementation NSHashTable (BXHOM)
+- (void) _BX_Collect: (NSInvocation *) invocation userInfo: (Class) retclass
+{
+	id retval = [[[retclass alloc] initWithCapacity: [self count]] autorelease];
+	CollectAndPerform (self, retval, invocation, [self objectEnumerator]);
+}
+
+
+- (void) _BX_CollectD: (NSInvocation *) invocation userInfo: (id) ignored
+{
+	id retval = [[[NSMutableDictionary alloc] initWithCapacity: [self count]] autorelease];
+	CollectAndPerformD (self, retval, invocation, [self objectEnumerator]);
+}
+
+
+- (void) _BX_CollectDK: (NSInvocation *) invocation userInfo: (id) ignored
+{
+	id retval = [[[NSMutableDictionary alloc] initWithCapacity: [self count]] autorelease];
+	CollectAndPerformDK (self, retval, invocation, [self objectEnumerator]);
+}
+
+
+- (void) _BX_Do: (NSInvocation *) invocation userInfo: (id) anObject
+{
+	Do (invocation, [self objectEnumerator]);
+}
+
+
+- (void) _BX_Visit: (NSInvocation *) invocation userInfo: (id) userInfo
+{
+	Visit (invocation, [self objectEnumerator]);
+}
+
+
+- (id) BX_Any
+{
+	return [self anyObject];
+}
+
+
+- (id) BX_Collect
+{
+	return [self BX_CollectReturning: [NSMutableSet class]];
+}
+
+
+- (id) BX_CollectReturning: (Class) aClass
+{
+	return HOMTrampoline (self, @selector (_BX_Collect:userInfo:), aClass);
+}
+
+
+- (id) BX_CollectD
+{
+	return HOMTrampoline (self, @selector (_BX_CollectD:userInfo:), nil);
+}
+
+
+- (id) BX_CollectDK
+{
+	return HOMTrampoline (self, @selector (_BX_CollectDK:userInfo:), nil);
+}
+
+
+- (id) BX_SelectFunction: (int (*)(id)) fptr
+{
+	id retval = [NSMutableSet setWithCapacity: [self count]];
+	return SelectFunction (self, retval, fptr);
+}
+
+
+- (id) BX_SelectFunction: (int (*)(id, void*)) fptr argument: (void *) arg
+{
+	id retval = [NSMutableSet setWithCapacity: [self count]];
+	return SelectFunction2 (self, retval, fptr, arg);
+}
+
+
+- (id) BX_Do
+{
+	return HOMTrampoline (self, @selector (_BX_Do:userInfo:), nil);
+}
+
+
+- (id) BX_Visit: (id) visitor
+{
+	return VisitorTrampoline (self, visitor, @selector (_BX_Visit:userInfo:), nil);
+}
+@end
+
+
+
 @implementation NSArray (BXHOM)
 - (void) _BX_Collect: (NSInvocation *) invocation userInfo: (Class) retclass
 {
 	return SelectFunction2 (self, retval, fptr, arg);
 }
 @end
+
+
+
+@implementation NSMapTable (BXHOM)
+- (void) _BX_Collect: (NSInvocation *) invocation userInfo: (Class) retclass
+{
+	id retval = [[[retclass alloc] initWithCapacity: [self count]] autorelease];
+	CollectAndPerform (self, retval, invocation, [self objectEnumerator]);
+}
+
+
+- (void) _BX_CollectD: (NSInvocation *) invocation userInfo: (id) ignored
+{
+	id retval = [[[NSMutableDictionary alloc] initWithCapacity: [self count]] autorelease];
+	CollectAndPerformD (self, retval, invocation, [self objectEnumerator]);
+}
+
+
+- (void) _BX_CollectDK: (NSInvocation *) invocation userInfo: (id) ignored
+{
+	id retval = [[[NSMutableDictionary alloc] initWithCapacity: [self count]] autorelease];
+	CollectAndPerformDK (self, retval, invocation, [self objectEnumerator]);
+}
+
+
+- (void) _BX_KeyCollectD: (NSInvocation *) invocation userInfo: (id) ignored
+{
+	id retval = [[[NSMutableDictionary alloc] initWithCapacity: [self count]] autorelease];
+	BXEnumerate (currentKey, e, [self keyEnumerator])
+	{
+		id value = [self objectForKey: currentKey];
+		id newKey = nil;
+		[invocation invokeWithTarget: currentKey];
+		[invocation getReturnValue: &newKey];
+		if (newKey)
+			[retval setObject: value forKey: newKey];
+	}
+	retval = [[retval copy] autorelease];
+	[invocation setReturnValue: &retval];
+}
+
+
+- (void) _BX_Do: (NSInvocation *) invocation userInfo: (id) userInfo
+{
+	Do (invocation, [self objectEnumerator]);
+}
+
+
+- (void) _BX_Visit: (NSInvocation *) invocation userInfo: (id) userInfo
+{
+	Visit (invocation, [self objectEnumerator]);
+}
+
+
+- (id) BX_Any
+{
+	return [[self objectEnumerator] nextObject];
+}
+
+
+- (id) BX_Collect
+{
+	return [self BX_CollectReturning: [NSMutableArray class]];
+}
+
+
+- (id) BX_CollectReturning: (Class) aClass
+{
+	return HOMTrampoline (self, @selector (_BX_Collect:userInfo:), aClass);
+}
+
+
+- (id) BX_CollectD
+{
+	return HOMTrampoline (self, @selector (_BX_CollectD:userInfo:), nil);
+}
+
+
+- (id) BX_CollectDK
+{
+	return HOMTrampoline (self, @selector (_BX_CollectDK:userInfo:), nil);
+}
+
+
+- (id) BX_KeyCollectD
+{
+	return KeyTrampoline (self, @selector (_BX_KeyCollectD:userInfo:), nil);
+}
+
+
+- (id) BX_Do
+{
+	return HOMTrampoline (self, @selector (_BX_Do:userInfo:), nil);
+}
+
+
+- (id) BX_Visit: (id) visitor
+{
+	return VisitorTrampoline (self, visitor, @selector (_BX_Visit:userInfo:), nil);
+}
+
+
+- (id) BX_ValueSelectFunction: (int (*)(id)) fptr
+{
+	id retval = [NSMutableArray arrayWithCapacity: [self count]];
+	return SelectFunction (self, retval, fptr);
+}
+
+
+- (id) BX_ValueSelectFunction: (int (*)(id, void*)) fptr argument: (void *) arg
+{
+	id retval = [NSMutableArray arrayWithCapacity: [self count]];
+	return SelectFunction2 (self, retval, fptr, arg);
+}
+@end

File Sources/BXObjCPair.h

+//
+// BXObjCPair.h
+// BaseTen
+//
+// Copyright (C) 2008-2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+#import <Foundation/Foundation.h>
+
+
+#if defined(__cplusplus)
+#import <BaseTen/BXObjCPtr.h>
+
+namespace BaseTen
+{
+	template <typename T, typename U>
+	struct ObjCPair
+	{
+		ObjCPtr <T> first;
+		ObjCPtr <U> second;
+		
+		explicit ObjCPair (T a, U b):
+			first (a), second (b) {}
+		
+		ObjCPair (const ObjCPair& p):
+			first (* p.first), second (* p.second) {}
+		
+		bool operator== (const ObjCPair <T, U> &other) const
+		{
+			return (first == other.first && second == other.second);
+		}		
+	};	
+}
+
+
+namespace std {
+	
+	namespace tr1 {
+		
+		template <typename T, typename U>
+		struct hash <BaseTen::ObjCPair <T, U> > {
+			
+			std::size_t
+			operator() (BaseTen::ObjCPair <T, U> const &val) const
+			{
+				return (val.first.hash () ^ val.second.hash ());
+			}
+		};
+	}
+}
+#endif

File Sources/BXObjCPtr.h

+//
+// BXObjCPtr.h
+// BaseTen
+//
+// Copyright (C) 2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://basetenframework.org/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+#import <Foundation/Foundation.h>
+
+
+#if defined(__cplusplus)
+#import <cstddef>
+#import <tr1/functional>
+
+
+namespace BaseTen {
+	
+	class ObjCPtrBase {
+		
+	protected:
+		__strong id mPtr;
+		
+	private:
+		ObjCPtrBase (ObjCPtrBase const &);
+		ObjCPtrBase &operator= (ObjCPtrBase const &);
+		
+	public:
+		explicit ObjCPtrBase (): mPtr (nil) {}
+		~ObjCPtrBase () { assign (nil); }
+		
+		void assign (id ptr);
+		
+		std::size_t hash () const { return [mPtr hash]; }
+	};
+	
+
+	template <typename T>
+	class ObjCPtr : public ObjCPtrBase {
+		
+	private:
+		ObjCPtr &operator= (ObjCPtr const &);
+		
+	public:
+		typedef T element_type;
+		
+		explicit ObjCPtr (T ptr = nil) { assign (ptr); }
+		ObjCPtr (ObjCPtr const &other) { assign (other.mPtr); }
+		T operator() () const { return mPtr; }
+		T operator*  () const { return mPtr; }
+		
+		bool operator== (ObjCPtr <T> const &other) const { 
+			std::equal_to <T> eq;
+			return (mPtr == other.mPtr || eq (mPtr, other.mPtr));
+		}
+	};
+}
+
+
+
+namespace std {
+	
+	template <>
+    struct equal_to <NSString *>
+    {
+		bool
+		operator() (NSString const * const &a, NSString const * const &b) const
+		{
+			return [a isEqualToString: b];
+		}
+    };
+	
+	
+	template <>
+	struct equal_to <id>
+	{
+		bool
+		operator() (id const &a, id const &b) const
+		{
+			return [a isEqual: b];
+		}
+	};
+	
+	
+	
+	namespace tr1 {
+		
+		template <typename T>
+		struct hash <BaseTen::ObjCPtr <T> > {
+			
+			std::size_t
+			operator() (const BaseTen::ObjCPtr <T> &val) const
+			{
+				return val.hash ();
+			}
+		};
+	}
+}
+#endif

File Sources/BXObjCPtr.mm

+//
+// BXObjCPtr.mm
+// BaseTen
+//
+// Copyright (C) 2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://basetenframework.org/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+#import "BXObjCPtr.h"
+#import "BXScannedMemoryAllocator.h"
+#import <objc/objc-auto.h>
+
+
+void
+BaseTen::ObjCPtrBase::assign (id ptr)
+{
+	if (BaseTen::ScannedMemoryAllocatorBase::collection_enabled)
+	{
+		// To make sure we manually set the write barrier.
+		objc_assign_strongCast (ptr, &mPtr);
+	}
+	else
+	{
+		// Use RR instead.
+		if (mPtr != ptr)
+		{
+			[mPtr release];
+			mPtr = [ptr retain];
+		}
+	}
+}

File Sources/BXPGDatabaseDescription.h

 
 #import <Foundation/Foundation.h>
 #import <BaseTen/PGTSDatabaseDescription.h>
-#import <BaseTen/PGTSCollections.h>
+#import <BaseTen/BXCollections.h>
 
 
 @class BXPGForeignKeyDescription;
 
 
-#if defined(__cplusplus)
-#import <BaseTen/PGTSScannedMemoryAllocator.h>
-#import <tr1/unordered_map>
-namespace PGTS 
-{
-	typedef std::tr1::unordered_map <NSInteger, id, 
-		std::tr1::hash <NSInteger>, 
-		std::equal_to <NSInteger>, 
-		PGTS::scanned_memory_allocator <std::pair <const NSInteger, id> > > 
-		IdentifierMap;	
-}
-#define PGTS_IdentifierMap PGTS::IdentifierMap
-
-#else
-#define PGTS_IdentifierMap void
-#endif
-
-
 @interface BXPGDatabaseDescription : PGTSDatabaseDescription
 {
 	NSNumber* mSchemaVersion;
 	NSNumber* mSchemaCompatibilityVersion;
 	BOOL mHasBaseTenSchema;
-	PGTS_IdentifierMap* mForeignKeysByIdentifier;
+	BX_IndexMap* mForeignKeysByIdentifier;
 }
 - (BOOL) hasBaseTenSchema;
 - (NSNumber *) schemaVersion;

File Sources/BXPGDatabaseDescription.m

 #import "PGTSResultSet.h"
 #import "BXPGTableDescription.h"
 #import "BXPGForeignKeyDescription.h"
+#import "BXCollectionFunctions.h"
 
-namespace PGTS 
-{
-	void InsertConditionally (IdentifierMap* map, BXPGForeignKeyDescription* description);
-}
 
-void PGTS::InsertConditionally (IdentifierMap* map, BXPGForeignKeyDescription* description)
-{
-	NSInteger identifier = [description identifier];
-	if (! (* map) [identifier])
-		(* map) [identifier] = [description retain];	
-}
+using namespace BaseTen::CollectionFunctions;
 
 
-using namespace PGTS;
-
 @implementation BXPGDatabaseDescription
 - (id) init
 {
 	if ((self = [super init]))
 	{
-		mForeignKeysByIdentifier = new IdentifierMap ();
+		mForeignKeysByIdentifier = new BaseTen::IndexMap ();
 	}
 	return self;
 }
 {
 	[mSchemaVersion release];
 	[mSchemaCompatibilityVersion release];
-	for (IdentifierMap::const_iterator it = mForeignKeysByIdentifier->begin (), end = mForeignKeysByIdentifier->end (); 
-		 it != end; it++)
-	{
-		[it->second release];
-	}
-	
 	delete mForeignKeysByIdentifier;
 	[super dealloc];
 }
 
-- (void) finalize
-{
-	delete mForeignKeysByIdentifier;
-	[super finalize];
-}
-
 - (BOOL) hasBaseTenSchema
 {
 	return mHasBaseTenSchema;
 
 - (void) addForeignKey: (BXPGForeignKeyDescription *) fkey
 {
-	InsertConditionally (mForeignKeysByIdentifier, fkey);
+	InsertConditionally (mForeignKeysByIdentifier, [fkey identifier], fkey);
 }
 
 - (BXPGForeignKeyDescription *) foreignKeyWithIdentifier: (NSInteger) identifier

File Sources/BXPGForeignKeyDescription.h

 @interface BXPGForeignKeyDescription : PGTSAbstractDescription <BXForeignKey>
 {
 	NSInteger mIdentifier;
-	PGTS_RetainingIdPairSet* mFieldNames;
+	BX_IdPairSet* mFieldNames;
 	pthread_rwlock_t mFieldNameLock;
 	NSDeleteRule mDeleteRule;
 }

File Sources/BXPGForeignKeyDescription.mm

 
 #import "BXPGForeignKeyDescription.h"
 #import "BXLogger.h"
+#import "BXCollections.h"
+#import "BXCollectionFunctions.h"
 #import <iterator>
 
 
-using namespace PGTS;
+using namespace BaseTen;
+using namespace BaseTen::CollectionFunctions;
 
 
 @implementation BXPGForeignKeyDescription
 {
 	if ((self = [super init]))
 	{
-		mFieldNames = new RetainingIdPairSet ();
+		mFieldNames = new IdPairSet ();
 		Expect (0 == pthread_rwlock_init (&mFieldNameLock, NULL));
 	}
 	return self;
 
 - (void) finalize
 {
-	delete mFieldNames;
 	pthread_rwlock_destroy (&mFieldNameLock);
 	[super finalize];
 }
 - (void) addSrcFieldName: (NSString *) srcFName dstFieldName: (NSString *) dstFName
 {
 	pthread_rwlock_wrlock (&mFieldNameLock);
-	mFieldNames->insert (RetainingIdPair (srcFName, dstFName));
+	mFieldNames->insert (IdPair (srcFName, dstFName));
 	pthread_rwlock_unlock (&mFieldNameLock);
 }
 
 - (void) iterateColumnNames: (void (*)(NSString* srcName, NSString* dstName, void* context)) callback context: (void *) context
 {
 	pthread_rwlock_rdlock (&mFieldNameLock);
-	for (RetainingIdPairSet::const_iterator it = mFieldNames->begin (), end = mFieldNames->end ();
+	for (IdPairSet::const_iterator it = mFieldNames->begin (), end = mFieldNames->end ();
 		 it != end; it++)
 	{
-		callback (it->first, it->second, context);
+		callback (*it->first, *it->second, context);
 	}
 	pthread_rwlock_unlock (&mFieldNameLock);
 }
 - (void) iterateReversedColumnNames: (void (*)(NSString* dstName, NSString* srcName, void* context)) callback context: (void *) context
 {
 	pthread_rwlock_rdlock (&mFieldNameLock);
-	for (RetainingIdPairSet::const_iterator it = mFieldNames->begin (), end = mFieldNames->end ();
+	for (IdPairSet::const_iterator it = mFieldNames->begin (), end = mFieldNames->end ();
 		 it != end; it++)
 	{
-		callback (it->second, it->first, context);
+		callback (*it->second, *it->first, context);
 	}
 	pthread_rwlock_unlock (&mFieldNameLock);
 }

File Sources/BXPGLockHandler.mm

 #import "BXDatabaseObjectIDPrivate.h"
 #import "BXLogger.h"
 #import "PGTSAdditions.h"
-#import "PGTSScannedMemoryAllocator.h"
+#import "BXScannedMemoryAllocator.h"
+#import "BXScannedMemoryObject.h"
 #import "PGTSOids.h"
 #import <tr1/unordered_map>
 
 
-struct lock_st 
-{
-	__strong NSMutableArray* l_for_update;
-	__strong NSMutableArray* l_for_delete;
+struct lock_st : public BaseTen::ScannedMemoryObject {
+	__strong NSMutableArray *l_for_update;
+	__strong NSMutableArray *l_for_delete;
 };
+
 typedef std::tr1::unordered_map <long, lock_st, 
 	std::tr1::hash <long>, 
 	std::equal_to <long>, 
-	PGTS::scanned_memory_allocator <std::pair <const long, lock_st> > > 
+	BaseTen::ScannedMemoryAllocator <std::pair <const long, lock_st> > > 
 	LockMap;
 
 
 			[self setLastCheck: [res valueForKey: @"baseten_lock_timestamp"]];
 		
 		//Sort the locks by relation.
-		LockMap* locks = new LockMap ([res count]);
+		LockMap locks ([res count]);
 		while ([res advanceRow])
 		{
 			NSDictionary* row = [res currentRowAsDictionary];
 			unichar lockType = [[row valueForKey: @"baseten_lock_query_type"] characterAtIndex: 0];
 			long relid = [[row valueForKey: @"baseten_lock_relid"] longValue];
 			
-			struct lock_st ls = (* locks) [relid];
+			struct lock_st ls = locks [relid];
 			
 			NSMutableArray* ids = nil;
 			switch (lockType) 
 		}
 		
 		//Send changes.
-		LockMap::const_iterator iterator = locks->begin ();
+		LockMap::const_iterator iterator = locks.begin ();
 		BXDatabaseContext* ctx = [mInterface databaseContext];
-		while (locks->end () != iterator)
+		while (locks.end () != iterator)
 		{
 			lock_st ls = iterator->second;
 			if (ls.l_for_update) [ctx lockedObjectsInDatabase: ls.l_for_update status: kBXObjectLockedStatus];
 			if (ls.l_for_delete) [ctx lockedObjectsInDatabase: ls.l_for_delete status: kBXObjectDeletedStatus];
 		}
-		
-		delete locks;
 	}
 }
 @end

File Sources/BXPGModificationHandler.mm

 #import "BXPGModificationHandler.h"
 #import "BXEntityDescriptionPrivate.h"
 #import "BXDatabaseObjectIDPrivate.h"
-#import "PGTSScannedMemoryAllocator.h"
+#import "BXScannedMemoryAllocator.h"
 #import "BXHOM.h"
 #import "BXEnumerate.h"
 #import <tr1/unordered_map>
 typedef std::tr1::unordered_map <unichar, NSMutableArray*,
 	std::tr1::hash <unichar>,
 	std::equal_to <unichar>,
-	PGTS::scanned_memory_allocator <std::pair <const unichar, NSMutableArray*> > > 
-	ChangeMap;
+	BaseTen::ScannedMemoryAllocator <std::pair <
+		const unichar, BaseTen::ObjCPtr <NSMutableArray *>
+	> > 
+> ChangeMap;
 
 
 @interface PGTSColumnDescription (BXPGModificationHandlerAdditions)
 		[self setLastCheck: [res valueForKey: @"baseten_modification_timestamp"]];
 	
 	//Sort the changes by type.
-	ChangeMap* changes = new ChangeMap (3);
+	ChangeMap changes = ChangeMap (3);
 	NSMutableArray *changedAttrs = [NSMutableArray arrayWithCapacity: [res count]];
 	[res goBeforeFirstRow];
     while ([res advanceRow])
     {
 		unichar modificationType = [[res valueForKey: @"baseten_modification_type"] characterAtIndex: 0];                            
-		NSMutableArray* objectIDs = (* changes) [modificationType];
+		NSMutableArray *objectIDs = changes [modificationType];
 		if (! objectIDs)
 		{
 			objectIDs = [NSMutableArray arrayWithCapacity: [res count]];
-			(* changes) [modificationType] = objectIDs;
+			changes [modificationType] = objectIDs;
 		}
 		
 		BXDatabaseObjectID* objectID = [BXDatabaseObjectID IDWithEntity: mEntity primaryKeyFields: [res currentRowAsDictionary]];
 	}
 	
 	//Send changes.
-	ChangeMap::const_iterator iterator = changes->begin ();
-    while (changes->end () != iterator)
+	ChangeMap::const_iterator iterator = changes.begin ();
+    while (changes.end () != iterator)
     {
 		unichar type = iterator->first;
 		NSArray* objectIDs = iterator->second;
 				break;
 		}
         iterator++;
-    }
-	
-	//Contents have already been autoreleased.
-	delete changes;
+    }	
 }
 
 - (void) setIdentifier: (NSInteger) identifier

File Sources/BXScannedMemoryAllocator.h

+//
+// BXScannedMemoryAllocator.h
+// BaseTen
+//
+// Copyright (C) 2008-2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+
+#import <Foundation/Foundation.h>
+#import <objc/objc-auto.h>
+#import <new>
+#import <limits>
+
+
+namespace BaseTen {
+	class ScannedMemoryAllocatorBase {
+	public:
+		static BOOL collection_enabled;
+		static void *allocate (size_t);
+		static void deallocate (void *);
+	};	
+	
+	
+	template <typename T> 
+	class ScannedMemoryAllocator : private ScannedMemoryAllocatorBase {
+		
+	public:		
+		typedef T                 value_type;
+		typedef value_type*       pointer;
+		typedef const value_type* const_pointer;
+		typedef value_type&       reference;
+		typedef const value_type& const_reference;
+		typedef std::size_t       size_type;
+		typedef std::ptrdiff_t    difference_type;
+		
+		template <typename U> struct rebind { typedef ScannedMemoryAllocator <U> other; };
+		
+		explicit ScannedMemoryAllocator () {}
+		ScannedMemoryAllocator (const ScannedMemoryAllocator&) {}
+		
+		template <typename U> ScannedMemoryAllocator (const ScannedMemoryAllocator <U> &) {}
+		~ScannedMemoryAllocator () {}
+		
+		pointer address (reference x) const { return &x; }
+		const_pointer address (const_reference x) const { return x; }
+		
+		pointer allocate (size_type n, const_pointer = 0) 
+		{
+			return static_cast <pointer> (ScannedMemoryAllocatorBase::allocate (n * sizeof (T)));
+		}
+		
+		void deallocate (pointer p, size_type n) 
+		{
+			ScannedMemoryAllocatorBase::deallocate (p);
+		}
+		
+		size_type max_size () const 
+		{
+			return std::numeric_limits <size_type>::max () / sizeof (T);
+		}
+		
+		void construct (pointer p, const value_type& x) 
+		{ 
+			new (p) value_type (x); 
+		}
+		
+		void destroy (pointer p) 
+		{ 
+			p->~value_type (); 
+		}
+		
+	private:
+		void operator= (const ScannedMemoryAllocator&);
+	};
+	
+	
+	template <> class ScannedMemoryAllocator <void>
+	{
+	public:
+		typedef void			value_type;
+		typedef void*			pointer;
+		typedef const void*		const_pointer;
+		typedef std::size_t		size_type;
+		typedef std::ptrdiff_t	difference_type;
+		
+		template <typename U> 
+		struct rebind { typedef ScannedMemoryAllocator <U> other; };
+		
+		void *allocate (size_type n, const_pointer = 0)
+		{
+			return ScannedMemoryAllocatorBase::allocate (n);
+		}
+		
+		void deallocate (pointer p, size_type = 0)
+		{
+			ScannedMemoryAllocatorBase::deallocate (p);
+		}		
+	};
+	
+	
+	template <typename T> inline bool 
+	operator== (const ScannedMemoryAllocator <T> &, const ScannedMemoryAllocator <T> &)
+	{
+		return true;
+	}
+	
+	
+	template <typename T> inline bool 
+	operator!= (const ScannedMemoryAllocator <T> &, const ScannedMemoryAllocator <T> &) 
+	{
+		return false;
+	}
+}

File Sources/BXScannedMemoryAllocator.mm

+//
+// BXScannedMemoryAllocator.mm
+// BaseTen
+//
+// Copyright (C) 2008-2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+#import "BXScannedMemoryAllocator.h"
+
+
+static BOOL 
+IsCollectionEnabled ()
+{
+	BOOL retval = NO;
+    //Symbol existence verification requires NULL != -like comparison.
+	if (NULL != NSAllocateCollectable && [NSGarbageCollector defaultCollector])
+		retval = YES;
+	return retval;
+}
+
+BOOL BaseTen::ScannedMemoryAllocatorBase::collection_enabled = IsCollectionEnabled ();
+
+
+void *
+BaseTen::ScannedMemoryAllocatorBase::allocate (size_t size)
+{
+	void *retval = NULL;
+	
+#if defined (OBJC_NO_GC)
+	retval = malloc (size);
+#else
+	if (BaseTen::ScannedMemoryAllocatorBase::collection_enabled)
+		retval = NSAllocateCollectable (size, NSScannedOption);
+	else
+		retval = malloc (size);
+#endif
+	
+	if (! retval)
+		throw std::bad_alloc ();
+	
+	return retval;
+}
+
+
+void
+BaseTen::ScannedMemoryAllocatorBase::deallocate (void *ptr)
+{
+#if defined (OBJC_NO_GC)
+	free (ptr);
+#else
+	if (! BaseTen::ScannedMemoryAllocatorBase::collection_enabled)
+		free (ptr);
+#endif
+}

File Sources/BXScannedMemoryObject.h

+//
+// BXScannedMemoryObject.h
+// BaseTen
+//
+// Copyright (C) 2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+
+#import <BaseTen/BXScannedMemoryAllocator.h>
+
+
+namespace BaseTen {
+	
+	class ScannedMemoryObject {
+	public:
+		void *operator new (size_t);
+		void  operator delete (void *);
+	};
+}

File Sources/BXScannedMemoryObject.mm

+//
+// BXScannedMemoryObject.mm
+// BaseTen
+//
+// Copyright (C) 2010 Marko Karppinen & Co. LLC.
+//
+// Before using this software, please review the available licensing options
+// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
+// us at sales@karppinen.fi. Without an additional license, this software
+// may be distributed only in compliance with the GNU General Public License.
+//
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 2.0,
+// as published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+// $Id$
+//
+
+#import "BXScannedMemoryObject.h"
+
+
+void *
+BaseTen::ScannedMemoryObject::operator new (size_t size)
+{
+	BaseTen::ScannedMemoryAllocator <void> allocator;
+	return allocator.allocate (size);
+}
+
+
+void
+BaseTen::ScannedMemoryObject::operator delete (void *ptr)
+{
+	BaseTen::ScannedMemoryAllocator <void> allocator;
+	allocator.deallocate (ptr);
+}

File Sources/PGTSAbstractClassDescription.mm

 #import "PGTSAbstractClassDescription.h"
 #import "PGTSACLItem.h"
 #import "PGTSRoleDescription.h"
+#import "BXCollectionFunctions.h"
 #import "BXEnumerate.h"
 #import "BXLogger.h"
 
 
 using namespace PGTS;
+using namespace BaseTen::CollectionFunctions;
 
 
 /** 
 
 - (void) dealloc
 {
-	for (OidMap::const_iterator it = mACLItemsByRoleOid->begin (); mACLItemsByRoleOid->end () != it; it++)
-		[it->second release];
-	
 	delete mACLItemsByRoleOid;
-
     [super dealloc];
 }
 
-- (void) finalize
-{
-	delete mACLItemsByRoleOid;	
-    [super finalize];
-}
 
 - (void) setACL: (NSArray *) ACL
 {
 		[self addACLItem: currentItem];
 }
 
+
 - (void) addACLItem: (PGTSACLItem *) item
 {
 	ExpectV (item);
 	Oid oid = [[item role] oid];
-	if (! (* mACLItemsByRoleOid) [oid])
-		(* mACLItemsByRoleOid) [oid] = [item retain];
+	if (! ContainsKey (mACLItemsByRoleOid, oid))
+		mACLItemsByRoleOid->insert (std::make_pair (oid, item));
 }
 
 - (char) kind
     //The owner has all the privileges.
     BOOL retval = (mOwner == aRole || [mOwner isEqual: aRole]);
     if (! retval)
-        (0 != (aPrivilege & [FindObject (mACLItemsByRoleOid, [aRole oid]) privileges]));
+	{
+		PGTSACLItem *item = FindObject (mACLItemsByRoleOid, [aRole oid]);
+        retval = (0 != (aPrivilege & [item privileges]));
+	}
+	
     if (! retval)
+	{
         retval = (0 != (aPrivilege & [FindObject (mACLItemsByRoleOid, kPGTSPUBLICOid) privileges]));
+	}
+	
     if (! retval)
     {
 		for (OidMap::const_iterator it = mACLItemsByRoleOid->begin (); mACLItemsByRoleOid->end () != it; it++)
 		{
-            if (aPrivilege & [it->second privileges] && [[it->second role] hasMember: aRole])
+            if (aPrivilege & [*it->second privileges] && [[*it->second role] hasMember: aRole])
             {
                 retval = YES;
                 break;

File Sources/PGTSAbstractDescription.h

 
 
 #if defined (__cplusplus)
-#import <BaseTen/PGTSCollections.h>
+#import <BaseTen/BXCollections.h>
 #import <BaseTen/PGTSOids.h>
 namespace PGTS 
 {
-	//FIXME: this isn't very good but apparently partial function template specialization isn't easy.
-	template <typename T> NSMutableDictionary*
-	CreateCFMutableDictionaryWithNames (T *map)
+	template <typename T> 
+	NSMutableDictionary *CreateCFMutableDictionaryWithNames (T *map)
 	{
 		NSMutableDictionary* retval = [[NSMutableDictionary alloc] initWithCapacity: map->size ()];
 		for (typename T::const_iterator it = map->begin (), end = map->end (); end != it; it++)
 		{
-			id currentObject = it->second;
+			typename T::mapped_type::element_type currentObject = *it->second;
 			[retval setObject: currentObject forKey: [currentObject name]];
 		}
 		
 		return retval;				
 	}
-	
-	void InsertConditionally (IdMap* map, PGTSAbstractDescription* description);
 }
 #endif

File Sources/PGTSAbstractDescription.mm

 #import "PGTSAbstractDescription.h"
 
 
-void 
-PGTS::InsertConditionally (IdMap* map, PGTSAbstractDescription* description)
-{
-	NSString* name = [description name];
-	if (! (* map) [name])
-		(* map) [[name retain]] = [description retain];
-}
-
-
 /** 
  * \internal
  * \brief Abstract base class.

File Sources/PGTSAbstractObjectDescription.h

 @class PGTSAbstractObjectDescription;
 
 
-#if defined (__cplusplus)
-namespace PGTS 
-{
-	void InsertConditionally (OidMap* map, PGTSAbstractObjectDescription* description);
-}
-#endif
-
-
 @interface PGTSAbstractObjectDescription : PGTSAbstractDescription 
 {
     Oid mOid;

File Sources/PGTSAbstractObjectDescription.mm

 #import "PGTSAbstractObjectDescription.h"
 
 
-void PGTS::InsertConditionally (OidMap* map, PGTSAbstractObjectDescription* description)
-{
-	Oid oid = [description oid];
-	if (! (* map) [oid])
-		(* map) [oid] = [description retain];	
-}
-
-
 @implementation PGTSAbstractObjectDescription
 - (id) init
 {

File Sources/PGTSCollections.h

-//
-// PGTSCollections.h
-// BaseTen
-//
-// Copyright (C) 2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://www.karppinen.fi/baseten/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program 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 General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <Foundation/Foundation.h>
-#import <BaseTen/BXExport.h>
-
-
-#if defined(__cplusplus)
-#import <BaseTen/PGTSScannedMemoryAllocator.h>
-#import <list>
-#import <tr1/unordered_set>
-#import <tr1/unordered_map>
-namespace PGTS 
-{
-	struct ObjectHash
-	{
-		size_t operator() (const id anObject) const { return [anObject hash]; }
-	};
-	
-	template <typename T>
-	struct ObjectCompare
-	{
-		bool operator() (const T x, const T y) const { return ([x isEqual: y] ? true : false); }
-	};
-	
-	template <>
-	struct ObjectCompare <NSString *>
-	{
-		bool operator() (const NSString* x, const NSString* y) const { return ([x isEqualToString: y] ? true : false); }
-	};
-	
-	template <typename T>
-	id FindObject (T *container, typename T::key_type key)
-	{
-		id retval = nil;
-		if (container)
-		{
-			typename T::const_iterator it = container->find (key);
-			if (container->end () != it)
-				retval = it->second;
-		}
-		return retval;
-	}
-	
-	struct RetainingIdPair
-	{
-		id first;
-		id second;
-		
-		explicit RetainingIdPair (id a, id b)
-		: first ([a retain]), second ([b retain]) {}
-		
-		RetainingIdPair (const RetainingIdPair& p)
-		: first ([p.first retain]), second ([p.second retain]) {}
-		
-		~RetainingIdPair ()
-		{
-			[first release];
-			[second release];
-		}
-						
-		struct Hash 
-		{
-			size_t operator() (const RetainingIdPair& p) const { return ([p.first hash] ^ [p.second hash]); }
-		};
-	};
-	
-	inline bool operator== (const RetainingIdPair& a, const RetainingIdPair& b)
-	{
-		return ([a.first isEqual: b.first] && [a.second isEqual: b.second]);
-	}	
-	
-	typedef std::list <id, PGTS::scanned_memory_allocator <id> > IdList;
-	
-	typedef std::tr1::unordered_set  <RetainingIdPair,
-		RetainingIdPair::Hash,
-		std::equal_to <RetainingIdPair>,
-		PGTS::scanned_memory_allocator <RetainingIdPair> >
-		RetainingIdPairSet;
-	
-	typedef std::tr1::unordered_map <id, id, 
-		PGTS::ObjectHash, 
-		PGTS::ObjectCompare <id>, 
-		PGTS::scanned_memory_allocator <std::pair <const id, id> > >
-		IdMap;
-	
-	typedef std::tr1::unordered_map <NSInteger, id, 
-		std::tr1::hash <NSInteger>, 
-		std::equal_to <NSInteger>, 
-		PGTS::scanned_memory_allocator <std::pair <const NSInteger, id> > > 
-		IndexMap;	
-}
-
-#define PGTS_IdList PGTS::IdList
-#define PGTS_IdMap PGTS::IdMap
-#define PGTS_IndexMap PGTS::IndexMap
-#define PGTS_RetainingIdPairSet PGTS::RetainingIdPairSet
-
-#else
-#define PGTS_IdList void
-#define PGTS_IdMap void
-#define PGTS_IndexMap void
-#define PGTS_RetainingIdPairSet void
-#endif

File Sources/PGTSDatabaseDescription.h

 #import <BaseTen/libpq-fe.h>
 #import <BaseTen/PGTSAbstractDescription.h>
 #import <BaseTen/PGTSOids.h>
-#import <BaseTen/PGTSCollections.h>
+#import <BaseTen/BXCollections.h>
 
 @class PGTSSchemaDescription;
 @class PGTSTableDescription;

File Sources/PGTSDatabaseDescription.mm

 
 #import "PGTSDatabaseDescription.h"
 #import "PGTSOids.h"
-#import "PGTSScannedMemoryAllocator.h"
+#import "BXScannedMemoryAllocator.h"
 #import "PGTSAbstractDescription.h"
 #import "PGTSAbstractObjectDescription.h"
 #import "PGTSTableDescription.h"
 #import "PGTSSchemaDescription.h"
 #import "PGTSTypeDescription.h"
 #import "PGTSRoleDescription.h"
-#import "PGTSCollections.h"
+#import "BXCollections.h"
 #import "BXLogger.h"
 #import "BXArraySize.h"
+#import "BXCollectionFunctions.h"
 
 
 using namespace PGTS;
+using namespace BaseTen::CollectionFunctions;
 
 
 static NSArray*
 
 - (void) dealloc
 {
-	OidMap* maps [] = {mSchemasByOid, mTablesByOid, mTypesByOid, mRolesByOid};
-	for (int i = 0, count = BXArraySize (maps); i < count; i++)
-	{
-		OidMap::const_iterator iterator = maps [i]->begin ();
-		while (maps [i]->end () != iterator)
-		{
-			[iterator->second autorelease];
-			iterator++;
-		}
-		delete maps [i];
-	}
+	delete mSchemasByOid;
+	delete mTablesByOid;
+	delete mTypesByOid;
+	delete mRolesByOid;
 	
 	[mSchemasByName release];
 	[mRolesByName release];
 }
 
 
-- (void) finalize
-{
-	delete mSchemasByOid;
-	delete mTablesByOid;
-	delete mTypesByOid;
-	delete mRolesByOid;
-	[super finalize];
-}
-
-
 - (id) init
 {
 	if ((self = [super init]))
 - (void) addTable: (PGTSTableDescription *) table
 {
 	ExpectV (table);
-	InsertConditionally (mTablesByOid, table);
+	InsertConditionally (mTablesByOid, [table oid], table);
 	
 	PGTSSchemaDescription* schema = [table schema];
 	ExpectV (schema);
 		mSchemasByName = nil;
 	}
 	[mSchemaLock unlock];
-	InsertConditionally (mSchemasByOid, schema);
+	InsertConditionally (mSchemasByOid, [schema oid], schema);
 }
 
 
 - (void) addType: (PGTSTypeDescription *) type
 {
 	ExpectV (type);
-	InsertConditionally (mTypesByOid, type);
+	InsertConditionally (mTypesByOid, [type oid], type);
 }
 
 
 		mRolesByName = nil;
 	}	
 	[mRoleLock unlock];
-	InsertConditionally (mRolesByOid, role);
+	InsertConditionally (mRolesByOid, [role oid], role);
 }
 
 

File Sources/PGTSOids.h