Patches.h

Go to the documentation of this file.
00001 #ifndef TAGCOLL_PATCHES_H
00002 #define TAGCOLL_PATCHES_H
00003 
00008 /*
00009  * Copyright (C) 2003,2004,2005  Enrico Zini <enrico@debian.org>
00010  *
00011  * This library is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU Lesser General Public
00013  * License as published by the Free Software Foundation; either
00014  * version 2.1 of the License, or (at your option) any later version.
00015  *
00016  * This library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with this library; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00024  */
00025 
00026 #include <tagcoll/Consumer.h>
00027 #include <tagcoll/Filter.h>
00028 #include <tagcoll/Collection.h>
00029 
00030 #include <map>
00031 #include <string>
00032 
00033 namespace Tagcoll
00034 {
00035 
00039 template <typename ITEM, typename TAG>
00040 class Patch
00041 {
00042 protected:
00043     ITEM item;
00044     OpSet<TAG> added;
00045     OpSet<TAG> removed;
00046 
00047 public:
00048     Patch(const Patch<ITEM, TAG>& p) throw () : item(p.item), added(p.added), removed(p.removed) {}
00049     Patch(const ITEM& item) throw () : item(item) {}
00050     Patch(const ITEM& item, const OpSet<TAG>& added, const OpSet<TAG>& removed) throw ()
00051         : item(item), added(added-removed), removed(removed-added) {}
00052     ~Patch() {}
00053 
00054     void add(const TAG& tag) throw () { added += tag; removed -= tag; }
00055     void add(const OpSet<TAG>& tags) throw () { added += tags; removed -= tags; }
00056     void remove(const TAG& tag) throw () { removed += tag; added -= tag; }
00057     void remove(const OpSet<TAG>& tags) throw () { removed += tags; added -= tags; }
00058 
00059     const ITEM& getItem() const throw () { return item; }
00060     const OpSet<TAG>& getAdded() const throw () { return added; }
00061     const OpSet<TAG>& getRemoved() const throw () { return removed; }
00062 
00063     Patch<ITEM, TAG> getReverse() const throw ()
00064     {
00065         return Patch<ITEM, TAG>(item, removed, added);
00066     }
00067 
00068     void mergeWith(const Patch<ITEM, TAG>& patch) throw ()
00069     {
00070         add(patch.getAdded());
00071         remove(patch.getRemoved());
00072     }
00073 
00074     OpSet<TAG> apply(const OpSet<TAG>& ts) const throw ()
00075     {
00076         return (ts + added) - removed;
00077     }
00078 
00079     void removeRedundant(const OpSet<TAG> ts) throw ()
00080     {
00081         // Don't add what already exists
00082         added -= ts;
00083         // Don't remove what does not exist
00084         removed -= (removed - ts);
00085     }
00086 };
00087 
00091 template <class ITEM, class TAG>
00092 class PatchList : public std::map<ITEM, Patch<ITEM, TAG> >, public Filter<ITEM, TAG> 
00093 {
00094 protected:
00096     virtual void consumeItemUntagged(const ITEM& item);
00097 
00099     virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);
00100 
00101 public:
00102     PatchList() : Filter<ITEM, TAG>() {}
00103     PatchList(Consumer<ITEM, TAG>& consumer) : Filter<ITEM, TAG>(consumer) {}
00104     PatchList(const PatchList& pl) : std::map<ITEM, Patch<ITEM, TAG> >(pl), Filter<ITEM, TAG>(pl) {}
00105     PatchList(const PatchList& pl, Consumer<ITEM, TAG>& consumer) : 
00106         std::map<ITEM, Patch<ITEM, TAG> >(pl),
00107         Filter<ITEM, TAG>(consumer) {}
00108     virtual ~PatchList() throw () {}
00109 
00110     typedef typename std::map<ITEM, Patch<ITEM, TAG> >::const_iterator const_iterator;
00111     typedef typename std::map<ITEM, Patch<ITEM, TAG> >::iterator iterator;
00112 
00116     void addPatch(const ReadonlyCollection<ITEM, TAG>& im1, const ReadonlyCollection<ITEM, TAG>& im2) throw ();
00117 
00121     void addPatch(const Patch<ITEM, TAG>& patch) throw ();
00122 
00126     void addPatch(const PatchList<ITEM, TAG>& patches) throw ();
00127 
00134     OpSet<TAG> patch(const ITEM& item, const OpSet<TAG>& tagset) const throw ();
00135 
00136     /*
00137     // Output the patch list to a TagcollConsumer
00138     void output(TagcollConsumer<ITEM, std::string>& consumer) const throw ();
00139     */
00140 
00141     PatchList<ITEM, TAG> getReverse() const throw ();
00142 };
00143 
00144 };
00145 
00146 // vim:set ts=4 sw=4:
00147 #endif

Generated on Wed Jun 20 19:19:06 2007 for libtagcoll by  doxygen 1.5.2