#pragma once
#ifndef NDEBUG
#include <wtf/text/TextStream.h>
#endif
namespace WebCore {
template<class T, class UserData> class PODIntervalBase {
public:
const T& low() const { return m_low; }
const T& high() const { return m_high; }
const UserData& data() const { return m_data; }
bool overlaps(const T& low, const T& high) const
{
return !(m_high < low || high < m_low);
}
bool overlaps(const PODIntervalBase& other) const
{
return overlaps(other.m_low, other.m_high);
}
const T& maxHigh() const { return m_maxHigh; }
void setMaxHigh(const T& maxHigh) { m_maxHigh = maxHigh; }
protected:
PODIntervalBase(const T& low, const T& high, UserData&& data)
: m_low(low)
, m_high(high)
, m_data(WTFMove(data))
, m_maxHigh(high)
{
}
#if COMPILER(MSVC)
PODIntervalBase(const T& low, const T& high, const UserData& data)
: m_low(low)
, m_high(high)
, m_data(data)
, m_maxHigh(high)
{
}
#endif
private:
T m_low;
T m_high;
UserData m_data { };
T m_maxHigh;
};
template<class T, class UserData> class PODInterval : public PODIntervalBase<T, UserData> {
public:
PODInterval(const T& low, const T& high, UserData&& data = { })
: PODIntervalBase<T, UserData>(low, high, WTFMove(data))
{
}
PODInterval(const T& low, const T& high, const UserData& data)
: PODIntervalBase<T, UserData>(low, high, UserData { data })
{
}
bool operator<(const PODInterval& other) const
{
if (Base::low() < other.Base::low())
return true;
if (other.Base::low() < Base::low())
return false;
if (Base::high() < other.Base::high())
return true;
if (other.Base::high() < Base::high())
return false;
return Base::data() < other.Base::data();
}
bool operator==(const PODInterval& other) const
{
return Base::low() == other.Base::low()
&& Base::high() == other.Base::high()
&& Base::data() == other.Base::data();
}
private:
using Base = PODIntervalBase<T, UserData>;
};
template<class T, class U> class PODInterval<T, WTF::WeakPtr<U>> : public PODIntervalBase<T, WTF::WeakPtr<U>> {
public:
PODInterval(const T& low, const T& high, WTF::WeakPtr<U>&& data)
: PODIntervalBase<T, WTF::WeakPtr<U>>(low, high, WTFMove(data))
{
}
bool operator<(const PODInterval& other) const
{
if (Base::low() < other.Base::low())
return true;
if (other.Base::low() < Base::low())
return false;
return Base::high() < other.Base::high();
}
private:
using Base = PODIntervalBase<T, WTF::WeakPtr<U>>;
};
#ifndef NDEBUG
template<class T, class UserData>
TextStream& operator<<(TextStream& stream, const PODInterval<T, UserData>& interval)
{
return stream << "[PODInterval (" << interval.low() << ", " << interval.high() << "), data=" << *interval.data() << ", maxHigh=" << interval.maxHigh() << ']';
}
#endif
}