- Create the cache directly from the schema (installed) file.
[platform/upstream/libzypp.git] / zypp / Edition.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Edition.h
10  *
11 */
12 #ifndef ZYPP_EDITION_H
13 #define ZYPP_EDITION_H
14
15 #include <iosfwd>
16 #include <functional>
17 #include <string>
18
19 #include "zypp/base/PtrTypes.h"
20
21 #include "zypp/RelCompare.h"
22 #include "zypp/Range.h"
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27
28   ///////////////////////////////////////////////////////////////////
29   //
30   //    CLASS NAME : Edition
31   //
32   /** Edition represents <code>[epoch:]version[-release]</code>
33    *
34    * \li \c epoch   (optional) number, Edition::noepoch if not supplied
35    * \li \c version (required) string, may not contain '-'
36    * \li \c release (optional) string, may not contain '-'
37    *
38    * Comparison is actually \reg g_BackendSpecific.
39    *
40    * \li \b RPM: Edition are ordered according to \c epoch, then \c version,
41    * then \c release. Version and release strings are compared by splitting
42    * them into segments of alpha or digit sequences. Segments are compared
43    * according to their type. On mixed types a string compares less than a
44    * number.
45    * \code
46    *   compare( 1.a, 1.0 ) == -1 (<)
47    *   compare( 1.0, 1.a ) ==  1 (>)
48    *   compare( 1.0, 1_0 ) ==  0 (==)
49    * \endcode
50    *
51    * \attention operator< defines equivalence classes of version strings, as non
52    * alphanumeric chars are ignored. That' why \c 1.0 and \c 1_0 compare equal
53    * in the example.<BR>
54    * If Edition is used as key in a std::container, per default
55    * <em>plain string comparison</em> is used. If you want to compare by
56    * version, let the container use \ref CompareByLT<Edition> to compare.
57    *
58    * \attention Edition::match compares two editions, treating empty
59    * version or release strings as wildcard. Thus match is not transitive,
60    * and you don't want to use it to order keys in a a std::container.
61    *
62    * \ingroup g_BackendSpecific
63    * \todo Define exceptions.
64    * \todo optimize implementation(e.g don't store epoch if noepoch)
65    * \todo implement debian comparison and make choice backend specific
66    * \todo optimize noedition. unified Impl and quick check in compare.
67   */
68   class Edition
69   {
70   public:
71     /** Type of an epoch. */
72     typedef unsigned epoch_t;
73
74     /** Value representing \c noepoch. */
75     static const epoch_t noepoch = 0;
76
77     /** Value representing \c noedition.
78      * This is in fact a valid Edition. It's what the default ctor
79      * creates or will be parsed from an empty string.
80     */
81     static const Edition noedition;
82
83   public:
84     /** Default ctor: \ref noedition. */
85     Edition();
86
87     /** Ctor taking edition as string.
88      * \throw INTERNAL if \a edition_r does not make a valid Edition.
89     */
90     Edition( const std::string & edition_r );
91
92     /** Ctor taking \a version_r, \a release_r and optional \a epoch_r
93      * \throw INTERNAL if \a version_r or \a release_r are not valid.
94     */
95     Edition( const std::string & version_r,
96              const std::string & release_r,
97              epoch_t epoch_r = noepoch );
98
99     /** Ctor taking \a version_r, \a release_r and optional \a epoch_r as string.
100      * \throw INTERNAL if \a version_r or \a release_r \a epoch_r are
101      * not valid.
102     */
103     Edition( const std::string & version_r,
104              const std::string & release_r,
105              const std::string & epoch_r );
106
107     /** Dtor */
108     ~Edition();
109
110   public:
111     /** Epoch */
112     epoch_t epoch() const;
113
114     /** Version */
115     const std::string & version() const;
116
117     /** Release */
118     const std::string & release() const;
119
120     /** String representation of Edition. */
121     std::string asString() const;
122
123   public:
124     /** Compare two Editions returning <tt>-1,0,1</tt>.
125      * \return <tt>-1,0,1</tt> if editions are <tt>\<,==,\></tt>.
126      *
127      * \attention An empty version or release string is not treated
128      * specialy. It's the least possible value. If you want an empty
129      * string treated as \c ANY, use \ref match.
130     */
131     static int compare( const Edition & lhs, const Edition & rhs );
132
133     /** */
134     int compare( const Edition & rhs ) const
135     { return compare( *this, rhs ); }
136
137     /** \ref compare functor.
138      * \see \ref RelCompare.
139     */
140     typedef Compare<Edition> Compare;
141
142     /** \ref Edition \ref Range based on \ref Compare.
143      * \see \ref RelCompare.
144     */
145     typedef Range<Edition> CompareRange;
146
147   public:
148     /** Match two Editions returning <tt>-1,0,1</tt>, treating empty
149      *  strings as \c ANY.
150      * \return <tt>-1,0,1</tt> if editions match <tt>\<,==,\></tt>.
151     */
152     static int match( const Edition & lhs, const Edition & rhs );
153
154     /** */
155     int match( const Edition & rhs ) const
156     { return match( *this, rhs ); }
157
158     /** \ref match functor.
159      * \see \ref RelCompare.
160     */
161     struct Match: public std::binary_function<Edition,Edition,int>
162     {
163       int operator()( const Edition & lhs, const Edition & rhs ) const
164       { return Edition::match( lhs, rhs ); }
165     };
166
167     /** \ref Edition \ref Range based on \ref Match.
168      * \see \ref RelCompare.
169     */
170     typedef Range<Edition, Match> MatchRange;
171
172   private:
173     /** Hides implementation */
174     struct Impl;
175     /** Pointer to implementation */
176     RW_pointer<Impl> _pimpl;
177   };
178   ///////////////////////////////////////////////////////////////////
179
180   /** \relates Edition Stream output. */
181   inline std::ostream & operator<<( std::ostream & str, const Edition & obj )
182   { return str << obj.asString(); }
183
184   /** \name Comaprison based on epoch, version, and release. */
185   //@{
186   /** \relates Edition */
187   inline bool operator==( const Edition & lhs, const Edition & rhs )
188   { return compareByRel( Rel::EQ, lhs, rhs ); }
189
190   /** \relates Edition */
191   inline bool operator!=( const Edition & lhs, const Edition & rhs )
192   { return compareByRel( Rel::NE, lhs, rhs ); }
193
194   /** \relates Edition */
195   inline bool operator<( const Edition & lhs, const Edition & rhs )
196   { return compareByRel( Rel::LT, lhs, rhs ); }
197
198   /** \relates Edition */
199   inline bool operator<=( const Edition & lhs, const Edition & rhs )
200   { return compareByRel( Rel::LE, lhs, rhs ); }
201
202   /** \relates Edition */
203   inline bool operator>( const Edition & lhs, const Edition & rhs )
204   { return compareByRel( Rel::GT, lhs, rhs ); }
205
206   /** \relates Edition */
207   inline bool operator>=( const Edition & lhs, const Edition & rhs )
208   { return compareByRel( Rel::GE, lhs, rhs ); }
209   //@}
210
211   /////////////////////////////////////////////////////////////////
212 } // namespace zypp
213 ///////////////////////////////////////////////////////////////////
214
215 ///////////////////////////////////////////////////////////////////
216 namespace std
217 { /////////////////////////////////////////////////////////////////
218
219   /** \relates zypp::Edition Default to lexicographical order in std::container.*/
220   template<>
221     inline bool less<zypp::Edition>::operator()( const zypp::Edition & lhs, const zypp::Edition & rhs ) const
222     { return lhs.asString() < rhs.asString(); }
223
224   /** \relates zypp::Edition Lexicographical equal for std::container. */
225   template<>
226     inline bool equal_to<zypp::Edition>::operator()( const zypp::Edition & lhs, const zypp::Edition & rhs ) const
227     { return lhs.asString() == rhs.asString(); }
228
229   /////////////////////////////////////////////////////////////////
230 } // namespace std
231 ///////////////////////////////////////////////////////////////////
232
233 #endif // ZYPP_EDITION_H