1 /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2 * Use of this file is governed by the BSD 3-clause license that
3 * can be found in the LICENSE.txt file in the project root.
8 #include "misc/Interval.h"
9 #include "Exceptions.h"
15 * This class implements the {@link IntSet} backed by a sorted array of
16 * non-overlapping intervals. It is particularly efficient for representing
17 * large collections of numbers, where the majority of elements appear as part
18 * of a sequential range of numbers that are all part of the set. For example,
19 * the set { 1, 2, 3, 4, 7, 8 } may be represented as { [1, 4], [7, 8] }.
22 * This class is able to represent sets containing any combination of values in
23 * the range {@link Integer#MIN_VALUE} to {@link Integer#MAX_VALUE}
26 class ANTLR4CPP_PUBLIC IntervalSet {
28 static IntervalSet const COMPLETE_CHAR_SET;
29 static IntervalSet const EMPTY_SET;
32 /// The list of sorted, disjoint intervals.
33 std::vector<Interval> _intervals;
35 explicit IntervalSet(std::vector<Interval>&& intervals);
39 IntervalSet(IntervalSet const& set);
40 IntervalSet(IntervalSet&& set);
42 template<typename T1, typename... T_NEXT>
43 IntervalSet(int, T1 t1, T_NEXT&&... next) : IntervalSet() {
44 // The first int argument is an ignored count for compatibility
45 // with the previous varargs based interface.
46 addItems(t1, std::forward<T_NEXT>(next)...);
49 IntervalSet& operator=(IntervalSet const& set);
50 IntervalSet& operator=(IntervalSet&& set);
52 /// Create a set with a single element, el.
53 static IntervalSet of(ssize_t a);
55 /// Create a set with all ints within range [a..b] (inclusive)
56 static IntervalSet of(ssize_t a, ssize_t b);
60 /// Add a single element to the set. An isolated element is stored
61 /// as a range el..el.
64 /// Add interval; i.e., add all integers from a to b to set.
65 /// If b<a, do nothing.
66 /// Keep list in sorted order (by left range value).
67 /// If overlap, combine ranges. For example,
68 /// If this is {1..5, 10..20}, adding 6..7 yields
69 /// {1..5, 6..7, 10..20}. Adding 4..8 yields {1..8, 10..20}.
70 void add(ssize_t a, ssize_t b);
72 /// combine all sets in the array returned the or'd value
73 static IntervalSet Or(const std::vector<IntervalSet> &sets);
75 // Copy on write so we can cache a..a intervals and sets of that.
76 void add(const Interval &addition);
77 IntervalSet& addAll(const IntervalSet &set);
79 template<typename T1, typename... T_NEXT>
80 void addItems(T1 t1, T_NEXT&&... next) {
82 addItems(std::forward<T_NEXT>(next)...);
85 IntervalSet complement(ssize_t minElement, ssize_t maxElement) const;
87 /// Given the set of possible values (rather than, say UNICODE or MAXINT),
88 /// return a new set containing all elements in vocabulary, but not in
89 /// this. The computation is (vocabulary - this).
91 /// 'this' is assumed to be either a subset or equal to vocabulary.
92 IntervalSet complement(const IntervalSet &vocabulary) const;
94 /// Compute this-other via this&~other.
95 /// Return a new set containing all elements in this but not in other.
96 /// other is assumed to be a subset of this;
97 /// anything that is in other but not in this will be ignored.
98 IntervalSet subtract(const IntervalSet &other) const;
101 * Compute the set difference between two interval sets. The specific
102 * operation is {@code left - right}. If either of the input sets is
103 * {@code null}, it is treated as though it was an empty set.
105 static IntervalSet subtract(const IntervalSet &left, const IntervalSet &right);
107 IntervalSet Or(const IntervalSet &a) const;
109 /// Return a new set with the intersection of this set with other. Because
110 /// the intervals are sorted, we can use an iterator for each list and
111 /// just walk them together. This is roughly O(min(n,m)) for interval
112 /// list lengths n and m.
113 IntervalSet And(const IntervalSet &other) const;
115 /// Is el in any range of this set?
116 bool contains(size_t el) const; // For mapping of e.g. Token::EOF to -1 etc.
117 bool contains(ssize_t el) const;
119 /// return true if this set has no members
120 bool isEmpty() const;
122 /// If this set is a single integer, return it otherwise Token.INVALID_TYPE.
123 ssize_t getSingleElement() const;
126 * Returns the maximum value contained in the set.
128 * @return the maximum value contained in the set. If the set is empty, this
129 * method returns {@link Token#INVALID_TYPE}.
131 ssize_t getMaxElement() const;
134 * Returns the minimum value contained in the set.
136 * @return the minimum value contained in the set. If the set is empty, this
137 * method returns {@link Token#INVALID_TYPE}.
139 ssize_t getMinElement() const;
142 /// Return a list of Interval objects. </summary>
143 std::vector<Interval> const& getIntervals() const;
145 size_t hashCode() const;
147 /// Are two IntervalSets equal? Because all intervals are sorted
148 /// and disjoint, equals is a simple linear walk over both lists
149 /// to make sure they are the same.
150 bool operator == (const IntervalSet &other) const;
151 std::string toString() const;
152 std::string toString(bool elemAreChar) const;
155 * @deprecated Use {@link #toString(Vocabulary)} instead.
157 std::string toString(const std::vector<std::string> &tokenNames) const;
158 std::string toString(const dfa::Vocabulary &vocabulary) const;
162 * @deprecated Use {@link #elementName(Vocabulary, int)} instead.
164 std::string elementName(const std::vector<std::string> &tokenNames, ssize_t a) const;
165 std::string elementName(const dfa::Vocabulary &vocabulary, ssize_t a) const;
169 std::vector<ssize_t> toList() const;
170 std::set<ssize_t> toSet() const;
172 /// Get the ith element of ordered set. Used only by RandomPhrase so
173 /// don't bother to implement if you're not doing that for a new
174 /// ANTLR code gen target.
175 ssize_t get(size_t i) const;
176 void remove(size_t el); // For mapping of e.g. Token::EOF to -1 etc.
177 void remove(ssize_t el);
180 void addItems() { /* No-op */ }
184 } // namespace antlr4
186 // Hash function for IntervalSet.
189 using antlr4::misc::IntervalSet;
191 template <> struct hash<IntervalSet>
193 size_t operator() (const IntervalSet &x) const