13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef _TCUINTERVAL_HPP
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define _TCUINTERVAL_HPP
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Interval arithmetic and floating point precisions.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuDefs.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iostream>
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_INFINITY	(::std::numeric_limits<float>::infinity())
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_NAN			(::std::numeric_limits<float>::quiet_NaN())
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// RAII context for temporarily changing the rounding mode
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ScopedRoundingMode
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							ScopedRoundingMode	(deRoundingMode mode)
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								: m_oldMode (deGetRoundingMode()) { deSetRoundingMode(mode); }
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							ScopedRoundingMode	(void) : m_oldMode (deGetRoundingMode()) {}
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~ScopedRoundingMode	(void)	{ deSetRoundingMode(m_oldMode); }
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							ScopedRoundingMode	(const ScopedRoundingMode&);
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ScopedRoundingMode&		operator=			(const ScopedRoundingMode&);
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deRoundingMode	m_oldMode;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Interval
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Empty interval.
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Interval		(void)
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					: m_hasNaN	(false)
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					, m_lo		(TCU_INFINITY)
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					, m_hi		(-TCU_INFINITY) {}
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Intentionally not explicit. Conversion from double to Interval is common
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// and reasonable.
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Interval		(double val)
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					: m_hasNaN	(!!deIsNaN(val))
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					, m_lo		(m_hasNaN ? TCU_INFINITY : val)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					, m_hi		(m_hasNaN ? -TCU_INFINITY : val) {}
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
73afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker				Interval		(bool hasNaN_, double lo_, double hi_)
74afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker					: m_hasNaN(hasNaN_), m_lo(lo_), m_hi(hi_) {}
75afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Interval		(const Interval& a, const Interval& b)
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					: m_hasNaN	(a.m_hasNaN || b.m_hasNaN)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					, m_lo		(de::min(a.lo(), b.lo()))
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					, m_hi		(de::max(a.hi(), b.hi())) {}
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	double		length			(void) const { return m_hi - m_lo; }
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	double		lo				(void) const { return m_lo; }
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	double		hi				(void) const { return m_hi; }
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		hasNaN			(void) const { return m_hasNaN; }
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval	nan				(void) const { return m_hasNaN ? TCU_NAN : Interval(); }
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		empty			(void) const { return m_lo > m_hi; }
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		isFinite		(void) const { return m_lo > -TCU_INFINITY && m_hi < TCU_INFINITY; }
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		isOrdinary		(void) const { return !hasNaN() && !empty() && isFinite(); }
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval	operator|		(const Interval& other) const
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Interval(m_hasNaN || other.m_hasNaN,
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::min(m_lo, other.m_lo),
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::max(m_hi, other.m_hi));
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval&	operator|=		(const Interval& other)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (*this = *this | other);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval	operator&		(const Interval& other) const
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Interval(m_hasNaN && other.m_hasNaN,
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::max(m_lo, other.m_lo),
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::min(m_hi, other.m_hi));
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval&	operator&=		(const Interval& other)
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (*this = *this & other);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		contains		(const Interval& other) const
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (other.lo() >= lo() && other.hi() <= hi() &&
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(!other.hasNaN() || hasNaN()));
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		intersects		(const Interval& other) const
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
124b3637d2f4c8c33317e4b9e7d5e637e8e33766e00Pyry Haulos		return ((other.hi() >= lo() && other.lo() <= hi()) ||
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(other.hasNaN() && hasNaN()));
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Interval	operator-		(void) const
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Interval(hasNaN(), -hi(), -lo());
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static Interval	unbounded	(bool nan = false)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Interval(nan, -TCU_INFINITY, TCU_INFINITY);
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	double		midpoint		(void) const
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.5 * (hi() + lo()); // returns NaN when not bounded
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		operator==		(const Interval& other) const
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return ((m_hasNaN == other.m_hasNaN) &&
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				((empty() && other.empty()) ||
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 (m_lo == other.m_lo && m_hi == other.m_hi)));
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		m_hasNaN;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	double		m_lo;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	double		m_hi;
15493df37596ea66700965094b3aa2830cf4f2ca5aaJarkko Pöyry} DE_WARN_UNUSED_TYPE;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Interval	operator+	(const Interval& x) { return x; }
1573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval		exp2		(const Interval& x);
1583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval		exp			(const Interval& x);
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint				sign		(const Interval& x);
1603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval		abs			(const Interval& x);
1613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval		inverseSqrt	(const Interval& x);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval		operator+	(const Interval& x,		const Interval& y);
1643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval		operator-	(const Interval& x,		const Interval& y);
1653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval		operator*	(const Interval& x,		const Interval& y);
1663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval		operator/	(const Interval& nom,	const Interval& den);
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Interval& operator+=	(Interval& x,	const Interval& y) { return (x = x + y); }
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Interval& operator-=	(Interval& x,	const Interval& y) { return (x = x - y); }
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Interval& operator*=	(Interval& x,	const Interval& y) { return (x = x * y); }
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Interval& operator/=	(Interval& x,	const Interval& y) { return (x = x / y); }
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream&	operator<<	(std::ostream& os, const Interval& interval);
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_SET_INTERVAL_BOUNDS(DST, VAR, SETLOW, SETHIGH) do	\
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{																\
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::tcu::ScopedRoundingMode	VAR##_ctx_;						\
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::tcu::Interval&			VAR##_dst_	= (DST);			\
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::tcu::Interval				VAR##_lo_;						\
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::tcu::Interval				VAR##_hi_;						\
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																\
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{															\
183dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh		::tcu::Interval&	(VAR) = VAR##_lo_;					\
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		::deSetRoundingMode(DE_ROUNDINGMODE_TO_NEGATIVE_INF);	\
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SETLOW;													\
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}															\
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{															\
188dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh		::tcu::Interval&	(VAR) = VAR##_hi_;					\
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		::deSetRoundingMode(DE_ROUNDINGMODE_TO_POSITIVE_INF);	\
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SETHIGH;												\
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}															\
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																\
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VAR##_dst_ = VAR##_lo_ | VAR##_hi_;							\
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} while (::deGetFalse())
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_SET_INTERVAL(DST, VAR, BODY)						\
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_SET_INTERVAL_BOUNDS(DST, VAR, BODY, BODY)
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Set the interval DST to the image of BODY on ARG, assuming that BODY on
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! ARG is a monotone function. In practice, BODY is evaluated on both the
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! upper and lower bound of ARG, and DST is set to the union of these
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! results. While evaluating BODY, PARAM is bound to the bound of ARG, and
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! the output of BODY should be stored in VAR.
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_INTERVAL_APPLY_MONOTONE1(DST, PARAM, ARG, VAR, BODY) do		\
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{																	\
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ::tcu::Interval&	VAR##_arg_		= (ARG);					\
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::tcu::Interval&		VAR##_dst_		= (DST);					\
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::tcu::Interval			VAR##_lo_;									\
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::tcu::Interval			VAR##_hi_;									\
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (VAR##_arg_.empty())												\
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VAR##_dst_ = Interval();										\
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else																\
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{																	\
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{																\
215dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh			const double		(PARAM)	= VAR##_arg_.lo();				\
216dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh			::tcu::Interval&	(VAR)	= VAR##_lo_;					\
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			BODY;														\
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}																\
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{																\
220dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh			const double		(PARAM)	= VAR##_arg_.hi();				\
221dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh			::tcu::Interval&	(VAR)	= VAR##_hi_;					\
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			BODY;														\
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}																\
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VAR##_dst_ = VAR##_lo_ | VAR##_hi_;								\
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}																	\
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (VAR##_arg_.hasNaN())											\
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VAR##_dst_ |= TCU_NAN;											\
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} while (::deGetFalse())
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_INTERVAL_APPLY_MONOTONE2(DST, P0, A0, P1, A1, VAR, BODY)	\
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_INTERVAL_APPLY_MONOTONE1(										\
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DST, P0, A0, tmp2_,												\
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_INTERVAL_APPLY_MONOTONE1(tmp2_, P1, A1, VAR, BODY))
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_INTERVAL_APPLY_MONOTONE3(DST, P0, A0, P1, A1, P2, A2, VAR, BODY) \
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_INTERVAL_APPLY_MONOTONE1(										\
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DST, P0, A0, tmp3_,												\
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_INTERVAL_APPLY_MONOTONE2(tmp3_, P1, A1, P2, A2, VAR, BODY))
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef double		DoubleFunc1			(double);
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef double		DoubleFunc2			(double, double);
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef double		DoubleFunc3			(double, double, double);
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Interval	DoubleIntervalFunc1	(double);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Interval	DoubleIntervalFunc2	(double, double);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Interval	DoubleIntervalFunc3	(double, double, double);
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval	applyMonotone	(DoubleFunc1&			func,
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const Interval&		arg0);
2493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval	applyMonotone	(DoubleFunc2&			func,
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const Interval&		arg0,
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const Interval&		arg1);
2523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval	applyMonotone	(DoubleIntervalFunc1&	func,
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const Interval&		arg0);
2543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterval	applyMonotone	(DoubleIntervalFunc2&	func,
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const Interval&		arg0,
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 const Interval&		arg1);
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _TCUINTERVAL_HPP
262