#ifndef __JLANG__JMULTICOMPARABLE__
#define __JLANG__JMULTICOMPARABLE__
#include "JLang/JNullType.hh"
#include "JLang/JTypeList.hh"
#include "JLang/JType.hh"
/**
* \author mdejong
*/
namespace JLANG {}
namespace JPP { using namespace JLANG; }
namespace JLANG {
/**
* Template definition of auxiliary base class for composite data structures
* composed of base classes with comparisons capabilities.
*
* Each data type T in the type list should have the corresponding operator:
*
* bool operator<(const T&, const T& second);
*
* This class uses in-class friend operators (see Barton-Nackman trick).
*
* This class implements the operators < > <= >= == != .
*/
template
struct JMultiComparable {
protected:
/**
* Less than method for composite data types.
*
* \param first first object
* \param second second object
* \param type type
* \return true if first object is less than second object; else false
*/
template
static inline bool lt(const JClass_t& first,
const JClass_t& second,
const JType >& type)
{
if (static_cast(first) <
static_cast(second))
return true;
else if (static_cast(second) <
static_cast(first))
return false;
else
return lt(first, second, JType());
}
/**
* Less than method for composite data types.
*
* \param first first object
* \param second second object
* \param type type
* \return true if first object is less than second object; else false
*/
template
static inline bool lt(const JClass_t& first,
const JClass_t& second,
const JType >& type)
{
return (static_cast(first) <
static_cast(second));
}
public:
/**
* Less than operator.
*
* \param first first object
* \param second second object
* \return true if first object is less than second object; else false
*/
friend bool operator<(const JClass_t& first,
const JClass_t& second)
{
return lt(first, second, JType());
}
/**
* Greater than operator.
*
* \param first first object
* \param second second object
* \return true if first object is greater than second object; else false
*/
friend bool operator>(const JClass_t& first,
const JClass_t& second)
{
return lt(second, first, JType());
}
/**
* Less than or equal operator.
*
* \param first first object
* \param second second object
* \return true if first object is less than or equal to second object; else false
*/
friend bool operator<=(const JClass_t& first,
const JClass_t& second)
{
return !lt(second, first, JType());
}
/**
* Greater than or equal operator.
*
* \param first first object
* \param second second object
* \return true if first object is greater than or equal to second object; else false
*/
friend bool operator>=(const JClass_t& first,
const JClass_t& second)
{
return !lt(first, second, JType());
}
/**
* Equal operator.
*
* \param first first object
* \param second second object
* \return true if two objects are equal; else false
*/
friend bool operator==(const JClass_t& first,
const JClass_t& second)
{
return (!lt(first, second, JType()) &&
!lt(second, first, JType()));
}
/**
* Not equal operator.
*
* \param first first object
* \param second second object
* \return true if two objects are not equal; else false
*/
friend bool operator!=(const JClass_t& first,
const JClass_t& second)
{
return (lt(first, second, JType()) ||
lt(second, first, JType()));
}
};
}
#endif