a97d5d96d6946fad8b23491cf20dbba65a920023
[platform/upstream/libzypp.git] / zypp / base / SetRelationMixin.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/base/SetRelationMixin.h
10  */
11 #ifndef ZYPP_BASE_SETRELATIONMIXIN_H
12 #define ZYPP_BASE_SETRELATIONMIXIN_H
13
14 #include <iosfwd>
15 #include <string>
16
17 #include "zypp/base/Easy.h"
18 #include "zypp/base/EnumClass.h"
19
20 ///////////////////////////////////////////////////////////////////
21 namespace zypp
22 {
23   ///////////////////////////////////////////////////////////////////
24   /// \class _SetCompareDef
25   /// \brief Result of set comparison (use like 'enum class \ref SetCompare')
26   /// This is the type a \c compare function should return.
27   ///////////////////////////////////////////////////////////////////
28   struct _SetCompareDef {
29     enum Enum {
30       uncomparable      = 0,            ///< "{?}"
31       equal             = (1<<0),       ///< "{=}"
32       properSubset      = (1<<1),       ///< "{<}"
33       properSuperset    = (1<<2),       ///< "{>}"
34       disjoint          = (1<<3),       ///< "{ }"
35     };
36     /** String representantion */
37     static const std::string & asString( Enum val_r );
38   };
39   /** \relates _SetCompareDef typedef 'enum class SetCompare' */
40   typedef base::EnumClass<_SetCompareDef> SetCompare;
41
42   /** \relates SetCompare Stream output */
43   inline std::ostream & operator<<( std::ostream & str, const SetCompare::Enum & obj )
44   { return str << SetCompare::asString( obj ); }
45   /** \overload */
46   inline std::ostream & operator<<( std::ostream & str, const SetCompare & obj )
47   { return str << obj.asEnum(); }
48
49   ///////////////////////////////////////////////////////////////////
50   /// \class _SetRelationDef
51   /// \brief Set Relation based on \ref SetCompare (use like 'enum class \ref SetRelation')
52   /// Comparison (\c== \c!=) between \ref SetRelation  and \ref SetCompare
53   /// is defined to let \c SetRelation::subset match \c SetCompare::equal
54   /// as well as \c SetCompare::properSubset. Accordingly \c SetRelation::subset
55   /// matches \c SetCompare::equal as well as \c SetCompare::properSuperset.
56   ///////////////////////////////////////////////////////////////////
57   struct _SetRelationDef {
58     enum Enum {
59       uncomparable      = SetCompare::uncomparable,     ///< "{??}"
60       equal             = SetCompare::equal,            ///< "{==}"
61       properSubset      = SetCompare::properSubset,     ///< "{<<}"
62       properSuperset    = SetCompare::properSuperset,   ///< "{>>}"
63       disjoint          = SetCompare::disjoint,         ///< "{  }"
64       subset            = properSubset|equal,           ///< "{<=}"
65       superset          = properSuperset|equal,         ///< "{>=}"
66     };
67     /** String representantion */
68     static const std::string & asString( Enum val_r );
69   };
70   /** \relates _SetRelationDef typedef 'enum class SetRelation' */
71   typedef base::EnumClass<_SetRelationDef> SetRelation;
72
73   /** \relates SetRelation Stream output */
74   inline std::ostream & operator<<( std::ostream & str, const SetRelation::Enum & obj )
75   { return str << SetRelation::asString( obj ); }
76   /** \overload */
77   inline std::ostream & operator<<( std::ostream & str, const SetRelation & obj )
78   { return str << obj.asEnum(); }
79
80   /** \relates SetRelation \relates SetCompare Matching \ref SetCompare and \ref SetRelation */
81   inline bool operator==( const SetRelation::Enum & lhs, const SetCompare::Enum & rhs )
82   { return( lhs&rhs || !(lhs|rhs) ); }
83   /** \overload */
84   inline bool operator==( const SetRelation::Enum & lhs, const SetCompare & rhs )
85   { return( lhs == rhs.asEnum() ); }
86   /** \overload */
87   inline bool operator==( const SetRelation & lhs, const SetCompare::Enum & rhs )
88   { return( lhs.asEnum() == rhs ); }
89   /** \overload */
90   inline bool operator==( const SetRelation & lhs, const SetCompare & rhs )
91   { return( lhs.asEnum() == rhs.asEnum() ); }
92   /** \overload */
93   inline bool operator==( const SetCompare::Enum & lhs, const SetRelation::Enum & rhs )
94   { return( rhs == lhs ); }
95   /** \overload */
96   inline bool operator==( const SetCompare::Enum & lhs, const SetRelation & rhs )
97   { return( rhs == lhs ); }
98   /** \overload */
99   inline bool operator==( const SetCompare & lhs, const SetRelation::Enum & rhs )
100   { return( rhs == lhs ); }
101   /** \overload */
102   inline bool operator==( const SetCompare & lhs, const SetRelation & rhs )
103   { return( rhs == lhs ); }
104
105   /** \relates SetRelation \relates SetCompare Matching \ref SetCompare and \ref SetRelation */
106   inline bool operator!=( const SetRelation::Enum & lhs, const SetCompare::Enum & rhs )
107   { return !( lhs == rhs ); }
108   /** \overload */
109   inline bool operator!=( const SetRelation::Enum & lhs, const SetCompare & rhs )
110   { return !( lhs == rhs ); }
111   /** \overload */
112   inline bool operator!=( const SetRelation & lhs, const SetCompare::Enum & rhs )
113   { return !( lhs == rhs ); }
114   /** \overload */
115   inline bool operator!=( const SetRelation & lhs, const SetCompare & rhs )
116   { return !( lhs == rhs ); }
117   /** \overload */
118   inline bool operator!=( const SetCompare::Enum & lhs, const SetRelation::Enum & rhs )
119   { return !( lhs == rhs ); }
120   /** \overload */
121   inline bool operator!=( const SetCompare::Enum & lhs, const SetRelation & rhs )
122   { return !( lhs == rhs ); }
123   /** \overload */
124   inline bool operator!=( const SetCompare & lhs, const SetRelation::Enum & rhs )
125   { return !( lhs == rhs ); }
126   /** \overload */
127   inline bool operator!=( const SetCompare & lhs, const SetRelation & rhs )
128   { return !( lhs == rhs ); }
129
130   ///////////////////////////////////////////////////////////////////
131   namespace base
132   {
133     ///////////////////////////////////////////////////////////////////
134     /// \class SetRelationMixin
135     /// \brief Provide set relation methods based on Derived::setRelationMixinCompare
136     /// A class using this mixin must provide:
137     /// \code
138     ///   SetCompare setRelationMixinCompare( const Derived & rhs ) const;
139     /// \endcode
140     /// \see \ref SETRELATIONMIXIN_DEFINE_COMPARE_BETWEEN
141     /// \ingroup g_CRTP
142     ///////////////////////////////////////////////////////////////////
143     template <class Derived>
144     class SetRelationMixin
145     {
146     public:
147       /** Compare sets */
148       SetCompare compare( const Derived & trg ) const
149       { return derived().setRelationMixinCompare( trg ); }
150       /** \overload */
151       SetCompare compare( const SetRelationMixin<Derived> & trg ) const
152       { return compare( trg.derived() ); }
153
154       /** Compare sets and match against \ref SetCompare */
155       bool compare( const Derived & trg, SetCompare cmp ) const
156       { return compare( trg ) == cmp; }
157       /** \overload */
158       bool compare( const SetRelationMixin<Derived> & trg, SetCompare cmp ) const
159       { return compare( trg ) == cmp; }
160
161       /** Compare sets and match against \ref SetRelation */
162       bool compare( const Derived & trg, SetRelation rel ) const
163       { return compare( trg ) == rel; }
164       /** \overload */
165       bool compare( const SetRelationMixin<Derived> & trg, SetRelation rel ) const
166       { return compare( trg ) == rel; }
167
168     protected:
169       SetRelationMixin() {}
170       DEFAULT_COPYABLE( SetRelationMixin );
171       DEFAULT_MOVABLE( SetRelationMixin );
172       ~SetRelationMixin() {}
173
174     private:
175       /** Access to sublass Derived*/
176       const Derived & derived() const
177       { return *static_cast<const Derived*>( this ); }
178     };
179
180     /** \relates SetRelationMixin Compare sets */
181     template <class Derived>
182     inline SetCompare compare( const SetRelationMixin<Derived> & src, const SetRelationMixin<Derived> & trg )
183     { return src.compare( trg ); }
184
185     /** \relates SetRelationMixin Compare sets and match against \ref SetCompare */
186     template <class Derived>
187     inline bool compare( const SetRelationMixin<Derived> & src, const SetRelationMixin<Derived> & trg, SetCompare cmp )
188     { return src.compare( trg, cmp ); }
189
190     /** \relates SetRelationMixin Compare sets and match against \ref SetRelation */
191     template <class Derived>
192     inline bool compare( const SetRelationMixin<Derived> & src, const SetRelationMixin<Derived> & trg, SetRelation rel )
193     { return src.compare( trg, rel ); }
194
195     /** \relates SetRelationMixin Equal */
196     template <class Derived>
197     inline bool operator==( const SetRelationMixin<Derived> & src, const SetRelationMixin<Derived> & trg )
198     { return src.compare( trg, SetRelation::equal ); }
199
200     /** \relates SetRelationMixin Unequal */
201     template <class Derived>
202     inline bool operator!=( const SetRelationMixin<Derived> & src, const SetRelationMixin<Derived> & trg )
203     { return !( src == trg ); }
204
205     /** \relates SetRelationMixin Define compare between Derived and some other type (e.g. std::string)
206      * \code
207      *   class Foo : public base::SetRelationMixin<Foo> {...};
208      *   SETRELATIONMIXIN_DEFINE_COMPARE_BETWEEN( Foo, const char * );
209      *   SETRELATIONMIXIN_DEFINE_COMPARE_BETWEEN( Foo, const std::string & );
210      * \endcode
211      */
212 #define SETRELATIONMIXIN_DEFINE_COMPARE_BETWEEN(DERIVED_TYPE,OTHER_TYPE)        \
213   inline SetCompare compare( const base::SetRelationMixin<DERIVED_TYPE> & src, OTHER_TYPE trg ) \
214   { return src.compare( DERIVED_TYPE(trg) ); }  \
215   inline SetCompare compare( OTHER_TYPE src, const base::SetRelationMixin<DERIVED_TYPE> & trg ) \
216   { return DERIVED_TYPE(src).compare( trg ); }  \
217         \
218   inline bool compare( const base::SetRelationMixin<DERIVED_TYPE> & src, OTHER_TYPE trg, SetCompare cmp )       \
219   { return src.compare( DERIVED_TYPE(trg), cmp ); }     \
220   inline bool compare( OTHER_TYPE src, const base::SetRelationMixin<DERIVED_TYPE> & trg, SetCompare cmp )       \
221   { return DERIVED_TYPE(src).compare( trg, cmp ); }     \
222         \
223   inline bool compare( const base::SetRelationMixin<DERIVED_TYPE> & src, OTHER_TYPE trg, SetRelation rel )      \
224   { return src.compare( DERIVED_TYPE(trg), rel ); }     \
225   inline bool compare( OTHER_TYPE src, const base::SetRelationMixin<DERIVED_TYPE> & trg, SetRelation rel )      \
226   { return DERIVED_TYPE(src).compare( trg, rel ); }     \
227         \
228   inline bool operator==( const base::SetRelationMixin<DERIVED_TYPE> & src, OTHER_TYPE trg )    \
229   { return src.compare( DERIVED_TYPE(trg), SetRelation::equal ); }      \
230   inline bool operator==( OTHER_TYPE src, const base::SetRelationMixin<DERIVED_TYPE> & trg )    \
231   { return DERIVED_TYPE(src).compare( trg, SetRelation::equal ); }      \
232         \
233   inline bool operator!=( const base::SetRelationMixin<DERIVED_TYPE> & src, OTHER_TYPE trg )    \
234   { return !( src == trg ); }   \
235   inline bool operator!=( OTHER_TYPE src, const base::SetRelationMixin<DERIVED_TYPE> & trg )    \
236   { return !( src == trg ); }
237
238   } // namespace base
239   ///////////////////////////////////////////////////////////////////
240 } // namespace zypp
241 ///////////////////////////////////////////////////////////////////
242 #endif // ZYPP_BASE_SETRELATIONMIXIN_H