Logo Search packages:      
Sourcecode: tagcoll version File versions  Download package

Patches.h

Go to the documentation of this file.
#ifndef TAGCOLL_PATCHES_H
#define TAGCOLL_PATCHES_H

/** \file
 * Classes handling tag patches
 */

/*
 * Copyright (C) 2003,2004,2005  Enrico Zini <enrico@debian.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 */

#include <tagcoll/Consumer.h>
#include <tagcoll/Filter.h>
#include <tagcoll/Collection.h>

#include <map>
#include <string>

namespace Tagcoll
{

/**
 * Patch for the tagset of a specific item
 */
template <typename ITEM, typename TAG>
00040 class Patch
{
protected:
      ITEM item;
      OpSet<TAG> added;
      OpSet<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 ()
            : 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; }

      const ITEM& getItem() const throw () { return item; }
      const OpSet<TAG>& getAdded() const throw () { return added; }
      const OpSet<TAG>& getRemoved() const throw () { return removed; }

      Patch<ITEM, TAG> getReverse() const throw ()
      {
            return Patch<ITEM, TAG>(item, removed, added);
      }

      void mergeWith(const Patch<ITEM, TAG>& patch) throw ()
      {
            add(patch.getAdded());
            remove(patch.getRemoved());
      }

      OpSet<TAG> apply(const OpSet<TAG>& ts) const throw ()
      {
            return (ts + added) - removed;
      }

      void removeRedundant(const OpSet<TAG> ts) throw ()
      {
            // Don't add what already exists
            added -= ts;
            // Don't remove what does not exist
            removed -= (removed - ts);
      }
};

/**
 * List of patches that can be applied to a TaggedCollection
 */
template <class ITEM, class TAG>
00092 class PatchList : public std::map<ITEM, Patch<ITEM, TAG> >, public Filter<ITEM, TAG> 
{
protected:
      /// Process an untagged item
      virtual void consumeItemUntagged(const ITEM& item);

      /// Process a tagged item, with its tags
      virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);

public:
      PatchList() : Filter<ITEM, TAG>() {}
      PatchList(Consumer<ITEM, TAG>& consumer) : Filter<ITEM, TAG>(consumer) {}
      PatchList(const PatchList& pl) : std::map<ITEM, Patch<ITEM, TAG> >(pl) {}
      PatchList(const PatchList& pl, Consumer<ITEM, TAG>& consumer) : 
            std::map<ITEM, Patch<ITEM, TAG> >(pl),
            Filter<ITEM, TAG>(consumer) {}
      virtual ~PatchList() throw () {}

      typedef typename std::map<ITEM, Patch<ITEM, TAG> >::const_iterator const_iterator;
      typedef typename std::map<ITEM, Patch<ITEM, TAG> >::iterator iterator;

      /**
       * Add to this patchlist the patches needed to transform `im1' in `im2'
       */
      void addPatch(const Collection<ITEM, TAG>& im1, const Collection<ITEM, TAG>& im2) throw ();

      /**
       * Add `patch' to this PatchList
       */
      void addPatch(const Patch<ITEM, TAG>& patch) throw ();

      /**
       * Add `patches' to this PatchList
       */
      void addPatch(const PatchList<ITEM, TAG>& patches) throw ();

      /**
       * Patch a tagged item
       *
       * @return
       *   The new (patched) set of tags
       */
      OpSet<TAG> patch(const ITEM& item, const OpSet<TAG>& tagset) const throw ();

      /*
      // Output the patch list to a TagcollConsumer
      void output(TagcollConsumer<ITEM, std::string>& consumer) const throw ();
      */

      PatchList<ITEM, TAG> getReverse() const throw ();
};

};

// vim:set ts=4 sw=4:
#endif

Generated by  Doxygen 1.6.0   Back to index