Opened 37 hours ago
Closed 16 hours ago
#850 closed defect (fixed)
MSetIterator traits mismatch operator*, breaks libc++
| Reported by: | Daniel Colascione | Owned by: | Olly Betts |
|---|---|---|---|
| Priority: | normal | Milestone: | 1.4.31 |
| Component: | Library API | Version: | 1.4.30 |
| Severity: | normal | Keywords: | |
| Cc: | Daniel Colascione | Blocked By: | |
| Blocking: | Operating System: | All |
Description
Xapian::MSetIterator has typedefs that mark it STL-compatible, but they're incorrect.
Current master xapian-core/include/xapian/mset.h:
Xapian::docid operator*() const; ... typedef std::string value_type; typedef std::string& reference;
So operator* returns a numeric docid, but traits claim string/reference-to-string.
On libc++ this breaks things like std::insert into a std::vector<Xapian::docid>: libc++ validates against iterator traits and rejects the overload in confusion when it sees reference = std::string&.
#include <xapian.h>
#include <vector>
void f(const Xapian::MSet& mset) {
std::vector<Xapian::docid> ids;
ids.insert(ids.end(), mset.begin(), mset.end()); // fails on libc++
}
error: no matching member function for call to 'insert' ... candidate template ignored: requirement 'is_constructible<unsigned int, std::string &>::value' was not satisfied
MSetIterator traits should match dereference type (docid) so standard STL iterator operations work consistently.
Change History (2)
comment:1 by , 22 hours ago
| Component: | Xapian-bindings → Library API |
|---|---|
| Milestone: | → 1.4.31 |
| Status: | new → assigned |
| Version: | → 1.4.30 |
comment:2 by , 16 hours ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
Fixed in git master by c1ff519bda1dba5635b95ea78e4e0c4085ebdbc1; backported for 1.4.31 in 55c54246cc889a92b67357df77d9e881ff9a5d21.
As part of that I've added a testcase which checks value_type, reference and pointer are consistent with dereferencing for all our iterator types (this was the only incorrect set).

Thanks for spotting and reporting. Looks like this was probably copied from
ESetIteratorand has been wrong since it was added in 9d334768b8f94b6fd8d9c3445be1f5c051cbebac.