[Debtags-commits] [svn] r1684 - in tagcoll/2.0: . tagcoll tests

Enrico Zini enrico at costa.debian.org
Tue May 2 00:54:49 UTC 2006


Author: enrico
Date: Tue May  2 00:54:47 2006
New Revision: 1684

Modified:
   tagcoll/2.0/   (props changed)
   tagcoll/2.0/tagcoll/BasicStringDiskIndex.cc
   tagcoll/2.0/tagcoll/BasicStringDiskIndex.h
   tagcoll/2.0/tagcoll/CardinalityStore.cc
   tagcoll/2.0/tagcoll/CardinalityStore.h
   tagcoll/2.0/tagcoll/Collection.h
   tagcoll/2.0/tagcoll/Consumer.h
   tagcoll/2.0/tagcoll/DerivedTags.h
   tagcoll/2.0/tagcoll/Expression.cc
   tagcoll/2.0/tagcoll/Expression.h
   tagcoll/2.0/tagcoll/Filter.h
   tagcoll/2.0/tagcoll/Filters.cc
   tagcoll/2.0/tagcoll/Filters.h
   tagcoll/2.0/tagcoll/Implications.cc
   tagcoll/2.0/tagcoll/Implications.h
   tagcoll/2.0/tagcoll/InputMerger.cc
   tagcoll/2.0/tagcoll/InputMerger.h
   tagcoll/2.0/tagcoll/IntDiskIndex.cc
   tagcoll/2.0/tagcoll/IntDiskIndex.h
   tagcoll/2.0/tagcoll/OpSet.h
   tagcoll/2.0/tagcoll/PatchCollection.cc
   tagcoll/2.0/tagcoll/PatchCollection.h
   tagcoll/2.0/tagcoll/Patches.cc
   tagcoll/2.0/tagcoll/Patches.h
   tagcoll/2.0/tagcoll/ReadonlyCollection.h
   tagcoll/2.0/tagcoll/Serializer.cc
   tagcoll/2.0/tagcoll/Serializer.h
   tagcoll/2.0/tagcoll/SmartHierarchy.cc
   tagcoll/2.0/tagcoll/SmartHierarchy.h
   tagcoll/2.0/tagcoll/TDBIndexer.cc
   tagcoll/2.0/tagcoll/TDBIndexer.h
   tagcoll/2.0/tagcoll/TextFormat.cc
   tagcoll/2.0/tagcoll/TextFormat.h
   tagcoll/2.0/tagcoll/TextFormat.tcc
   tagcoll/2.0/tagcoll/experiments.cc
   tagcoll/2.0/tagcoll/experiments.h
   tagcoll/2.0/tagcoll/test-utils.cc
   tagcoll/2.0/tests/mkgraph.cc
   tagcoll/2.0/tests/normalize.cc
   tagcoll/2.0/tests/test-utils.h
Log:
 r2539 at viaza:  enrico | 2006-05-02 02:39:12 +0200
 Migrated from OpSet to std::set+wibble::operators


Modified: tagcoll/2.0/tagcoll/BasicStringDiskIndex.cc
==============================================================================
--- tagcoll/2.0/tagcoll/BasicStringDiskIndex.cc	(original)
+++ tagcoll/2.0/tagcoll/BasicStringDiskIndex.cc	Tue May  2 00:54:47 2006
@@ -44,11 +44,11 @@
 	pkgs.map(item.c_str());
 }
 
-void BasicStringDiskIndexer::consumeItem(const string& item, const OpSet<string>& tags)
+void BasicStringDiskIndexer::consumeItem(const string& item, const std::set<string>& tags)
 {
 	cache.consume(item, tags);
 	pkgs.map(item.c_str());
-	for (OpSet<string>::iterator i = tags.begin(); i != tags.end(); i++)
+	for (std::set<string>::iterator i = tags.begin(); i != tags.end(); i++)
 		this->tags.map(i->c_str());
 }
 
@@ -86,9 +86,9 @@
 
 #include <iostream>
 
