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

       1                 : #ifndef TAGCOLL_COLL_BASE_H
       2                 : #define TAGCOLL_COLL_BASE_H
       3                 : 
       4                 : /** \file
       5                 :  * Base mixins for tagged collections
       6                 :  */
       7                 : 
       8                 : /*
       9                 :  * Copyright (C) 2003,2004,2005,2006  Enrico Zini <enrico@debian.org>
      10                 :  *
      11                 :  * This library is free software; you can redistribute it and/or
      12                 :  * modify it under the terms of the GNU Lesser General Public
      13                 :  * License as published by the Free Software Foundation; either
      14                 :  * version 2.1 of the License, or (at your option) any later version.
      15                 :  *
      16                 :  * This library 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 GNU
      19                 :  * Lesser General Public License for more details.
      20                 :  *
      21                 :  * You should have received a copy of the GNU Lesser General Public
      22                 :  * License along with this library; if not, write to the Free Software
      23                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
      24                 :  */
      25                 : 
      26                 : #include <wibble/mixin.h>
      27                 : #include <vector>
      28                 : 
      29                 : namespace std {
      30                 : template<typename A, typename B> class pair;
      31                 : }
      32                 : 
      33                 : namespace tagcoll {
      34                 : namespace coll {
      35                 : 
      36                 : template<typename T>
      37                 : class coll_traits;
      38                 :         
      39                 : /**
      40                 :  * Interface for all collections of tagged items.
      41                 :  *
      42                 :  * \note The point of a collection is to track the tags attached to items, and
      43                 :  * not to store the items themselves.  This means that collections are not
      44                 :  * required to keep track of items with no tags.
      45                 :  */
      46                 : template<typename Self>
      47                 : class ReadonlyCollection
      48              37 : {
      49           84611 :         const Self& self() const { return *static_cast<const Self*>(this); }
      50                 : 
      51                 :         class CardinalityOrder
      52                 :         {
      53                 :                 const Self& coll;
      54                 :         public:
      55                 :                 CardinalityOrder(const Self& coll) : coll(coll) {}
      56                 :                 bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2)
      57                 :                 {
      58                 :                         // Returns true if t1 precedes t2, and false otherwise
      59                 :                         return coll.getCardinality(t1) < coll.getCardinality(t2);
      60                 :                 }
      61                 :         };
      62                 : 
      63                 :         class DiscriminanceOrder
      64                 :         {
      65                 :                 const Self& coll;
      66                 :         public:
      67                 :                 DiscriminanceOrder(const Self& coll) : coll(coll) {}
      68                 :                 bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2)
      69                 :                 {
      70                 :                         // Returns true if t1 precedes t2, and false otherwise
      71                 :                         return coll.getDiscriminance(t1) < coll.getDiscriminance(t2);
      72                 :                 }
      73                 :         };
      74                 : 
      75                 :         template<typename COLL>
      76                 :         class RelevanceOrder
      77                 :         {
      78                 :                 const COLL& first;
      79                 :                 const Self& second;
      80                 :         public:
      81                 :                 RelevanceOrder(const COLL& first, const Self& second)
      82                 :                         : first(first), second(second) {}
      83                 :                 bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2);
      84                 :         };
      85                 : 
      86                 :         /**
      87                 :          * Get the items which are tagged with at least the tag `tag'
      88                 :          *
      89                 :          * \return
      90                 :          *   The items found, or an empty set if no items have that tag
      91                 :          */
      92                 :         //virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const = 0;
      93                 : 
      94                 :         /**
      95                 :          * Get the tags attached to an item.
      96                 :          *
      97                 :          * \param item
      98                 :          *   The item to query
      99                 :          * \return 
     100                 :          *   The set of tags, or an empty set if the item has no tags or it does
     101                 :          *   not exist.
     102                 :          */
     103                 :         //virtual std::set<TAG> getTagsOfItem(const ITEM& item) const = 0;
     104                 : 
     105                 : public:
     106                 :         /**
     107                 :          * Check if the collection contains a tag
     108                 :          *
     109                 :          * \param tag
     110                 :          *   The tag to look for
     111                 :          * \return 
     112                 :          *   true if the collection contains tag, false otherwise
     113                 :          */
     114                 :         bool hasTag(const typename coll_traits<Self>::tag_type& tag) const;
     115                 : 
     116                 :         /**
     117                 :          * Get the tags of item `item'.  Return an empty set if `item' does not exist
     118                 :          */
     119                 :         //std::set<Self::tag_type> getTags(const typename Self::item_type& item) const = 0;
     120                 : 
     121                 :         /**
     122                 :          * Get all the tags attached to the items in a set.
     123                 :          *
     124                 :          * \param items
     125                 :          *   The items to query
     126                 :          * \return 
     127                 :          *   The set of tags, or an empty set if the items have no tags or do not
     128                 :          *   exist.
     129                 :          */
     130                 :         template<typename ITEMS>
     131                 :         typename coll_traits<Self>::tagset_type getTagsOfItems(const ITEMS& items) const;
     132                 : 
     133                 :         /**
     134                 :          * Get the items with tag `tag'.  Return an empty set if `tag' does not exist
     135                 :          */
     136                 :         //std::set<typename Self::item_type> getItems(const TAG& tag) const { return getItemsHavingTag(tag); }
     137                 : 
     138                 :         /**
     139                 :          * Get the items which are tagged with at least the tags `tags'
     140                 :          *
     141                 :          * \return
     142                 :          *   The items found, or an empty set if no items have that tag
     143                 :          */
     144                 :         template<typename TAGS>
     145               2 :         typename coll_traits<Self>::itemset_type getItemsHavingTags(const TAGS& tags) const;
     146                 : 
     147                 :         /**
     148                 :          * Get the set of all the items that have tags according to this collection
     149                 :          */
     150                 :         //virtual std::set<Self::item_type> getTaggedItems() const = 0;
     151                 : 
     152                 :         /**
     153                 :          * Get the set of all the tags in this collection
     154                 :          */
     155                 :         //virtual std::set<Self::tag_type> getAllTags() const = 0;
     156                 :         
     157                 :         /**
     158                 :          * Get all the tags in the collectin, as a vector
     159                 :          */
     160                 :         std::vector<typename coll_traits<Self>::tag_type> getAllTagsAsVector() const;
     161                 : 
     162                 :         /**
     163                 :          * Get the cardinality of tag `tag' (that is, the number of items who have it)
     164                 :          */
     165                 :         unsigned int getCardinality(const typename coll_traits<Self>::tag_type& tag) const;
     166                 : 
     167                 :         /**
     168                 :          * Return the discriminance value for this tag, that is, the minimum number
     169                 :          * of packages that would be eliminated by selecting only those tagged with
     170                 :          * this tag or only those not tagged with this tag.
     171                 :          */
     172                 :         unsigned int getDiscriminance(const typename coll_traits<Self>::tag_type& tag) const
     173                 :         {
     174                 :                 return self().getCardinality(tag) < self().tagCount() - self().getCardinality(tag) ?
     175                 :                                 self().getCardinality(tag) :
     176                 :                                 self().tagCount() - self().getCardinality(tag);
     177                 :         }
     178                 : 
     179                 :         /**
     180                 :          * Get the set of all tags in this collection that appear in tagsets
     181                 :          * containing `tags'
     182                 :          *
     183                 :          * Example:
     184                 :          * \code
     185                 :          * void refineSelection(const std::set<Tag>& selection)
     186                 :          * {
     187                 :          *    std::set<Tag> extraTags = collection.getCompanionTags(selection);
     188                 :          *    tagMenu.setAvailableOptions(extraTags);
     189                 :          * }
     190                 :          * \endcode
     191                 :          */
     192                 :         template<typename TAGS>
     193                 :         typename coll_traits<Self>::tagset_type getCompanionTags(const TAGS& tags) const;
     194                 : 
     195                 :         /**
     196                 :          * Get the related items at the given maximum distance
     197                 :          *
     198                 :          * Examples:
     199                 :          * \code
     200                 :          * // Get the items related to a given one, at the given distance
     201                 :          * std::set<Item> getRelated(const Item& item, int distance)
     202                 :          * {
     203                 :          *    std::set<Item> res = collection.getRelatedItems(collection.getTags(item), distance);
     204                 :          *    return res - item;
     205                 :          * }
     206                 :          *
     207                 :          * // Get the items related to the given ones, at the given distance
     208                 :          * std::set<Item> getRelated(const std::set<Item>& items, int distance)
     209                 :          * {
     210                 :          *    std::set<Item> res = collection.getRelatedItems(collection.getTags(items), distance);
     211                 :          *    return res - items;
     212                 :          * }
     213                 :          *
     214                 :          * // Get the related items, increasing the distance until it finds at
     215                 :          * // least 'minimum' items
     216                 :          * std::set<Item> getRelated(const Item& item, int minimum)
     217                 :          * {
     218                 :          *    std::set<Tag> tags = collection.getTags(item);
     219                 :          *    std::set<Item> res;
     220                 :          *    for (int i = 0; i < tags.size() && res.size() < minimum; i++)
     221                 :          *       res += collection.getRelatedItems(tags, i);
     222                 :          *        return res - item;
     223                 :          * }
     224                 :          * \endcode
     225                 :          */
     226                 :         template<typename TAGS>
     227                 :         typename coll_traits<Self>::itemset_type getRelatedItems(const TAGS& tags, int maxdistance = 1) const;
     228                 : 
     229                 :         /**
     230                 :          * Output all the contents of the collection to an output iterator
     231                 :          */
     232                 :         template<typename OUT>
     233               5 :         void output(OUT out) const;
     234                 : 
     235                 :         /**
     236                 :          * Send to a consumer all the items which are tagged with at least the
     237                 :          * given tags
     238                 :          */
     239                 :         template<typename TAGS, typename OUT>
     240                 :         void outputHavingTags(const TAGS& tags, OUT out) const;
     241                 : 
     242                 :         /**
     243                 :          * Get a vector containing all tags in this collection, sorted by
     244                 :          * increasing cardinality
     245                 :          */
     246                 :         std::vector<typename coll_traits<Self>::tag_type> tagsInCardinalityOrder() const;
     247                 : 
     248                 :         /**
     249                 :          * Get a vector containing all tags in this collection, sorted by
     250                 :          * increasing discriminance value (@see getDiscriminance)
     251                 :          */
     252                 :         std::vector<typename coll_traits<Self>::tag_type> tagsInDiscriminanceOrder() const;
     253                 : 
     254                 :         /**
     255                 :          * Get a vector containing all tags in this collection, sorted by
     256                 :          * increasing relevance to the filtering applied between coll and this
     257                 :          * collection
     258                 :          */
     259                 :         template<typename COLL>
     260                 :         std::vector<typename coll_traits<Self>::tag_type> tagsInRelevanceOrder(const COLL& coll) const;
     261                 : };
     262                 : 
     263                 : 
     264                 : /**
     265                 :  * Interface for all collections of tagged items.
     266                 :  *
     267                 :  * \note The point of a collection is to track the tags attached to items, and
     268                 :  * not to store the items themselves.  This means that collections are not
     269                 :  * required to keep track of items with no tags.
     270                 :  */
     271                 : template<typename Self>
     272                 : class Collection : public ReadonlyCollection<Self>
     273              27 : {
     274                 : //protected:
     275                 :         /*
     276                 :          * Implementation note: to avoid problems with classes implementing only
     277                 :          * some of the virtual methods, they are given different names.  The common
     278                 :          * 'comsume' methods are just inlined calls to the right virtual functions,
     279                 :          * and are a way of keeping the unoverridden methods from being hidden.
     280                 :          */
     281                 : 
     282                 :         //void consumeItemUntagged(const ITEM&) {}
     283                 :         //void consumeItemsUntagged(const std::set<ITEM>&) {}
     284                 : 
     285                 : public:
     286                 :         //virtual ~Collection() {}
     287                 :         
     288                 :         /**
     289                 :          * Apply a patch to the collection
     290                 :          *
     291                 :          * Example:
     292                 :          * \code
     293                 :          * void perform(const PatchList<ITEM, TAG>& change)
     294                 :          * {
     295                 :          *    collection.applyChange(change);
     296                 :          *    undo.push_back(change.getReverse());
     297                 :          * }
     298                 :          * \endcode
     299                 :          */
     300                 : //      void applyChange(
     301                 : //                      const PatchList<
     302                 : //                              typename coll_traits<Self>::item_type,
     303                 : //                              typename coll_traits<Self>::tag_type>& change);
     304                 : };
     305                 : 
     306                 : 
     307                 : template<typename COLL>
     308                 : class Inserter : public wibble::mixin::OutputIterator< Inserter<COLL> >
     309                 : {
     310                 :         COLL& coll;
     311                 : 
     312                 : public:
     313              10 :         Inserter(COLL& coll) : coll(coll) {}
     314                 : 
     315                 :         template<typename Items, typename Tags>
     316           63426 :         Inserter<COLL>& operator=(const std::pair<Items, Tags>& data)
     317                 :         {
     318           63426 :                 coll.insert(data.first, data.second);
     319           63426 :                 return *this;
     320                 :         }
     321                 : };
     322                 : 
     323                 : template<typename COLL>
     324              10 : Inserter<COLL> inserter(COLL& target)
     325                 : {
     326              10 :         return Inserter<COLL>(target);
     327                 : }
     328                 : 
     329                 : }
     330                 : }
     331                 : 
     332                 : // vim:set ts=4 sw=4:
     333                 : #endif

Generated by: LTP GCOV extension version 1.6