#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