Skip to content

Instantly share code, notes, and snippets.

@chriswailes
Created August 15, 2012 22:35
Show Gist options
  • Save chriswailes/3364325 to your computer and use it in GitHub Desktop.
Save chriswailes/3364325 to your computer and use it in GitHub Desktop.
C++11 Type Trait Issue
#ifndef RATIONAL_H
#define RATIONAL_H
/*
* Standard Includes
*/
#include <type_traits>
/*
* Project Includes
*/
/*
* Macros
*/
/*
* Types
*/
/*
* Data
*/
/*
* Classes and Functions
*/
template <typename Type>
class Rational {
public:
// The numerator and denominator of the rational number.
Type n;
Type d;
/*
* Default constructor.
*/
inline Rational(Type num = 0, Type den = 1) : n(num), d(den) {}
/*
* Copy constructors.
*/
template <typename OtherType>
inline Rational(const Rational<OtherType>& other) : n(other.n), d(other.d) {}
template <typename NumType, typename = typename std::enable_if<std::is_arithmetic<NumType>::value>::type>
inline operator NumType () const {
return (NumType)this->n / (NumType)this->d;
}
};
/*
* Comparisons
*/
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
inline bool operator<(const NativeType left, const Rational<RationalType>& right) {
return (left * right.d) < right.n;
}
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
inline bool operator>(const NativeType left, const Rational<RationalType>& right) {
return (left * right.d) > right.n;
}
template <typename IntType, typename RationalType>
inline bool operator==(const typename std::enable_if<std::is_integral<IntType>::value, IntType>::type left, const Rational<RationalType>& right) {
return (left * right.d) == right.n;
}
template <typename FloatType, typename RationalType>
inline bool operator==(const typename std::enable_if<std::is_floating_point<FloatType>::value, FloatType>::type left, const Rational<RationalType>& right) {
return FP_EQUAL(left, ((FloatType)right));
}
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
inline bool operator!=(const NativeType left, const Rational<RationalType>& right) {
return !(left == right);
}
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
inline bool operator<=(const NativeType left, const Rational<RationalType>& right) {
return (left < right) or (left == right);
}
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
inline bool operator>=(const NativeType left, const Rational<RationalType>& right) {
return (left > right) or (left == right);
}
#endif // RATIONAL_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment