blob: 3a9fe6680cd4f3a7100549594774b16d66f4846c [file] [log] [blame]
kbr@google.comff07a0d2010-09-04 00:24:58 +00001/*
kbr@google.com13e94552010-09-06 04:38:44 +00002 * Copyright (C) 2010 Google Inc. All rights reserved.
darin@apple.com5a28ef12020-01-14 03:18:09 +00003 * Copyright (C) 2020 Apple Inc. All rights reserved.
kbr@google.comff07a0d2010-09-04 00:24:58 +00004 *
5 * Redistribution and use in source and binary forms, with or without
kbr@google.com13e94552010-09-06 04:38:44 +00006 * modification, are permitted provided that the following conditions
7 * are met:
kbr@google.comff07a0d2010-09-04 00:24:58 +00008 *
kbr@google.com13e94552010-09-06 04:38:44 +00009 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
kbr@google.comff07a0d2010-09-04 00:24:58 +000014 *
kbr@google.com13e94552010-09-06 04:38:44 +000015 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kbr@google.comff07a0d2010-09-04 00:24:58 +000025 */
26
darin@apple.com486af442019-12-09 17:12:48 +000027#pragma once
kbr@google.comff07a0d2010-09-04 00:24:58 +000028
29#ifndef NDEBUG
darin@apple.com486af442019-12-09 17:12:48 +000030#include <wtf/text/TextStream.h>
kbr@google.comff07a0d2010-09-04 00:24:58 +000031#endif
32
33namespace WebCore {
34
darin@apple.com5a28ef12020-01-14 03:18:09 +000035// Class template representing a closed interval which can hold arbitrary
36// endpoints and a piece of user data. Ordering and equality are defined
37// including the UserData, except in the special case of WeakPtr.
kbr@google.comff07a0d2010-09-04 00:24:58 +000038//
darin@apple.com5a28ef12020-01-14 03:18:09 +000039// Both the T and UserData types must support a copy constructor, operator<,
40// operator==, and operator=, except that this does not depend on operator<
41// or operator== for WeakPtr.
kbr@google.comff07a0d2010-09-04 00:24:58 +000042//
43// In debug mode, printing of intervals and the data they contain is
darin@apple.com486af442019-12-09 17:12:48 +000044// enabled. This uses WTF::TextStream.
kbr@google.comff07a0d2010-09-04 00:24:58 +000045//
darin@apple.com5a28ef12020-01-14 03:18:09 +000046// Note that this class supplies a copy constructor and assignment
47// operator in order so it can be stored in the red-black tree.
kbr@google.comff07a0d2010-09-04 00:24:58 +000048
darin@apple.com486af442019-12-09 17:12:48 +000049// FIXME: The prefix "POD" here isn't correct; this works with non-POD types.
50
darin@apple.com5a28ef12020-01-14 03:18:09 +000051template<class T, class UserData> class PODIntervalBase {
kbr@google.comff07a0d2010-09-04 00:24:58 +000052public:
darin@apple.com5a28ef12020-01-14 03:18:09 +000053 const T& low() const { return m_low; }
54 const T& high() const { return m_high; }
55 const UserData& data() const { return m_data; }
56
57 bool overlaps(const T& low, const T& high) const
kbr@google.comff07a0d2010-09-04 00:24:58 +000058 {
darin@apple.com5a28ef12020-01-14 03:18:09 +000059 return !(m_high < low || high < m_low);
kbr@google.comff07a0d2010-09-04 00:24:58 +000060 }
61
darin@apple.com5a28ef12020-01-14 03:18:09 +000062 bool overlaps(const PODIntervalBase& other) const
kbr@google.comff07a0d2010-09-04 00:24:58 +000063 {
darin@apple.com5a28ef12020-01-14 03:18:09 +000064 return overlaps(other.m_low, other.m_high);
kbr@google.comff07a0d2010-09-04 00:24:58 +000065 }
66
darin@apple.com5a28ef12020-01-14 03:18:09 +000067 const T& maxHigh() const { return m_maxHigh; }
68 void setMaxHigh(const T& maxHigh) { m_maxHigh = maxHigh; }
69
70protected:
71 PODIntervalBase(const T& low, const T& high, UserData&& data)
darin@apple.com486af442019-12-09 17:12:48 +000072 : m_low(low)
73 , m_high(high)
74 , m_data(WTFMove(data))
75 , m_maxHigh(high)
76 {
77 }
78
darin@apple.com5a28ef12020-01-14 03:18:09 +000079#if COMPILER(MSVC)
80 // Work around an MSVC bug.
81 PODIntervalBase(const T& low, const T& high, const UserData& data)
82 : m_low(low)
83 , m_high(high)
84 , m_data(data)
85 , m_maxHigh(high)
kbr@google.comff07a0d2010-09-04 00:24:58 +000086 {
kbr@google.comff07a0d2010-09-04 00:24:58 +000087 }
darin@apple.com5a28ef12020-01-14 03:18:09 +000088#endif
kbr@google.comff07a0d2010-09-04 00:24:58 +000089
kbr@google.comff07a0d2010-09-04 00:24:58 +000090private:
91 T m_low;
92 T m_high;
darin@apple.com486af442019-12-09 17:12:48 +000093 UserData m_data { };
kbr@google.comff07a0d2010-09-04 00:24:58 +000094 T m_maxHigh;
95};
96
darin@apple.com5a28ef12020-01-14 03:18:09 +000097template<class T, class UserData> class PODInterval : public PODIntervalBase<T, UserData> {
98public:
99 PODInterval(const T& low, const T& high, UserData&& data = { })
100 : PODIntervalBase<T, UserData>(low, high, WTFMove(data))
101 {
102 }
103
104 PODInterval(const T& low, const T& high, const UserData& data)
105 : PODIntervalBase<T, UserData>(low, high, UserData { data })
106 {
107 }
108
109 bool operator<(const PODInterval& other) const
110 {
111 if (Base::low() < other.Base::low())
112 return true;
113 if (other.Base::low() < Base::low())
114 return false;
115 if (Base::high() < other.Base::high())
116 return true;
117 if (other.Base::high() < Base::high())
118 return false;
119 return Base::data() < other.Base::data();
120 }
121
122 bool operator==(const PODInterval& other) const
123 {
124 return Base::low() == other.Base::low()
125 && Base::high() == other.Base::high()
126 && Base::data() == other.Base::data();
127 }
128
129private:
130 using Base = PODIntervalBase<T, UserData>;
131};
132
133template<class T, class U> class PODInterval<T, WTF::WeakPtr<U>> : public PODIntervalBase<T, WTF::WeakPtr<U>> {
134public:
135 PODInterval(const T& low, const T& high, WTF::WeakPtr<U>&& data)
136 : PODIntervalBase<T, WTF::WeakPtr<U>>(low, high, WTFMove(data))
137 {
138 }
139
140 bool operator<(const PODInterval& other) const
141 {
142 if (Base::low() < other.Base::low())
143 return true;
144 if (other.Base::low() < Base::low())
145 return false;
146 return Base::high() < other.Base::high();
147 }
148
149private:
150 using Base = PODIntervalBase<T, WTF::WeakPtr<U>>;
151};
152
darin@apple.com486af442019-12-09 17:12:48 +0000153#ifndef NDEBUG
kbr@google.comff07a0d2010-09-04 00:24:58 +0000154
darin@apple.com486af442019-12-09 17:12:48 +0000155template<class T, class UserData>
156TextStream& operator<<(TextStream& stream, const PODInterval<T, UserData>& interval)
157{
158 return stream << "[PODInterval (" << interval.low() << ", " << interval.high() << "), data=" << *interval.data() << ", maxHigh=" << interval.maxHigh() << ']';
159}
160
161#endif
162
163} // namespace WebCore