#ifndef __JLANG__JCOMPARISONAVAILABLE__ #define __JLANG__JCOMPARISONAVAILABLE__ #include #include "JLang/JNullType.hh" /** * \author mdejong */ namespace JLANG {} namespace JPP { using namespace JLANG; } namespace JLANG { /** * Local namespace for fallback implementations for comparison operators. */ namespace JLOCAL { template class JTypedef { template static auto first_type(U*) -> decltype(std::declval()); template static auto first_type(...) -> std::false_type; template static auto second_type(U*) -> decltype(std::declval()); template static auto second_type(...) -> std::false_type; template static auto value_type(U*) -> decltype(std::declval()); template static auto value_type(...) -> std::false_type; public: static const bool has_first_type = !std::is_same (0))>::value; static const bool has_second_type = !std::is_same(0))>::value; static const bool has_value_type = !std::is_same (0))>::value; }; /** * Template definition of test availability of comparison operators. */ template::has_first_type && JTypedef::has_second_type, bool has_value_type = JTypedef::has_value_type> class JComparisonAvailable; /** * Template specialisation of test availability of comparison operators of non-composite data types. */ template class JComparisonAvailable { template static auto eq(U*) -> decltype(std::declval() == std::declval()); template static auto ne(U*) -> decltype(std::declval() != std::declval()); template static auto lt(U*) -> decltype(std::declval() < std::declval()); template static auto gt(U*) -> decltype(std::declval() > std::declval()); template static auto le(U*) -> decltype(std::declval() <= std::declval()); template static auto ge(U*) -> decltype(std::declval() >= std::declval()); template static auto eq(...) -> std::false_type; template static auto ne(...) -> std::false_type; template static auto lt(...) -> std::false_type; template static auto gt(...) -> std::false_type; template static auto le(...) -> std::false_type; template static auto ge(...) -> std::false_type; public: static const bool has_eq = std::is_same(0))>::value; //!< true if operator== available; else false static const bool has_ne = std::is_same(0))>::value; //!< true if operator!= available; else false static const bool has_lt = std::is_same(0))>::value; //!< true if operator< available; else false static const bool has_gt = std::is_same(0))>::value; //!< true if operator> available; else false static const bool has_le = std::is_same(0))>::value; //!< true if operator<= available; else false static const bool has_ge = std::is_same(0))>::value; //!< true if operator>= available; else false }; /** * Template specialisation of test availability of comparison operators of composite data types which have a type definitions for first_type and second_type.\n * This applies to STL containers such as std::pair.\n * Note that STL provides for the comparison of the container based on comparisons of its elements. */ template class JComparisonAvailable { typedef typename T::first_type first_type; typedef typename T::second_type second_type; public: static const bool has_eq = JComparisonAvailable::has_eq && JComparisonAvailable::has_eq; static const bool has_ne = JComparisonAvailable::has_ne && JComparisonAvailable::has_ne; static const bool has_lt = JComparisonAvailable::has_lt && JComparisonAvailable::has_lt; static const bool has_gt = JComparisonAvailable::has_gt && JComparisonAvailable::has_gt; static const bool has_le = JComparisonAvailable::has_le && JComparisonAvailable::has_le; static const bool has_ge = JComparisonAvailable::has_ge && JComparisonAvailable::has_ge; }; /** * Template specialisation of test availability of comparison operators of composite data types which have a type definition for for value_type.\n * This applies to STL containers such as std::vector and std::set.\n * Note that STL provides for the comparison of the container based on comparisons of its elements.\n */ template class JComparisonAvailable : public JComparisonAvailable {}; /** * Template base class for data structures without equality capability. * This class implements the operators == != . */ template class JNoequals { private: /** * Equal operator. * * \param first first object * \param second second object * \return true if two objects are equal; else false */ friend inline JNullType operator==(const T& first, const T& second) { return JNullType(); } /** * Not equal operator. * * \param first first object * \param second second object * \return true if two objects are not equal; else false */ friend inline JNullType operator!=(const T& first, const T& second) { return JNullType(); } }; } using JLOCAL::JComparisonAvailable; using JLOCAL::JNoequals; } #endif