LTP GCOV extension - code coverage report
Current view: directory - usr/include/tagcoll-2.0.11/tagcoll/coll - patched.h
Test: lcov.info
Date: 2008-08-14 Instrumented lines: 57
Code covered: 66.7 % Executed lines: 38

       1                 : #ifndef TAGCOLL_COLL_PATCHED_H
       2                 : #define TAGCOLL_COLL_PATCHED_H
       3                 : 
       4                 : /** \file
       5                 :  * Wrap a Collection, preserving modifications as patches
       6                 :  */
       7                 : 
       8                 : /*
       9                 :  * Copyright (C) 2005,2006  Enrico Zini <enrico@debian.org>
      10                 :  *
      11                 :  * This program is free software; you can redistribute it and/or modify
      12                 :  * it under the terms of the GNU General Public License as published by
      13                 :  * the Free Software Foundation; either version 2 of the License, or
      14                 :  * (at your option) any later version.
      15                 :  *
      16                 :  * This program is distributed in the hope that it will be useful,
      17                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :  * GNU General Public License for more details.
      20                 :  *
      21                 :  * You should have received a copy of the GNU General Public License
      22                 :  * along with this program; if not, write to the Free Software
      23                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      24                 :  */
      25                 : 
      26                 : #include <tagcoll/coll/base.h>
      27                 : #include <tagcoll/patch.h>
      28                 : 
      29                 : namespace tagcoll {
      30                 : template<typename T1, typename T2> class PatchList;
      31                 : 
      32                 : namespace coll {
      33                 : template<typename ROCOLL>
      34                 : class Patched;
      35                 : 
      36                 : template<typename ROCOLL>
      37                 : struct coll_traits< Patched<ROCOLL> >
      38                 : {
      39                 :         typedef typename coll_traits<ROCOLL>::item_type item_type;
      40                 :         typedef typename coll_traits<ROCOLL>::tag_type tag_type;
      41                 :         typedef typename coll_traits<ROCOLL>::tagset_type tagset_type;
      42                 :         typedef typename coll_traits<ROCOLL>::itemset_type itemset_type;
      43                 : };
      44                 : 
      45                 : /**
      46                 :  * Wraps a collection by intercepting all changes to it and preserving them as
      47                 :  * a PatchList.
      48                 :  */
      49                 : template<typename ROCOLL>
      50                 : class Patched : public coll::Collection< Patched<ROCOLL> >
      51              10 : {
      52                 : public:
      53                 :         typedef tagcoll::Patch<
      54                 :                 typename coll_traits<ROCOLL>::item_type,
      55                 :                 typename coll_traits<ROCOLL>::tag_type> Patch;
      56                 :         typedef tagcoll::PatchList<
      57                 :                 typename coll_traits<ROCOLL>::item_type,
      58                 :                 typename coll_traits<ROCOLL>::tag_type> Patches;
      59                 :         typedef tagcoll::Patch<
      60                 :                 typename coll_traits<ROCOLL>::tag_type,
      61                 :                 typename coll_traits<ROCOLL>::item_type> RPatch;
      62                 :         typedef tagcoll::PatchList<
      63                 :                 typename coll_traits<ROCOLL>::tag_type,
      64                 :                 typename coll_traits<ROCOLL>::item_type> RPatches;
      65                 : 
      66                 : protected:
      67                 :         typedef typename coll_traits<ROCOLL>::item_type Item;
      68                 :         typedef typename coll_traits<ROCOLL>::tag_type Tag;
      69                 :         typedef typename coll_traits<ROCOLL>::itemset_type ItemSet;
      70                 :         typedef typename coll_traits<ROCOLL>::tagset_type TagSet;
      71                 : 
      72                 :         const ROCOLL& coll;
      73                 :         Patches m_changes;
      74                 :         RPatches m_rchanges;
      75                 : 
      76                 : #if 0
      77                 :         virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
      78                 : 
      79                 :         virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const;
      80                 :         virtual std::set<TAG> getTagsOfItem(const ITEM& item) const;
      81                 : #endif
      82                 : 
      83                 : public:
      84                 :         typedef std::pair<Item, TagSet> value_type;
      85                 : 
      86                 :         class const_iterator
      87                 :         {
      88                 :                 const Patched<ROCOLL>& coll;
      89                 :                 typename ROCOLL::const_iterator ci;
      90                 :                 typename Patches::const_iterator pi;
      91                 :                 mutable typename Patched<ROCOLL>::value_type* cached_val;
      92                 : 
      93                 :         protected:
      94                 :                 const_iterator(const Patched<ROCOLL>& coll,
      95                 :                                                 const typename ROCOLL::const_iterator& ci,
      96           84592 :                                                 const typename Patches::const_iterator& pi)
      97           84592 :                         : coll(coll), ci(ci), pi(pi), cached_val(0) {}
      98                 :         
      99                 :         public:
     100          148035 :                 ~const_iterator()
     101                 :                 {
     102          148035 :                         if (cached_val)
     103               0 :                                 delete cached_val;
     104          148035 :                 }
     105           84580 :                 const typename Patched<ROCOLL>::value_type operator*() const
     106                 :                 {
     107           84580 :                         if (cached_val)
     108               0 :                                 return *cached_val;
     109                 : 
     110           84580 :                         if (ci == coll.coll.end() && pi == coll.m_changes.end())
     111               0 :                                 return *(typename Patched<ROCOLL>::value_type*)0;
     112           84580 :                         else if (pi == coll.m_changes.end())
     113           84580 :                                 return *ci;
     114               0 :                         else if (ci == coll.coll.end())
     115               0 :                                 return make_pair(pi->first, pi->second.added);
     116               0 :                         else if (ci->first < pi->first)
     117               0 :                                 return *ci;
     118               0 :                         else if (ci->first > pi->first)
     119               0 :                                 return make_pair(pi->first, pi->second.added);
     120                 :                         else
     121               0 :                                 return make_pair(ci->first, pi->second.apply(ci->second));
     122                 :                 }
     123          211450 :                 const typename Patched<ROCOLL>::value_type* operator->() const
     124                 :                 {
     125          211450 :                         if (cached_val)
     126          126870 :                                 return cached_val;
     127           84580 :                         return cached_val = new typename Patched<ROCOLL>::value_type(*(*this));
     128                 :                 }
     129           84580 :                 const_iterator& operator++()
     130                 :                 {
     131           84580 :                         if (ci == coll.coll.end() && pi == coll.m_changes.end())
     132                 :                                 ;
     133           84580 :                         else if (pi == coll.m_changes.end())
     134           84580 :                                 ++ci;
     135               0 :                         else if (ci == coll.coll.end())
     136               0 :                                 ++pi;
     137               0 :                         else if (ci->first < pi->first)
     138               0 :                                 ++ci;
     139               0 :                         else if (ci->first > pi->first)
     140               0 :                                 ++pi;
     141                 :                         else
     142                 :                         {
     143               0 :                                 ++ci;
     144               0 :                                 ++pi;
     145                 :                         }
     146           84580 :                         if (cached_val)
     147                 :                         {
     148           84580 :                                 delete cached_val;
     149           84580 :                                 cached_val = 0;
     150                 :                         }
     151           84580 :                         return *this;
     152                 :                 }
     153               1 :                 bool operator==(const const_iterator& iter) const
     154                 :                 {
     155               1 :                         return ci == iter.ci && pi == iter.pi;
     156                 :                 }
     157           84585 :                 bool operator!=(const const_iterator& iter) const
     158                 :                 {
     159           84585 :                         return ci != iter.ci || pi != iter.pi;
     160                 :                 }
     161                 :                 
     162                 :                 friend class Patched<ROCOLL>;
     163                 :         };
     164               6 :         const_iterator begin() const { return const_iterator(*this, coll.begin(), m_changes.begin()); }
     165           84586 :         const_iterator end() const { return const_iterator(*this, coll.end(), m_changes.end()); }
     166                 : 
     167              10 :         Patched(const ROCOLL& coll) : coll(coll) {}
     168                 : 
     169                 :         template<typename ITEMS, typename TAGS>
     170                 :         void insert(const ITEMS& items, const TAGS& tags);
     171                 : 
     172                 :         template<typename ITEMS>
     173                 :         void insert(const ITEMS& items, const wibble::Empty<Tag>& tags)
     174                 :         {
     175                 :                 // Nothing to do in this case
     176                 :         }
     177                 : 
     178                 :         /**
     179                 :          * Removes all items from the collection
     180                 :          */
     181                 :         void clear();
     182                 : 
     183                 :         /**
     184                 :          * Get the changes that have been applied to this collection
     185                 :          */
     186               4 :         const Patches& changes() const { return m_changes; }
     187                 : 
     188                 :         /**
     189                 :          * Throw away all changes previously applied to this collection
     190                 :          */
     191                 :         void resetChanges() { m_changes.clear(); m_rchanges.clear(); }
     192                 : 
     193                 :         /**
     194                 :          * Set the changes list to a specific patch list
     195                 :          */
     196               0 :         void setChanges(const Patches& changes);
     197                 : 
     198                 :         /**
     199                 :          * Add a specific patch list to the changes list
     200                 :          */
     201               2 :         void addChanges(const Patches& changes);
     202                 : 
     203                 :     bool hasTag(const Tag& tag) const;
     204                 : 
     205               5 :         TagSet getTagsOfItem(const Item& item) const
     206                 :         {
     207               5 :                 return m_changes.patch(item, coll.getTagsOfItem(item));
     208                 :         }
     209               9 :         ItemSet getItemsHavingTag(const typename coll_traits<ROCOLL>::tag_type& tag) const
     210                 :         {
     211               9 :                 return m_rchanges.patch(tag, coll.getItemsHavingTag(tag));
     212                 :         }
     213                 : 
     214                 :         ItemSet getTaggedItems() const;
     215               1 :         TagSet getAllTags() const;
     216                 : 
     217                 :         unsigned int tagCount() const { return getAllTags().size(); }
     218                 : 
     219                 :         unsigned int getCardinality(const Tag& tag) const;
     220                 : 
     221               2 :         void applyChange(const Patches& change) { this->addChanges(change); }
     222                 : 
     223                 : #if 0
     224                 :         template<typename OUT>
     225                 :         void output(OUT out) const
     226                 :         {
     227                 :                 for (const_iterator i = begin(); i != end(); ++i)
     228                 :                 {
     229                 :                         *out = *i;
     230                 :                         ++out;
     231                 :                 }
     232                 :         }
     233                 : #endif
     234                 : };
     235                 : 
     236                 : }
     237                 : }
     238                 : 
     239                 : // vim:set ts=4 sw=4:
     240                 : #endif

Generated by: LTP GCOV extension version 1.6