Merge pull request #23 from openSUSE/drop_package_manager
[platform/upstream/libzypp.git] / zypp / Rel.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Rel.h
10  *
11 */
12 #ifndef ZYPP_REL_H
13 #define ZYPP_REL_H
14
15 #include <iosfwd>
16 #include <string>
17
18 ///////////////////////////////////////////////////////////////////
19 namespace zypp
20 { /////////////////////////////////////////////////////////////////
21
22   ///////////////////////////////////////////////////////////////////
23   //
24   //    CLASS NAME : Rel
25   //
26   /** Relational operators.
27    * Yes, it could as well be simply an \c enum.<BR>
28    * Yes, you can use the relational operators as if it was an \c enum.<BR>
29    * Except for use in a \c switch statement; see \ref inSwitch for this.
30    *
31    * But we want to construct them from a string representation, as well as
32    * providing one. And this way they are wrapped into a namespace, which is
33    * a good idea anyway.
34    *
35    * \ref ANY and \ref NONE are somewhat special. \ref ANY is the
36    * operator created by the default ctor, and it should always resolve
37    * to \c true. This may be handy in queries when you're looking for a
38    * Resolvable in \c ANY Edition if no operator was specified.
39    * While \ref NONE should always resolve to \c false.
40    *
41    * \ingroup g_EnumerationClass
42   */
43   struct Rel
44   {
45     /** \name Relational operators
46      * These are the \em real relational operator contants to
47      * use. Don't mind that it's not an enum. See also: \ref zypp::Rel::inSwitch
48     */
49     //@{
50     static const Rel EQ;
51     static const Rel NE;
52     static const Rel LT;
53     static const Rel LE;
54     static const Rel GT;
55     static const Rel GE;
56     static const Rel ANY;
57     static const Rel NONE;
58     //@}
59
60     /** Enumarators provided \b only for use \ref inSwitch statement.
61      * \see inSwitch
62      * \note Enumarator values also correspond to the values libsolv
63      * uses to encode these relations.
64     */
65     enum for_use_in_switch {
66       NONE_e = 0U,
67       GT_e   = 1U,
68       EQ_e   = 2U,
69       LT_e   = 4U,
70       GE_e   = GT_e|EQ_e,
71       LE_e   = LT_e|EQ_e,
72       NE_e   = GT_e|LT_e,
73       ANY_e  = GT_e|EQ_e|LT_e,
74     };
75
76     /** DefaultCtor ANY. */
77     Rel()
78     : _op( ANY_e )
79     {}
80
81     /** Ctor from string.
82      * Legal values for \a strval_r are: "==", "!=", "<", "<=", ">", ">=",<BR>
83      * as well as "EQ", "NE", "LT", "LE", "GT", "GE", "ANY", "NONE"<BR>
84      * and "" (empty string resolves to ANY).
85      *
86      * Lower case names are accepted as well.
87      *
88      * \throw PARSE if \a strval_r is not legal.
89      * \todo refine exceptions and check throw.
90      */
91     explicit
92     Rel( const std::string & strval_r );
93
94     /** Ctor from string (non-throwing).
95      * Illegal string values resolve to \c default_r
96      */
97     Rel( const std::string & strval_r, const Rel & default_r );
98
99     /** Assign from string IFF it contains a legal value.
100      * \return Whether \a strval_r contained a legal value.
101     */
102     bool parseFrom( const std::string & strval_r );
103
104     /** Ctor from bits. */
105     explicit
106     Rel( unsigned bits_r )
107     : _op( for_use_in_switch(bits_r & ANY_e) )
108     {}
109
110     /** Test whether \a bits_r is a valid \ref Rel (no extra bits set). */
111     static bool isRel( unsigned bits_r )
112     { return (bits_r & ANY_e) == bits_r; }
113
114     /** String representation of relational operator.
115      * \return "==", "!=", "<", "<=", ">", ">=", "ANY" or "NONE"
116     */
117     const std::string & asString() const;
118     /** \overload */
119     const char * c_str() const
120     { return asString().c_str(); }
121
122     /** Enumarator provided for use in \c switch statement.
123      * The sole reason for providing enum \ref for_use_in_switch is,
124      * that we may want to use the relational operators in a \c switch
125      * statement. Tht's the only case where you should have to use the
126      * enumarator.
127      * \code
128      *   Rel op;
129      *   switch ( op.inSwitch() )
130      *     {
131      *     case Rel::EQ_e:
132      *       ...
133      *       break;
134      *     case Rel::NE_e:
135      *       ...
136      *
137      *     // No default! Let compiler warn if case is missing
138      *     }
139      * \endcode
140     */
141     for_use_in_switch inSwitch() const
142     { return _op; }
143
144     /** Enumarator values suitable for libsolv. */
145     unsigned bits() const
146     { return _op; }
147
148   private:
149     /** Ctor to initialize the relational operator contants. */
150     Rel( for_use_in_switch op_r )
151     : _op( op_r )
152     {}
153     /** The operator. */
154     for_use_in_switch _op;
155   };
156   ///////////////////////////////////////////////////////////////////
157
158   /** \relates Rel Stream output. */
159   inline std::ostream & operator<<( std::ostream & str, const Rel & obj )
160   { return str << obj.asString(); }
161
162   ///////////////////////////////////////////////////////////////////
163
164   /** \relates Rel */
165   inline bool operator==( const Rel & lhs, const Rel & rhs )
166   { return lhs.inSwitch() == rhs.inSwitch(); }
167
168   /** \relates Rel */
169   inline bool operator!=( const Rel & lhs, const Rel & rhs )
170   { return ! ( lhs == rhs ); }
171
172   /////////////////////////////////////////////////////////////////
173 } // namespace zypp
174 ///////////////////////////////////////////////////////////////////
175 #endif // ZYPP_REL_H