/* ZPair.hpp Author: James Russell Created: 9/12/2011 Purpose: Templated tuple implementation. License: This program is free software. It comes without any warranty, to the extent permitted by applicable law. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar. See http://sam.zoy.org/wtfpl/COPYING for more details. */ #pragma once #ifndef _ZPAIR_HPP #define _ZPAIR_HPP #include //Forward Declaration of ZPair template class ZPair; /* Forward Declaration of ZPair Method Implementation Structures Existence of these structures allows for template specialization of individual methods of the ZPair class. In order to specialize a single method of ZPair for a function, simply specialize the corresponding method implementation structure. */ //Forward Declaration of ZPair::operator < struct template struct ZPair_OperatorLessThanImpl { inline static bool Call(const ZPair& _self, const ZPair& _other); }; //Forward Declaration of ZPair::operator = struct template struct ZPair_OperatorEqualsAssignImpl { inline static ZPair& Call(ZPair& _self, const ZPair& _other); }; //Forward Declaration of ZPair::operator == struct template struct ZPair_OperatorEqualsCompareImpl { inline static bool Call(const ZPair& _self, const ZPair& _other); }; //Forward Declaration of ZPair::operator != struct template struct ZPair_OperatorNotEqualImpl { inline static bool Call(const ZPair& _self, const ZPair& _other); }; //Forward Declaration of ZPair::Swap struct template struct ZPair_SwapImpl { inline static ZPair Call(const ZPair& _self); }; /* Dynamic tuple implementation. The template parameter T1 is the type of the first contained value. The template parameter T2 is the type of the second contained value. */ template class ZPair { friend struct ZPair_OperatorLessThanImpl; friend struct ZPair_OperatorEqualsAssignImpl; friend struct ZPair_OperatorEqualsCompareImpl; friend struct ZPair_OperatorNotEqualImpl; friend struct ZPair_SwapImpl; public: //The first value T1 First; //The second value T2 Second; /* Default constructor. */ ZPair() : First(), Second() { } /* Copy constructor. @param _other - the other pair */ ZPair(const ZPair& _other) : First(_other.First), Second(_other.Second) { } /* Parameterized constructor. @param _first - the first value @param _second - the second value */ ZPair(const T1& _first, const T2& _second) : First(_first), Second(_second) { } /* operator < override, used to ensure ZPair can be compared using the default ZComparator. @param _other - the other pair @return (bool) - true if this ZPair is less than the other, false otherwise */ bool operator < (const ZPair& _other) const { return ZPair_OperatorLessThanImpl::Call(*this, _other); } /* operator = override, used to assign the ZPair to another. @param _other - the other pair @return (ZPair&) - this pair */ ZPair& operator = (const ZPair& _other) { return ZPair_OperatorEqualsAssignImpl::Call(*this, _other); } /* operator == override. @param _other - the other pair @return (bool) - true if this pair is equal to the other, false otherwise */ bool operator == (const ZPair& _other) const { return ZPair_OperatorEqualsCompareImpl::Call(*this, _other); } /* operator != override. @param _other - the other pair @return (bool) - true if this pair is not equal to the other, false otherwise */ bool operator != (const ZPair& _other) const { return ZPair_OperatorNotEqualImpl::Call(*this, _other); } /* public ZPair::Swap Returns another pair that is has swapped the first and second values of this pair. @return (ZPair) - a pair with swapped first/second values */ ZPair Swap() const { return ZPair_SwapImpl::Call(*this); } }; //////////////////////////////////////////// /* Non-Specialized Method Implementations */ //////////////////////////////////////////// template bool ZPair_OperatorLessThanImpl::Call( const ZPair& _self, const ZPair& _other ) { if (_self.First < _other.First) return true; return (_self.Second < _other.Second); } template ZPair& ZPair_OperatorEqualsAssignImpl::Call( ZPair& _self, const ZPair& _other ) { _self.First = _other.First; _self.Second = _other.Second; return _self; } template bool ZPair_OperatorEqualsCompareImpl::Call( const ZPair& _self, const ZPair& _other ) { if (_self.First == _other.First && _self.Second == _other.Second) return true; return false; } template bool ZPair_OperatorNotEqualImpl::Call( const ZPair& _self, const ZPair& _other ) { return !(_self == _other); } template ZPair ZPair_SwapImpl::Call( const ZPair& _self ) { return ZPair(_self.Second, _self.First); } #endif