infinity.h

Back to Numbers

pastel/sys/

// Description: Infinity
// Documentation: numbers.txt

#ifndef PASTELSYS_INFINITY_H
#define PASTELSYS_INFINITY_H

#include "pastel/sys/sfinae.h"

#include <type_traits>
#include <limits>

#include <boost/operators.hpp>

namespace Pastel
{

    template <bool Positive>
    class Infinity_
    {
    public:
        template <
            typename Type,
            Requires<std::is_integral<Type>> = 0
        >
        operator Type() const
        {
            return Positive ? 
                std::numeric_limits<Type>::max() :
                -std::numeric_limits<Type>::max();
        }

        template <
            typename Type,
            Requires<std::is_floating_point<Type>> = 0
        >
        operator Type() const
        {
            return Positive ?
                std::numeric_limits<Type>::infinity() :
                -std::numeric_limits<Type>::infinity();
        }

        template <
            typename Type,
            Requires<
                std::is_arithmetic<Type>
            > = 0
        >
        bool operator==(const Type& that) const
        {
            return that == (Type)*this;
        }

        template <typename Type>
        friend bool operator==(const Type& that, const Infinity_& inf)
        {
            return inf == that;
        }

        template <
            typename Type,
            Requires<
                std::is_arithmetic<Type>
            > = 0
        >
        bool operator!=(const Type& that) const
        {
            return !(that == *this);
        }

        template <typename Type>
        friend bool operator!=(const Type& that, const Infinity_& inf)
        {
            return inf != that;
        }

        Infinity_<!Positive> operator-() const
        {
            return Infinity_<!Positive>();
        }
    };

    using Infinity = Infinity_<true>;
    using MinusInfinity = Infinity_<false>;

    template <typename Type>
    bool isInfinity(const Type& that)
    {
        return that == Infinity();
    }

    template <typename Type>
    bool isMinusInfinity(const Type& that)
    {
        return that == MinusInfinity();
    }

    template <typename Type>
    Type infinity()
    {
        return (Type)Infinity();
    }

}

#endif