Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / IdStringType.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/IdStringType.h
10  *
11 */
12 #ifndef ZYPP_IDSTRINGTYPE_H
13 #define ZYPP_IDSTRINGTYPE_H
14
15 #include "zypp/IdString.h"
16
17 ///////////////////////////////////////////////////////////////////
18 namespace zypp
19 { /////////////////////////////////////////////////////////////////
20
21   ///////////////////////////////////////////////////////////////////
22   //
23   //    CLASS NAME : IdStringType<Derived>
24   //
25   /** Base class for creating \ref IdString based types.
26    *
27    * Just by deriving from \ref IdStringType a class provides all
28    * the operations an \ref IdString does. (incl. conversion to string types,
29    * comparison of string types and stream output).
30    *
31    * To disable any comparison, declare (but do not define) \ref _doCompare
32    * in your class.
33    * \code
34    * class NoCompare : public IdStringType<NoCompare>
35    * {
36    *   private:
37    *   static int _doCompare( const char * lhs,  const char * rhs );
38    *
39    * };
40    * \endcode
41    *
42    * If you need a different than the default lexicographical
43    * order, write your own \ref _doCompare.
44    *
45    * \code
46    *    // uses default lexicographical order
47    *    class CaseCmp : public IdStringType<CaseCmp>
48    *    {
49    *      public:
50    *        CaseCmp() {}
51    *        explicit CaseCmp( const char * cstr_r ) : _str( cstr_r )  {}
52    *      private:
53    *        friend class IdStringType<CaseCmp>;
54    *        IdString _str;
55    *    };
56    *
57    *    // uses case insensitive comparison order
58    *    class NoCaseCmp : public IdStringType<NoCaseCmp>
59    *    {
60    *      public:
61    *        NoCaseCmp() {}
62    *        explicit NoCaseCmp( const char * cstr_r ) : _str( cstr_r )  {}
63    *      private:
64    *        static int _doCompare( const char * lhs,  const char * rhs )
65    *        {
66    *          if ( lhs == rhs ) return 0;
67    *          if ( lhs && rhs ) return ::strcasecmp( lhs, rhs );
68    *          return( lhs ? 1 : -1 );
69    *        }
70    *      private:
71    *        friend class IdStringType<NoCaseCmp>;
72    *        IdString _str;
73    *    };
74    *
75    *    CaseCmp   ca( "a" );
76    *    NoCaseCmp na( "a" );
77    *    DBG << "ca == a ? " << (ca == "a") << endl;   // ca == a ? 1
78    *    DBG << "ca == A ? " << (ca == "A") << endl;   // ca == A ? 0
79    *    DBG << "na == a ? " << (na == "a") << endl;   // na == a ? 1
80    *    DBG << "na == A ? " << (na == "A") << endl;   // na == A ? 1
81    * \endcode
82    * \todo allow redefinition of order vis _doCompare not only for char* but on any level
83    * \ingroup g_CRTP
84    */
85   template <class Derived>
86   class IdStringType : protected sat::detail::PoolMember
87   {
88     public:
89       typedef IdString::IdType IdType;
90
91     protected:
92       IdStringType() {}
93       IdStringType(const IdStringType &) {}
94       void operator=(const IdStringType &) {}
95       ~IdStringType() {}
96
97     private:
98       const Derived & self() const { return *static_cast<const Derived*>( this ); }
99
100     public:
101       const IdString & idStr()    const { return self()._str; }
102
103       bool          empty()       const { return idStr().empty(); }
104       unsigned      size()        const { return idStr().size(); }
105       const char *  c_str()       const { return idStr().c_str(); }
106       std::string   asString()    const { return idStr().asString(); }
107
108       IdType        id()          const { return idStr().id(); }
109
110     public:
111       /** Evaluate in a boolean context <tt>( ! empty() )</tt>. */
112       explicit operator bool() const
113       { return ! empty(); }
114
115     public:
116       // - break it down to idString/const char* <=> idString/cont char*
117       // - handle idString(0)/NULL being the least value
118       // - everything else goes to _doCompare (no NULL)
119       static int compare( const Derived & lhs,     const Derived & rhs )     { return compare( lhs.idStr(), rhs.idStr() ); }
120       static int compare( const Derived & lhs,     const IdString & rhs )    { return compare( lhs.idStr(), rhs ); }
121       static int compare( const Derived & lhs,     const std::string & rhs ) { return compare( lhs.idStr(), rhs.c_str() ); }
122       static int compare( const Derived & lhs,     const char * rhs )        { return compare( lhs.idStr(), rhs );}
123
124       static int compare( const IdString & lhs,    const Derived & rhs )     { return compare( lhs, rhs.idStr() ); }
125       static int compare( const IdString & lhs,    const IdString & rhs )    { return lhs == rhs ? 0 : Derived::_doCompare( (lhs ? lhs.c_str() : (const char *)0 ),
126                                                                                                                             (rhs ? rhs.c_str() : (const char *)0 ) ); }
127       static int compare( const IdString & lhs,    const std::string & rhs ) { return compare( lhs, rhs.c_str() ); }
128       static int compare( const IdString & lhs,    const char * rhs )        { return Derived::_doCompare( (lhs ? lhs.c_str() : (const char *)0 ), rhs ); }
129
130       static int compare( const std::string & lhs, const Derived & rhs )     { return compare( lhs.c_str(), rhs.idStr() ); }
131       static int compare( const std::string & lhs, const IdString & rhs )    { return compare( lhs.c_str(), rhs ); }
132       static int compare( const std::string & lhs, const std::string & rhs ) { return compare( lhs.c_str(), rhs.c_str() ); }
133       static int compare( const std::string & lhs, const char * rhs )        { return compare( lhs.c_str(), rhs ); }
134
135       static int compare( const char * lhs,        const Derived & rhs )     { return compare( lhs, rhs.idStr() ); }
136       static int compare( const char * lhs,        const IdString & rhs )    { return Derived::_doCompare( lhs, (rhs ? rhs.c_str() : (const char *)0 ) ); }
137       static int compare( const char * lhs,        const std::string & rhs ) { return compare( lhs, rhs.c_str() ); }
138       static int compare( const char * lhs,        const char * rhs )        { return Derived::_doCompare( lhs, rhs ); }
139
140     public:
141       int compare( const Derived & rhs )      const { return compare( idStr(), rhs.idStr() ); }
142       int compare( const IdStringType & rhs ) const { return compare( idStr(), rhs.idStr() ); }
143       int compare( const IdString & rhs )     const { return compare( idStr(), rhs ); }
144       int compare( const std::string & rhs )  const { return compare( idStr(), rhs.c_str() ); }
145       int compare( const char * rhs )         const { return compare( idStr(), rhs ); }
146
147     private:
148       static int _doCompare( const char * lhs,  const char * rhs )
149       {
150         if ( ! lhs ) return rhs ? -1 : 0;
151         return rhs ? ::strcmp( lhs, rhs ) : 1;
152       }
153   };
154   ///////////////////////////////////////////////////////////////////
155
156   /** \relates IdStringType Stream output */
157   template <class Derived>
158   inline std::ostream & operator<<( std::ostream & str, const IdStringType<Derived> & obj )
159   { return str << obj.c_str(); }
160
161   /** \relates IdStringType Equal */
162   template <class Derived>
163   inline bool operator==( const IdStringType<Derived> & lhs, const IdStringType<Derived> & rhs )
164   { return lhs.compare( rhs ) == 0; }
165   /** \overload */
166   template <class Derived>
167   inline bool operator==( const IdStringType<Derived> & lhs, const IdString & rhs )
168   { return lhs.compare( rhs ) == 0; }
169   /** \overload */
170   template <class Derived>
171   inline bool operator==( const IdStringType<Derived> & lhs, const char * rhs )
172   { return lhs.compare( rhs ) == 0; }
173   /** \overload */
174   template <class Derived>
175   inline bool operator==( const IdStringType<Derived> & lhs, const std::string & rhs )
176   { return lhs.compare( rhs ) == 0; }
177   /** \overload */
178   template <class Derived>
179   inline bool operator==( const IdString & lhs, const IdStringType<Derived> & rhs )
180   { return rhs.compare( lhs ) == 0; }
181   /** \overload */
182   template <class Derived>
183   inline bool operator==( const char * lhs, const IdStringType<Derived> & rhs )
184   { return rhs.compare( lhs ) == 0; }
185   /** \overload */
186   template <class Derived>
187   inline bool operator==( const std::string & lhs, const IdStringType<Derived> & rhs )
188   { return rhs.compare( lhs ) == 0; }
189
190   /** \relates IdStringType NotEqual */
191   template <class Derived>
192   inline bool operator!=( const IdStringType<Derived> & lhs, const IdStringType<Derived> & rhs )
193   { return lhs.compare( rhs ) != 0; }
194   /** \overload */
195   template <class Derived>
196   inline bool operator!=( const IdStringType<Derived> & lhs, const IdString & rhs )
197   { return lhs.compare( rhs ) != 0; }
198   /** \overload */
199   template <class Derived>
200   inline bool operator!=( const IdStringType<Derived> & lhs, const char * rhs )
201   { return lhs.compare( rhs ) != 0; }
202   /** \overload */
203   template <class Derived>
204   inline bool operator!=( const IdStringType<Derived> & lhs, const std::string & rhs )
205   { return lhs.compare( rhs ) != 0; }
206   /** \overload */
207   template <class Derived>
208   inline bool operator!=( const IdString & lhs, const IdStringType<Derived> & rhs )
209   { return rhs.compare( lhs ) != 0; }
210   /** \overload */
211   template <class Derived>
212   inline bool operator!=( const char * lhs, const IdStringType<Derived> & rhs )
213   { return rhs.compare( lhs ) != 0; }
214   /** \overload */
215   template <class Derived>
216   inline bool operator!=( const std::string & lhs, const IdStringType<Derived> & rhs )
217   { return rhs.compare( lhs ) != 0; }
218
219   /** \relates IdStringType Less */
220   template <class Derived>
221   inline bool operator<( const IdStringType<Derived> & lhs, const IdStringType<Derived> & rhs )
222   { return lhs.compare( rhs ) < 0; }
223   /** \overload */
224   template <class Derived>
225   inline bool operator<( const IdStringType<Derived> & lhs, const IdString & rhs )
226   { return lhs.compare( rhs ) < 0; }
227   /** \overload */
228   template <class Derived>
229   inline bool operator<( const IdStringType<Derived> & lhs, const char * rhs )
230   { return lhs.compare( rhs ) < 0; }
231   /** \overload */
232   template <class Derived>
233   inline bool operator<( const IdStringType<Derived> & lhs, const std::string & rhs )
234   { return lhs.compare( rhs ) < 0; }
235   /** \overload */
236   template <class Derived>
237   inline bool operator<( const IdString & lhs, const IdStringType<Derived> & rhs )
238   { return rhs.compare( lhs ) >= 0; }
239   /** \overload */
240   template <class Derived>
241   inline bool operator<( const char * lhs, const IdStringType<Derived> & rhs )
242   { return rhs.compare( lhs ) >= 0; }
243   /** \overload */
244   template <class Derived>
245   inline bool operator<( const std::string & lhs, const IdStringType<Derived> & rhs )
246   { return rhs.compare( lhs ) >= 0; }
247
248   /** \relates IdStringType LessEqual */
249   template <class Derived>
250   inline bool operator<=( const IdStringType<Derived> & lhs, const IdStringType<Derived> & rhs )
251   { return lhs.compare( rhs ) <= 0; }
252   /** \overload */
253   template <class Derived>
254   inline bool operator<=( const IdStringType<Derived> & lhs, const IdString & rhs )
255   { return lhs.compare( rhs ) <= 0; }
256   /** \overload */
257   template <class Derived>
258   inline bool operator<=( const IdStringType<Derived> & lhs, const char * rhs )
259   { return lhs.compare( rhs ) <= 0; }
260   /** \overload */
261   template <class Derived>
262   inline bool operator<=( const IdStringType<Derived> & lhs, const std::string & rhs )
263   { return lhs.compare( rhs ) <= 0; }
264   /** \overload */
265   template <class Derived>
266   inline bool operator<=( const IdString & lhs, const IdStringType<Derived> & rhs )
267   { return rhs.compare( lhs ) > 0; }
268   /** \overload */
269   template <class Derived>
270   inline bool operator<=( const char * lhs, const IdStringType<Derived> & rhs )
271   { return rhs.compare( lhs ) > 0; }
272   /** \overload */
273   template <class Derived>
274   inline bool operator<=( const std::string & lhs, const IdStringType<Derived> & rhs )
275   { return rhs.compare( lhs ) > 0; }
276
277   /** \relates IdStringType Greater */
278   template <class Derived>
279   inline bool operator>( const IdStringType<Derived> & lhs, const IdStringType<Derived> & rhs )
280   { return lhs.compare( rhs ) > 0; }
281   /** \overload */
282   template <class Derived>
283   inline bool operator>( const IdStringType<Derived> & lhs, const IdString & rhs )
284   { return lhs.compare( rhs ) > 0; }
285   /** \overload */
286   template <class Derived>
287   inline bool operator>( const IdStringType<Derived> & lhs, const char * rhs )
288   { return lhs.compare( rhs ) > 0; }
289   /** \overload */
290   template <class Derived>
291   inline bool operator>( const IdStringType<Derived> & lhs, const std::string & rhs )
292   { return lhs.compare( rhs ) > 0; }
293   /** \overload */
294   template <class Derived>
295   inline bool operator>( const IdString & lhs, const IdStringType<Derived> & rhs )
296   { return rhs.compare( lhs ) <= 0; }
297   /** \overload */
298   template <class Derived>
299   inline bool operator>( const char * lhs, const IdStringType<Derived> & rhs )
300   { return rhs.compare( lhs ) <= 0; }
301   /** \overload */
302   template <class Derived>
303   inline bool operator>( const std::string & lhs, const IdStringType<Derived> & rhs )
304   { return rhs.compare( lhs ) <= 0; }
305
306   /** \relates IdStringType GreaterEqual */
307   template <class Derived>
308   inline bool operator>=( const IdStringType<Derived> & lhs, const IdStringType<Derived> & rhs )
309   { return lhs.compare( rhs ) >= 0; }
310   /** \overload */
311   template <class Derived>
312   inline bool operator>=( const IdStringType<Derived> & lhs, const IdString & rhs )
313   { return lhs.compare( rhs ) >= 0; }
314   /** \overload */
315   template <class Derived>
316   inline bool operator>=( const IdStringType<Derived> & lhs, const char * rhs )
317   { return lhs.compare( rhs ) >= 0; }
318   /** \overload */
319   template <class Derived>
320   inline bool operator>=( const IdStringType<Derived> & lhs, const std::string & rhs )
321   { return lhs.compare( rhs ) >= 0; }
322   /** \overload */
323   template <class Derived>
324   inline bool operator>=( const IdString & lhs, const IdStringType<Derived> & rhs )
325   { return rhs.compare( lhs ) < 0; }
326   /** \overload */
327   template <class Derived>
328   inline bool operator>=( const char * lhs, const IdStringType<Derived> & rhs )
329   { return rhs.compare( lhs ) < 0; }
330   /** \overload */
331   template <class Derived>
332   inline bool operator>=( const std::string & lhs, const IdStringType<Derived> & rhs )
333   { return rhs.compare( lhs ) < 0; }
334
335   /////////////////////////////////////////////////////////////////
336 } // namespace zypp
337 ///////////////////////////////////////////////////////////////////
338 #endif // ZYPP_IDSTRINGTYPE_H