Class floating_point

Synopsis

#include <include/type_safe/floating_point.hpp>

template <typename FloatT>
class floating_point

Description

A type safe floating point class.

It is a tiny, no overhead wrapper over a standard floating point type. It behaves exactly like the built-in types except it does not allow narrowing conversions.

\requires FloatT must be a floating point type. \notes It intentionally does not provide equality or increment/decrement operators. \module types

Mentioned in

Methods

floating_point overload\effects Initializes the floating point with the given value
floating_point overload\group constructor
get\group conversion
operator floating_point_typeReturns: The stored value as the native floating point type
operator+Returns: The value unchanged.
operator+=\effects Same as the operation on the floating point type
operator-Returns: The negative value.
operator= overload\effects Assigns the floating point the given value
operator= overload\group assignment
TYPE_SAFE_DETAIL_MAKE_OP\group compound_assign

Source

Lines 74-259 in include/type_safe/floating_point.hpp.

template <typename FloatT>
class floating_point
{
    static_assert(std::is_floating_point<FloatT>::value, "must be a floating point type");

public:
    using floating_point_type = FloatT;

    //=== constructors ===//
#if TYPE_SAFE_DELETE_FUNCTIONS
    /// \exclude
    floating_point() = delete;
#endif

    /// \effects Initializes the floating point with the given value.
    /// \notes These functions do not participate in overload resolution,
    /// if `T` is not a floating point type safely convertible to this type.
    /// \group constructor
    /// \param 1
    /// \exclude
    template <typename T,
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>
    TYPE_SAFE_FORCE_INLINE constexpr floating_point(const T& val) noexcept : value_(val)
    {}

    /// \group constructor
    /// \param 1
    /// \exclude
    template <typename T,
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>
    TYPE_SAFE_FORCE_INLINE constexpr floating_point(const floating_point<T>& val) noexcept
    : value_(static_cast<T>(val))
    {}

#if TYPE_SAFE_DELETE_FUNCTIONS
    /// \exclude
    template <typename T,
              typename = detail::fallback_safe_floating_point_conversion<T, floating_point_type>>
    constexpr floating_point(T) = delete;
    /// \exclude
    template <typename T,
              typename = detail::fallback_safe_floating_point_conversion<T, floating_point_type>>
    constexpr floating_point(const floating_point<T>&) = delete;
#endif

    //=== assignment ===//
    /// \effects Assigns the floating point the given value.
    /// \notes These functions do not participate in overload resolution,
    /// if `T` is not a floating point type safely convertible to this type.
    /// \group assignment
    /// \param 1
    /// \exclude
    template <typename T,
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>
    TYPE_SAFE_FORCE_INLINE floating_point& operator=(const T& val) noexcept
    {
        value_ = val;
        return *this;
    }

    /// \group assignment
    /// \param 1
    /// \exclude
    template <typename T,
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>
    TYPE_SAFE_FORCE_INLINE floating_point& operator=(const floating_point<T>& val) noexcept
    {
        value_ = static_cast<T>(val);
        return *this;
    }

#if TYPE_SAFE_DELETE_FUNCTIONS
    /// \exclude
    template <typename T,
              typename = detail::fallback_safe_floating_point_conversion<T, floating_point_type>>
    floating_point& operator=(T) = delete;
    /// \exclude
    template <typename T,
              typename = detail::fallback_safe_floating_point_conversion<T, floating_point_type>>
    floating_point& operator=(const floating_point<T>&) = delete;
#endif

    //=== conversion back ===//
    /// \returns The stored value as the native floating point type.
    /// \group conversion
    TYPE_SAFE_FORCE_INLINE explicit constexpr operator floating_point_type() const noexcept
    {
        return value_;
    }

    /// \group conversion
    TYPE_SAFE_FORCE_INLINE constexpr floating_point_type get() const noexcept
    {
        return value_;
    }

    //=== unary operators ===//
    /// \returns The value unchanged.
    TYPE_SAFE_FORCE_INLINE constexpr floating_point operator+() const noexcept
    {
        return *this;
    }

    /// \returns The negative value.
    TYPE_SAFE_FORCE_INLINE constexpr floating_point operator-() const noexcept
    {
        return -value_;
    }

//=== compound assignment ====//
/// \entity TYPE_SAFE_DETAIL_MAKE_OP
/// \exclude
#define TYPE_SAFE_DETAIL_MAKE_OP(Op)                                                               \
    /** \group compound_assign                                                                     \
     * \module types                                                                               \
     * \param 1                                                                                    \
     * \exclude                                                                                    \
     */                                                                                            \
    template <typename T,                                                                          \
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>    \
    TYPE_SAFE_FORCE_INLINE floating_point& operator Op(const T& other) noexcept                    \
    {                                                                                              \
        return *this Op floating_point<T>(other);                                                  \
    }                                                                                              \
    /** \exclude */                                                                                \
    template <typename T,                                                                          \
              typename = detail::fallback_safe_floating_point_conversion<T, floating_point_type>>  \
    floating_point& operator Op(floating_point<T>) = delete;                                       \
    /** \exclude */                                                                                \
    template <typename T,                                                                          \
              typename = detail::fallback_safe_floating_point_conversion<T, floating_point_type>>  \
    floating_point& operator Op(T) = delete;

    /// \effects Same as the operation on the floating point type.
    /// \notes These functions do not participate in overload resolution,
    /// if `T` is not a floating point type safely convertible to this type.
    /// \group compound_assign Compound assignment
    /// \module types
    /// \param 1
    /// \exclude
    template <typename T,
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>
    TYPE_SAFE_FORCE_INLINE floating_point& operator+=(const floating_point<T>& other) noexcept
    {
        value_ += static_cast<T>(other);
        return *this;
    }
    TYPE_SAFE_DETAIL_MAKE_OP(+=)

    /// \group compound_assign
    /// \param 1
    /// \exclude
    template <typename T,
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>
    TYPE_SAFE_FORCE_INLINE floating_point& operator-=(const floating_point<T>& other) noexcept
    {
        value_ -= static_cast<T>(other);
        return *this;
    }
    TYPE_SAFE_DETAIL_MAKE_OP(-=)

    /// \group compound_assign
    /// \param 1
    /// \exclude
    template <typename T,
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>
    TYPE_SAFE_FORCE_INLINE floating_point& operator*=(const floating_point<T>& other) noexcept
    {
        value_ *= static_cast<T>(other);
        return *this;
    }
    TYPE_SAFE_DETAIL_MAKE_OP(*=)

    /// \group compound_assign
    /// \param 1
    /// \exclude
    template <typename T,
              typename = detail::enable_safe_floating_point_conversion<T, floating_point_type>>
    TYPE_SAFE_FORCE_INLINE floating_point& operator/=(const floating_point<T>& other) noexcept
    {
        value_ /= static_cast<T>(other);
        return *this;
    }
    TYPE_SAFE_DETAIL_MAKE_OP(/=)

#undef TYPE_SAFE_DETAIL_MAKE_OP





Add Discussion as Guest

Log in