#include <utility>
#include <set>
#include <iostream>
#include <algorithm>
template<class T>
class CompareWords {
public:
bool operator()(T s1, T s2)
{
if (s1.length() == s2.length())
{
return ( s1 < s2 );
}
else return ( s1.length() < s2.length() );
}
};
template<class Iterator, class Clumps, class Compare>
void reduce_clumps( Iterator begin, Iterator end, Clumps&& clumps, Compare&& compare) {
if (begin==end) return;
typedef decltype(*begin) value_type;
std::size_t count = 1;
Iterator run_end = std::find_if( std::next(begin), end, [&]( value_type v ){
if (!compare(*begin, v)) {
++count;
return false;
}
return true;
});
clumps( begin, run_end, count );
return reduce_clumps( std::move(run_end), std::move(end), std::forward<Clumps>(clumps), std::forward<Compare>(compare) );
}
int main() {
typedef std::multiset<std::string> mySet;
typedef std::multiset<std::string>::iterator mySetItr;
mySet mWords { "A", "A", "B" };
reduce_clumps( mWords.begin(), mWords.end(),
[]( mySetItr run_start, mySetItr run_end, std::size_t count )
{
std::cout << "Word \"" << *run_start << "\" occurs " << count << " times\n";
},
CompareWords<std::string>{}
);
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxzZXQ+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGFsZ29yaXRobT4KCnRlbXBsYXRlPGNsYXNzIFQ+CmNsYXNzIENvbXBhcmVXb3JkcyB7CnB1YmxpYzoKICAgIGJvb2wgb3BlcmF0b3IoKShUIHMxLCBUIHMyKQogICAgewogICAgICAgIGlmIChzMS5sZW5ndGgoKSA9PSBzMi5sZW5ndGgoKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAoIHMxIDwgczIgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSByZXR1cm4gKCBzMS5sZW5ndGgoKSA8IHMyLmxlbmd0aCgpICk7CiAgICB9Cn07CgogICAgdGVtcGxhdGU8Y2xhc3MgSXRlcmF0b3IsIGNsYXNzIENsdW1wcywgY2xhc3MgQ29tcGFyZT4KICAgIHZvaWQgcmVkdWNlX2NsdW1wcyggSXRlcmF0b3IgYmVnaW4sIEl0ZXJhdG9yIGVuZCwgQ2x1bXBzJiYgY2x1bXBzLCBDb21wYXJlJiYgY29tcGFyZSkgewogICAgICBpZiAoYmVnaW49PWVuZCkgcmV0dXJuOwogICAgICB0eXBlZGVmIGRlY2x0eXBlKCpiZWdpbikgdmFsdWVfdHlwZTsKICAgICAgc3RkOjpzaXplX3QgY291bnQgPSAxOwogICAgICBJdGVyYXRvciBydW5fZW5kID0gc3RkOjpmaW5kX2lmKCBzdGQ6Om5leHQoYmVnaW4pLCBlbmQsIFsmXSggdmFsdWVfdHlwZSB2ICl7CiAgICAgICAgaWYgKCFjb21wYXJlKCpiZWdpbiwgdikpIHsKICAgICAgICAgICsrY291bnQ7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9KTsKICAgICAgY2x1bXBzKCBiZWdpbiwgcnVuX2VuZCwgY291bnQgKTsKICAgICAgcmV0dXJuIHJlZHVjZV9jbHVtcHMoIHN0ZDo6bW92ZShydW5fZW5kKSwgc3RkOjptb3ZlKGVuZCksIHN0ZDo6Zm9yd2FyZDxDbHVtcHM+KGNsdW1wcyksIHN0ZDo6Zm9yd2FyZDxDb21wYXJlPihjb21wYXJlKSApOwogICAgfQoKICAgIGludCBtYWluKCkgewogICAgICB0eXBlZGVmIHN0ZDo6bXVsdGlzZXQ8c3RkOjpzdHJpbmc+IG15U2V0OwogICAgICB0eXBlZGVmIHN0ZDo6bXVsdGlzZXQ8c3RkOjpzdHJpbmc+OjppdGVyYXRvciBteVNldEl0cjsKCiAgICAgIG15U2V0IG1Xb3JkcyB7ICJBIiwgIkEiLCAiQiIgfTsKCiAgICAgIHJlZHVjZV9jbHVtcHMoIG1Xb3Jkcy5iZWdpbigpLCBtV29yZHMuZW5kKCksCiAgICAgICAgW10oIG15U2V0SXRyIHJ1bl9zdGFydCwgbXlTZXRJdHIgcnVuX2VuZCwgc3RkOjpzaXplX3QgY291bnQgKQogICAgICAgIHsKICAgICAgICAgIHN0ZDo6Y291dCA8PCAiV29yZCBcIiIgPDwgKnJ1bl9zdGFydCA8PCAiXCIgb2NjdXJzICIgPDwgY291bnQgPDwgIiB0aW1lc1xuIjsKICAgICAgICB9LAogICAgICAgIENvbXBhcmVXb3JkczxzdGQ6OnN0cmluZz57fQogICAgICApOwogICAgfQ==