-static void outts(const OpSet<string>& s)
+static void outts(const std::set<string>& s)
 {
-	for (OpSet<string>::const_iterator i = s.begin(); i != s.end(); i++)
+	for (std::set<string>::const_iterator i = s.begin(); i != s.end(); i++)
 		if (i == s.begin())
 			cerr << *i;
 		else
@@ -118,10 +118,10 @@
 
 #if 0
 	cerr << "Items: ";
-	OpSet<string> s = idx.getTaggedItems();
+	std::set<string> s = idx.getTaggedItems();
 	outts(s);
 	cerr << endl;
-	for (OpSet<string>::const_iterator i = s.begin(); i != s.end(); i++)
+	for (std::set<string>::const_iterator i = s.begin(); i != s.end(); i++)
 	{
 		cerr << "  " << *i << ": ";
 		outts(idx.getTags(*i));
@@ -133,7 +133,7 @@
 	s = idx.getAllTags();
 	outts(s);
 	cerr << endl;
-	for (OpSet<string>::const_iterator i = s.begin(); i != s.end(); i++)
+	for (std::set<string>::const_iterator i = s.begin(); i != s.end(); i++)
 	{
 		cerr << "  " << *i << ": ";
 		outts(idx.getItems(*i));

Modified: tagcoll/2.0/tagcoll/BasicStringDiskIndex.h
==============================================================================
--- tagcoll/2.0/tagcoll/BasicStringDiskIndex.h	(original)
+++ tagcoll/2.0/tagcoll/BasicStringDiskIndex.h	Tue May  2 00:54:47 2006
@@ -68,7 +68,7 @@
 	StringIndexer tags;
 
 	virtual void consumeItemUntagged(const std::string& item);
-	virtual void consumeItem(const std::string& item, const OpSet<std::string>& tags);
+	virtual void consumeItem(const std::string& item, const std::set<std::string>& tags);
 
 public:
 	virtual ~BasicStringDiskIndexer() {}

Modified: tagcoll/2.0/tagcoll/CardinalityStore.cc
==============================================================================
--- tagcoll/2.0/tagcoll/CardinalityStore.cc	(original)
+++ tagcoll/2.0/tagcoll/CardinalityStore.cc	Tue May  2 00:54:47 2006
@@ -36,6 +36,7 @@
 #endif
 
 using namespace std;
+using namespace wibble::operators;
 using namespace tagcoll;
 
 template<class T>
@@ -59,8 +60,8 @@
 	// Tagsets to be deleted because they became empty
 	for (typename PatchList<ITEM, TAG>::const_iterator i = change.begin(); i != change.end(); i++)
 	{
-		OpSet<TAG> oldts = getTags(i->first);
-		OpSet<TAG> newts = i->second.apply(oldts);
+		std::set<TAG> oldts = getTags(i->first);
+		std::set<TAG> newts = i->second.apply(oldts);
 
 		// Remove the item from the old tagset
 		typename tagsets_t::iterator oldi = tagsets.find(oldts);
@@ -71,7 +72,7 @@
 				tagsets.erase(oldi->first);
 
 			// Decrement the tag cardinalities accordingly
-			for (typename OpSet<TAG>::const_iterator j = oldts.begin();
+			for (typename std::set<TAG>::const_iterator j = oldts.begin();
 					j != oldts.end(); j++)
 				tags.del(*j, 1);
 		}
@@ -105,7 +106,7 @@
 }
 
 template<class ITEM, class TAG>
-void CardinalityStore<ITEM, TAG>::consumeItem(const ITEM& item, const OpSet<TAG>& tagset)
+void CardinalityStore<ITEM, TAG>::consumeItem(const ITEM& item, const std::set<TAG>& tagset)
 {
 	if (tagset.size() == 0)
 		return;
@@ -116,25 +117,25 @@
 	if (i != tagsets.end())
 	{
 		// If it already exists, insert the item
-		pair<typename OpSet<ITEM>::iterator, bool> r = i->second.insert(item);
+		pair<typename std::set<ITEM>::iterator, bool> r = i->second.insert(item);
 		added = r.second;
 	} else {
 		// Else insert the item as a new set
-		OpSet<ITEM> items;
-		items += item;
+		std::set<ITEM> items;
+		items |= item;
 		tagsets.insert(make_pair(tagset, items));
 		added = true;
 	}
 
 	// Update tags accordingly
 	if (added)
-		for (typename OpSet<TAG>::const_iterator i = tagset.begin();
+		for (typename std::set<TAG>::const_iterator i = tagset.begin();
 				i != tagset.end(); i++)
 			tags.add(*i, 1);
 }
 
 template<class ITEM, class TAG>
-void CardinalityStore<ITEM, TAG>::consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tagset)
+void CardinalityStore<ITEM, TAG>::consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tagset)
 {
 	if (tagset.size() == 0 || items.size() == 0)
 		return;
@@ -145,10 +146,10 @@
 	if (i != tagsets.end())
 	{
 		// If it already exists, merge the items
-		for (typename OpSet<ITEM>::const_iterator j = items.begin();
+		for (typename std::set<ITEM>::const_iterator j = items.begin();
 				j != items.end(); j++)
 		{
-			pair<typename OpSet<ITEM>::iterator, bool> r = i->second.insert(*j);
+			pair<typename std::set<ITEM>::iterator, bool> r = i->second.insert(*j);
 			if (r.second)
 				inserted++;
 		}
@@ -159,7 +160,7 @@
 	}
 
 	// Update tags accordingly
-	for (typename OpSet<TAG>::const_iterator i = tagset.begin();
+	for (typename std::set<TAG>::const_iterator i = tagset.begin();
 			i != tagset.end(); i++)
 		tags.add(*i, inserted);
 }
@@ -177,11 +178,11 @@
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> CardinalityStore<ITEM, TAG>::getItemsExactMatch(const OpSet<TAG>& ts) const
+std::set<ITEM> CardinalityStore<ITEM, TAG>::getItemsExactMatch(const std::set<TAG>& ts) const
 {
 	typename tagsets_t::const_iterator i = tagsets.find(ts);
 	if (i == tagsets.end())
-		return OpSet<ITEM>();
+		return std::set<ITEM>();
 	else
 		return i->second;
 }
@@ -191,116 +192,116 @@
 {
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (t->second.contains(item))
+		if (set_contains(t->second, item))
 			return true;
 	return false;
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> CardinalityStore<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
+std::set<ITEM> CardinalityStore<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
 {
-	OpSet<ITEM> res;
+	std::set<ITEM> res;
 
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (t->first.contains(tag))
-			res += t->second;
+		if (set_contains(t->first, tag))
+			res |= t->second;
 
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> CardinalityStore<ITEM, TAG>::getItemsHavingTags(const OpSet<TAG>& tags) const
+std::set<ITEM> CardinalityStore<ITEM, TAG>::getItemsHavingTags(const std::set<TAG>& tags) const
 {
-	OpSet<ITEM> res;
+	std::set<ITEM> res;
 
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (t->first.contains(tags))
-			res += t->second;
+		if (set_contains(t->first, tags))
+			res |= t->second;
 
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> CardinalityStore<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
+std::set<TAG> CardinalityStore<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
 {
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (t->second.contains(item))
+		if (set_contains(t->second, item))
 			return t->first;
-	return OpSet<TAG>();
+	return std::set<TAG>();
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> CardinalityStore<ITEM, TAG>::getTagsOfItems(const OpSet<ITEM>& items) const
+std::set<TAG> CardinalityStore<ITEM, TAG>::getTagsOfItems(const std::set<ITEM>& items) const
 {
-	OpSet<TAG> res;
+	std::set<TAG> res;
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (!(t->second ^ items).empty())
-			res +=  t->first;
+		if (!(t->second & items).empty())
+			res |= t->first;
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> CardinalityStore<ITEM, TAG>::getAllTags() const
+std::set<TAG> CardinalityStore<ITEM, TAG>::getAllTags() const
 {
-	OpSet<TAG> res;
+	std::set<TAG> res;
 
 	for (typename TagContainer::const_iterator t = tags.begin();
 			t != tags.end(); t++)
-		res += t->first;
+		res |= t->first;
 
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> CardinalityStore<ITEM, TAG>::getTaggedItems() const
+std::set<ITEM> CardinalityStore<ITEM, TAG>::getTaggedItems() const
 {
-	OpSet<ITEM> res;
+	std::set<ITEM> res;
 
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		res += t->second;
+		res |= t->second;
 
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> CardinalityStore<ITEM, TAG>::getCompanionTags(const OpSet<TAG>& ts) const
+std::set<TAG> CardinalityStore<ITEM, TAG>::getCompanionTags(const std::set<TAG>& ts) const
 {
-	OpSet<TAG> res;
+	std::set<TAG> res;
 
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (t->first.contains(ts))
-			res += t->first - ts;
+		if (set_contains(t->first, ts))
+			res |= t->first - ts;
 
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> CardinalityStore<ITEM, TAG>::getCompanionItems(const OpSet<TAG>& ts) const
+std::set<ITEM> CardinalityStore<ITEM, TAG>::getCompanionItems(const std::set<TAG>& ts) const
 {
-	OpSet<ITEM> res;
+	std::set<ITEM> res;
 
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (t->first.contains(ts))
-			res += t->second;
+		if (set_contains(t->first, ts))
+			res |= t->second;
 
 	return res;
 }
 
 template<class ITEM, class TAG>
-map<ITEM, OpSet<TAG> > CardinalityStore<ITEM, TAG>::getCompanionItemsAndTagsets(const OpSet<TAG>& ts) const
+map<ITEM, std::set<TAG> > CardinalityStore<ITEM, TAG>::getCompanionItemsAndTagsets(const std::set<TAG>& ts) const
 {
-	map<ITEM, OpSet<TAG> > res;
+	map<ITEM, std::set<TAG> > res;
 
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (t->first.contains(ts))
+		if (set_contains(t->first, ts))
 			for (typename set<ITEM>::const_iterator i = t->second.begin();
 					i != t->second.end(); i++)
 				res.insert(make_pair(*i, t->first));
@@ -309,24 +310,24 @@
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> CardinalityStore<ITEM, TAG>::getRelatedItems(const OpSet<TAG>& ts, int maxdistance) const
+std::set<ITEM> CardinalityStore<ITEM, TAG>::getRelatedItems(const std::set<TAG>& ts, int maxdistance) const
 {
-	list< OpSet<TAG> > tagsets = getRelatedTagsets(ts, maxdistance);
-	OpSet<ITEM> items;
-	for (typename list< OpSet<TAG> >::const_iterator i = tagsets.begin(); i != tagsets.end(); i++)
-		items += getItemsExactMatch(*i);
+	list< std::set<TAG> > tagsets = getRelatedTagsets(ts, maxdistance);
+	std::set<ITEM> items;
+	for (typename list< std::set<TAG> >::const_iterator i = tagsets.begin(); i != tagsets.end(); i++)
+		items |= getItemsExactMatch(*i);
 	return items;
 }
 
 template<class ITEM, class TAG>
-list< OpSet<TAG> > CardinalityStore<ITEM, TAG>::getRelatedTagsets(const OpSet<TAG>& ts, int maxdistance) const
+list< std::set<TAG> > CardinalityStore<ITEM, TAG>::getRelatedTagsets(const std::set<TAG>& ts, int maxdistance) const
 {
-	list< OpSet<TAG> > res;
+	list< std::set<TAG> > res;
 
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
 	{
-		int dist = ts.distance(t->first);
+		int dist = set_distance(ts, t->first);
 		if (dist > 0 && dist <= maxdistance)
 			res.push_back(t->first);
 	}
@@ -335,27 +336,27 @@
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> CardinalityStore<ITEM, TAG>::getImplyingOneOf(const OpSet<TAG>& tags) const
+std::set<TAG> CardinalityStore<ITEM, TAG>::getImplyingOneOf(const std::set<TAG>& tags) const
 {
-	OpSet<TAG> allWith;
-	OpSet<TAG> allWithout;
+	std::set<TAG> allWith;
+	std::set<TAG> allWithout;
 
 	for (typename tagsets_t::const_iterator ts = tagsets.begin();
 			ts != tagsets.end(); ts++)
 	{
-		OpSet<TAG> intersection = ts->first ^ tags;
+		std::set<TAG> intersection = ts->first & tags;
 
 		if (intersection.size() == 0)
-			allWithout += ts->first;
+			allWithout |= ts->first;
 		else
-			allWith += ts->first;
+			allWith |= ts->first;
 	}
 
 	return allWith - allWithout;
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> CardinalityStore<ITEM, TAG>::getImpliedBy(const TAG& tag) const
+std::set<TAG> CardinalityStore<ITEM, TAG>::getImpliedBy(const TAG& tag) const
 {
 	// The tags implied by `tag' are the result of the intersection between all
 	// tagsets that contain tag
@@ -365,10 +366,10 @@
 	for ( ; ts != tagsets.end() && ts->first.find(tag) == ts->first.end(); ts++)
 		;
 	if (ts == tagsets.end())
-		return OpSet<TAG>();
+		return std::set<TAG>();
 
 	// Initialize the intersection set with it
-	OpSet<TAG> res = ts->first;
+	std::set<TAG> res = ts->first;
 	// Remove tag
 	res -= tag;
 
@@ -378,7 +379,7 @@
 		else
 			// For all tagsets that contain tag
 			// Intersect them with `res'
-			res = ts->first ^ res;
+			res = ts->first & res;
 
 	return res;
 }
@@ -395,7 +396,7 @@
 		// for all tagsets ts having tag
 
 		// Insert the tagset, without tag
-		OpSet<TAG> newts = ts->first;
+		std::set<TAG> newts = ts->first;
 		newts.erase(tag);
 
 		// Check if we make orphans, and preserve them
@@ -408,9 +409,9 @@
 }
 
 template<class ITEM, class TAG>
-CardinalityStore<ITEM, TAG> CardinalityStore<ITEM, TAG>::getCollectionWithoutTags(const OpSet<TAG>& tags) const
+CardinalityStore<ITEM, TAG> CardinalityStore<ITEM, TAG>::getCollectionWithoutTags(const std::set<TAG>& tags) const
 {
-	OpSet<TAG> candidates = getImplyingOneOf(tags);
+	std::set<TAG> candidates = getImplyingOneOf(tags);
 
 	// remove all tags contained in `candidates', merging categories that
 	// result with the same tagset;
@@ -419,7 +420,7 @@
 	for (typename tagsets_t::const_iterator ts = tagsets.begin();
 			ts != tagsets.end(); ts++)
 	{
-		OpSet<TAG> newts = ts->first - candidates;
+		std::set<TAG> newts = ts->first - candidates;
 
 		if (newts.size() > 0)
 		{
@@ -451,13 +452,13 @@
 }
 
 template<class ITEM, class TAG>
-CardinalityStore<ITEM, TAG> CardinalityStore<ITEM, TAG>::getCollectionWithoutTagsetsHavingAnyOf(const OpSet<TAG>& tags) const
+CardinalityStore<ITEM, TAG> CardinalityStore<ITEM, TAG>::getCollectionWithoutTagsetsHavingAnyOf(const std::set<TAG>& tags) const
 {
 	CardinalityStore<ITEM, TAG> res;
 	for (typename tagsets_t::const_iterator ts = tagsets.begin();
 			ts != tagsets.end(); ts++)
 	{
-		OpSet<TAG> inters = ts->first ^ tags;
+		std::set<TAG> inters = ts->first & tags;
 		if (!inters.empty())
 			continue;
 		// For all tagsets that do not contain some of the tags in `tag`
@@ -480,14 +481,14 @@
 }
 
 template<class ITEM, class TAG>
-TAG CardinalityStore<ITEM, TAG>::findTagWithMaxCardinalityNotIn(const OpSet<TAG>& ntags, int* card) const
+TAG CardinalityStore<ITEM, TAG>::findTagWithMaxCardinalityNotIn(const std::set<TAG>& ntags, int* card) const
 {
 	TAG candidate;
 	int maxcard = 0;
 
 	for (typename TagContainer::const_iterator i = tags.begin();
 			i != tags.end(); i++)
-		if (!ntags.contains(i->first) && i->second > maxcard)
+		if (!set_contains(ntags, i->first) && i->second > maxcard)
 		{
 			maxcard = i->second;
 			candidate = i->first;
@@ -503,15 +504,15 @@
 {
 //fprintf(stderr, "mergeEquivalentTags\n");
 	// Build a card->tags mapping
-	map<int, OpSet<TAG> > cards;
+	map<int, std::set<TAG> > cards;
 	for (typename TagContainer::const_iterator t = tags.begin();
 			t != tags.end(); t++)
-		cards[t->second] += t->first;
+		cards[t->second] |= t->first;
 
 	// Look for tags with the same cardinality
 	map<TAG, TAG> renames;
-	OpSet<TAG> items_to_rename;
-	for (typename map<int, OpSet<TAG> >::const_iterator c = cards.begin();
+	std::set<TAG> items_to_rename;
+	for (typename map<int, std::set<TAG> >::const_iterator c = cards.begin();
 			c != cards.end(); c++)
 		if (c->second.size() > 1)
 		{
@@ -522,11 +523,11 @@
 			// Intersect every set of tags with the same cardinality
 			// with all tagsets in the collection which gives non-null
 			// intersection.  The tags in the resulting set are equivalent.
-			OpSet<TAG> equivs = c->second;
+			std::set<TAG> equivs = c->second;
 			for (typename tagsets_t::const_iterator i = tagsets.begin();
 					i != tagsets.end() && equivs.size() > 1; i++)
 			{
-				OpSet<TAG> intersection = c->second ^ i->first;
+				std::set<TAG> intersection = c->second & i->first;
 				if (!intersection.empty())
 					equivs = intersection;
 			}
@@ -540,7 +541,7 @@
 				// tag
 
 				// Compute the merged name
-				typename OpSet<TAG>::const_iterator j = equivs.begin();
+				typename std::set<TAG>::const_iterator j = equivs.begin();
 				TAG merged = *j;
 				int card = tags[*j];
 				for (j++; j != equivs.end(); j++)
@@ -554,11 +555,11 @@
 
 				// Store the renames to be done
 				// Remove the now-merged items from `tags'
-				for (typename OpSet<TAG>::const_iterator j = equivs.begin();
+				for (typename std::set<TAG>::const_iterator j = equivs.begin();
 						j != equivs.end(); j++)
 				{
 					renames.insert(make_pair(*j, merged));
-					items_to_rename += *j;
+					items_to_rename |= *j;
 					tags.erase(*j);
 				}
 			}
@@ -569,34 +570,33 @@
 		// Perform the renames
 
 		// Find the tagsets that need rename
-		vector< OpSet<TAG> > to_rename;
+		vector< std::set<TAG> > to_rename;
 		for (typename tagsets_t::const_iterator i = tagsets.begin(); i != tagsets.end(); i++)
 		{
-			OpSet<TAG> inters = i->first ^ items_to_rename;
-			if (!inters.empty())
+			if (!(i->first & items_to_rename).empty())
 				to_rename.push_back(i->first);
 		}
 
 		// Rename the tags inside the selected tagsets
-		for (typename vector< OpSet<TAG> >::const_iterator i = to_rename.begin();
+		for (typename vector< std::set<TAG> >::const_iterator i = to_rename.begin();
 				i != to_rename.end(); i++)
 		{
 			// Store the old tag data and remove it from tagsets
 			typename tagsets_t::iterator t = tagsets.find(*i);
-			OpSet<TAG> tags = t->first;
-			OpSet<ITEM> items = t->second;
+			std::set<TAG> tags = t->first;
+			std::set<ITEM> items = t->second;
 			tagsets.erase(t);
 			
 			// Compute the renamed tagset
-			OpSet<TAG> newtags;
-			for (typename OpSet<TAG>::const_iterator r = tags.begin();
+			std::set<TAG> newtags;
+			for (typename std::set<TAG>::const_iterator r = tags.begin();
 					r != tags.end(); r++)
 			{
 				typename map<TAG, TAG>::const_iterator ren = renames.find(*r);
 				if (ren == renames.end())
-					newtags += *r;
+					newtags |= *r;
 				else
-					newtags += ren->second;
+					newtags |= ren->second;
 			}
 
 			// Insert the resulting tagset back into tagsets
@@ -609,45 +609,45 @@
 void CardinalityStore<ITEM, TAG>::removeTagsWithCardinalityLessThan(int card)
 {
 	// Build the list of tags to remove
-	OpSet<TAG> to_remove;
+	std::set<TAG> to_remove;
 	for (typename TagContainer::const_iterator i = tags.begin();
 			i != tags.end(); i++)
 		if (i->second < card)
-			to_remove += i->first;
+			to_remove |= i->first;
 
 	// Remove the tags from `tags'
-	for (typename OpSet<TAG>::const_iterator i = to_remove.begin();
+	for (typename std::set<TAG>::const_iterator i = to_remove.begin();
 			i != to_remove.end(); i++)
 		tags.erase(*i);
 
 	// Select the tagsets to be changed from `tagsets'
-	vector< OpSet<TAG> > to_change;
+	vector< std::set<TAG> > to_change;
 	for (typename tagsets_t::const_iterator i = tagsets.begin();
 			i != tagsets.end(); i++)
 	{
-		OpSet<TAG> inters = i->first ^ to_remove;
+		std::set<TAG> inters = i->first & to_remove;
 		if (! inters.empty())
 			to_change.push_back(i->first);
 	}
 
 	// Remove the tags from `tagsets'
-	for (typename vector< OpSet<TAG> >::const_iterator i = to_change.begin();
+	for (typename vector< std::set<TAG> >::const_iterator i = to_change.begin();
 			i != to_change.end(); i++)
 	{
 		// Remove the old mapping
 		typename tagsets_t::iterator t = tagsets.find(*i);
-		OpSet<ITEM> items = t->second;
+		std::set<ITEM> items = t->second;
 		tagsets.erase(t);
 
 		// Compute the new tagset
-		OpSet<TAG> newts = *i - to_remove;
+		std::set<TAG> newts = *i - to_remove;
 
 		// Insert the new mapping
 		t = tagsets.find(newts);
 		if (t == tagsets.end())
 			tagsets.insert(make_pair(newts, items));
 		else
-			t->second += items;
+			t->second |= items;
 	}
 }
 
@@ -659,11 +659,11 @@
 }
 
 template<class ITEM, class TAG>
-void CardinalityStore<ITEM, TAG>::outputHavingTags(const OpSet<TAG>& ts, Consumer<ITEM, TAG>& consumer) const
+void CardinalityStore<ITEM, TAG>::outputHavingTags(const std::set<TAG>& ts, Consumer<ITEM, TAG>& consumer) const
 {
 	for (typename tagsets_t::const_iterator t = tagsets.begin();
 			t != tagsets.end(); t++)
-		if (t->first.contains(ts))
+		if (set_contains(t->first, ts))
 			consumer.consume(t->second, t->first);
 }
 

Modified: tagcoll/2.0/tagcoll/CardinalityStore.h
==============================================================================
--- tagcoll/2.0/tagcoll/CardinalityStore.h	(original)
+++ tagcoll/2.0/tagcoll/CardinalityStore.h	Tue May  2 00:54:47 2006
@@ -25,6 +25,7 @@
 
 #include <tagcoll/Collection.h>
 
+#include <wibble/operators.h>
 #include <set>
 #include <map>
 #include <list>
@@ -52,7 +53,7 @@
 class CardinalityStore : public Collection<ITEM, TAG>
 {
 public:
-	typedef std::map<OpSet<TAG>, OpSet<ITEM> > tagsets_t;
+	typedef std::map<std::set<TAG>, std::set<ITEM> > tagsets_t;
 
 protected:
 	class TagContainer : public std::map<TAG, int>
@@ -75,15 +76,15 @@
 	/**
 	 * Get the list of tags that imply one of the tags in `tags'
 	 */
-	OpSet<TAG> getImplyingOneOf(const OpSet<TAG>& tags) const;
+	std::set<TAG> getImplyingOneOf(const std::set<TAG>& tags) const;
 
-	void consumeItem(const ITEM& item, const OpSet<TAG>& tagset);
-	void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tagset);
+	void consumeItem(const ITEM& item, const std::set<TAG>& tagset);
+	void consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tagset);
 
-	virtual OpSet<ITEM> getItemsHavingTag(const TAG& tag) const;
-	virtual OpSet<ITEM> getItemsHavingTags(const OpSet<TAG>& tags) const;
-	virtual OpSet<TAG> getTagsOfItem(const ITEM& item) const;
-	virtual OpSet<TAG> getTagsOfItems(const OpSet<ITEM>& items) const;
+	virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const;
+	virtual std::set<ITEM> getItemsHavingTags(const std::set<TAG>& tags) const;
+	virtual std::set<TAG> getTagsOfItem(const ITEM& item) const;
+	virtual std::set<TAG> getTagsOfItems(const std::set<ITEM>& items) const;
 
 	
 public:
@@ -112,26 +113,26 @@
 	int tagsetCount() const { return tagsets.size(); }
 
 	/// Get the set of items with exactly the given tagset
-	OpSet<ITEM> getItemsExactMatch(const OpSet<TAG>& ts) const;
+	std::set<ITEM> getItemsExactMatch(const std::set<TAG>& ts) const;
 
 	bool hasItem(const ITEM& item) const;
 	bool hasTag(const TAG& tag) const { return getCardinality(tag) > 0; }
 
-	OpSet<TAG> getAllTags() const;
-	OpSet<ITEM> getTaggedItems() const;
+	std::set<TAG> getAllTags() const;
+	std::set<ITEM> getTaggedItems() const;
 
-	OpSet<TAG> getCompanionTags(const OpSet<TAG>& ts) const;
+	std::set<TAG> getCompanionTags(const std::set<TAG>& ts) const;
 
 	/// Get the set of all items in this collection whose tagsets contain `ts'
-	OpSet<ITEM> getCompanionItems(const OpSet<TAG>& ts) const;
+	std::set<ITEM> getCompanionItems(const std::set<TAG>& ts) const;
 
 	/// Get the set of all items in this collection whose tagsets contain `ts'
-	std::map< ITEM, OpSet<TAG> > getCompanionItemsAndTagsets(const OpSet<TAG>& ts) const;
+	std::map< ITEM, std::set<TAG> > getCompanionItemsAndTagsets(const std::set<TAG>& ts) const;
 
-	OpSet<ITEM> getRelatedItems(const OpSet<TAG>& ts, int maxdistance = 1) const;
+	std::set<ITEM> getRelatedItems(const std::set<TAG>& ts, int maxdistance = 1) const;
 
 	/// Get the list of tagsets related to the given one, with distance > 0 and <= maxdistance
-	std::list< OpSet<TAG> > getRelatedTagsets(const OpSet<TAG>& ts, int maxdistance = 1) const;
+	std::list< std::set<TAG> > getRelatedTagsets(const std::set<TAG>& ts, int maxdistance = 1) const;
 
 	void applyChange(const PatchList<ITEM, TAG>& change);
 
@@ -142,7 +143,7 @@
 
 	/// Return a tagged collection with all tagsets of this one that are
 	/// nonempty when stripped by the tag `tag' and all tags that imply it 
-	CardinalityStore<ITEM, TAG> getCollectionWithoutTags(const OpSet<TAG>& tag) const;
+	CardinalityStore<ITEM, TAG> getCollectionWithoutTags(const std::set<TAG>& tag) const;
 
 	/// Return the tagged collection with all tagsets of this one that do not
 	/// contain the tag `tag'
@@ -150,15 +151,15 @@
 
 	/// Return the tagged collection with all tagsets of this one that do not
 	/// contain the tags in `tags'
-	CardinalityStore<ITEM, TAG> getCollectionWithoutTagsetsHavingAnyOf(const OpSet<TAG>& tag) const;
+	CardinalityStore<ITEM, TAG> getCollectionWithoutTagsetsHavingAnyOf(const std::set<TAG>& tag) const;
 
 	/// Return the list of tags that the given tag implies
-	OpSet<TAG> getImpliedBy(const TAG& tag) const;
+	std::set<TAG> getImpliedBy(const TAG& tag) const;
 	
 	int getCardinality(const TAG& tag) const;
 
 	// Return the tag with maximum cardinality
-	TAG findTagWithMaxCardinalityNotIn(const OpSet<TAG>& tags, int* card = 0) const;
+	TAG findTagWithMaxCardinalityNotIn(const std::set<TAG>& tags, int* card = 0) const;
 		
 	// Return a collection where equivalent tags are merged.
 	// Equivalent tags are tags which are attached to the same set of items
@@ -170,7 +171,7 @@
 	void removeTagsWithCardinalityLessThan(int card);
 	
 	void output(Consumer<ITEM, TAG>& cons) const;
-	void outputHavingTags(const OpSet<TAG>& ts, Consumer<ITEM, TAG>& consumer) const;
+	void outputHavingTags(const std::set<TAG>& ts, Consumer<ITEM, TAG>& consumer) const;
 };
 
 };

Modified: tagcoll/2.0/tagcoll/Collection.h
==============================================================================
--- tagcoll/2.0/tagcoll/Collection.h	(original)
+++ tagcoll/2.0/tagcoll/Collection.h	Tue May  2 00:54:47 2006
@@ -49,7 +49,7 @@
 	 */
 
 	void consumeItemUntagged(const ITEM&) {}
-	void consumeItemsUntagged(const OpSet<ITEM>&) {}
+	void consumeItemsUntagged(const std::set<ITEM>&) {}
 
 public:
 	virtual ~Collection() {}

Modified: tagcoll/2.0/tagcoll/Consumer.h
==============================================================================
--- tagcoll/2.0/tagcoll/Consumer.h	(original)
+++ tagcoll/2.0/tagcoll/Consumer.h	Tue May  2 00:54:47 2006
@@ -23,8 +23,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
 
-#include <tagcoll/OpSet.h>
 #include <wibble/empty.h>
+#include <set>
 
 namespace tagcoll
 {
@@ -47,24 +47,24 @@
 	virtual void consumeItemUntagged(const ITEM& item) = 0;
 
 	/// Process a tagged item, with its tags
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags) = 0;
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags) = 0;
 
 	/// Process a set of items, all with no tags
-	virtual void consumeItemsUntagged(const OpSet<ITEM>& items)
+	virtual void consumeItemsUntagged(const std::set<ITEM>& items)
 	{
 		// Default implementation for consumer that have no special handling of
 		// item groups
-		for (typename OpSet<ITEM>::const_iterator i = items.begin();
+		for (typename std::set<ITEM>::const_iterator i = items.begin();
 				i != items.end(); i++)
 			consume(*i);
 	}
 
 	/// Process a set of items identically tagged, with their tags
-	virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
+	virtual void consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tags)
 	{
 		// Default implementation for consumer that have no special handling of
 		// item groups
-		for (typename OpSet<ITEM>::const_iterator i = items.begin();
+		for (typename std::set<ITEM>::const_iterator i = items.begin();
 				i != items.end(); i++)
 			consume(*i, tags);
 	}
@@ -76,13 +76,13 @@
 	void consume(const ITEM& item) { consumeItemUntagged(item); }
 
 	/// Process a tagged item, with its tags
-	void consume(const ITEM& item, const OpSet<TAG>& tags) { consumeItem(item, tags); }
+	void consume(const ITEM& item, const std::set<TAG>& tags) { consumeItem(item, tags); }
 
 	/// Process a set of items, all with no tags
-	void consume(const OpSet<ITEM>& items) { consumeItemsUntagged(items); }
+	void consume(const std::set<ITEM>& items) { consumeItemsUntagged(items); }
 
 	/// Process a set of items identically tagged, with their tags
-	void consume(const OpSet<ITEM>& items, const OpSet<TAG>& tags) { consumeItems(items, tags); }
+	void consume(const std::set<ITEM>& items, const std::set<TAG>& tags) { consumeItems(items, tags); }
 };
 
 template<class ITEM, class TAG>

Modified: tagcoll/2.0/tagcoll/DerivedTags.h
==============================================================================
--- tagcoll/2.0/tagcoll/DerivedTags.h	(original)
+++ tagcoll/2.0/tagcoll/DerivedTags.h	Tue May  2 00:54:47 2006
@@ -27,6 +27,7 @@
 #include <tagcoll/Filter.h>
 #include <tagcoll/Expression.h>
 
+#include <wibble/operators.h>
 #include <map>
 #include <string>
 
@@ -55,14 +56,15 @@
 	/**
 	 * Return the tags in `tags', plus all the derived tags that matched `tags'
 	 */
-	OpSet<std::string> derivedTags(const OpSet<std::string>& tags) const
+	std::set<std::string> derivedTags(const std::set<std::string>& tags) const
 	{
-		OpSet<std::string> res;
+		using namespace wibble::operators;
+		std::set<std::string> res;
 		for (const_iterator i = begin(); i != end(); i++)
 		{
 			TagexprContext context(tags, *this);
 			if (i->second(context))
-				res += i->first;
+				res |= i->first;
 		}
 		return res;
 
@@ -80,19 +82,21 @@
 
 	virtual void consumeItemUntagged(const ITEM& item)
 	{
-		this->consumer->consume(item, dtags.derivedTags(OpSet<std::string>()));
+		this->consumer->consume(item, dtags.derivedTags(std::set<std::string>()));
 	}
-	virtual void consumeItem(const ITEM& item, const OpSet<std::string>& tags)
+	virtual void consumeItem(const ITEM& item, const std::set<std::string>& tags)
 	{
-		this->consumer->consume(item, tags + dtags.derivedTags(tags));
+		using namespace wibble::operators;
+		this->consumer->consume(item, tags | dtags.derivedTags(tags));
 	}
-	virtual void consumeItemsUntagged(const OpSet<ITEM>& items)
+	virtual void consumeItemsUntagged(const std::set<ITEM>& items)
 	{
-		this->consumer->consume(items, dtags.derivedTags(OpSet<std::string>()));
+		this->consumer->consume(items, dtags.derivedTags(std::set<std::string>()));
 	}
-	virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<std::string>& tags)
+	virtual void consumeItems(const std::set<ITEM>& items, const std::set<std::string>& tags)
 	{
-		this->consumer->consume(items, tags + dtags.derivedTags(tags));
+		using namespace wibble::operators;
+		this->consumer->consume(items, tags | dtags.derivedTags(tags));
 	}
 	
 public:
@@ -127,16 +131,18 @@
 	{
 		this->consumer->consume(item);
 	}
-	virtual void consumeItem(const ITEM& item, const OpSet<std::string>& tags)
+	virtual void consumeItem(const ITEM& item, const std::set<std::string>& tags)
 	{
+		using namespace wibble::operators;
 		this->consumer->consume(item, tags - dtags.derivedTags(tags));
 	}
-	virtual void consumeItemsUntagged(const OpSet<ITEM>& items)
+	virtual void consumeItemsUntagged(const std::set<ITEM>& items)
 	{
 		this->consumer->consume(items);
 	}
-	virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<std::string>& tags)
+	virtual void consumeItems(const std::set<ITEM>& items, const std::set<std::string>& tags)
 	{
+		using namespace wibble::operators;
 		this->consumer->consume(items, tags - dtags.derivedTags(tags));
 	}
 

Modified: tagcoll/2.0/tagcoll/Expression.cc
==============================================================================
--- tagcoll/2.0/tagcoll/Expression.cc	(original)
+++ tagcoll/2.0/tagcoll/Expression.cc	Tue May  2 00:54:47 2006
@@ -304,6 +304,8 @@
 
 }
 
+#include <tagcoll/TextFormat.tcc>
+
 #endif
 
 // vim:set ts=4 sw=4:

Modified: tagcoll/2.0/tagcoll/Expression.h
==============================================================================
--- tagcoll/2.0/tagcoll/Expression.h	(original)
+++ tagcoll/2.0/tagcoll/Expression.h	Tue May  2 00:54:47 2006
@@ -113,7 +113,15 @@
 	Expression operator not ();
 
 	template<typename Tags>
-	bool operator()(const Tags& tags) const { return m_impl->eval(tags); }
+	bool operator()(const Tags& tags) const
+	{
+		std::set<std::string> stags;
+		for (typename Tags::const_iterator i = tags.begin();
+				i != tags.end(); ++i)
+			stags.insert(*i);
+		return m_impl->eval(stags);
+	}
+	bool operator()(const std::set<std::string>& tags) const { return m_impl->eval(tags); }
 
 	bool operator()(const TagexprContext& context) const { return m_impl->eval(context); }
 
@@ -240,7 +248,7 @@
 	
 	// output iterator interface
 
-	FilterItemsByExpression& operator++() const { return *this; }
+	FilterItemsByExpression& operator++() { return *this; }
 
 	template<typename Items, typename Tags>
 	FilterItemsByExpression& operator=(const std::pair<Items, Tags>& data)

Modified: tagcoll/2.0/tagcoll/Filter.h
==============================================================================
--- tagcoll/2.0/tagcoll/Filter.h	(original)
+++ tagcoll/2.0/tagcoll/Filter.h	Tue May  2 00:54:47 2006
@@ -42,9 +42,9 @@
 	Consumer<ITEM, TAG>* consumer;
 
 	virtual void consumeItemUntagged(const ITEM& item) { consumer->consume(item); }
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags) { consumer->consume(item, tags); }
-	//virtual void consumeItemsUntagged(const OpSet<ITEM>& items) { consumer->consume(items); }
-	//virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags) { consumer->consume(items, tags); }
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags) { consumer->consume(item, tags); }
+	//virtual void consumeItemsUntagged(const std::set<ITEM>& items) { consumer->consume(items); }
+	//virtual void consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tags) { consumer->consume(items, tags); }
 
 public:
 	/**

Modified: tagcoll/2.0/tagcoll/Filters.cc
==============================================================================
--- tagcoll/2.0/tagcoll/Filters.cc	(original)
+++ tagcoll/2.0/tagcoll/Filters.cc	Tue May  2 00:54:47 2006
@@ -20,8 +20,11 @@
 
 #include <tagcoll/Filters.h>
 
+#include <wibble/operators.h>
 #include <iostream>
 
+using namespace wibble::operators;
+
 namespace tagcoll {
 
 template<typename ITEM>
@@ -31,13 +34,13 @@
 }
 
 template<typename ITEM>
-void UnfacetedRemover<ITEM>::consumeItem(const ITEM& item, const OpSet<std::string>& tags)
+void UnfacetedRemover<ITEM>::consumeItem(const ITEM& item, const std::set<std::string>& tags)
 {
-	OpSet<std::string> patched;
-	for (OpSet<std::string>::const_iterator i = tags.begin();
-			i != tags.end(); i++)
+	std::set<std::string> patched;
+	for (std::set<std::string>::const_iterator i = tags.begin();
+			i != tags.end(); ++i)
 		if (i->find(separator) != std::string::npos)
-			patched += *i;
+			patched |= *i;
 
 	if (patched.size())
 		this->consumer->consume(item, patched);
@@ -46,19 +49,19 @@
 }
 
 template<typename ITEM>
-void UnfacetedRemover<ITEM>::consumeItemsUntagged(const OpSet<ITEM>& items)
+void UnfacetedRemover<ITEM>::consumeItemsUntagged(const std::set<ITEM>& items)
 {
 	this->consumer->consume(items);
 }
 
 template<typename ITEM>
-void UnfacetedRemover<ITEM>::consumeItems(const OpSet<ITEM>& items, const OpSet<std::string>& tags)
+void UnfacetedRemover<ITEM>::consumeItems(const std::set<ITEM>& items, const std::set<std::string>& tags)
 {
-	OpSet<std::string> patched;
-	for (OpSet<std::string>::const_iterator i = tags.begin();
+	std::set<std::string> patched;
+	for (std::set<std::string>::const_iterator i = tags.begin();
 			i != tags.end(); i++)
 		if (i->find(separator) != std::string::npos)
-			patched += *i;
+			patched |= *i;
 
 	if (patched.size())
 		this->consumer->consume(items, patched);
@@ -160,5 +163,7 @@
 
 }
 
+#include <tagcoll/TextFormat.tcc>
+
 #endif
 // vim:set ts=4 sw=4:

Modified: tagcoll/2.0/tagcoll/Filters.h
==============================================================================
--- tagcoll/2.0/tagcoll/Filters.h	(original)
+++ tagcoll/2.0/tagcoll/Filters.h	Tue May  2 00:54:47 2006
@@ -33,7 +33,7 @@
 {
 
 /**
- * Store a list of substitutions to operate on OpSets
+ * Store a list of substitutions to operate on std::set
  *
  * It uses a Consumer interface to allow to be populated using a decoder for
  * collections such as TextFormat.
@@ -54,7 +54,7 @@
 	public:
 		SubstitutionsInserter(Substitutions<IT>& out)
 			: out(out) {}
-		SubstitutionsInserter& operator++() const { return *this; }
+		SubstitutionsInserter& operator++() { return *this; }
 
 		template<typename NewItems, typename OldItems>
 		SubstitutionsInserter& operator=(const std::pair<NewItems, OldItems>& data)
@@ -64,6 +64,7 @@
 				for (typename OldItems::const_iterator j = data.second.begin();
 						j != data.second.end(); ++j)
 					out.add(*j, *i);
+			return *this;
 		}
 	};
 
@@ -135,13 +136,14 @@
 	 */
 	const Substitutions<T>& substitutions() const { return changes; }
 
-	Substitute<T, OUT>& operator++() const { return *this; }
+	Substitute<T, OUT>& operator++() { return *this; }
 
 	template<typename Items, typename Tags>
 	Substitute<T, OUT>& operator=(const std::pair<Items, Tags>& data)
 	{
 		out = make_pair(data.first, changes.change(data.second));
 		++out;
+		return *this;
 	}
 };
 
@@ -168,7 +170,7 @@
 		if (inverse)
 			this->consumer->consume(item);
 	}
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags)
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags)
 	{
 		if (inverse)
 		{
@@ -179,12 +181,12 @@
 				this->consumer->consume(item, tags);
 		}
 	}
-	virtual void consumeItemsUntagged(const OpSet<ITEM>& items)
+	virtual void consumeItemsUntagged(const std::set<ITEM>& items)
 	{
 		if (inverse)
 			this->consumer->consume(items);
 	}
-	virtual void consumeItemss(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
+	virtual void consumeItemss(const std::set<ITEM>& items, const std::set<TAG>& tags)
 	{
 		if (inverse)
 		{
@@ -214,9 +216,9 @@
 	std::string separator;
 		
 	virtual void consumeItemUntagged(const ITEM& item);
-	virtual void consumeItem(const ITEM& item, const OpSet<std::string>& tags);
-	virtual void consumeItemsUntagged(const OpSet<ITEM>& items);
-	virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<std::string>& tags);
+	virtual void consumeItem(const ITEM& item, const std::set<std::string>& tags);
+	virtual void consumeItemsUntagged(const std::set<ITEM>& items);
+	virtual void consumeItems(const std::set<ITEM>& items, const std::set<std::string>& tags);
 
 public:
 	UnfacetedRemover() : separator("::") {}

Modified: tagcoll/2.0/tagcoll/Implications.cc
==============================================================================
--- tagcoll/2.0/tagcoll/Implications.cc	(original)
+++ tagcoll/2.0/tagcoll/Implications.cc	Tue May  2 00:54:47 2006
@@ -19,30 +19,32 @@
  */
 
 #include <tagcoll/Implications.h>
+#include <wibble/operators.h>
 
 #include <algorithm>
 
 using namespace std;
 using namespace tagcoll;
+using namespace wibble::operators;
 
 template<class TAG>
-OpSet<TAG> Implications<TAG>::getDestinations(const TAG& tag, const OpSet<TAG>& seen) const
+std::set<TAG> Implications<TAG>::getDestinations(const TAG& tag, const std::set<TAG>& seen) const
 {
 	typename impl_t::const_iterator i = implications.find(tag);
 	if (i == implications.end())
-		return OpSet<TAG>();
+		return std::set<TAG>();
 
 	// res <- the union of all the destinations of the tag
-	OpSet<TAG> res;
-	for (typename OpSet<TAG>::const_iterator t = i->second.begin();
+	std::set<TAG> res;
+	for (typename std::set<TAG>::const_iterator t = i->second.begin();
 			t != i->second.end(); t++)
 	{
 		// If the tag is already in res, then also all his destinations are
 		// already there
-		if (!res.contains(*t) && !seen.contains(*t))
+		if (!set_contains(res, *t) && !set_contains(seen, *t))
 		{
-			res += *t;
-			res += getDestinations(*t, seen + tag);
+			res |= *t;
+			res |= getDestinations(*t, seen | tag);
 		}
 	}
 
@@ -50,7 +52,7 @@
 }
 
 template<class TAG>
-bool Implications<TAG>::reaches(const TAG& tag1, const TAG& tag2, const OpSet<TAG>& seen) const
+bool Implications<TAG>::reaches(const TAG& tag1, const TAG& tag2, const std::set<TAG>& seen) const
 {
 	// Check if we've reached the target
 	if (tag1 == tag2)
@@ -62,9 +64,9 @@
 		return false;
 
 	// Try all paths
-	for (typename OpSet<TAG>::const_iterator t = i->second.begin();
+	for (typename std::set<TAG>::const_iterator t = i->second.begin();
 			t != i->second.end(); t++)
-		if (!seen.contains(*t) && reaches(*t, tag2, seen + tag1))
+		if (!set_contains(seen, *t) && reaches(*t, tag2, seen | tag1))
 			return true;
 
 	// Nothing has been found
@@ -79,33 +81,33 @@
 	for (typename impl_t::iterator i = implications.begin();
 			i != implications.end(); i++)
 	{
-		OpSet<TAG> redundant;
+		std::set<TAG> redundant;
 
 		// For every couple of parents A and B, if A -> B but not B -> A, then B is redundant
 		// I need to check every combination; however, I can ignore in the
 		// search items that have already been found as redundant
 
-		OpSet<TAG> candidates = i->second;
+		std::set<TAG> candidates = i->second;
 		while (candidates.size() > 1)
 		{
-			typename OpSet<TAG>::const_iterator a = candidates.begin();
-			typename OpSet<TAG>::const_iterator b = a;
-			OpSet<TAG> got;
+			typename std::set<TAG>::const_iterator a = candidates.begin();
+			typename std::set<TAG>::const_iterator b = a;
+			std::set<TAG> got;
 			for (++b; b != candidates.end(); b++)
 			{
 				bool ab = reaches(*a, *b);
 				bool ba = reaches(*b, *a);
 				if (ab && !ba)
 				{
-					got += *b;
+					got |= *b;
 					break;
 				} else if (ba && !ab) {
-					got += *a;
+					got |= *a;
 					break;
 				}
 			}
 			candidates -= got;
-			redundant += got;
+			redundant |= got;
 			if (!candidates.empty())
 				candidates.erase(candidates.begin());
 		}
@@ -115,16 +117,16 @@
 }
 
 template <class TAG>
-OpSet<TAG> Implications<TAG>::compress(const OpSet<TAG>& tags) const
+std::set<TAG> Implications<TAG>::compress(const std::set<TAG>& tags) const
 {
 	// Create the union of the expansion sets of each single tag, without the tag
 	// tags = tags - this union
-	OpSet<TAG> redundant;
-	for (typename OpSet<TAG>::const_iterator t = tags.begin();
+	std::set<TAG> redundant;
+	for (typename std::set<TAG>::const_iterator t = tags.begin();
 			t != tags.end(); t++)
 	{
-		OpSet<TAG> expanded = expand(*t);
-		for (typename OpSet<TAG>::const_iterator i = expanded.begin();
+		std::set<TAG> expanded = expand(*t);
+		for (typename std::set<TAG>::const_iterator i = expanded.begin();
 				i != expanded.end(); i++)
 			if (*i != *t)
 				redundant.insert(*i);

Modified: tagcoll/2.0/tagcoll/Implications.h
==============================================================================
--- tagcoll/2.0/tagcoll/Implications.h	(original)
+++ tagcoll/2.0/tagcoll/Implications.h	Tue May  2 00:54:47 2006
@@ -26,6 +26,7 @@
 #include <tagcoll/Consumer.h>
 #include <tagcoll/Filter.h>
 
+#include <wibble/operators.h>
 #include <map>
 
 namespace tagcoll
@@ -39,18 +40,18 @@
 {
 protected:
 	// DAG of arcs: child -> {parents}
-	typedef std::map< TAG, OpSet<TAG> > impl_t;
+	typedef std::map< TAG, std::set<TAG> > impl_t;
 	impl_t implications;
 
 	/// Get the set of all tags seen when walking through all parent lists
-	OpSet<TAG> getDestinations(const TAG& tag, const OpSet<TAG>& seen = OpSet<TAG>()) const;
+	std::set<TAG> getDestinations(const TAG& tag, const std::set<TAG>& seen = std::set<TAG>()) const;
 
 	/// Return true if tag1 can reach tag2 walking through some path in its parent list
-	bool reaches(const TAG& tag1, const TAG& tag2, const OpSet<TAG>& seen = OpSet<TAG>()) const;
+	bool reaches(const TAG& tag1, const TAG& tag2, const std::set<TAG>& seen = std::set<TAG>()) const;
 
 	virtual void consumeItemUntagged(const TAG& item) {}
 
-	virtual void consumeItem(const TAG& item, const OpSet<TAG>& tags)
+	virtual void consumeItem(const TAG& item, const std::set<TAG>& tags)
 	{
 		implications.insert(make_pair(item, tags));
 	}
@@ -59,23 +60,27 @@
 	virtual ~Implications() {}
 	
 	/// Expand a single tag
-	OpSet<TAG> expand(const TAG& tag) const { return getDestinations(tag) + tag; }
+	std::set<TAG> expand(const TAG& tag) const
+	{
+		using namespace wibble::operators;
+		return getDestinations(tag) | tag;
+	}
 
 
 	/// Expand a full tagset
-	OpSet<TAG> expand(const OpSet<TAG>& tags) const
+	std::set<TAG> expand(const std::set<TAG>& tags) const
 	{
-		OpSet<TAG> res = tags;
+		std::set<TAG> res = tags;
 
-		for (typename OpSet<TAG>::const_iterator t = tags.begin();
+		for (typename std::set<TAG>::const_iterator t = tags.begin();
 				t != tags.end(); t++)
-			res += expand(*t);
+			res |= expand(*t);
 
 		return res;
 	}
 
 	/// Compress a tagset removing implied tags
-	OpSet<TAG> compress(const OpSet<TAG>& tags) const;
+	std::set<TAG> compress(const std::set<TAG>& tags) const;
 
 	// Remove unnecessary arcs from the dag
 	void pack();
@@ -86,7 +91,7 @@
 		for (typename impl_t::const_iterator i = implications.begin();
 				i != implications.end(); i++)
 		{
-			OpSet<TAG> destinations = getDestinations(i->first);
+			std::set<TAG> destinations = getDestinations(i->first);
 
 			if (destinations.empty())
 				consumer.consume(i->first);
@@ -117,12 +122,12 @@
 	Implications<TAG> impls;
 
 	virtual void consumeItemUntagged(const ITEM& item) { this->consumer->consume(item); }
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags)
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags)
 	{
 		this->consumer->consume(item, impls.expand(tags));
 	}
-	virtual void consumeItemsUntagged(const OpSet<ITEM>& items) { this->consumer->consume(items); }
-	virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
+	virtual void consumeItemsUntagged(const std::set<ITEM>& items) { this->consumer->consume(items); }
+	virtual void consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tags)
 	{
 		this->consumer->consume(items, impls.expand(tags));
 	}
@@ -156,12 +161,12 @@
 	Implications<TAG> impls;
 
 	virtual void consumeItemUntagged(const ITEM& item) { this->consumer->consume(item); }
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags)
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags)
 	{
 		this->consumer->consume(item, impls.compress(tags));
 	}
-	virtual void consumeItemsUntagged(const OpSet<ITEM>& items) { this->consumer->consume(items); }
-	virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
+	virtual void consumeItemsUntagged(const std::set<ITEM>& items) { this->consumer->consume(items); }
+	virtual void consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tags)
 	{
 		this->consumer->consume(items, impls.compress(tags));
 	}

Modified: tagcoll/2.0/tagcoll/InputMerger.cc
==============================================================================
--- tagcoll/2.0/tagcoll/InputMerger.cc	(original)
+++ tagcoll/2.0/tagcoll/InputMerger.cc	Tue May  2 00:54:47 2006
@@ -21,57 +21,60 @@
 #include <tagcoll/InputMerger.h>
 #include <tagcoll/Patches.h>
 
+#include <wibble/operators.h>
+
 using namespace std;
+using namespace wibble::operators;
 
 namespace tagcoll {
 
 template<class T, class Tag>
-void InputMerger<T, Tag>::consumeItem(const T& item, const OpSet<Tag>& tags)
+void InputMerger<T, Tag>::consumeItem(const T& item, const std::set<Tag>& tags)
 {
-	typename map< T, OpSet<Tag> >::iterator i = coll.find(item);
+	typename map< T, std::set<Tag> >::iterator i = coll.find(item);
 	if (i == coll.end())
 		coll.insert(make_pair(item, tags));
 	else
-		i->second += tags;
+		i->second |= tags;
 }
 
 template<class T, class Tag>
-OpSet<Tag> InputMerger<T, Tag>::getTagsOfItem(const T& item) const
+std::set<Tag> InputMerger<T, Tag>::getTagsOfItem(const T& item) const
 {
-	typename map< T, OpSet<Tag> >::const_iterator i = coll.find(item);
+	typename map< T, std::set<Tag> >::const_iterator i = coll.find(item);
 	
 	if (i == coll.end())
-		return OpSet<Tag>();
+		return std::set<Tag>();
 	else
 		return i->second;
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> InputMerger<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
+std::set<ITEM> InputMerger<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
 {
-	OpSet<ITEM> res;
-	for (typename map< ITEM, OpSet<TAG> >::const_iterator i = coll.begin();
+	std::set<ITEM> res;
+	for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin();
 			i != coll.end(); i++)
-		if (i->second.contains(tag))
-			res += i->first;
+		if (i->second.find(tag) != i->second.end())
+			res |= i->first;
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> InputMerger<ITEM, TAG>::getItemsHavingTags(const OpSet<TAG>& tags) const
+std::set<ITEM> InputMerger<ITEM, TAG>::getItemsHavingTags(const std::set<TAG>& tags) const
 {
-	OpSet<ITEM> res;
-	for (typename map< ITEM, OpSet<TAG> >::const_iterator i = coll.begin();
+	std::set<ITEM> res;
+	for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin();
 			i != coll.end(); i++)
-		if (i->second.contains(tags))
-			res += i->first;
+		if (set_contains(i->second, tags))
+			res |= i->first;
 	return res;
 }
 
 template<class T, class Tag>
 void InputMerger<T, Tag>::output(Consumer<T, Tag>& consumer) const
 {
-	for (typename map< T, OpSet<Tag> >::const_iterator i = coll.begin();
+	for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
 			i != coll.end(); i++)
 		if (!i->second.empty())
 			consumer.consume(i->first, i->second);
@@ -80,21 +83,21 @@
 template<class T, class Tag>
 void InputMerger<T, Tag>::outputReversed(Consumer<Tag, T>& consumer) const
 {
-	for (typename map< T, OpSet<Tag> >::const_iterator i = coll.begin();
+	for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
 			i != coll.end(); i++)
 	{
-		OpSet<T> items;
-		items += i->first;
+		std::set<T> items;
+		items |= i->first;
 		consumer.consume(i->second, items);
 	}
 }
 
 template<class ITEM, class TAG>
-void InputMerger<ITEM, TAG>::outputHavingTags(const OpSet<TAG>& ts, Consumer<ITEM, TAG>& consumer) const
+void InputMerger<ITEM, TAG>::outputHavingTags(const std::set<TAG>& ts, Consumer<ITEM, TAG>& consumer) const
 {
-	for (typename map< ITEM, OpSet<TAG> >::const_iterator i = coll.begin();
+	for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin();
 			i != coll.end(); i++)
-		if (i->second.contains(ts))
+		if (set_contains(i->second, ts))
 			consumer.consume(i->first, i->second);
 }
 
@@ -106,7 +109,7 @@
 {
 	for (typename PatchList<T, Tag>::const_iterator i = change.begin(); i != change.end(); i++)
 	{
-		typename map< T, OpSet<Tag> >::iterator it = coll.find(i->first);
+		typename map< T, std::set<Tag> >::iterator it = coll.find(i->first);
 		if (it == coll.end())
 		{
 			// If the item doesn't exist, create it
@@ -118,41 +121,41 @@
 }
 
 template<class T, class Tag>
-OpSet<Tag> InputMerger<T, Tag>::getAllTags() const
+std::set<Tag> InputMerger<T, Tag>::getAllTags() const
 {
-	OpSet<Tag> tags;
+	std::set<Tag> tags;
 
-	for (typename map< T, OpSet<Tag> >::const_iterator i = coll.begin();
+	for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
 			i != coll.end(); i++)
-		tags += i->second;
+		tags |= i->second;
 	
 	return tags;
 }
 
 template<class T, class Tag>
-OpSet<Tag> InputMerger<T, Tag>::getCompanionTags(const OpSet<Tag>& ts) const
+std::set<Tag> InputMerger<T, Tag>::getCompanionTags(const std::set<Tag>& ts) const
 {
-	OpSet<Tag> tags;
+	std::set<Tag> tags;
 
-	for (typename map< T, OpSet<Tag> >::const_iterator i = coll.begin();
+	for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
 			i != coll.end(); i++)
-		if (i->second.contains(ts))
-			tags += i->second - ts;
+		if (set_contains(i->second, (ts)))
+			tags |= i->second - ts;
 	
 	return tags;
 }
 
 template<class T, class Tag>
-OpSet<T> InputMerger<T, Tag>::getRelatedItems(const OpSet<Tag>& tags, int maxdistance) const
+std::set<T> InputMerger<T, Tag>::getRelatedItems(const std::set<Tag>& tags, int maxdistance) const
 {
-	OpSet<T> res;
+	std::set<T> res;
 
-	for (typename map< T, OpSet<Tag> >::const_iterator i = coll.begin();
+	for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
 			i != coll.end(); i++)
 	{
-		int dist = tags.distance(i->second);
+		int dist = set_distance(tags, i->second);
 		if (dist >= 0 && dist <= maxdistance)
-			res += i->first;
+			res |= i->first;
 	}
 	
 	return res;

Modified: tagcoll/2.0/tagcoll/InputMerger.h
==============================================================================
--- tagcoll/2.0/tagcoll/InputMerger.h	(original)
+++ tagcoll/2.0/tagcoll/InputMerger.h	Tue May  2 00:54:47 2006
@@ -46,13 +46,13 @@
 class InputMerger : public Collection<ITEM, TAG>
 {
 protected:
-	std::map< ITEM, OpSet<TAG> > coll;
+	std::map< ITEM, std::set<TAG> > coll;
 	
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
 
-	virtual OpSet<TAG> getTagsOfItem(const ITEM& item) const;
-	virtual OpSet<ITEM> getItemsHavingTag(const TAG& tag) const;
-	virtual OpSet<ITEM> getItemsHavingTags(const OpSet<TAG>& tags) const;
+	virtual std::set<TAG> getTagsOfItem(const ITEM& item) const;
+	virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const;
+	virtual std::set<ITEM> getItemsHavingTags(const std::set<TAG>& tags) const;
 
 
 public:
@@ -61,7 +61,7 @@
 	bool hasItem(const ITEM& item) const { return coll.find(item) != coll.end(); }
 
 	void output(Consumer<ITEM, TAG>& consumer) const;
-	void outputHavingTags(const OpSet<TAG>& ts, Consumer<ITEM, TAG>& consumer) const;
+	void outputHavingTags(const std::set<TAG>& ts, Consumer<ITEM, TAG>& consumer) const;
 
 	/**
 	 * Send the merged data to a consumer, but reversed: the tag become items,
@@ -71,20 +71,20 @@
 
 	void applyChange(const PatchList<ITEM, TAG>& change);
 
-	virtual OpSet<ITEM> getTaggedItems() const
+	virtual std::set<ITEM> getTaggedItems() const
 	{
-		OpSet<ITEM> res;
-		for (typename std::map< ITEM, OpSet<TAG> >::const_iterator i = coll.begin();
+		std::set<ITEM> res;
+		for (typename std::map< ITEM, std::set<TAG> >::const_iterator i = coll.begin();
 				i != coll.end(); i++)
-			res += i->first;
+			res.insert(i->first);
 		return res;
 	}
 	
-	OpSet<TAG> getAllTags() const;
+	std::set<TAG> getAllTags() const;
 
-	OpSet<TAG> getCompanionTags(const OpSet<TAG>& ts) const;
+	std::set<TAG> getCompanionTags(const std::set<TAG>& ts) const;
 
-	OpSet<ITEM> getRelatedItems(const OpSet<TAG>& ts, int maxdistance = 1) const;
+	std::set<ITEM> getRelatedItems(const std::set<TAG>& ts, int maxdistance = 1) const;
 
 	/**
 	 * Count the number of items

Modified: tagcoll/2.0/tagcoll/IntDiskIndex.cc
==============================================================================
--- tagcoll/2.0/tagcoll/IntDiskIndex.cc	(original)
+++ tagcoll/2.0/tagcoll/IntDiskIndex.cc	Tue May  2 00:54:47 2006
@@ -19,10 +19,12 @@
  */
 
 #include <tagcoll/IntDiskIndex.h>
+#include <wibble/operators.h>
 #include <list>
 
 using namespace std;
 using namespace tagcoll;
+using namespace wibble::operators;
 
 //#define TRACE_ISI
 
@@ -207,7 +209,7 @@
 	}
 
 	template<typename T>
-	OpSet<T> intersect(const Converter<int, T>& conv)
+	std::set<T> intersect(const Converter<int, T>& conv)
 	{
 		print("begin");
 		/*
@@ -215,7 +217,7 @@
 		 *   and move on
 		 * * Else, advance the minor ones until they all get the same
 		 */
-		OpSet<T> res;
+		std::set<T> res;
 		while (size() > 1)
 		{
 			print("pre-flatten");
@@ -224,7 +226,7 @@
 			if (size() > 1)
 			{
 				// Store the common item
-				res += conv(*(begin()->second));
+				res |= conv(*(begin()->second));
 				//cerr << "Selected: " << *(begin()->second) << endl;
 
 				// Advance all lists
@@ -241,7 +243,7 @@
 		return res;
 	}
 
-	OpSet<int> intersect()
+	std::set<int> intersect()
 	{
 		print("begin");
 		/*
@@ -249,7 +251,7 @@
 		 *   and move on
 		 * * Else, advance the minor ones until they all get the same
 		 */
-		OpSet<int> res;
+		std::set<int> res;
 		while (size() > 1)
 		{
 			print("pre-flatten");
@@ -258,7 +260,7 @@
 			if (size() > 1)
 			{
 				// Store the common item
-				res += *(begin()->second);
+				res |= *(begin()->second);
 				//cerr << "Selected: " << *(begin()->second) << endl;
 
 				// Advance all lists
@@ -336,36 +338,36 @@
 	}
 
 	template<typename T>
-	OpSet<T> merge(const Converter<int, T>& conv)
+	std::set<T> merge(const Converter<int, T>& conv)
 	{
 		/*
 		vector<T> sortedmerge;
 		while (!empty())
 			sortedmerge.push_back(conv(extractmin()));
-		return OpSet<T>(sortedmerge.begin(), sortedmerge.end());
+		return std::set<T>(sortedmerge.begin(), sortedmerge.end());
 		*/
-		return OpSet<T>(mergeBegin<T>(conv), mergeEnd<T>(conv));
+		return std::set<T>(mergeBegin<T>(conv), mergeEnd<T>(conv));
 	}
 };
 
 template<typename ITEM, typename TAG>
-OpSet<ITEM> IntDiskIndex<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
+std::set<ITEM> IntDiskIndex<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
 {
 	int id = fromtag(tag);
-	return OpSet<ITEM>(IntSetIterator<ITEM>(tagidx.data(id), tagidx.size(id), *m_toitem), IntSetIterator<ITEM>(*m_toitem));
+	return std::set<ITEM>(IntSetIterator<ITEM>(tagidx.data(id), tagidx.size(id), *m_toitem), IntSetIterator<ITEM>(*m_toitem));
 }
 
 template<typename ITEM, typename TAG>
-OpSet<ITEM> IntDiskIndex<ITEM, TAG>::getItemsHavingTags(const OpSet<TAG>& tags) const
+std::set<ITEM> IntDiskIndex<ITEM, TAG>::getItemsHavingTags(const std::set<TAG>& tags) const
 {
 	if (tags.empty())
-		return OpSet<ITEM>();
+		return std::set<ITEM>();
 	if (tags.size() == 1)
 		return getItemsHavingTag(*tags.begin());
 
 	// Create a vector with the item lists
 	IntSets items;
-	for (typename OpSet<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
+	for (typename std::set<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
 	{
 		int id = fromtag(*i);
 		items.push_back(make_pair(tagidx.size(id), tagidx.data(id)));
@@ -374,21 +376,21 @@
 }
 
 template<typename ITEM, typename TAG>
-OpSet<TAG> IntDiskIndex<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
+std::set<TAG> IntDiskIndex<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
 {
 	int id = fromitem(item);
-	return OpSet<TAG>(IntSetIterator<TAG>(pkgidx.data(id), pkgidx.size(id), *m_totag), IntSetIterator<TAG>(*m_totag));
+	return std::set<TAG>(IntSetIterator<TAG>(pkgidx.data(id), pkgidx.size(id), *m_totag), IntSetIterator<TAG>(*m_totag));
 }
 
 template<typename ITEM, typename TAG>
-OpSet<TAG> IntDiskIndex<ITEM, TAG>::getTagsOfItems(const OpSet<ITEM>& items) const
+std::set<TAG> IntDiskIndex<ITEM, TAG>::getTagsOfItems(const std::set<ITEM>& items) const
 {
 	if (items.empty())
-		return OpSet<TAG>();
+		return std::set<TAG>();
 
 	// Create a vector with the item lists
 	IntSets tags;
-	for (typename OpSet<ITEM>::const_iterator i = items.begin(); i != items.end(); i++)
+	for (typename std::set<ITEM>::const_iterator i = items.begin(); i != items.end(); i++)
 	{
 		int id = fromitem(*i);
 		tags.push_back(make_pair(pkgidx.size(id), pkgidx.data(id)));
@@ -397,51 +399,51 @@
 }
 
 template<typename ITEM, typename TAG>
-OpSet<ITEM> IntDiskIndex<ITEM, TAG>::getTaggedItems() const
+std::set<ITEM> IntDiskIndex<ITEM, TAG>::getTaggedItems() const
 {
-	return OpSet<ITEM>(
+	return std::set<ITEM>(
 			NonemptyIntSeqIterator<ITEM>(pkgidx, 0, *m_toitem),
 			NonemptyIntSeqIterator<ITEM>(pkgidx, pkgidx.size(), *m_toitem));
 }
 
 template<typename ITEM, typename TAG>
-OpSet<TAG> IntDiskIndex<ITEM, TAG>::getAllTags() const
+std::set<TAG> IntDiskIndex<ITEM, TAG>::getAllTags() const
 {
-	return OpSet<TAG>(IntSeqIterator<TAG>(0, *m_totag), IntSeqIterator<TAG>(tagidx.size(), *m_totag));
+	return std::set<TAG>(IntSeqIterator<TAG>(0, *m_totag), IntSeqIterator<TAG>(tagidx.size(), *m_totag));
 }
 
 template<typename ITEM, typename TAG>
-OpSet<TAG> IntDiskIndex<ITEM, TAG>::getCompanionTags(const OpSet<TAG>& tags) const
+std::set<TAG> IntDiskIndex<ITEM, TAG>::getCompanionTags(const std::set<TAG>& tags) const
 {
 	// This is basically a reimplementation of:
 	// return getTagsOfItems(getItemsHavingTags(tags)) - tags;
 	// without the conversion to and from ITEM and TAG
 
 	if (tags.empty())
-		return OpSet<TAG>();
+		return std::set<TAG>();
 
-	OpSet<int> itags = (*m_fromtag)(tags);
-	OpSet<int> items;
+	std::set<int> itags = (*m_fromtag)(tags);
+	std::set<int> items;
 
 	if (itags.size() == 1)
 	{
 		int itag = *itags.begin();
 		for (unsigned int i = 0; i < tagidx.size(itag); i++)
-			items += tagidx.data(itag)[i];
+			items |= tagidx.data(itag)[i];
 	} else {
 		// Create a vector with the item lists
 		IntSets inters;
-		for (OpSet<int>::const_iterator i = itags.begin(); i != itags.end(); i++)
+		for (std::set<int>::const_iterator i = itags.begin(); i != itags.end(); i++)
 			inters.push_back(make_pair(tagidx.size(*i), tagidx.data(*i)));
 		items = inters.intersect();
 	}
 
 	if (items.empty())
-		return OpSet<TAG>();
+		return std::set<TAG>();
 
 	// Create a vector with the item lists
 	IntSets merge;
-	for (OpSet<int>::const_iterator i = items.begin(); i != items.end(); i++)
+	for (std::set<int>::const_iterator i = items.begin(); i != items.end(); i++)
 		merge.push_back(make_pair(pkgidx.size(*i), pkgidx.data(*i)));
 	return merge.merge<TAG>(*m_totag);
 }
@@ -451,7 +453,7 @@
 {
 	for (unsigned int i = 0; i < pkgidx.size(); i++)
 		if (pkgidx.size(i) > 0)
-			consumer.consume(toitem(i), OpSet<TAG>(IntSetIterator<TAG>(pkgidx.data(i), pkgidx.size(i), *m_totag), IntSetIterator<TAG>(*m_totag)));
+			consumer.consume(toitem(i), std::set<TAG>(IntSetIterator<TAG>(pkgidx.data(i), pkgidx.size(i), *m_totag), IntSetIterator<TAG>(*m_totag)));
 }
 
 
@@ -462,12 +464,12 @@
 	: fromitem(fromitem), fromtag(fromtag) {}
 
 template<class ITEM, class TAG>
-void IntDiskIndexer<ITEM, TAG>::consumeItem(const ITEM& item, const OpSet<TAG>& tags)
+void IntDiskIndexer<ITEM, TAG>::consumeItem(const ITEM& item, const std::set<TAG>& tags)
 {
 	int iitem = fromitem(item);
 	if (iitem == -1)
 		return;
-	for (typename OpSet<TAG>::iterator i = tags.begin(); i != tags.end(); i++)
+	for (typename std::set<TAG>::iterator i = tags.begin(); i != tags.end(); i++)
 	{
 		int itag = fromtag(*i);
 		if (itag == -1)
@@ -589,9 +591,9 @@
 #include <iostream>
 
 #if 0
-static void outts(const OpSet<string>& s)
+static void outts(const std::set<string>& s)
 {
-	for (OpSet<string>::const_iterator i = s.begin(); i != s.end(); i++)
+	for (std::set<string>::const_iterator i = s.begin(); i != s.end(); i++)
 		if (i == s.begin())
 			cerr << *i;
 		else
@@ -608,10 +610,10 @@
 
 #if 0
 	cerr << "Items: ";
-	OpSet<string> s = idx.getTaggedItems();
+	std::set<string> s = idx.getTaggedItems();
 	outts(s);
 	cerr << endl;
-	for (OpSet<string>::const_iterator i = s.begin(); i != s.end(); i++)
+	for (std::set<string>::const_iterator i = s.begin(); i != s.end(); i++)
 	{
 		cerr << "  " << *i << ": ";
 		outts(idx.getTags(*i));
@@ -623,7 +625,7 @@
 	s = idx.getAllTags();
 	outts(s);
 	cerr << endl;
-	for (OpSet<string>::const_iterator i = s.begin(); i != s.end(); i++)
+	for (std::set<string>::const_iterator i = s.begin(); i != s.end(); i++)
 	{
 		cerr << "  " << *i << ": ";
 		outts(idx.getItems(*i));

Modified: tagcoll/2.0/tagcoll/IntDiskIndex.h
==============================================================================
--- tagcoll/2.0/tagcoll/IntDiskIndex.h	(original)
+++ tagcoll/2.0/tagcoll/IntDiskIndex.h	Tue May  2 00:54:47 2006
@@ -58,10 +58,10 @@
 	inline ITEM toitem(const int& tag) const { return (*m_toitem)(tag); }
 	inline TAG totag(const int& tag) const { return (*m_totag)(tag); }
 
-	virtual OpSet<ITEM> getItemsHavingTag(const TAG& tag) const;
-	virtual OpSet<ITEM> getItemsHavingTags(const OpSet<TAG>& tags) const;
-	virtual OpSet<TAG> getTagsOfItem(const ITEM& item) const;
-	virtual OpSet<TAG> getTagsOfItems(const OpSet<ITEM>& items) const;
+	virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const;
+	virtual std::set<ITEM> getItemsHavingTags(const std::set<TAG>& tags) const;
+	virtual std::set<TAG> getTagsOfItem(const ITEM& item) const;
+	virtual std::set<TAG> getTagsOfItems(const std::set<ITEM>& items) const;
 
 public:
 	/**
@@ -120,16 +120,16 @@
 		return tagidx.size(fromtag(tag)) > 0;
 	}
 
-	virtual OpSet<ITEM> getTaggedItems() const;
+	virtual std::set<ITEM> getTaggedItems() const;
 
-	virtual OpSet<TAG> getAllTags() const;
+	virtual std::set<TAG> getAllTags() const;
 
 	virtual int getCardinality(const TAG& tag) const
 	{
 		return tagidx.size(fromtag(tag));
 	}
 
-	virtual OpSet<TAG> getCompanionTags(const OpSet<TAG>& tags) const;
+	virtual std::set<TAG> getCompanionTags(const std::set<TAG>& tags) const;
 
 	virtual void output(Consumer<ITEM, TAG>& consumer) const;
 };
@@ -144,7 +144,7 @@
 	const Converter<TAG, int>& fromtag;
 
 	virtual void consumeItemUntagged(const ITEM&) {}
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
 
 public:
 	IntDiskIndexer(

Modified: tagcoll/2.0/tagcoll/OpSet.h
==============================================================================
--- tagcoll/2.0/tagcoll/OpSet.h	(original)
+++ tagcoll/2.0/tagcoll/OpSet.h	Tue May  2 00:54:47 2006
@@ -31,6 +31,7 @@
 namespace tagcoll
 {
 
+#if 0
 /**
  * OpSet is just the standard std::set extended with set operations.
  *
@@ -143,6 +144,59 @@
 	 */
 	OpSet<T>& operator^=(const OpSet<T>& ts);
 };
+#endif
+
+template<typename T>
+int set_distance(const std::set<T>& set1, const std::set<T>& set2)
+{
+	int res = 0;
+	int intCount = 0;
+
+	typename std::set<T>::const_iterator a = set1.begin();
+	typename std::set<T>::const_iterator b = set2.begin();
+
+	while (a != set1.end() || b != set2.end())
+		if ((b == set2.end()) || (a != set1.end() && *a < *b))
+		{
+			res++;
+			a++;
+		}
+		else if ((a == set1.end()) || (b != set2.end() && *b < *a))
+		{
+			res++;
+			b++;
+		}
+		else
+		{
+			a++;
+			b++;
+			intCount++;
+		}
+	
+	return intCount ? res : -1;
+}
+
+template<typename T>
+bool set_contains(const std::set<T>& set1, const std::set<T>& set2)
+{
+	typename std::set<T>::const_iterator b = set2.begin();
+
+	for (typename std::set<T>::const_iterator a = set1.begin(); a != set1.end(); ++a)
+		if (b == set2.end())
+			return true;
+		else if (*a == *b)
+			b++;
+		else if (*b < *a)
+			return false;
+
+	return b == set2.end();
+}
+
+template<typename T>
+bool set_contains(const std::set<T>& set1, const T& item)
+{
+	return set1.find(item) != set1.end();
+}
 
 };
 

Modified: tagcoll/2.0/tagcoll/PatchCollection.cc
==============================================================================
--- tagcoll/2.0/tagcoll/PatchCollection.cc	(original)
+++ tagcoll/2.0/tagcoll/PatchCollection.cc	Tue May  2 00:54:47 2006
@@ -20,42 +20,45 @@
 
 #include <tagcoll/PatchCollection.h>
 
+#include <wibble/operators.h>
+
 using namespace std;
+using namespace wibble::operators;
 
 namespace tagcoll
 {
 
 template<class ITEM, class TAG>
-void PatchCollection<ITEM, TAG>::consumeItem(const ITEM& item, const OpSet<TAG>& tags)
+void PatchCollection<ITEM, TAG>::consumeItem(const ITEM& item, const std::set<TAG>& tags)
 {
 	if (!tags.empty())
-		changes.addPatch(Patch<ITEM, TAG>(item, tags, OpSet<TAG>()));
+		changes.addPatch(Patch<ITEM, TAG>(item, tags, std::set<TAG>()));
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> PatchCollection<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
+std::set<ITEM> PatchCollection<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
 {
-	OpSet<ITEM> items(coll.getItems(tag));
-	OpSet<ITEM> res;
+	std::set<ITEM> items(coll.getItems(tag));
+	std::set<ITEM> res;
 
 	// Check items in coll first
-	for (typename OpSet<ITEM>::const_iterator i = items.begin();
+	for (typename std::set<ITEM>::const_iterator i = items.begin();
 			i != items.end(); i++)
 		// If they are unmodified, then we can trust coll.getItems
 		if (changes.find(*i) == changes.end())
-			res += *i;
+			res |= *i;
 
 	// Then check items in the patch
 	for (typename PatchList<ITEM, TAG>::const_iterator i = changes.begin();
 			i != changes.end(); i++)
-		if (changes.patch(i->first, coll.getTags(i->first)).contains(tag))
-			res += i->first;
+		if (set_contains(changes.patch(i->first, coll.getTags(i->first)), tag))
+			res |= i->first;
 
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> PatchCollection<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
+std::set<TAG> PatchCollection<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
 {
 	return changes.patch(item, coll.getTags(item));
 }
@@ -73,7 +76,7 @@
 		{
 			Patch<ITEM, TAG> newChange(i->second);
 
-			OpSet<TAG> tags(coll.getTags(i->first));
+			std::set<TAG> tags(coll.getTags(i->first));
 			newChange.removeRedundant(tags);
 
 			// Empty patches are filtered out by PatchList so we don't need to do
@@ -95,10 +98,10 @@
 template<class ITEM, class TAG>
 bool PatchCollection<ITEM, TAG>::hasTag(const TAG& tag) const
 {
-	OpSet<ITEM> items(coll.getItems(tag));
+	std::set<ITEM> items(coll.getItems(tag));
 
 	// Check items in coll first
-	for (typename OpSet<ITEM>::const_iterator i = items.begin();
+	for (typename std::set<ITEM>::const_iterator i = items.begin();
 			i != items.end(); i++)
 		// If they are unmodified, then we can trust coll.getItems
 		if (changes.find(*i) == changes.end())
@@ -107,41 +110,41 @@
 	// Then check items in the patch
 	for (typename PatchList<ITEM, TAG>::const_iterator i = changes.begin();
 			i != changes.end(); i++)
-		if (i->second.getAdded().contains(tag))
+		if (set_contains(i->second.getAdded(), tag))
 			return true;
 
 	return false;
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> PatchCollection<ITEM, TAG>::getTaggedItems() const
+std::set<ITEM> PatchCollection<ITEM, TAG>::getTaggedItems() const
 {
-	OpSet<ITEM> res(coll.getTaggedItems());
+	std::set<ITEM> res(coll.getTaggedItems());
 	for (typename PatchList<ITEM, TAG>::const_iterator i = changes.begin();
 			i != changes.end(); i++)
-		res += i->first;
+		res |= i->first;
 	return res;
 }
 
 template<typename ITEM, typename TAG>
-class TagCollector : public Consumer<ITEM, TAG>, public OpSet<TAG>
+class TagCollector : public Consumer<ITEM, TAG>, public std::set<TAG>
 {
 protected:
 	virtual void consumeItemUntagged(const ITEM&) {}
-	virtual void consumeItemsUntagged(const OpSet<ITEM>&) {}
+	virtual void consumeItemsUntagged(const std::set<ITEM>&) {}
 
-	virtual void consumeItem(const ITEM&, const OpSet<TAG>& tags)
+	virtual void consumeItem(const ITEM&, const std::set<TAG>& tags)
 	{
-		*this += tags;
+		*this |= tags;
 	}
-	virtual void consumeItems(const OpSet<ITEM>&, const OpSet<TAG>& tags)
+	virtual void consumeItems(const std::set<ITEM>&, const std::set<TAG>& tags)
 	{
-		*this += tags;
+		*this |= tags;
 	}
 };
 
 template<class ITEM, class TAG>
-OpSet<TAG> PatchCollection<ITEM, TAG>::getAllTags() const
+std::set<TAG> PatchCollection<ITEM, TAG>::getAllTags() const
 {
 	TagCollector<ITEM, TAG> res;
 
@@ -156,7 +159,7 @@
 protected:
 	const PatchList<ITEM, TAG>& changes;
 
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags)
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags)
 	{
 		if (changes.find(item) == changes.end())
 			this->consumer->consume(item, tags);
@@ -203,9 +206,9 @@
 	for (typename PatchList<ITEM, TAG>::const_iterator i = changes.begin();
 			i != changes.end(); i++)
 	{
-		if (i->second.getAdded().contains(tag))
+		if (set_contains(i->second.getAdded(), tag))
 			card++;
-		else if (i->second.getRemoved().contains(tag))
+		else if (set_contains(i->second.getRemoved(), tag))
 			card--;
 	}
 

Modified: tagcoll/2.0/tagcoll/PatchCollection.h
==============================================================================
--- tagcoll/2.0/tagcoll/PatchCollection.h	(original)
+++ tagcoll/2.0/tagcoll/PatchCollection.h	Tue May  2 00:54:47 2006
@@ -40,10 +40,10 @@
 	const ReadonlyCollection<ITEM, TAG>& coll;
 	PatchList<ITEM, TAG> changes;
 
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
 
-	virtual OpSet<ITEM> getItemsHavingTag(const TAG& tag) const;
-	virtual OpSet<TAG> getTagsOfItem(const ITEM& item) const;
+	virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const;
+	virtual std::set<TAG> getTagsOfItem(const ITEM& item) const;
 
 public:
 	PatchCollection(const ReadonlyCollection<ITEM, TAG>& coll) : coll(coll) {}
@@ -71,8 +71,8 @@
 
     virtual bool hasTag(const TAG& tag) const;
 
-	virtual OpSet<ITEM> getTaggedItems() const;
-	virtual OpSet<TAG> getAllTags() const;
+	virtual std::set<ITEM> getTaggedItems() const;
+	virtual std::set<TAG> getAllTags() const;
 
 	virtual int getCardinality(const TAG& tag) const;
 

Modified: tagcoll/2.0/tagcoll/Patches.cc
==============================================================================
--- tagcoll/2.0/tagcoll/Patches.cc	(original)
+++ tagcoll/2.0/tagcoll/Patches.cc	Tue May  2 00:54:47 2006
@@ -25,6 +25,7 @@
 #include <tagcoll/stringf.h>
 
 using namespace std;
+using namespace wibble::operators;
 
 namespace tagcoll {
 
@@ -38,17 +39,17 @@
 	// Process an untagged item
 	virtual void consumeItemUntagged(const ITEM& item)
 	{
-		OpSet<TAG> ts2 = second.getTags(item);
+		std::set<TAG> ts2 = second.getTags(item);
 		if (!ts2.empty())
-			target.addPatch(Patch<ITEM, TAG>(item, ts2, OpSet<TAG>()));
+			target.addPatch(Patch<ITEM, TAG>(item, ts2, std::set<TAG>()));
 	}
 
 	// Process a tagged item, with its tags
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& ts1)
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& ts1)
 	{
-		OpSet<TAG> ts2 = second.getTags(item);
-		OpSet<TAG> added = ts2 - ts1;
-		OpSet<TAG> removed = ts1 - ts2;
+		std::set<TAG> ts2 = second.getTags(item);
+		std::set<TAG> added = ts2 - ts1;
+		std::set<TAG> removed = ts1 - ts2;
 		if (!added.empty() || !removed.empty())
 			target.addPatch(Patch<ITEM, TAG>(item, added, removed));
 	}
@@ -88,7 +89,7 @@
 }
 
 template <class ITEM, class TAG>
-OpSet<TAG> PatchList<ITEM, TAG>::patch(const ITEM& item, const OpSet<TAG>& tagset) const throw ()
+std::set<TAG> PatchList<ITEM, TAG>::patch(const ITEM& item, const std::set<TAG>& tagset) const throw ()
 {
 	// Find the patch record for this item
 	const_iterator p = this->find(item);
@@ -113,7 +114,7 @@
 
 /*
 template <class ITEM>
-void PatchList<ITEM>::consume(const ITEM& item, const OpSet<string>& tags) throw ()
+void PatchList<ITEM>::consume(const ITEM& item, const std::set<string>& tags) throw ()
 {
 	patches.insert(make_pair(item, tags));
 }
@@ -122,7 +123,7 @@
 template <class ITEM>
 void PatchList<ITEM>::output(TagcollConsumer<ITEM, std::string>& consumer) const throw ()
 {
-	for (typename map< ITEM, OpSet<string> >::const_iterator i = patches.begin();
+	for (typename map< ITEM, std::set<string> >::const_iterator i = patches.begin();
 			i != patches.end(); i++)
 		if (i->second.size() == 0)
 			consumer.consume(i->first);
@@ -134,7 +135,7 @@
 template <class ITEM, class TAG>
 void PatchList<ITEM, TAG>::consumeItemUntagged(const ITEM& item)
 {
-	OpSet<TAG> patched = patch(item, OpSet<TAG>());
+	std::set<TAG> patched = patch(item, std::set<TAG>());
 
 	if (patched.size())
 		this->consumer->consume(item, patched);
@@ -143,9 +144,9 @@
 }
 
 template <class ITEM, class TAG>
-void PatchList<ITEM, TAG>::consumeItem(const ITEM& item, const OpSet<TAG>& tags)
+void PatchList<ITEM, TAG>::consumeItem(const ITEM& item, const std::set<TAG>& tags)
 {
-	OpSet<TAG> patched = patch(item, tags);
+	std::set<TAG> patched = patch(item, tags);
 
 	if (patched.size())
 		this->consumer->consume(item, patched);
@@ -155,14 +156,6 @@
 
 }
 
-#ifndef INSTANTIATING_TEMPLATES
-namespace tagcoll {
-template class Patch<std::string, std::string>;
-template class PatchList<std::string, std::string>;
-}
-#endif
-
-
 #ifdef COMPILE_TESTSUITE
 
 #include <tests/test-utils.h>
@@ -170,6 +163,7 @@
 
 namespace tut {
 using namespace tut_tagcoll;
+using namespace wibble::operators;
 
 struct tagcoll_patches_shar {
 };
@@ -193,19 +187,19 @@
 	InputMerger<string, string> result;
 	PatchList<string, string> patches(result);
 
-	OpSet<string> added;
-	OpSet<string> removed;
+	std::set<string> added;
+	std::set<string> removed;
 
-	added += "b";
-	removed += "c"; removed += "d";
+	added.insert("b");
+	removed.insert("c"); removed.insert("d");
 	patches.addPatch(Patch<string, string>("a", added, removed));
 
-	added.clear(); added += "b", added += "c", added += "b";
-	removed.clear(); removed += "a";
+	added.clear(); added.insert("b"), added.insert("c"), added.insert("b");
+	removed.clear(); removed.insert("a");
 	patches.addPatch(Patch<string, string>("b", added, removed));
 
-	added.clear(); added += "c::D", added += "c::d";
-	removed.clear(); removed += "f::g";
+	added.clear(); added.insert("c::D"), added.insert("c::d");
+	removed.clear(); removed.insert("f::g");
 	patches.addPatch(Patch<string, string>("d", added, removed));
 
 	outputCollection(input_coll, patches);

Modified: tagcoll/2.0/tagcoll/Patches.h
==============================================================================
--- tagcoll/2.0/tagcoll/Patches.h	(original)
+++ tagcoll/2.0/tagcoll/Patches.h	Tue May  2 00:54:47 2006
@@ -27,6 +27,7 @@
 #include <tagcoll/Filter.h>
 #include <tagcoll/Collection.h>
 
+#include <wibble/operators.h>
 #include <map>
 #include <string>
 
@@ -41,24 +42,40 @@
 {
 protected:
 	ITEM item;
-	OpSet<TAG> added;
-	OpSet<TAG> removed;
+	std::set<TAG> added;
+	std::set<TAG> removed;
 
 public:
 	Patch(const Patch<ITEM, TAG>& p) throw () : item(p.item), added(p.added), removed(p.removed) {}
 	Patch(const ITEM& item) throw () : item(item) {}
-	Patch(const ITEM& item, const OpSet<TAG>& added, const OpSet<TAG>& removed) throw ()
+	Patch(const ITEM& item, const std::set<TAG>& added, const std::set<TAG>& removed) throw ()
 		: item(item), added(added-removed), removed(removed-added) {}
 	~Patch() {}
 
-	void add(const TAG& tag) throw () { added += tag; removed -= tag; }
-	void add(const OpSet<TAG>& tags) throw () { added += tags; removed -= tags; }
-	void remove(const TAG& tag) throw () { removed += tag; added -= tag; }
-	void remove(const OpSet<TAG>& tags) throw () { removed += tags; added -= tags; }
+	void add(const TAG& tag) throw ()
+	{
+		using namespace wibble::operators;
+		added |= tag; removed -= tag;
+	}
+	void add(const std::set<TAG>& tags) throw ()
+	{
+		using namespace wibble::operators;
+		added |= tags; removed -= tags;
+	}
+	void remove(const TAG& tag) throw ()
+	{
+		using namespace wibble::operators;
+		removed |= tag; added -= tag;
+	}
+	void remove(const std::set<TAG>& tags) throw ()
+	{
+		using namespace wibble::operators;
+		removed |= tags; added -= tags;
+	}
 
 	const ITEM& getItem() const throw () { return item; }
-	const OpSet<TAG>& getAdded() const throw () { return added; }
-	const OpSet<TAG>& getRemoved() const throw () { return removed; }
+	const std::set<TAG>& getAdded() const throw () { return added; }
+	const std::set<TAG>& getRemoved() const throw () { return removed; }
 
 	Patch<ITEM, TAG> getReverse() const throw ()
 	{
@@ -71,13 +88,15 @@
 		remove(patch.getRemoved());
 	}
 
-	OpSet<TAG> apply(const OpSet<TAG>& ts) const throw ()
+	std::set<TAG> apply(const std::set<TAG>& ts) const throw ()
 	{
-		return (ts + added) - removed;
+		using namespace wibble::operators;
+		return (ts | added) - removed;
 	}
 
-	void removeRedundant(const OpSet<TAG> ts) throw ()
+	void removeRedundant(const std::set<TAG> ts) throw ()
 	{
+		using namespace wibble::operators;
 		// Don't add what already exists
 		added -= ts;
 		// Don't remove what does not exist
@@ -96,7 +115,7 @@
 	virtual void consumeItemUntagged(const ITEM& item);
 
 	/// Process a tagged item, with its tags
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
 
 public:
 	PatchList() : Filter<ITEM, TAG>() {}
@@ -131,7 +150,7 @@
 	 * @return
 	 *   The new (patched) set of tags
 	 */
-	OpSet<TAG> patch(const ITEM& item, const OpSet<TAG>& tagset) const throw ();
+	std::set<TAG> patch(const ITEM& item, const std::set<TAG>& tagset) const throw ();
 
 	/*
 	// Output the patch list to a TagcollConsumer

Modified: tagcoll/2.0/tagcoll/ReadonlyCollection.h
==============================================================================
--- tagcoll/2.0/tagcoll/ReadonlyCollection.h	(original)
+++ tagcoll/2.0/tagcoll/ReadonlyCollection.h	Tue May  2 00:54:47 2006
@@ -24,6 +24,8 @@
  */
 
 #include <tagcoll/Consumer.h>
+#include <tagcoll/OpSet.h>
+#include <wibble/operators.h>
 
 namespace tagcoll
 {
@@ -44,7 +46,7 @@
 	 * \return
 	 *   The items found, or an empty set if no items have that tag
 	 */
-	virtual OpSet<ITEM> getItemsHavingTag(const TAG& tag) const = 0;
+	virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const = 0;
 
 	/**
 	 * Get the items which are tagged with at least the tags `tags'
@@ -52,16 +54,17 @@
 	 * \return
 	 *   The items found, or an empty set if no items have that tag
 	 */
-	virtual OpSet<ITEM> getItemsHavingTags(const OpSet<TAG>& tags) const
+	virtual std::set<ITEM> getItemsHavingTags(const std::set<TAG>& tags) const
 	{
+		using namespace wibble::operators;
 		if (tags.empty())
-			return OpSet<ITEM>();
+			return std::set<ITEM>();
 
-		typename OpSet<TAG>::const_iterator i = tags.begin();
-		OpSet<ITEM> res = getItemsHavingTag(*i);
+		typename std::set<TAG>::const_iterator i = tags.begin();
+		std::set<ITEM> res = getItemsHavingTag(*i);
 
 		for ( ; i != tags.end(); i++)
-			res ^= getItemsHavingTag(*i);
+			res &= getItemsHavingTag(*i);
 
 		return res;
 
@@ -76,7 +79,7 @@
 	 *   The set of tags, or an empty set if the item has no tags or it does
 	 *   not exist.
 	 */
-	virtual OpSet<TAG> getTagsOfItem(const ITEM& item) const = 0;
+	virtual std::set<TAG> getTagsOfItem(const ITEM& item) const = 0;
 
 	/**
 	 * Get all the tags attached to the items in a set.
@@ -87,12 +90,13 @@
 	 *   The set of tags, or an empty set if the items have no tags or do not
 	 *   exist.
 	 */
-	virtual OpSet<TAG> getTagsOfItems(const OpSet<ITEM>& items) const
+	virtual std::set<TAG> getTagsOfItems(const std::set<ITEM>& items) const
 	{
-		OpSet<TAG> res;
-		for (typename OpSet<ITEM>::const_iterator i = items.begin();
+		using namespace wibble::operators;
+		std::set<TAG> res;
+		for (typename std::set<ITEM>::const_iterator i = items.begin();
 				i != items.end(); i++)
-			res += getTagsOfItem(*i);
+			res |= getTagsOfItem(*i);
 		return res;
 	}
 
@@ -115,32 +119,32 @@
 	/**
 	 * Get the tags of item `item'.  Return an empty set if `item' does not exist
 	 */
-	OpSet<TAG> getTags(const ITEM& item) const { return getTagsOfItem(item); }
+	std::set<TAG> getTags(const ITEM& item) const { return getTagsOfItem(item); }
 
 	/**
 	 * Get all the tags of items `items'.  Return an empty set if all of `item' do not exist
 	 */
-	OpSet<TAG> getTags(const OpSet<ITEM>& items) const { return getTagsOfItems(items); }
+	std::set<TAG> getTags(const std::set<ITEM>& items) const { return getTagsOfItems(items); }
 
 	/**
 	 * Get the items with tag `tag'.  Return an empty set if `tag' does not exist
 	 */
-	OpSet<ITEM> getItems(const TAG& tag) const { return getItemsHavingTag(tag); }
+	std::set<ITEM> getItems(const TAG& tag) const { return getItemsHavingTag(tag); }
 
 	/**
 	 * Get the items with tag `tag'.  Return an empty set if `tag' does not exist
 	 */
-	OpSet<ITEM> getItems(const OpSet<TAG>& tags) const { return getItemsHavingTags(tags); }
+	std::set<ITEM> getItems(const std::set<TAG>& tags) const { return getItemsHavingTags(tags); }
 
 	/**
 	 * Get the set of all the items that have tags according to this collection
 	 */
-	virtual OpSet<ITEM> getTaggedItems() const = 0;
+	virtual std::set<ITEM> getTaggedItems() const = 0;
 
 	/**
 	 * Get the set of all the tags in this collection
 	 */
-	virtual OpSet<TAG> getAllTags() const = 0;
+	virtual std::set<TAG> getAllTags() const = 0;
 
 	/**
 	 * Get the cardinality of tag `tag' (that is, the number of items who have it)
@@ -156,15 +160,16 @@
 	 *
 	 * Example:
 	 * \code
-	 * void refineSelection(const OpSet<Tag>& selection)
+	 * void refineSelection(const std::set<Tag>& selection)
 	 * {
-	 *    OpSet<Tag> extraTags = collection.getCompanionTags(selection);
+	 *    std::set<Tag> extraTags = collection.getCompanionTags(selection);
 	 *    tagMenu.setAvailableOptions(extraTags);
 	 * }
 	 * \endcode
 	 */
-	virtual OpSet<TAG> getCompanionTags(const OpSet<TAG>& tags) const
+	virtual std::set<TAG> getCompanionTags(const std::set<TAG>& tags) const
 	{
+		using namespace wibble::operators;
 		return getTagsOfItems(getItemsHavingTags(tags)) - tags;
 	}
 
@@ -174,46 +179,48 @@
 	 * Examples:
 	 * \code
 	 * // Get the items related to a given one, at the given distance
-	 * OpSet<Item> getRelated(const Item& item, int distance)
+	 * std::set<Item> getRelated(const Item& item, int distance)
 	 * {
-	 *    OpSet<Item> res = collection.getRelatedItems(collection.getTags(item), distance);
+	 *    std::set<Item> res = collection.getRelatedItems(collection.getTags(item), distance);
 	 *    return res - item;
 	 * }
 	 *
 	 * // Get the items related to the given ones, at the given distance
-	 * OpSet<Item> getRelated(const OpSet<Item>& items, int distance)
+	 * std::set<Item> getRelated(const std::set<Item>& items, int distance)
 	 * {
-	 *    OpSet<Item> res = collection.getRelatedItems(collection.getTags(items), distance);
+	 *    std::set<Item> res = collection.getRelatedItems(collection.getTags(items), distance);
 	 *    return res - items;
 	 * }
 	 *
 	 * // Get the related items, increasing the distance until it finds at
 	 * // least 'minimum' items
-	 * OpSet<Item> getRelated(const Item& item, int minimum)
+	 * std::set<Item> getRelated(const Item& item, int minimum)
 	 * {
-	 *    OpSet<Tag> tags = collection.getTags(item);
-	 *    OpSet<Item> res;
+	 *    std::set<Tag> tags = collection.getTags(item);
+	 *    std::set<Item> res;
 	 *    for (int i = 0; i < tags.size() && res.size() < minimum; i++)
 	 *    	 res += collection.getRelatedItems(tags, i);
 	 *	  return res - item;
 	 * }
 	 * \endcode
 	 */
-	virtual OpSet<ITEM> getRelatedItems(const OpSet<TAG>& tags, int maxdistance = 1) const
+	virtual std::set<ITEM> getRelatedItems(const std::set<TAG>& tags, int maxdistance = 1) const
 	{
-		OpSet<ITEM> packages;
-		OpSet<ITEM> res;
+		using namespace wibble::operators;
+
+		std::set<ITEM> packages;
+		std::set<ITEM> res;
 
 		// First get a list of packages that have a non-empty intersection with `tags'
-		for (typename OpSet<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
-			packages += getItemsHavingTag(*i);
+		for (typename std::set<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
+			packages |= getItemsHavingTag(*i);
 
 		// Then keep only those within the given distance
-		for (typename OpSet<ITEM>::const_iterator i = packages.begin(); i != packages.end(); i++)
+		for (typename std::set<ITEM>::const_iterator i = packages.begin(); i != packages.end(); i++)
 		{
-			int dist = tags.distance(getTagsOfItem(*i));
+			int dist = set_distance(tags, getTagsOfItem(*i));
 			if (dist >= 0 && dist <= maxdistance)
-				res += *i;
+				res |= *i;
 		}
 
 		return res;
@@ -228,10 +235,10 @@
 	 * Send to a consumer all the items which are tagged with at least the
 	 * given tags
 	 */
-	virtual void outputHavingTags(const OpSet<TAG>& tags, Consumer<ITEM, TAG>& consumer) const
+	virtual void outputHavingTags(const std::set<TAG>& tags, Consumer<ITEM, TAG>& consumer) const
 	{
-		OpSet<ITEM> items = getItemsHavingTags(tags);
-		for (typename OpSet<ITEM>::const_iterator i = items.begin();
+		std::set<ITEM> items = getItemsHavingTags(tags);
+		for (typename std::set<ITEM>::const_iterator i = items.begin();
 				i != items.end(); i++)
 			consumer.consume(*i, getTagsOfItem(*i));
 	}

Modified: tagcoll/2.0/tagcoll/Serializer.cc
==============================================================================
--- tagcoll/2.0/tagcoll/Serializer.cc	(original)
+++ tagcoll/2.0/tagcoll/Serializer.cc	Tue May  2 00:54:47 2006
@@ -31,11 +31,11 @@
 }
 
 template<typename IN, typename OUT>
-OpSet<OUT> Converter<IN, OUT>::operator()(const OpSet<IN>& items)
+std::set<OUT> Converter<IN, OUT>::operator()(const std::set<IN>& items)
 {
-	OpSet<OUT> res;
+	std::set<OUT> res;
 
-	for (typename OpSet<IN>::const_iterator i = items.begin();
+	for (typename std::set<IN>::const_iterator i = items.begin();
 			i != items.end(); i++)
 	{
 		OUT t = (*this)(*i);
@@ -47,15 +47,6 @@
 }
 #endif
 
-#ifndef INSTANTIATING_TEMPLATES
-#include <string>
-
-namespace tagcoll {
-	template class Converter<std::string, std::string>;
-	template class ConversionFilter<std::string, std::string, std::string, std::string>;
-}
-#endif
-
 #ifdef COMPILE_TESTSUITE
 
 #include <tests/test-utils.h>

Modified: tagcoll/2.0/tagcoll/Serializer.h
==============================================================================
--- tagcoll/2.0/tagcoll/Serializer.h	(original)
+++ tagcoll/2.0/tagcoll/Serializer.h	Tue May  2 00:54:47 2006
@@ -24,7 +24,7 @@
  */
 
 #include <tagcoll/Consumer.h>
-#include <tagcoll/OpSet.h>
+#include <set>
 
 namespace tagcoll
 {
@@ -46,16 +46,16 @@
 	/**
 	 * Convert a set of items
 	 */
-	virtual OpSet<OUT> operator()(const OpSet<IN>& items) const
+	virtual std::set<OUT> operator()(const std::set<IN>& items) const
 	{
-		OpSet<OUT> res;
+		std::set<OUT> res;
 
-		for (typename OpSet<IN>::const_iterator i = items.begin();
+		for (typename std::set<IN>::const_iterator i = items.begin();
 				i != items.end(); i++)
 		{
 			OUT t = (*this)(*i);
 			if (t != OUT())
-				res += t;
+				res.insert(t);
 		}
 
 		return res;
@@ -96,15 +96,15 @@
 	{
 		consumer->consume(citem(item));
 	}
-	virtual void consumeItem(const IN_ITEM& item, const OpSet<IN_TAG>& tags)
+	virtual void consumeItem(const IN_ITEM& item, const std::set<IN_TAG>& tags)
 	{
 		consumer->consume(citem(item), ctag(tags));
 	}
-	virtual void consumeItemsUntagged(const OpSet<IN_ITEM>& items)
+	virtual void consumeItemsUntagged(const std::set<IN_ITEM>& items)
 	{
 		consumer->consume(citem(items));
 	}
-	virtual void consumeItems(const OpSet<IN_ITEM>& items, const OpSet<IN_TAG>& tags)
+	virtual void consumeItems(const std::set<IN_ITEM>& items, const std::set<IN_TAG>& tags)
 	{
 		consumer->consume(citem(items), ctag(tags));
 	}

Modified: tagcoll/2.0/tagcoll/SmartHierarchy.cc
==============================================================================
--- tagcoll/2.0/tagcoll/SmartHierarchy.cc	(original)
+++ tagcoll/2.0/tagcoll/SmartHierarchy.cc	Tue May  2 00:54:47 2006
@@ -19,6 +19,7 @@
  */
 
 #include <tagcoll/SmartHierarchy.h>
+#include <wibble/operators.h>
 
 //#define VERB1 1
 //#define VERB_FLATTEN 1
@@ -36,6 +37,7 @@
 #endif
 
 using namespace std;
+using namespace wibble::operators;
 using namespace tagcoll;
 
 //template class SmartHierarchyNode<string>;
@@ -83,7 +85,7 @@
 
 	if (flattenThreshold > 0 && this->coll->itemCount() < flattenThreshold)
 	{
-		this->items = unexpandedItems + this->coll->getTaggedItems();
+		this->items = unexpandedItems | this->coll->getTaggedItems();
 #ifdef VERB_FLATTEN
 		fprintf(stderr, "Flattened: threshold: %d, items: %d\n", flattenThreshold, items.size());
 #endif
@@ -92,7 +94,7 @@
 	{
 		this->items = unexpandedItems;
 	
-		OpSet<TAG> processed;
+		std::set<TAG> processed;
 		CardinalityStore<ITEM, TAG> workcoll = *this->coll;
 
 		while (1)
@@ -110,7 +112,7 @@
 #ifdef VERB1
 			//print_spaces(nest);
 			fprintf(stderr, "   Processed: ");
-			for (OpSet<TAG>::const_iterator i = processed.begin();
+			for (std::set<TAG>::const_iterator i = processed.begin();
 					i != processed.end(); i++)
 				if (i == processed.begin())
 					fprintf(stderr, "%.*s", PFSTR(*i));
@@ -146,12 +148,12 @@
 	//fprintf(stderr, "CSHN::merged\n");
 	
 	if (this->flattenThreshold > 0 && this->coll->itemCount() < this->flattenThreshold)
-		this->items = this->unexpandedItems + this->coll->getTaggedItems();
+		this->items = this->unexpandedItems | this->coll->getTaggedItems();
 	else
 	{
 		this->items = this->unexpandedItems;
 	
-		OpSet<TAG> processed;
+		std::set<TAG> processed;
 		CardinalityStore<ITEM, TAG> workcoll = *this->coll;
 
 		while (1)

Modified: tagcoll/2.0/tagcoll/SmartHierarchy.h
==============================================================================
--- tagcoll/2.0/tagcoll/SmartHierarchy.h	(original)
+++ tagcoll/2.0/tagcoll/SmartHierarchy.h	Tue May  2 00:54:47 2006
@@ -38,7 +38,7 @@
 	TAG _tag;
 	CardinalityStore<ITEM, TAG>* coll;
 	std::vector<HierarchyNode<ITEM, TAG>*> children;
-	OpSet<ITEM> items;
+	std::set<ITEM> items;
 	HierarchyNode<ITEM, TAG>* _parent;
 
 public:
@@ -93,7 +93,7 @@
 	}
 
 	// Get the set of items present in this node
-	const OpSet<ITEM>& getItems()
+	const std::set<ITEM>& getItems()
 	{
 		if (coll)
 			expand();
@@ -107,7 +107,7 @@
 class SmartHierarchyNode : public HierarchyNode<ITEM, TAG>
 {
 protected:
-	OpSet<ITEM> unexpandedItems;
+	std::set<ITEM> unexpandedItems;
 
 	// Threshold of child items below which the child hierarchy is flattened
 	// and they all become children of this node
@@ -131,7 +131,7 @@
 			HierarchyNode<ITEM, TAG>(parent, tag, coll.getChildCollection(tag)),
 			flattenThreshold(flattenThreshold)
 		{
-			OpSet<TAG> tags; tags += tag;
+			std::set<TAG> tags; tags.insert(tag);
 			unexpandedItems = coll.getItemsExactMatch(tags);
 		}
 

Modified: tagcoll/2.0/tagcoll/TDBIndexer.cc
==============================================================================
--- tagcoll/2.0/tagcoll/TDBIndexer.cc	(original)
+++ tagcoll/2.0/tagcoll/TDBIndexer.cc	Tue May  2 00:54:47 2006
@@ -21,63 +21,57 @@
 #include <tagcoll/TDBIndexer.h>
 #include <tagcoll/Patches.h>
 
-#include <fcntl.h>	// O_RDONLY
-#include <string.h>	// strlen
-#include <errno.h>
-#include <assert.h>
-
-/*
-#include <stdlib.h>
-*/
+#include <wibble/operators.h>
 
 using namespace std;
 using namespace tagcoll;
+using namespace wibble::operators;
 
 
 template<class ITEM, class TAG>
-OpSet<ITEM> TDBIndexer<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
+std::set<ITEM> TDBIndexer<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
 {
-	typename map<TAG, OpSet<ITEM> >::const_iterator i = tags.find(tag);
+	typename map<TAG, std::set<ITEM> >::const_iterator i = tags.find(tag);
 	if (i != tags.end())
 		return i->second;
 	else
-		return OpSet<ITEM>();
+		return std::set<ITEM>();
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> TDBIndexer<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
+std::set<TAG> TDBIndexer<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
 {
-	typename map<ITEM, OpSet<TAG> >::const_iterator i = items.find(item);
+	typename map<ITEM, std::set<TAG> >::const_iterator i = items.find(item);
 	if (i != items.end())
 		return i->second;
 	else
-		return OpSet<TAG>();
+		return std::set<TAG>();
 }
 
 template<class ITEM, class TAG>
-OpSet<ITEM> TDBIndexer<ITEM, TAG>::getTaggedItems() const
+std::set<ITEM> TDBIndexer<ITEM, TAG>::getTaggedItems() const
 {
-	OpSet<ITEM> res;
-	for (typename map<ITEM, OpSet<TAG> >::const_iterator i = items.begin();
+	std::set<ITEM> res;
+	for (typename map<ITEM, std::set<TAG> >::const_iterator i = items.begin();
 			i != items.end(); i++)
-		res += i->first;
+		res |= i->first;
 	return res;
 }
 
 template<class ITEM, class TAG>
-OpSet<TAG> TDBIndexer<ITEM, TAG>::getAllTags() const
+std::set<TAG> TDBIndexer<ITEM, TAG>::getAllTags() const
 {
-	OpSet<TAG> res;
-	for (typename map<TAG, OpSet<ITEM> >::const_iterator i = tags.begin();
+	std::set<TAG> res;
+	for (typename map<TAG, std::set<ITEM> >::const_iterator i = tags.begin();
 			i != tags.end(); i++)
-		res += i->first;
+		res |= i->first;
 	return res;
 }
 
 template<class ITEM, class TAG>
 void TDBIndexer<ITEM, TAG>::output(Consumer<ITEM, TAG>& consumer) const
 {
-	for (typename map<ITEM, OpSet<TAG> >::const_iterator i = items.begin();
+	for (typename map<ITEM, std::set<TAG> >::const_iterator i = items.begin();
 			i != items.end(); i++)
 		consumer.consume(i->first, i->second);
 }
@@ -88,50 +82,50 @@
 	for (typename PatchList<ITEM, TAG>::const_iterator i = change.begin(); i != change.end(); i++)
 	{
 		// Save the previous tagset in `rev'
-		OpSet<TAG> prevTags = getTags(i->first);
-		OpSet<TAG> nextTags = i->second.apply(prevTags);
+		std::set<TAG> prevTags = getTags(i->first);
+		std::set<TAG> nextTags = i->second.apply(prevTags);
 
 		// Set the new tagset in the item
 		items[i->first] = nextTags;
 
 		// Fix the itemsets in the involved tags
-		OpSet<TAG> t = prevTags - nextTags;
-		for (typename OpSet<TAG>::const_iterator j = t.begin(); j != t.end(); j++)
+		std::set<TAG> t = prevTags - nextTags;
+		for (typename std::set<TAG>::const_iterator j = t.begin(); j != t.end(); j++)
 		{
-			OpSet<TAG> items = getItems(*j) - i->first;
+			std::set<TAG> items = getItems(*j) - i->first;
 			if (items.empty())
 				tags.erase(*j);
 			else
 				tags[*j] = items;
 		}
 		t = nextTags - prevTags;
-		for (typename OpSet<TAG>::const_iterator j  = t.begin(); j != t.end(); j++)
-			tags[*j] += i->first;
+		for (typename std::set<TAG>::const_iterator j  = t.begin(); j != t.end(); j++)
+			tags[*j] |= i->first;
 	}
 }
 
 
 template<class ITEM, class TAG>
-void TDBIndexer<ITEM, TAG>::consumeItem(const ITEM& item, const OpSet<TAG>& tags)
+void TDBIndexer<ITEM, TAG>::consumeItem(const ITEM& item, const std::set<TAG>& tags)
 {
 	// Add the tags to the item
-	items[item] += tags;
+	items[item] |= tags;
 
 	// Add the item to the tags
-	for (typename OpSet<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
-		this->tags[*i] += item;
+	for (typename std::set<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
+		this->tags[*i] |= item;
 }
 
 template<class ITEM, class TAG>
-void TDBIndexer<ITEM, TAG>::consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
+void TDBIndexer<ITEM, TAG>::consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tags)
 {
-	for (typename OpSet<ITEM>::const_iterator i = items.begin(); i != items.end(); i++)
+	for (typename std::set<ITEM>::const_iterator i = items.begin(); i != items.end(); i++)
 		// Add the tags to the item
-		this->items[*i] += tags;
+		this->items[*i] |= tags;
 
-	for (typename OpSet<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
+	for (typename std::set<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
 		// Add the items to the tag
-		this->tags[*i] += items;
+		this->tags[*i] |= items;
 }
 
 #ifndef INSTANTIATING_TEMPLATES

Modified: tagcoll/2.0/tagcoll/TDBIndexer.h
==============================================================================
--- tagcoll/2.0/tagcoll/TDBIndexer.h	(original)
+++ tagcoll/2.0/tagcoll/TDBIndexer.h	Tue May  2 00:54:47 2006
@@ -44,22 +44,22 @@
 class TDBIndexer : public Collection<ITEM, TAG>
 {
 protected:
-	std::map<ITEM, OpSet<TAG> > items;
-	std::map<TAG, OpSet<ITEM> > tags;
+	std::map<ITEM, std::set<TAG> > items;
+	std::map<TAG, std::set<ITEM> > tags;
 
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);
-	virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags);
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
+	virtual void consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tags);
 
-	virtual OpSet<ITEM> getItemsHavingTag(const TAG& tag) const;
-	virtual OpSet<TAG> getTagsOfItem(const ITEM& item) const;
+	virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const;
+	virtual std::set<TAG> getTagsOfItem(const ITEM& item) const;
 
 public:
 	virtual ~TDBIndexer() {}
 
     virtual bool hasItem(const ITEM& item) const { return items.find(item) != items.end(); }
     virtual bool hasTag(const TAG& tag) const { return tags.find(tag) != tags.end(); }
-	virtual OpSet<ITEM> getTaggedItems() const;
-	virtual OpSet<TAG> getAllTags() const;
+	virtual std::set<ITEM> getTaggedItems() const;
+	virtual std::set<TAG> getAllTags() const;
 	virtual void output(Consumer<ITEM, TAG>& consumer) const;
 	virtual void applyChange(const PatchList<ITEM, TAG>& change);
 

Modified: tagcoll/2.0/tagcoll/TextFormat.cc
==============================================================================
--- tagcoll/2.0/tagcoll/TextFormat.cc	(original)
+++ tagcoll/2.0/tagcoll/TextFormat.cc	Tue May  2 00:54:47 2006
@@ -18,22 +18,148 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
 
-#include <wibble/exception.h>
 #include <tagcoll/TextFormat.h>
-#include <tagcoll/Patches.h>
-#include <tagcoll/stringf.h>
-
-#include <errno.h>
 
 using namespace std;
 using namespace wibble;
-using namespace stringf;
-using namespace tagcoll;
+
+namespace tagcoll {
+namespace textformat {
+
+// Parse an element
+// Return the trailing separating char, that can be:
+//  ParserInput::Eof
+//  '\n'
+//  ':'
+//  ','
+// Return the item in `item'
+
+// element: \s*[^ \t,:]\s*([.:])\s*
+// or
+// element: \s*[^ \t,:].*?[^ \t,:]\s*([.:])\s+
+int parseElement(ParserInput& in, string& item) throw (tagcoll::exception::Parser)
+{
+	item = string();
+	string sep;
+	int c;
+	char sepchar = 0;
+	enum {LSPACE, ITEM, ISPACE, ISEP, TSPACE} state = LSPACE;
+	while ((c = in.nextChar()) != ParserInput::Eof)
+	{
+		if (c == '\n')
+		{
+			if (sepchar && sepchar != ':')
+				throw tagcoll::exception::Parser("separator character ends the line");
+			else
+				return '\n';
+		}
+		switch (state)
+		{
+			// Optional leading space
+			case LSPACE:
+				switch (c)
+				{
+					case ' ':
+					case '\t':
+						break;
+					case ':':
+					case ',':
+						throw tagcoll::exception::Parser("element cannot start with a separation character");
+						break;
+					default:
+						item += c;
+						state = ITEM;
+						break;
+				}
+				break;
+			// Non-separating characters
+			case ITEM:
+				switch (c)
+				{
+					case ' ':
+					case '\t':
+						sep += c;
+						state = ISPACE;
+						break;
+					case ':':
+					case ',':
+						sepchar = c;
+						sep += c;
+						state = ISEP;
+						break;
+					default:
+						item += c;
+						break;
+				}
+				break;
+			// Space inside item or at the end of item
+			case ISPACE:
+				switch (c)
+				{
+					case ' ':
+					case '\t':
+						sep += c;
+						break;
+					case ':':
+					case ',':
+						sepchar = c;
+						state = TSPACE;
+						break;
+					default:
+						item += sep;
+						item += c;
+						sep = string();
+						state = ITEM;
+						break;
+				}
+				break;
+			// Separator inside item or at the end of item
+			case ISEP:
+				switch (c)
+				{
+					case ' ':
+					case '\t':
+						if (sep.size() > 1)
+							throw tagcoll::exception::Parser("item is followed by more than one separator characters");
+						state = TSPACE;
+						break;
+					case ':':
+					case ',':
+						sep += c;
+						break;
+					default:
+						item += sep;
+						item += c;
+						sepchar = 0;
+						sep = string();
+						state = ITEM;
+						break;
+				}
+				break;
+			case TSPACE:
+				switch (c)
+				{
+					case ' ':
+					case '\t':
+						break;
+					default:
+						in.pushChar(c);
+						return sepchar;
+				}
+				break;
+		}
+	}
+	return ParserInput::Eof;
+}
+
+}
+}
 
 #ifdef COMPILE_TESTSUITE
 
 #include <tests/test-utils.h>
 #include <tagcoll/StringParserInput.h>
+#include <tagcoll/Patches.h>
 
 namespace tut {
 using namespace tut_tagcoll;
@@ -53,7 +179,7 @@
 	);
 	
 	TestConsumer<string, string> cons;
-	TextFormat<string, string>::parse(coll, consumer(cons));
+	textformat::parse(coll, consumer(cons));
 
 	gen_ensure_equals(cons.items, 4);
 	gen_ensure_equals(cons.tags, 5);
@@ -70,7 +196,7 @@
 	);
 	
 	TrivialConverter<string, string> a;
-	PatchList<string, string> plist(TextFormat<string, string>::parsePatch(a, a, coll));
+	PatchList<string, string> plist(textformat::parsePatch(a, a, coll));
 
 	/*
 	cerr << "Patchlist[" << plist.size() << "]:" << endl;
@@ -98,6 +224,8 @@
 
 }
 
+#include <tagcoll/TextFormat.tcc>
+
 #endif
 
 // vim:set ts=4 sw=4:

Modified: tagcoll/2.0/tagcoll/TextFormat.h
==============================================================================
--- tagcoll/2.0/tagcoll/TextFormat.h	(original)
+++ tagcoll/2.0/tagcoll/TextFormat.h	Tue May  2 00:54:47 2006
@@ -23,6 +23,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
 
+#include <wibble/empty.h>
+#include <wibble/singleton.h>
 #include <tagcoll/Consumer.h>
 #include <tagcoll/Serializer.h>
 #include <tagcoll/ParserBase.h>
@@ -36,6 +38,9 @@
 template<class ITEM, class TAG>
 class PatchList;
 
+namespace textformat
+{
+
 /**
  * TagcollConsumer that serializes its input to an output stream
  *
@@ -49,68 +54,104 @@
  *   ITEM1, ITEM2, ITEM3:
  *   ITEM1, ITEM2, ITEM3: TAG1, TAG2, TAG3
  */
+class StdioWriter
+{
+protected:
+	FILE* out;
+
+public:
+	StdioWriter(FILE* out) : out(out) {}
+
+	StdioWriter& operator++() { return *this; }
+
+	template<typename Items, typename Tags>
+	StdioWriter& operator=(const std::pair<Items, Tags>& data);
+};
+
+/**
+ * Parse an element from input
+ *
+ * @retval item
+ *   The item found on input
+ * @return
+ *   the trailing separating char, that can be:
+ *   \li ParserInput::Eof
+ *   \li '\n'
+ *   \li ':'
+ *   \li ','
+ */
+int parseElement(ParserInput& in, std::string& item) throw (tagcoll::exception::Parser);
+
+
+/**
+ * Serialize a patch
+ */
+template<typename ITEM, typename TAG>
+void outputPatch(
+		Converter<ITEM, std::string>& itemconv,
+		Converter<TAG, std::string>& tagconv,
+		const PatchList<ITEM, TAG>& patch,
+		FILE* out);
+
+/*
+ * Parse a tagged collection, sending the results to out.
+ *
+ * @param out
+ *   An output iterator accepting a std::pair<string, string>
+ */
+template<typename OUT>
+void parse(ParserInput& in, OUT out);
+
+/**
+ * Parse a tagcoll patch
+ */
+template<typename ITEM, typename TAG>
+PatchList<ITEM, TAG> parsePatch(
+		Converter<std::string, ITEM>& itemconv,
+		Converter<std::string, TAG>& tagconv,
+		ParserInput& in);
+
+}
+
+// This is outside of the textformat namespace for backwards compatibility.
+// New code should just use StdioWriter or an analogous new class
 template<class ITEM, class TAG>
 class TextFormat : public Consumer<ITEM, TAG>
 {
 protected:
 	const Converter<ITEM, std::string>& itemconv;
 	const Converter<TAG, std::string>& tagconv;
-	FILE* out;
+	textformat::StdioWriter writer;
 
 	static int parseElement(ParserInput& in, std::string& item) throw (tagcoll::exception::Parser);
 
-	virtual void consumeItemUntagged(const ITEM& item);
-	virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);
-	virtual void consumeItemsUntagged(const OpSet<ITEM>& items);
-	virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags);
+	virtual void consumeItemUntagged(const ITEM& item)
+	{
+		writer = make_pair(wibble::singleton(itemconv(item)), wibble::Empty<std::string>());
+		++writer;
+	}
+	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags)
+	{
+		writer = make_pair(wibble::singleton(itemconv(item)), tagconv(tags));
+		++writer;
+	}
+	virtual void consumeItemsUntagged(const std::set<ITEM>& items)
+	{
+		writer = make_pair(itemconv(items), wibble::Empty<std::string>());
+		++writer;
+	}
+	virtual void consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tags)
+	{
+		writer = make_pair(itemconv(items), tagconv(tags));
+		++writer;
+	}
 
 public:
-	TextFormat(
-			const Converter<ITEM, std::string>& itemconv,
-			const Converter<TAG, std::string>& tagconv,
-			FILE* out) : itemconv(itemconv), tagconv(tagconv), out(out) {}
-	virtual ~TextFormat() {}
-
-
-	/**
-	 * Serialize a patch
-	 */
-	static void outputPatch(
-			Converter<ITEM, std::string>& itemconv,
-			Converter<TAG, std::string>& tagconv,
-			const PatchList<ITEM, TAG>& patch,
-			FILE* out);
-
-	/**
-	 * Parse a tagged collection, sending the results to out.
-	 *
-	 * @param out
-	 *   An output iterator accepting a std::pair<string, string>
-	 */
-	template<typename OUT>
-	static void parse(ParserInput& in, OUT out);
-
-#if 0
-	/**
-	 * Parse a tagged collection, sending the data to `consumer'
-	 */
-	static void parse(
-			Converter<std::string, ITEM>& itemconv,
-			Converter<std::string, TAG>& tagconv,
-			ParserInput& in,
-			Consumer<ITEM, TAG>& consumer);
-#endif
-
-	/**
-	 * Parse a tagcoll patch
-	 */
-	static PatchList<ITEM, TAG> parsePatch(
-			Converter<std::string, ITEM>& itemconv,
-			Converter<std::string, TAG>& tagconv,
-			ParserInput& in);
+	TextFormat(const Converter<ITEM, std::string>& itemconv, const Converter<TAG, std::string>& tagconv, FILE* out)
+		: itemconv(itemconv), tagconv(tagconv), writer(out) {}
 };
 
-};
+}
 
 // vim:set ts=4 sw=4:
 #endif

Modified: tagcoll/2.0/tagcoll/TextFormat.tcc
==============================================================================
--- tagcoll/2.0/tagcoll/TextFormat.tcc	(original)
+++ tagcoll/2.0/tagcoll/TextFormat.tcc	Tue May  2 00:54:47 2006
@@ -18,29 +18,80 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
 
-#include <wibble/exception.h>
-#include <wibble/empty.h>
 #include <tagcoll/TextFormat.h>
 #include <tagcoll/Patches.h>
 #include <tagcoll/stringf.h>
 
+#include <wibble/exception.h>
+#include <wibble/empty.h>
+#include <wibble/operators.h>
 #include <errno.h>
 
 using namespace std;
 using namespace wibble;
-using namespace stringf;
-using namespace tagcoll;
+using namespace wibble::operators;
+
+static void printTagset(const std::set<string>& ts, FILE* out)
+{
+	for (std::set<string>::const_iterator i = ts.begin();
+			i != ts.end(); i++)
+		if (i == ts.begin())
+		{
+			if (fprintf(out, "%.*s", PFSTR(*i)) < 0)
+				throw wibble::exception::System("writing tagset");
+		}
+		else
+		{
+			if (fprintf(out, ", %.*s", PFSTR(*i)) < 0)
+				throw wibble::exception::System("writing tagset");
+		}
+}
+
+namespace tagcoll {
+namespace textformat {
+
+template<typename Items, typename Tags>
+StdioWriter& StdioWriter::operator=(const std::pair<Items, Tags>& data)
+{
+	for (typename Items::const_iterator i = data.first.begin();
+			i != data.first.end(); ++i)
+	{
+		if (i != data.first.begin())
+			if (fputs(", ", out) == EOF)
+				throw wibble::exception::System("writing comma after item");
+		if (fwrite(i->data(), i->size(), 1, out) != i->size())
+			throw wibble::exception::System("writing item");
+	}
+	if (data.second.begin() != data.second.end())
+	{
+		if (fputs(": ", out) == EOF)
+			throw wibble::exception::System("writing colon after items");
+		for (typename Tags::const_iterator i = data.second.begin();
+				i != data.second.end(); ++i)
+		{
+			if (i != data.second.begin())
+				if (fputs(", ", out) == EOF)
+					throw wibble::exception::System("writing comma after tag");
+			if (fwrite(i->data(), i->size(), 1, out) != i->size())
+				throw wibble::exception::System("writing tag");
+		}
+	}
+	if (fputc('\n', out) == EOF)
+		throw wibble::exception::System("writing newline after tagset");
+	return *this;
+}
+
 
 // item1, item2, item3: tag1, tag2, tag3
 
 //#define TRACE_PARSE
-template<typename ITEM, typename TAG> template<typename OUT>
-void TextFormat<ITEM, TAG>::parse(ParserInput& in, OUT out)
+template<typename OUT>
+void parse(ParserInput& in, OUT out)
 {
 	string item;
 
-	OpSet<string> itemset;
-	OpSet<string> tagset;
+	std::set<string> itemset;
+	std::set<string> tagset;
 	int sep;
 	enum {ITEMS, TAGS} state = ITEMS;
 	int line = 1;
@@ -56,9 +107,9 @@
 		
 		if (item.size() != 0)
 			if (state == ITEMS)
-				itemset += item;
+				itemset |= item;
 			else
-				tagset += item;
+				tagset |= item;
 		
 		switch (sep)
 		{
@@ -70,7 +121,7 @@
 					if (itemset.empty())
 						throw tagcoll::exception::Parser(line, "no elements before `:' separator");
 					if (tagset.empty())
-						out = make_pair(itemset, wibble::Empty<TAG>());
+						out = make_pair(itemset, wibble::Empty<std::string>());
 					else
 						out = make_pair(itemset, tagset);
 					++out;
@@ -90,63 +141,10 @@
 	} while (sep != ParserInput::Eof);
 }
 
-static void printTagset(const OpSet<string>& ts, FILE* out)
-{
-	for (OpSet<string>::const_iterator i = ts.begin();
-			i != ts.end(); i++)
-		if (i == ts.begin())
-		{
-			if (fprintf(out, "%.*s", PFSTR(*i)) < 0)
-				throw wibble::exception::System("writing tagset");
-		}
-		else
-		{
-			if (fprintf(out, ", %.*s", PFSTR(*i)) < 0)
-				throw wibble::exception::System("writing tagset");
-		}
-}
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::consumeItemUntagged(const ITEM& item)
-{
-	string sitem = itemconv(item);
-	if (fprintf(out, "%.*s\n", PFSTR(sitem)) < 0)
-		throw wibble::exception::System("writing item");
-}
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::consumeItem(const ITEM& item, const OpSet<TAG>& tags)
-{
-	string sitem = itemconv(item);
-	if (fprintf(out, "%.*s: ", PFSTR(sitem)) < 0)
-		throw wibble::exception::System("writing item");
-	printTagset(tagconv(tags), out);
-	if (fprintf(out, "\n") < 0)
-		throw wibble::exception::System("writing newline after tagset");
-}
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::consumeItemsUntagged(const OpSet<ITEM>& items)
-{
-	printTagset(itemconv(items), out);
-	if (fprintf(out, "\n") < 0)
-		throw wibble::exception::System("writing newline after items");
-}
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::consumeItems(const OpSet&l