//
// $Id: Memory.h,v 1.16 2005/07/12 19:15:37 will_mason Exp $
//
// vi: set ft=objc:

/*
 * ObjectiveLib - a library of containers and algorithms for Objective-C
 *
 * Copyright (c) 2004
 * Will Mason
 *
 * Portions:
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Copyright (c) 1996,1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Copyright (c) 1997
 * Moscow Center for SPARC Technology
 *
 * Copyright (c) 1999 
 * Boris Fomitchev
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * You may contact the author at will_mason@users.sourceforge.net.
 */

#if !defined(MEMORY_OL_GUARD)
#define MEMORY_OL_GUARD

#import <ObjectiveLib/Config.h>
#import <Foundation/NSObject.h>

/**
 * @class OLAllocator Memory.h ObjectiveLib/Memory.h
 *
 * A class for allocating memory. Allocators are used internally by all
 * functions in ObjectiveLib that allocate memory. The goal is to provide
 * control over how memory that the user does not actually allocate herself
 * gets allocated. In the simplest case, if one wishes to create a container
 * that allocates all of its memory in a shared memory space, one simply
 * creates the shared memory allocator and passes it to the container class.
 * From then on all allocations performed by the container, whether public
 * or private, will be done in the shared memory space.
 *
 * The default allocator uses the default zone allocator if the platform
 * has one, or malloc otherwise.
 */
@interface OLAllocator : NSObject
{
}

/**
 * Initialize the OLAllocator class before it is used. The default allocator is
 * merely set to an allocator that makes use of the NSZone returned by
 * NSDefaultMallocZone().
 */
+ (void) initialize;

/**
 * Return the default memory allocator. The default allocator uses the default
 * zone allocator is the platform has one, or malloc otherwise.
 *
 * @return the default allocator
 */
+ (OLAllocator*) defaultAllocator;

/**
 * Set the default allocator. Use this message to change the default allocator
 * to one of your choosing. This will not change the allocator already assigned
 * for use in the system, so this message should be used first if you want to
 * ensure that the old default allocator is never used.
 *
 * @param allocator the new allocator to use as the default
 */
+ (void) setDefaultAllocator: (OLAllocator*)allocator;

/**
 * Allocate a number of bytes. The bytes are allocated and a pointer to them is
 * returned.
 *
 * @param count the number of bytes to allocate
 * @return a pointer to the allocated bytes
 */
- (void*) allocateBytes: (unsigned)count;

/**
 * Allocate memory for an object of the given class. This message should be used prior
 * to initializing the object. Upon return the memory allocated for the object will
 * be set to zero, except the @c isa pointer, which will point to the class of the
 * object.
 *
 * @param cls the class for which to allocate an object
 * @return a newly forged object ready for initialization
 */
- (id) allocateObject: (Class)cls;

/**
 * Schedule @a object to be released later. If this allocator supports autoreleasing,
 * then the object will be queued for release. If not, then this message does nothing.
 * The default allocator does support autorelease if the Apple Cocoa framework is being
 * used.
 *
 * @param object the object to schedule for release
 * @return a reference to @a object
 */
- (id) autorelease: (id)object;

/**
 * Free memory that was allocated using #allocateBytes:.
 *
 * @param ptr the pointer previously returned by #allocateBytes:
 */
- (void) deallocateBytes: (void*)ptr;

/**
 * Free memory that was allocated using #allocateObject:. If reference counting is active
 * (in other words if you're using Apple's Cocoa framework), then this message may
 * not actually free any memory. This message will always decrement the reference count,
 * and memory is only freed if the reference count reaches zero.
 *
 * @param object the object to free as returned by #allocateObject:
 */
- (void) deallocateObject: (id)object;

/**
 * Return whether this object is equal to another one.
 *
 * @param object the object to test
 * @return YES if the allocator is equal to the object, NO if not
 */
- (BOOL) isEqual: (id)object;

/**
 * Return the number of bytes possible to allocate. There is no guarantee that an
 * allocation of the returned size will succeed. You'll just have to try it.
 *
 * @return the maximum possible size of an allocation
 */
- (unsigned) maxSize;

/**
 * Return whether this allocator supports autorelease. If both the platform and allocator
 * support autoreleasing objects, then #autorelease: will perform that function, otherwise
 * it does nothing. This message provides a way to test whether returned objects should
 * be explicitly deallocated.
 *
 * @return YES if this allocator supports autorelease, otherwise NO
 */
- (BOOL) supportsAutorelease;

@end

#endif
