/usr/include/boost/safe_numerics
Edit: /usr/include/boost/safe_numerics/interval.hpp (8357B)
#ifndef BOOST_NUMERIC_INTERVAL_HPP
#define BOOST_NUMERIC_INTERVAL_HPP
// Copyright (c) 2012 Robert Ramey
//
// 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)
#include
#include
#include
#include
#include // minmax, min, max
#include
#include "utility.hpp" // log
// from stack overflow
// http://stackoverflow.com/questions/23815138/implementing-variadic-min-max-functions
namespace boost {
namespace safe_numerics {
template
struct interval {
const R l;
const R u;
template
constexpr interval(const T & lower, const T & upper) :
l(lower),
u(upper)
{
// assert(static_cast(l <= u));
}
template
constexpr interval(const std::pair & p) :
l(p.first),
u(p.second)
{}
template
constexpr interval(const interval & rhs) :
l(rhs.l),
u(rhs.u)
{}
constexpr interval();
// return true if this interval contains the given point
constexpr tribool includes(const R & t) const {
return l <= t && t <= u;
}
// if this interval contains every point found in some other inteval t
// return true
// otherwise
// return false or indeterminate
constexpr tribool includes(const interval & t) const {
return u >= t.u && l <= t.l;
}
// return true if this interval contains the given point
constexpr tribool excludes(const R & t) const {
return t < l || t > u;
}
// if this interval excludes every point found in some other inteval t
// return true
// otherwise
// return false or indeterminate
constexpr tribool excludes(const interval & t) const {
return t.u < l || u < t.l;
}
};
template
constexpr interval make_interval(){
return interval();
}
template
constexpr interval make_interval(const R & r){
return interval(r, r);
}
template
constexpr interval::interval() :
l(std::numeric_limits::lowest()),
u(std::numeric_limits::max())
{}
// account for the fact that for floats and doubles
// the most negative value is called "lowest" rather
// than min
template<>
constexpr interval::interval() :
l(std::numeric_limits::lowest()),
u(std::numeric_limits::max())
{}
template<>
constexpr interval::interval() :
l(std::numeric_limits::lowest()),
u(std::numeric_limits::max())
{}
template
constexpr interval operator+(const interval & t, const interval & u){
// adapted from https://en.wikipedia.org/wiki/Interval_arithmetic
return {t.l + u.l, t.u + u.u};
}
template
constexpr interval operator-(const interval & t, const interval & u){
// adapted from https://en.wikipedia.org/wiki/Interval_arithmetic
return {t.l - u.u, t.u - u.l};
}
template
constexpr interval operator*(const interval & t, const interval & u){
// adapted from https://en.wikipedia.org/wiki/Interval_arithmetic
return utility::minmax(
std::initializer_list {
t.l * u.l,
t.l * u.u,
t.u * u.l,
t.u * u.u
}
);
}
// interval division
// note: presumes 0 is not included in the range of the denominator
template
constexpr interval operator/(const interval & t, const interval & u){
assert(static_cast(u.excludes(T(0))));
return utility::minmax(
std::initializer_list {
t.l / u.l,
t.l / u.u,
t.u / u.l,
t.u / u.u
}
);
}
// modulus of two intervals. This will give a new range of for the modulus.
// note: presumes 0 is not included in the range of the denominator
template
constexpr interval operator%(const interval & t, const interval & u){
assert(static_cast(u.excludes(T(0))));
return utility::minmax(
std::initializer_list {
t.l % u.l,
t.l % u.u,
t.u % u.l,
t.u % u.u
}
);
}
template
constexpr interval operator<<(const interval & t, const interval & u){
// static_assert(std::is_integral::value, "left shift only defined for integral type");
//return interval{t.l << u.l, t.u << u.u};
return utility::minmax(
std::initializer_list {
t.l << u.l,
t.l << u.u,
t.u << u.l,
t.u << u.u
}
);
}
template
constexpr interval operator>>(const interval & t, const interval & u){
// static_assert(std::is_integral::value, "right shift only defined for integral type");
//return interval{t.l >> u.u, t.u >> u.l};
return utility::minmax(
std::initializer_list {
t.l >> u.l,
t.l >> u.u,
t.u >> u.l,
t.u >> u.u
}
);
}
// union of two intervals
template
constexpr interval operator|(const interval & t, const interval & u){
const T & rl = std::min(t.l, u.l);
const T & ru = std::max(t.u, u.u);
return interval(rl, ru);
}
// intersection of two intervals
template
constexpr interval operator&(const interval & t, const interval & u){
const T & rl = std::max(t.l, u.l);
const T & ru = std::min(t.u, u.u);
return interval(rl, ru);
}
// determine whether two intervals intersect
template
constexpr boost::logic::tribool intersect(const interval & t, const interval & u){
return t.u >= u.l || t.l <= u.u;
}
template
constexpr boost::logic::tribool operator<(
const interval & t,
const interval & u
){
return
// if every element in t is less than every element in u
t.u < u.l ? boost::logic::tribool(true):
// if every element in t is greater than every element in u
t.l > u.u ? boost::logic::tribool(false):
// otherwise some element(s) in t are greater than some element in u
boost::logic::indeterminate
;
}
template
constexpr boost::logic::tribool operator>(
const interval & t,
const interval & u
){
return
// if every element in t is greater than every element in u
t.l > u.u ? boost::logic::tribool(true) :
// if every element in t is less than every element in u
t.u < u.l ? boost::logic::tribool(false) :
// otherwise some element(s) in t are greater than some element in u
boost::logic::indeterminate
;
}
template
constexpr bool operator==(
const interval & t,
const interval & u
){
// intervals have the same limits
return t.l == u.l && t.u == u.u;
}
template
constexpr bool operator!=(
const interval & t,
const interval & u
){
return ! (t == u);
}
template
constexpr boost::logic::tribool operator<=(
const interval & t,
const interval & u
){
return ! (t > u);
}
template
constexpr boost::logic::tribool operator>=(
const interval & t,
const interval & u
){
return ! (t < u);
}
} // safe_numerics
} // boost
#include
namespace std {
template
inline std::basic_ostream &
operator<<(
std::basic_ostream & os,
const boost::safe_numerics::interval & i
){
return os << '[' << i.l << ',' << i.u << ']';
}
template
inline std::basic_ostream &
operator<<(
std::basic_ostream & os,
const boost::safe_numerics::interval & i
){
os << "[" << (unsigned)i.l << "," << (unsigned)i.u << "]";
return os;
}
template
inline std::basic_ostream &
operator<<(
std::basic_ostream & os,
const boost::safe_numerics::interval & i
){
os << "[" << (int)i.l << "," << (int)i.u << "]";
return os;
}
} // std
#endif // BOOST_NUMERIC_INTERVAL_HPP