summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/atomic/test/value_with_epsilon.hpp
blob: 32180a7dba17be9c3ad2c15c2f9fec69f403122e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//  Copyright (c) 2018 Andrey Semashev
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_ATOMIC_TESTS_VALUE_WITH_EPSILON_H_INCLUDED_
#define BOOST_ATOMIC_TESTS_VALUE_WITH_EPSILON_H_INCLUDED_

#include <limits>
#include <iosfwd>

template< typename T >
class value_with_epsilon
{
private:
    T m_value;
    T m_epsilon;

public:
    value_with_epsilon(T value, T epsilon) : m_value(value), m_epsilon(epsilon) {}

    T value() const
    {
        return m_value;
    }

    T epsilon() const
    {
        return m_epsilon;
    }

    bool equal(T value) const
    {
        return value >= (m_value - m_epsilon) && value <= (m_value + m_epsilon);
    }

    friend bool operator== (T left, value_with_epsilon< T > const& right)
    {
        return right.equal(left);
    }
    friend bool operator== (value_with_epsilon< T > const& left, T right)
    {
        return left.equal(right);
    }

    friend bool operator!= (T left, value_with_epsilon< T > const& right)
    {
        return !right.equal(left);
    }
    friend bool operator!= (value_with_epsilon< T > const& left, T right)
    {
        return !left.equal(right);
    }
};

template< typename Char, typename Traits, typename T >
inline std::basic_ostream< Char, Traits >& operator<< (std::basic_ostream< Char, Traits >& strm, value_with_epsilon< T > const& val)
{
    // Note: libstdc++ does not provide output operators for __float128. There may also be no operators for long double.
    //       We don't use such floating point values in our tests where the cast would matter.
    strm << static_cast< double >(val.value()) << " (+/-" << static_cast< double >(val.epsilon()) << ")";
    return strm;
}

template< typename T, typename U >
inline value_with_epsilon< T > approx(T value, U epsilon)
{
    return value_with_epsilon< T >(value, static_cast< T >(epsilon));
}

template< typename T >
inline value_with_epsilon< T > approx(T value)
{
    return value_with_epsilon< T >(value, static_cast< T >(0.0000001));
}

#endif // BOOST_ATOMIC_TESTS_VALUE_WITH_EPSILON_H_INCLUDED_