1 : // -*- C++ -*-
2 : #ifndef EPT_DEBTAGS_TAG_H
3 : #define EPT_DEBTAGS_TAG_H
4 :
5 : /** \file
6 : * Debtags facets and tags
7 : */
8 :
9 : /*
10 : * Copyright (C) 2005,2006,2007 Enrico Zini <enrico@debian.org>
11 : *
12 : * This program is free software; you can redistribute it and/or modify
13 : * it under the terms of the GNU General Public License as published by
14 : * the Free Software Foundation; either version 2 of the License, or
15 : * (at your option) any later version.
16 : *
17 : * This program is distributed in the hope that it will be useful,
18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : * GNU General Public License for more details.
21 : *
22 : * You should have received a copy of the GNU General Public License
23 : * along with this program; if not, write to the Free Software
24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 : */
26 :
27 : #include <set>
28 : #include <string>
29 :
30 : namespace ept {
31 : namespace debtags {
32 :
33 : class Vocabulary;
34 :
35 : class Tag;
36 :
37 : /**
38 : * Representation of a facet.
39 : *
40 : * ept::debtags::Facet represents a Facet with all its informations.
41 : * It is guaranteed to have fast value-copy semantics, so it can be passed
42 : * around freely and efficiently without worrying about memory management
43 : * issues.
44 : *
45 : * The class is normally instantiated using a Vocabulary:
46 : * \code
47 : * Facet facet = vocabulary.faceByName("made-of");
48 : * \endcode
49 : *
50 : * Facets can contain an "invalid" value, in which case using any of their
51 : * methods will likely produce segfault. The "invalid" facets are useful as
52 : * "none" return values:
53 : *
54 : * \code
55 : * Facet facet = vocabulary.facetByName("made-of");
56 : * if (!facet)
57 : * throw SomeException("facet \"made-of\" has not been defined");
58 : * \endcode
59 : */
60 : class Facet
61 : {
62 : protected:
63 : const Vocabulary* m_tags;
64 : int m_id;
65 :
66 120 : Facet(const Vocabulary* tags, int id) : m_tags(tags), m_id(id) {}
67 :
68 : public:
69 : Facet() : m_tags(0), m_id(-1) {}
70 265 : ~Facet() {}
71 :
72 29 : bool operator==(const Facet& f) const { return m_id == f.m_id; }
73 : bool operator!=(const Facet& f) const { return m_id != f.m_id; }
74 600 : bool operator<(const Facet& f) const { return m_id < f.m_id; }
75 :
76 : /**
77 : * Return true if the facet is valid
78 : */
79 0 : operator bool() const { return m_id != -1; }
80 353 : bool valid() const { return m_id != -1; }
81 :
82 : /**
83 : * Return the name of the facet
84 : * @throws std::out_of_range if the facet is not valid
85 : */
86 : std::string name() const;
87 : /**
88 : * Return the name of the facet
89 : *
90 : * Returns d if the facet is not valid.
91 : */
92 : std::string name(const std::string& d) const;
93 :
94 : /**
95 : * Return the short description of the facet
96 : * @throws std::out_of_range if the facet is not valid
97 : */
98 : std::string shortDescription() const;
99 : /**
100 : * Return the short description of the facet
101 : *
102 : * Returns d if the facet is not valid.
103 : */
104 : std::string shortDescription(const std::string& d) const;
105 :
106 : /**
107 : * Return the long description of the facet
108 : * @throws std::out_of_range if the facet is not valid
109 : */
110 : std::string longDescription() const;
111 : /**
112 : * Return the long description of the facet
113 : *
114 : * Returns d if the facet is not valid.
115 : */
116 : std::string longDescription(const std::string& d) const;
117 :
118 : /**
119 : * Return true if the facet has a tag with the given name (name, not fullname)
120 : */
121 : bool hasTag(const std::string& name) const;
122 :
123 : /**
124 : * Return the list of tags in this facet
125 : */
126 : std::set<Tag> tags() const;
127 :
128 : /**
129 : * Return the ID of this facet
130 : *
131 : * @warning This method is exported to help in writing tests, but it is not
132 : * part of the normal API: do not use it, because future implementations may
133 : * not be based on IDs and therefore not have this method.
134 : */
135 58 : int id() const { return m_id; }
136 :
137 : friend class Vocabulary;
138 : };
139 :
140 : /**
141 : * Representation of a tag.
142 : *
143 : * ept::debtags::Tag represents a Tag with all its informations.
144 : * It is guaranteed to have fast value-copy semantics, so it can be passed
145 : * around freely and efficiently without worrying about memory management
146 : * issues.
147 : *
148 : * The class is normally instantiated using a Vocabulary:
149 : * \code
150 : * Tag tag = vocabulary.tagByName("made-of::lang:c++");
151 : * \endcode
152 : *
153 : * Tags can contain an "invalid" value, in which case using any of their
154 : * methods will likely produce segfault. The "invalid" facets are useful as
155 : * "none" return values:
156 : *
157 : * \code
158 : * Tag tag = vocabulary.tagByName("made-of");
159 : * if (!tag)
160 : * throw SomeException("tag \"mytag\" has not been defined");
161 : * \endcode
162 : */
163 : class Tag
164 : {
165 : protected:
166 : const Vocabulary* m_tags;
167 : int m_id;
168 :
169 745056 : Tag(const Vocabulary* tags, int id) : m_tags(tags), m_id(id) {}
170 :
171 : public:
172 : typedef std::set< Tag > Set;
173 :
174 2 : Tag() : m_tags(0), m_id(-1) {}
175 2229812 : ~Tag() {}
176 :
177 1228 : bool operator==(const Tag& f) const { return m_id == f.m_id; }
178 5 : bool operator!=(const Tag& f) const { return m_id != f.m_id; }
179 2300524 : bool operator<(const Tag& f) const { return m_id < f.m_id; }
180 :
181 1 : operator bool() const { return m_id != -1; }
182 324422 : bool valid() const { return m_id != -1; }
183 :
184 : Facet facet() const;
185 :
186 : /**
187 : * Return the name of the tag, without the facet:: prefix
188 : * @throws std::out_of_range if the tag is not valid
189 : */
190 : std::string name() const;
191 : /**
192 : * Return the short description of the tag
193 : *
194 : * Returns d if the tag is not valid.
195 : */
196 : std::string name(const std::string& d) const;
197 :
198 : /**
199 : * Return the name of the tag, with the facet:: prefix
200 : * @throws std::out_of_range if the tag is not valid
201 : */
202 : std::string fullname() const;
203 : /**
204 : * Return the short description of the tag
205 : *
206 : * Returns d if the tag is not valid.
207 : */
208 : std::string fullname(const std::string& d) const;
209 :
210 : /**
211 : * Return the short description of the tag
212 : * @throws std::out_of_range if the tag is not valid
213 : */
214 : std::string shortDescription() const;
215 : /**
216 : * Return the short description of the tag
217 : *
218 : * Returns d if the tag is not valid.
219 : */
220 : std::string shortDescription(const std::string& d) const;
221 :
222 : /**
223 : * Return the long description of the tag
224 : *
225 : * @throws std::out_of_range if the tag is not valid
226 : */
227 : std::string longDescription() const;
228 : /**
229 : * Return the long description of the tag
230 : *
231 : * Returns d if the tag is not valid.
232 : */
233 : std::string longDescription(const std::string& d) const;
234 :
235 : /**
236 : * Return the ID of this tag
237 : *
238 : * @warning This method is exported to help in writing tests, but it is not
239 : * part of the normal API: do not use it, because future implementations may
240 : * not be based on IDs and therefore not have this method.
241 : */
242 106853 : int id() const { return m_id; }
243 :
244 : friend class Vocabulary;
245 : };
246 :
247 : }
248 : }
249 :
250 : // vim:set ts=3 sw=3:
251 : #endif
|