2 * @brief Class representing a list of query expansion terms
4 /* Copyright (C) 2015,2016 Olly Betts
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 #ifndef XAPIAN_INCLUDED_ESET_H
23 #define XAPIAN_INCLUDED_ESET_H
25 #if !defined XAPIAN_IN_XAPIAN_H && !defined XAPIAN_LIB_BUILD
26 # error Never use <xapian/eset.h> directly; include <xapian.h> instead.
32 #include <xapian/attributes.h>
33 #include <xapian/intrusive_ptr.h>
34 #include <xapian/stem.h>
35 #include <xapian/types.h>
36 #include <xapian/visibility.h>
42 /// Class representing a list of search results.
43 class XAPIAN_VISIBILITY_DEFAULT ESet
{
44 friend class ESetIterator
;
47 /// Class representing the ESet internals.
49 /// @private @internal Reference counted internals.
50 Xapian::Internal::intrusive_ptr
<Internal
> internal
;
52 /** Copying is allowed.
54 * The internals are reference counted, so copying is cheap.
58 /** Copying is allowed.
60 * The internals are reference counted, so assignment is cheap.
62 ESet
& operator=(const ESet
& o
);
64 #ifdef XAPIAN_MOVE_SEMANTICS
68 /// Move assignment operator.
69 ESet
& operator=(ESet
&& o
);
72 /** Default constructor.
74 * Creates an empty ESet, mostly useful as a placeholder.
81 /** Return number of items in this ESet object. */
82 Xapian::termcount
size() const;
84 /** Return true if this ESet object is empty. */
85 bool empty() const { return size() == 0; }
87 /** Return a bound on the full size of this ESet object.
89 * This is a bound on size() if get_eset() had been called with
90 * maxitems set high enough that all results were returned.
92 Xapian::termcount
get_ebound() const;
94 /** Efficiently swap this ESet object with another. */
95 void swap(ESet
& o
) { internal
.swap(o
.internal
); }
97 /** Return iterator pointing to the first item in this ESet. */
98 ESetIterator
begin() const;
100 /** Return iterator pointing to just after the last item in this ESet. */
101 ESetIterator
end() const;
103 /** Return iterator pointing to the i-th object in this ESet. */
104 ESetIterator
operator[](Xapian::termcount i
) const;
106 /** Return iterator pointing to the last object in this ESet. */
107 ESetIterator
back() const;
109 /// Return a string describing this object.
110 std::string
get_description() const;
112 /** @private @internal ESet is what the C++ STL calls a container.
114 * The following typedefs allow the class to be used in templates in the
115 * same way the standard containers can be.
117 * These are deliberately hidden from the Doxygen-generated docs, as the
118 * machinery here isn't interesting to API users. They just need to know
119 * that Xapian container classes are compatible with the STL.
121 * See "The C++ Programming Language", 3rd ed. section 16.3.1:
125 typedef Xapian::ESetIterator value_type
;
127 typedef Xapian::termcount size_type
;
129 typedef Xapian::termcount_diff difference_type
;
131 typedef Xapian::ESetIterator iterator
;
133 typedef Xapian::ESetIterator const_iterator
;
135 typedef value_type
* pointer
;
137 typedef const value_type
* const_pointer
;
139 typedef value_type
& reference
;
141 typedef const value_type
& const_reference
;
144 /** @private @internal ESet is what the C++ STL calls a container.
146 * The following methods allow the class to be used in templates in the
147 * same way the standard containers can be.
149 * These are deliberately hidden from the Doxygen-generated docs, as the
150 * machinery here isn't interesting to API users. They just need to know
151 * that Xapian container classes are compatible with the STL.
154 // The size is fixed once created.
155 Xapian::termcount
max_size() const { return size(); }
159 /// Iterator over a Xapian::ESet.
160 class XAPIAN_VISIBILITY_DEFAULT ESetIterator
{
163 ESetIterator(const Xapian::ESet
& eset_
, Xapian::termcount off_from_end_
)
164 : eset(eset_
), off_from_end(off_from_end_
) { }
167 /** @private @internal The ESet we are iterating over. */
170 /** @private @internal The current position of the iterator.
172 * We store the offset from the end of @a eset, since that means
173 * ESet::end() just needs to set this member to 0.
175 Xapian::ESet::size_type off_from_end
;
177 /** Create an unpositioned ESetIterator. */
178 ESetIterator() : off_from_end(0) { }
180 /** Get the term at the current position. */
181 std::string
operator*() const;
183 /// Advance the iterator to the next position.
184 ESetIterator
& operator++() {
189 /// Advance the iterator to the next position (postfix version).
190 ESetIterator
operator++(int) {
191 ESetIterator retval
= *this;
196 /// Move the iterator to the previous position.
197 ESetIterator
& operator--() {
202 /// Move the iterator to the previous position (postfix version).
203 ESetIterator
operator--(int) {
204 ESetIterator retval
= *this;
209 /** @private @internal ESetIterator is what the C++ STL calls an
210 * random_access_iterator.
212 * The following typedefs allow std::iterator_traits<> to work so that
213 * this iterator can be used with the STL.
215 * These are deliberately hidden from the Doxygen-generated docs, as the
216 * machinery here isn't interesting to API users. They just need to know
217 * that Xapian iterator classes are compatible with the STL.
221 typedef std::random_access_iterator_tag iterator_category
;
223 typedef std::string value_type
;
225 typedef Xapian::termcount_diff difference_type
;
227 typedef std::string
* pointer
;
229 typedef std::string
& reference
;
232 /// Move the iterator forwards by n positions.
233 ESetIterator
& operator+=(difference_type n
) {
238 /// Move the iterator back by n positions.
239 ESetIterator
& operator-=(difference_type n
) {
244 /** Return the iterator incremented by @a n positions.
246 * If @a n is negative, decrements by (-n) positions.
248 ESetIterator
operator+(difference_type n
) const {
249 return ESetIterator(eset
, off_from_end
- n
);
252 /** Return the iterator decremented by @a n positions.
254 * If @a n is negative, increments by (-n) positions.
256 ESetIterator
operator-(difference_type n
) const {
257 return ESetIterator(eset
, off_from_end
+ n
);
260 /** Return the number of positions between @a o and this iterator. */
261 difference_type
operator-(const ESetIterator
& o
) const {
262 return difference_type(o
.off_from_end
) - difference_type(off_from_end
);
265 /** Get the weight for the current position. */
266 double get_weight() const;
268 /// Return a string describing this object.
269 std::string
get_description() const;
273 XAPIAN_NOTHROW(operator==(const ESetIterator
&a
, const ESetIterator
&b
));
275 /// Equality test for ESetIterator objects.
277 operator==(const ESetIterator
&a
, const ESetIterator
&b
) XAPIAN_NOEXCEPT
279 return a
.off_from_end
== b
.off_from_end
;
283 XAPIAN_NOTHROW(operator!=(const ESetIterator
&a
, const ESetIterator
&b
));
285 /// Inequality test for ESetIterator objects.
287 operator!=(const ESetIterator
&a
, const ESetIterator
&b
) XAPIAN_NOEXCEPT
293 XAPIAN_NOTHROW(operator<(const ESetIterator
&a
, const ESetIterator
&b
));
295 /// Inequality test for ESetIterator objects.
297 operator<(const ESetIterator
&a
, const ESetIterator
&b
) XAPIAN_NOEXCEPT
299 return a
.off_from_end
> b
.off_from_end
;
303 XAPIAN_NOTHROW(operator>(const ESetIterator
&a
, const ESetIterator
&b
));
305 /// Inequality test for ESetIterator objects.
307 operator>(const ESetIterator
&a
, const ESetIterator
&b
) XAPIAN_NOEXCEPT
313 XAPIAN_NOTHROW(operator>=(const ESetIterator
&a
, const ESetIterator
&b
));
315 /// Inequality test for ESetIterator objects.
317 operator>=(const ESetIterator
&a
, const ESetIterator
&b
) XAPIAN_NOEXCEPT
323 XAPIAN_NOTHROW(operator<=(const ESetIterator
&a
, const ESetIterator
&b
));
325 /// Inequality test for ESetIterator objects.
327 operator<=(const ESetIterator
&a
, const ESetIterator
&b
) XAPIAN_NOEXCEPT
332 /** Return ESetIterator @a it incremented by @a n positions.
334 * If @a n is negative, decrements by (-n) positions.
337 operator+(ESetIterator::difference_type n
, const ESetIterator
& it
)
342 // Inlined methods of ESet which need ESetIterator to have been defined:
345 ESet::begin() const {
346 return ESetIterator(*this, size());
351 // Decrementing the result of end() needs to work, so we must pass in
353 return ESetIterator(*this, 0);
357 ESet::operator[](Xapian::termcount i
) const {
358 return ESetIterator(*this, size() - i
);
363 return ESetIterator(*this, 1);
368 #endif // XAPIAN_INCLUDED_ESET_H