1 : #ifndef TAGCOLL_COLL_SIMPLE_H
2 : #define TAGCOLL_COLL_SIMPLE_H
3 :
4 : /** \file
5 : * Simple tagged collection.
6 : *
7 : * Also used for merging tags of items appearing multiple times in a stream of
8 : * tagged items
9 : */
10 :
11 : /*
12 : * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico@debian.org>
13 : *
14 : * This library is free software; you can redistribute it and/or
15 : * modify it under the terms of the GNU Lesser General Public
16 : * License as published by the Free Software Foundation; either
17 : * version 2.1 of the License, or (at your option) any later version.
18 : *
19 : * This library is distributed in the hope that it will be useful,
20 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 : * Lesser General Public License for more details.
23 : *
24 : * You should have received a copy of the GNU Lesser General Public
25 : * License along with this library; if not, write to the Free Software
26 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 : */
28 :
29 : #include <tagcoll/coll/base.h>
30 : #include <set>
31 : #include <map>
32 :
33 : namespace tagcoll {
34 : template<typename ITEM, typename TAG>
35 : class PatchList;
36 :
37 : namespace coll {
38 :
39 : template<typename ITEM, typename TAG>
40 : class Simple;
41 :
42 : template<typename ITEM, typename TAG>
43 : struct coll_traits< Simple<ITEM, TAG> >
44 : {
45 : typedef ITEM item_type;
46 : typedef TAG tag_type;
47 : typedef std::set<ITEM> tagset_type;
48 : typedef std::set<TAG> itemset_type;
49 : };
50 :
51 :
52 : /**
53 : * Simple Collection.
54 : *
55 : * It can be used to merge input values: if an item is added multiple times,
56 : * its various tagsets are merged in a single one.
57 : *
58 : * It is also a full-featured collection, although not very optimized.
59 : */
60 : template<typename ITEM, typename TAG>
61 : class Simple : public coll::Collection< Simple<ITEM, TAG> >
62 14 : {
63 : protected:
64 : std::map< ITEM, std::set<TAG> > coll;
65 :
66 : #if 0
67 : virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
68 :
69 : virtual std::set<ITEM> getItemsHavingTags(const std::set<TAG>& tags) const;
70 : #endif
71 :
72 : public:
73 : typedef typename std::map< ITEM, std::set<TAG> >::const_iterator const_iterator;
74 : typedef typename std::map< ITEM, std::set<TAG> >::iterator iterator;
75 : typedef typename std::map< ITEM, std::set<TAG> >::value_type value_type;
76 :
77 5 : const_iterator begin() const { return coll.begin(); }
78 42298 : const_iterator end() const { return coll.end(); }
79 1 : iterator begin() { return coll.begin(); }
80 21146 : iterator end() { return coll.end(); }
81 :
82 2 : bool empty() const { return coll.empty(); }
83 :
84 : template<typename ITEMS, typename TAGS>
85 2 : void insert(const ITEMS& items, const TAGS& tags);
86 :
87 : bool hasItem(const ITEM& item) const { return coll.find(item) != coll.end(); }
88 :
89 2 : std::set<TAG> getTagsOfItem(const ITEM& item) const;
90 : std::set<ITEM> getItemsHavingTag(const TAG& tag) const;
91 : template<typename TAGS>
92 : std::set<ITEM> getItemsHavingTags(const TAGS& tag) const;
93 :
94 : template<typename TAGS, typename OUT>
95 : void outputHavingTags(const TAGS& tags, OUT out) const;
96 :
97 : #if 0
98 : void output(Consumer<ITEM, TAG>& consumer) const;
99 : void outputHavingTags(const std::set<TAG>& ts, Consumer<ITEM, TAG>& consumer) const;
100 :
101 : /**
102 : * Send the merged data to a consumer, but reversed: the tag become items,
103 : * and they are tagged with the items that had them
104 : */
105 : void outputReversed(Consumer<TAG, ITEM>& consumer) const;
106 : #endif
107 :
108 : void applyChange(const PatchList<ITEM, TAG>& change);
109 :
110 : std::set<ITEM> getTaggedItems() const;
111 :
112 3 : std::set<TAG> getAllTags() const;
113 :
114 : std::set<TAG> getCompanionTags(const std::set<TAG>& ts) const;
115 :
116 : std::set<ITEM> getRelatedItems(const std::set<TAG>& ts, int maxdistance = 1) const;
117 :
118 : /**
119 : * Count the number of items
120 : */
121 5 : unsigned int itemCount() const;
122 :
123 3 : unsigned int tagCount() const { return getAllTags().size(); }
124 :
125 : /**
126 : * Empty the collection
127 : */
128 1 : void clear()
129 : {
130 1 : coll.clear();
131 1 : }
132 : };
133 :
134 : }
135 : }
136 :
137 : // vim:set ts=4 sw=4:
138 : #endif
|