xref: /minix3/external/bsd/llvm/dist/clang/include/clang/Serialization/ContinuousRangeMap.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- ContinuousRangeMap.h - Map with int range as key -------*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file defines the ContinuousRangeMap class, which is a highly
11f4a2713aSLionel Sambuc //  specialized container used by serialization.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15*0a6a1f1dSLionel Sambuc #ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
16*0a6a1f1dSLionel Sambuc #define LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
17f4a2713aSLionel Sambuc 
18f4a2713aSLionel Sambuc #include "clang/Basic/LLVM.h"
19f4a2713aSLionel Sambuc #include "llvm/ADT/SmallVector.h"
20f4a2713aSLionel Sambuc #include <algorithm>
21f4a2713aSLionel Sambuc #include <utility>
22f4a2713aSLionel Sambuc 
23f4a2713aSLionel Sambuc namespace clang {
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc /// \brief A map from continuous integer ranges to some value, with a very
26f4a2713aSLionel Sambuc /// specialized interface.
27f4a2713aSLionel Sambuc ///
28f4a2713aSLionel Sambuc /// CRM maps from integer ranges to values. The ranges are continuous, i.e.
29f4a2713aSLionel Sambuc /// where one ends, the next one begins. So if the map contains the stops I0-3,
30f4a2713aSLionel Sambuc /// the first range is from I0 to I1, the second from I1 to I2, the third from
31f4a2713aSLionel Sambuc /// I2 to I3 and the last from I3 to infinity.
32f4a2713aSLionel Sambuc ///
33f4a2713aSLionel Sambuc /// Ranges must be inserted in order. Inserting a new stop I4 into the map will
34f4a2713aSLionel Sambuc /// shrink the fourth range to I3 to I4 and add the new range I4 to inf.
35f4a2713aSLionel Sambuc template <typename Int, typename V, unsigned InitialCapacity>
36f4a2713aSLionel Sambuc class ContinuousRangeMap {
37f4a2713aSLionel Sambuc public:
38f4a2713aSLionel Sambuc   typedef std::pair<Int, V> value_type;
39f4a2713aSLionel Sambuc   typedef value_type &reference;
40f4a2713aSLionel Sambuc   typedef const value_type &const_reference;
41f4a2713aSLionel Sambuc   typedef value_type *pointer;
42f4a2713aSLionel Sambuc   typedef const value_type *const_pointer;
43f4a2713aSLionel Sambuc 
44f4a2713aSLionel Sambuc private:
45f4a2713aSLionel Sambuc   typedef SmallVector<value_type, InitialCapacity> Representation;
46f4a2713aSLionel Sambuc   Representation Rep;
47f4a2713aSLionel Sambuc 
48f4a2713aSLionel Sambuc   struct Compare {
operatorCompare49f4a2713aSLionel Sambuc     bool operator ()(const_reference L, Int R) const {
50f4a2713aSLionel Sambuc       return L.first < R;
51f4a2713aSLionel Sambuc     }
operatorCompare52f4a2713aSLionel Sambuc     bool operator ()(Int L, const_reference R) const {
53f4a2713aSLionel Sambuc       return L < R.first;
54f4a2713aSLionel Sambuc     }
operatorCompare55f4a2713aSLionel Sambuc     bool operator ()(Int L, Int R) const {
56f4a2713aSLionel Sambuc       return L < R;
57f4a2713aSLionel Sambuc     }
operatorCompare58f4a2713aSLionel Sambuc     bool operator ()(const_reference L, const_reference R) const {
59f4a2713aSLionel Sambuc       return L.first < R.first;
60f4a2713aSLionel Sambuc     }
61f4a2713aSLionel Sambuc   };
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc public:
insert(const value_type & Val)64f4a2713aSLionel Sambuc   void insert(const value_type &Val) {
65f4a2713aSLionel Sambuc     if (!Rep.empty() && Rep.back() == Val)
66f4a2713aSLionel Sambuc       return;
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc     assert((Rep.empty() || Rep.back().first < Val.first) &&
69f4a2713aSLionel Sambuc            "Must insert keys in order.");
70f4a2713aSLionel Sambuc     Rep.push_back(Val);
71f4a2713aSLionel Sambuc   }
72f4a2713aSLionel Sambuc 
insertOrReplace(const value_type & Val)73f4a2713aSLionel Sambuc   void insertOrReplace(const value_type &Val) {
74f4a2713aSLionel Sambuc     iterator I = std::lower_bound(Rep.begin(), Rep.end(), Val, Compare());
75f4a2713aSLionel Sambuc     if (I != Rep.end() && I->first == Val.first) {
76f4a2713aSLionel Sambuc       I->second = Val.second;
77f4a2713aSLionel Sambuc       return;
78f4a2713aSLionel Sambuc     }
79f4a2713aSLionel Sambuc 
80f4a2713aSLionel Sambuc     Rep.insert(I, Val);
81f4a2713aSLionel Sambuc   }
82f4a2713aSLionel Sambuc 
83f4a2713aSLionel Sambuc   typedef typename Representation::iterator iterator;
84f4a2713aSLionel Sambuc   typedef typename Representation::const_iterator const_iterator;
85f4a2713aSLionel Sambuc 
begin()86f4a2713aSLionel Sambuc   iterator begin() { return Rep.begin(); }
end()87f4a2713aSLionel Sambuc   iterator end() { return Rep.end(); }
begin()88f4a2713aSLionel Sambuc   const_iterator begin() const { return Rep.begin(); }
end()89f4a2713aSLionel Sambuc   const_iterator end() const { return Rep.end(); }
90f4a2713aSLionel Sambuc 
find(Int K)91f4a2713aSLionel Sambuc   iterator find(Int K) {
92f4a2713aSLionel Sambuc     iterator I = std::upper_bound(Rep.begin(), Rep.end(), K, Compare());
93f4a2713aSLionel Sambuc     // I points to the first entry with a key > K, which is the range that
94f4a2713aSLionel Sambuc     // follows the one containing K.
95f4a2713aSLionel Sambuc     if (I == Rep.begin())
96f4a2713aSLionel Sambuc       return Rep.end();
97f4a2713aSLionel Sambuc     --I;
98f4a2713aSLionel Sambuc     return I;
99f4a2713aSLionel Sambuc   }
find(Int K)100f4a2713aSLionel Sambuc   const_iterator find(Int K) const {
101f4a2713aSLionel Sambuc     return const_cast<ContinuousRangeMap*>(this)->find(K);
102f4a2713aSLionel Sambuc   }
103f4a2713aSLionel Sambuc 
back()104f4a2713aSLionel Sambuc   reference back() { return Rep.back(); }
back()105f4a2713aSLionel Sambuc   const_reference back() const { return Rep.back(); }
106f4a2713aSLionel Sambuc 
107f4a2713aSLionel Sambuc   /// \brief An object that helps properly build a continuous range map
108f4a2713aSLionel Sambuc   /// from a set of values.
109f4a2713aSLionel Sambuc   class Builder {
110f4a2713aSLionel Sambuc     ContinuousRangeMap &Self;
111f4a2713aSLionel Sambuc 
112f4a2713aSLionel Sambuc     Builder(const Builder&) LLVM_DELETED_FUNCTION;
113f4a2713aSLionel Sambuc     Builder &operator=(const Builder&) LLVM_DELETED_FUNCTION;
114f4a2713aSLionel Sambuc 
115f4a2713aSLionel Sambuc   public:
Builder(ContinuousRangeMap & Self)116f4a2713aSLionel Sambuc     explicit Builder(ContinuousRangeMap &Self) : Self(Self) { }
117f4a2713aSLionel Sambuc 
~Builder()118f4a2713aSLionel Sambuc     ~Builder() {
119f4a2713aSLionel Sambuc       std::sort(Self.Rep.begin(), Self.Rep.end(), Compare());
120*0a6a1f1dSLionel Sambuc       std::unique(Self.Rep.begin(), Self.Rep.end(),
121*0a6a1f1dSLionel Sambuc                   [](const_reference A, const_reference B) {
122*0a6a1f1dSLionel Sambuc         // FIXME: we should not allow any duplicate keys, but there are a lot of
123*0a6a1f1dSLionel Sambuc         // duplicate 0 -> 0 mappings to remove first.
124*0a6a1f1dSLionel Sambuc         assert((A == B || A.first != B.first) &&
125*0a6a1f1dSLionel Sambuc                "ContinuousRangeMap::Builder given non-unique keys");
126*0a6a1f1dSLionel Sambuc         return A == B;
127*0a6a1f1dSLionel Sambuc       });
128f4a2713aSLionel Sambuc     }
129f4a2713aSLionel Sambuc 
insert(const value_type & Val)130f4a2713aSLionel Sambuc     void insert(const value_type &Val) {
131f4a2713aSLionel Sambuc       Self.Rep.push_back(Val);
132f4a2713aSLionel Sambuc     }
133f4a2713aSLionel Sambuc   };
134f4a2713aSLionel Sambuc   friend class Builder;
135f4a2713aSLionel Sambuc };
136f4a2713aSLionel Sambuc 
137f4a2713aSLionel Sambuc }
138f4a2713aSLionel Sambuc 
139f4a2713aSLionel Sambuc #endif
140