Imported Upstream version 15.21.0
[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 <string>
17 #include <functional>
18
19 #include "zypp/IdStringType.h"
20 #include "zypp/RelCompare.h"
21 #include "zypp/Range.h"
22
23 ///////////////////////////////////////////////////////////////////
24 namespace zypp
25 { /////////////////////////////////////////////////////////////////
26
27   ///////////////////////////////////////////////////////////////////
28   //
29   //    CLASS NAME : Edition
30   //
31   /** Edition represents <code>[epoch:]version[-release]</code>
32    *
33    * \li \c epoch   (optional) number, Edition::noepoch if not supplied
34    * \li \c version (required) string, may not contain '-'
35    * \li \c release (optional) string, may not contain '-'
36    *
37    * Comparison is actually \reg g_BackendSpecific.
38    *
39    * \li \b RPM: Edition are ordered according to \c epoch, then \c version,
40    * then \c release. Version and release strings are compared by splitting
41    * them into segments of alpha or digit sequences. Segments are compared
42    * according to their type. On mixed types a string compares less than a
43    * number.
44    * \code
45    *   compare( 1.a, 1.0 ) == -1 (<)
46    *   compare( 1.0, 1.a ) ==  1 (>)
47    *   compare( 1.0, 1_0 ) ==  0 (==)
48    * \endcode
49    *
50    * \attention operator< defines equivalence classes of version strings, as non
51    * alphanumeric chars are ignored. That' why \c 1.0 and \c 1_0 compare equal
52    * in the example.<BR>
53    *
54    * \attention Edition::match compares two editions, treating empty
55    * version or release strings as wildcard. Thus match is not transitive,
56    * and you don't want to use it to order keys in a a std::container.
57    *
58    * \ingroup g_BackendSpecific
59   */
60   class Edition : public IdStringType<Edition>
61   {
62     public:
63       /** Type of an epoch. */
64       typedef unsigned epoch_t;
65
66       /** Value representing \c noepoch. */
67       static const epoch_t noepoch = 0;
68
69     /** Value representing \c noedition (<tt>""</tt>)
70      * This is in fact a valid Edition. It's what the default ctor
71      * creates or will be parsed from an empty string.
72      */
73       static const Edition noedition;
74
75     public:
76       /** Default ctor: \ref noedition. */
77       Edition() {}
78
79       /** Ctor taking edition as string. */
80       explicit Edition( IdString::IdType id_r )     : _str( id_r ) {}
81       explicit Edition( const IdString & idstr_r )  : _str( idstr_r ) {}
82       explicit Edition( const std::string & str_r ) : _str( str_r ) {}
83       explicit Edition( const char * cstr_r )       : _str( cstr_r ) {}
84
85       /** Ctor taking \a version_r, \a release_r and optional \a epoch_r */
86       Edition( const std::string & version_r,
87                const std::string & release_r,
88                epoch_t epoch_r = noepoch );
89       /** \overload */
90       Edition( const char * version_r,
91                const char * release_r,
92                epoch_t epoch_r = noepoch );
93
94       /** Ctor taking \a version_r, \a release_r and optional \a epoch_r as string. */
95       Edition( const std::string & version_r,
96                const std::string & release_r,
97                const std::string & epoch_r );
98       /** \overload */
99       Edition( const char * version_r,
100                const char * release_r,
101                const char * epoch_r );
102
103     public:
104       /** Epoch */
105       epoch_t epoch() const;
106
107       /** Version */
108       std::string version() const;
109
110       /** Release */
111       std::string release() const;
112
113     public:
114       /** \ref compare functor.
115        * \see \ref RelCompare.
116        */
117       typedef zypp::Compare<Edition> Compare;
118
119       /** \ref Edition \ref Range based on \ref Compare.
120        * \see \ref RelCompare.
121        */
122       typedef Range<Edition> CompareRange;
123
124     public:
125       /** \name Match two Editions
126        *  Match two Editions returning <tt>-1,0,1</tt>, treating empty
127        *  version/release strings as \c ANY.
128        */
129       //@{
130       static int match( const Edition & lhs,     const Edition & rhs )     { return match( lhs.idStr(), rhs.idStr() ); }
131       static int match( const Edition & lhs,     const IdString & rhs )    { return match( lhs.idStr(), rhs ); }
132       static int match( const Edition & lhs,     const std::string & rhs ) { return _doMatch( lhs.c_str(), rhs.c_str() ); }
133       static int match( const Edition & lhs,     const char * rhs )        { return _doMatch( lhs.c_str(), rhs );}
134
135       static int match( const IdString & lhs,    const Edition & rhs )     { return match( lhs, rhs.idStr() ); }
136       static int match( const IdString & lhs,    const IdString & rhs )    { return lhs.compareEQ( rhs ) ? 0 :
137                                                                                     _doMatch( lhs.c_str(), rhs.c_str() ); }
138       static int match( const IdString & lhs,    const std::string & rhs ) { return _doMatch( lhs.c_str(), rhs.c_str() ); }
139       static int match( const IdString & lhs,    const char * rhs )        { return _doMatch( lhs.c_str(), rhs ); }
140
141       static int match( const std::string & lhs, const Edition & rhs )     { return _doMatch( lhs.c_str(), rhs.c_str() );}
142       static int match( const std::string & lhs, const IdString & rhs )    { return _doMatch( lhs.c_str(), rhs.c_str() ); }
143       static int match( const std::string & lhs, const std::string & rhs ) { return _doMatch( lhs.c_str(), rhs.c_str() ); }
144       static int match( const std::string & lhs, const char * rhs )        { return _doMatch( lhs.c_str(), rhs ); }
145
146       static int match( const char * lhs,        const Edition & rhs )     { return _doMatch( lhs, rhs.c_str() );}
147       static int match( const char * lhs,        const IdString & rhs )    { return _doMatch( lhs, rhs.c_str() ); }
148       static int match( const char * lhs,        const std::string & rhs ) { return _doMatch( lhs, rhs.c_str() ); }
149       static int match( const char * lhs,        const char * rhs )        { return _doMatch( lhs, rhs ); }
150
151       int match( const Edition & rhs )     const { return match( idStr(), rhs.idStr() ); }
152       int match( const IdString & rhs )    const { return match( idStr(), rhs ); }
153       int match( const std::string & rhs ) const { return _doMatch( c_str(), rhs.c_str() ); }
154       int match( const char * rhs )        const { return _doMatch( c_str(), rhs ); }
155       //@}
156
157       /** \ref match functor.
158        * \see \ref RelCompare.
159        */
160       struct Match: public std::binary_function<Edition,Edition,int>
161       {
162         int operator()( const Edition & lhs, const Edition & rhs ) const
163         { return Edition::match( lhs, rhs ); }
164       };
165
166       /** \ref Edition \ref Range based on \ref Match.
167        * \see \ref RelCompare.
168        */
169       typedef Range<Edition, Match> MatchRange;
170
171     private:
172       static int _doCompare( const char * lhs,  const char * rhs );
173       static int _doMatch( const char * lhs,  const char * rhs );
174
175     private:
176       friend class IdStringType<Edition>;
177       IdString _str;
178   };
179   ///////////////////////////////////////////////////////////////////
180
181   /** \relates Edition XML output. */
182   inline std::ostream & dumpAsXmlOn( std::ostream & str, const Edition & obj )
183   { return str << "<edition"
184                << " epoch=\"" << obj.epoch() << "\""
185                << " version=\"" << obj.version() << "\""
186                << " release=\"" << obj.release() << "\""
187                << "/>";
188   }
189
190   /////////////////////////////////////////////////////////////////
191 } // namespace zypp
192 ///////////////////////////////////////////////////////////////////
193 #endif // ZYPP_EDITION_H