//
// $Id: Pair.h,v 1.18 2007/03/06 20:42:20 will_mason Exp $
//
// vi: set ft=objc:

/*
 * ObjectiveLib - a library of containers and algorithms for Objective-C
 *
 * Copyright (c) 2004-2007
 * 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(PAIR_OL_GUARD)
#define PAIR_OL_GUARD

#include <ObjectiveLib/ObjectBase.h>

/**
 * @class OLPair Pair.h ObjectiveLib/Pair.h
 *
 * A pair of objects. Pairs are used extensively in associative containers,
 * like @ref OLMap "maps", as the underlying storage for a key and its value.
 * It is simply a convenient way to keep two related objects together.
 */
@interface OLPair :
#if defined(OL_NO_OPENSTEP)
    Object <OLStreamable>
#else
    NSObject <OLStreamable, NSCopying, NSCoding>
#endif
{
@protected
    /**
     * The first of the pair
     */
    id      first;

    /**
     * The second of the pair
     */
    id      second;
}

/**
 * @name Initializers and Deallocators
 */
/* @{ */
#if !defined(OL_NO_OPENSTEP)
/**
 * Initialize the pair by loading a stored pair from an archive. The stored pair
 * is decoded and its data are used to create a new pair, namely this one.
 *
 * @post The pair returned will be identical to the pair set saved to the archive
 * using the #encodeWithCoder: message.
 *
 * @param decoder the coder which will decode the archived pair
 * @return a reference to this pair
 */
- (id) initWithCoder: (NSCoder*)decoder;
#endif

/**
 * Initialize the pair with its two values.
 *
 * @param f the first in the pair
 * @param s the second in the pair
 * @return a reference to this pair
 */
- (id) initWithFirst: (id)f second: (id)s;

- (id) initWithObjectInStream: (OLObjectInStream*)stream;

/**
 * Finalize the pair and deallocate any allocated memory.
 */
#if defined(OL_NO_OPENSTEP)
- (id) free;
#else
- (void) dealloc;
#endif
/* @} */

/**
 * Compare this pair to another object. If the other object is of type OLPair, then
 * the first object of the pair is compared to the first object of the other pair using
 * the @c compare: method. If the result is zero, then the same comparison is
 * subsequently performed on the two pairs' second objects.
 *
 * @param other the object with which to compare this one
 * @return a value greater than, equal to, or less than zero accoringly as this object
 * is greater than, equal to, or less than @a other
 */
- (int) compare: (id)other;
#if defined(OL_NO_OPENSTEP)
/**
 * Make a copy of this pair.
 *
 * @return the copy
 */
- (id) copy;
#else
/**
 * Make a copy of this pair allocating memory from the given zone.
 *
 * @param zone the zone from which to allocate memory
 * @return the copy
 */
- (id) copyWithZone: (NSZone*)zone;
#endif

#if !defined(OL_NO_OPENSTEP)
/**
 * Encode the pair. The pair is saved to an archive using @a encoder and will be
 * retrieved using the initializer #initWithCoder:.
 *
 * @param encoder the coder used to store the pair
 */
- (void) encodeWithCoder: (NSCoder*)encoder;
#endif

/**
 * Return the first of the pair.
 *
 * @return the first object
 */
- (id) first;

/**
 * Return whether this pair is equal to another one. Two pairs are considered equal
 * only if this pair's first value is equal to @a object's first value and this
 * pair's second value is equal to @a object's second value. Equality of the members
 * is determined using the method @c isEqual:.
 *
 * @param object the object to test for equality
 * @return YES if the two pairs are equal, NO otherwise
 */
- (BOOL) isEqual: (id)object;

/**
 * Return the second of the pair.
 *
 * @return the second object
 */
- (id) second;

/**
 * Set the first object to @a f.
 *
 * @param f the new first object
 */
- (void) setFirst: (id)f;

/**
 * Set the second object to @a s.
 *
 * @param s the new first object
 */
- (void) setSecond: (id)s;

- (void) writeSelfToStream: (OLObjectOutStream*)stream;

@end

#endif
