Opened 9 years ago

Closed 9 years ago

#9515 closed Bugs (fixed)

[range] uniqued adaptor (and hence adjacent_filtered) returns wrong elements

Reported by: Eric Niebler Owned by: Neil Groves
Milestone: To Be Determined Component: range
Version: Boost 1.54.0 Severity: Problem
Keywords: Cc:

Description

The following shows the difference between the boost::range::unique_copy algorithm and the boost::adaptors::unique adaptor.

#include <string>
#include <vector>
#include <iterator>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/algorithm/unique_copy.hpp>
#include <boost/range/adaptor/uniqued.hpp>

struct istring
{
    char const *c_str;
    istring(char const *s) : c_str(s) {}
    bool operator==(istring u) const
    {
        return boost::iequals(c_str, u.c_str);
    }
    friend std::ostream& operator<<(std::ostream& sout, istring s)
    {
        return sout << s.c_str;
    }
};

int main()
{
    std::vector<istring> strs;
    strs.push_back(istring("hello"));
    strs.push_back(istring("HELLO"));
    std::cout << "boost.range: \n";
    boost::range::copy(
        boost::adaptors::unique(strs),
        std::ostream_iterator<istring>(std::cout));

    std::cout << "\n";
    std::cout << "std algo: \n";
    boost::range::unique_copy(strs,
        std::ostream_iterator<istring>(std::cout));
    std::cout << "\n";
}

This prints:

boost.range:
HELLO
std algo:
hello

std::unique and std::unique_copy yield the *first* element in a sequence of equivalent elements. The Boost adaptor yields the last. This is an important and observable difference.

Since uniqued is implemented in terms of adjacent_filtered, the problem needs to be fixed there.

Change History (3)

comment:1 by Michel Morin, 9 years ago

Component: Nonerange
Owner: set to Neil Groves

comment:2 by Neil Groves, 9 years ago

Status: newassigned

comment:3 by Neil Groves, 9 years ago

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.