Originally Posted by
john.c
Thanks! I didn't see any single-header C++ libraries on the list but that does seem to be the search term I was looking for.
Also regarding the rules of operator overloading. Should they all be moved outside the class or not?
Code:
template <typename T>
class roughly
{
public:
T average, extrema;
roughly(const T& average = 0, const T& extrema = 0)
{
set(average, extrema);
}
roughly(const roughly& rhs)
{
set(rhs.average, rhs.extrema);
}
roughly& set(const T& average, const T& extrema = 0)
{
roughly& that = *this;
that.average = average;
that.extrema = extrema < 0 ? -extrema : extrema;
return that;
}
T low() const
{
return average - extrema;
}
T high() const
{
return average + extrema;
}
roughly& operator += (const roughly& rhs)
{
average += rhs.average;
extrema += rhs.extrema;
return *this;
}
roughly& operator -= (const roughly& rhs)
{
average -= rhs.average;
extrema -= rhs.extrema;
return *this;
}
roughly& meld(const T& lows, const T& highs)
{
average = (lows + highs) / 2;
extrema = average - lows;
return *this;
}
roughly& operator *= (const roughly& rhs)
{
return meld(low() * rhs.low(), high() * rhs.high());
}
roughly& operator /= (const roughly& rhs)
{
auto rl = rhs.low();
auto lows = rl ? low() / rl : 0;
auto rh = rhs.high();
auto highs = rh ? high() / rh : 0;
return meld(lows, highs);
}
};
template <typename T>
roughly<T>
inline operator +
(
const roughly<T>& lhs,
const roughly<T>& rhs
)
{
return roughly<T>(lhs) += rhs;
}
template <typename T>
roughly<T>
inline operator -
(
const roughly<T>& lhs,
const roughly<T>& rhs
)
{
return roughly<T>(lhs) -= rhs;
}
template <typename T>
roughly<T>
inline operator *
(
const roughly<T>& lhs,
const roughly<T>& rhs
)
{
return roughly<T>(lhs) *= rhs;
}
template <typename T>
roughly<T>
inline operator /
(
const roughly<T>& lhs,
const roughly<T>& rhs
)
{
return roughly<T>(lhs) /= rhs;
}
template <typename S, typename T>
S&
operator <<
(
S& stream,
const roughly<T>& data
)
{
return stream << data.average
<< " [+/-] " << data.extrema;
}