Added Edition::Less to allow std::container on Edition using
authorMichael Andres <ma@suse.de>
Fri, 25 Nov 2005 09:40:47 +0000 (09:40 +0000)
committerMichael Andres <ma@suse.de>
Fri, 25 Nov 2005 09:40:47 +0000 (09:40 +0000)
Edition::operator< as well as lexicogrophical order.

Namespace for string related tools and helper functions was
renamed from (zypp::)base::string to (zypp::)str. 'string'
is obviously not a good choice for a namespace, and the
additional base:: is superfluous and inconvenient.

devel/devel.ma/Main.cc
zypp/@DOXYGEN/DOXYGEN.h
zypp/Edition.cc
zypp/Edition.h
zypp/NeedAType.h
zypp/base/KindOf.h
zypp/base/Logger.cc
zypp/base/String.cc
zypp/base/String.h

index 9a37a5b..31f1e30 100644 (file)
@@ -8,10 +8,24 @@
 #include <zypp/Edition.h>
 #include <zypp/Rel.h>
 
-using namespace std;
+#include <boost/regex.hpp>
 
 
+using namespace std;
+template<class _C>
+  void outc( const _C & cont, ostream & str )
+  {
+    copy( cont.begin(), cont.end(),
+          ostream_iterator<typename _C::value_type>(str,"\n") );
+  }
+
+namespace zypp
+{
+
+}
 using namespace zypp;
+
+
 /******************************************************************
 **
 **
@@ -24,12 +38,6 @@ int main( int argc, char * argv[] )
 {
   INT << "===[START]==========================================" << endl;
 
-  DBG << Edition( "1.0", "1a" ) << endl;
-  DBG << Edition( "2.0", "13" ) << endl;
-  DBG << Edition( "2_0", "13" ) << endl;
-  DBG << Edition( "3.0", "13.4" ) << endl;
-
-
 
   INT << "===[END]============================================" << endl;
   return 0;
index c91f771..5370ab6 100644 (file)
@@ -28,3 +28,7 @@
  * \verbinclude g_EnumerationClass
 */
 ////////////////////////////////////////////////////////////////////////////////
+/*! \defgroup g_BackenSpecific Backend Specific
+ * \verbinclude g_BackenSpecific
+*/
+////////////////////////////////////////////////////////////////////////////////
index a674fd6..3f42d5a 100644 (file)
@@ -192,7 +192,7 @@ namespace zypp
     string ret;
 
     if ( _pimpl->_epoch )
-      ret += base::string::form(  "%d:", _pimpl->_epoch );
+      ret += str::form(  "%d:", _pimpl->_epoch );
 
     ret += _pimpl->_version;
 
index eb94cd3..73e68c2 100644 (file)
@@ -13,6 +13,7 @@
 #define ZYPP_EDITION_H
 
 #include <iosfwd>
+#include <functional>
 #include <string>
 
 #include "zypp/base/PtrTypes.h"
@@ -27,10 +28,35 @@ namespace zypp
   //
   //   CLASS NAME : Edition
   //
-  /** Edition
-   \todo doc
-   \todo optimize implementation
-   \todo implement debian comparison and make choice backend specific
+  /** Edition represents <code>[epoch:]version[-release]</code>
+   *
+   * \li \c epoch   (optional) number, Edition::noepoch if not supplied
+   * \li \c version (required) string, may not contain '-'
+   * \li \c release (optional) string, may not contain '-'
+   *
+   * Comparison is actually \reg g_BackendSpecific.
+   *
+   * \li \b RPM: Edition are ordered according to \c epoch, then \c version,
+   * then \c release. Version and release strings are compared by splitting
+   * them into segments of alpha or digit sequences. Segments are compared
+   * according to their type. On mixed types a string compares less than a
+   * number.
+   * \code
+   *   compare( 1.a, 1.0 ) == -1 (<)
+   *   compare( 1.0, 1.a ) ==  1 (>)
+   *   compare( 1.0, 1_0 ) ==  0 (==)
+   * \endcode
+   *
+   * \attention operator< defines equivalence classes of version strings, as non
+   * alphanumeric chars are ignored. That' why \c 1.0 and \c 1_0 compare equal
+   * in the example.<BR>
+   * If Edition is used as key in a std::container, per default
+   * <em>plain string comparison</em> is used. If you want to compare by
+   * version, let the container use Edition::Less to compare.
+   *
+   * \ingroup g_BackendSpecific
+   * \todo optimize implementation
+   * \todo implement debian comparison and make choice backend specific
   */
   class Edition
   {
@@ -44,18 +70,22 @@ namespace zypp
   public:
     /** Default ctor. */
     Edition();
+
     /** Ctor taking \a version_r, \a release_r and optional \a epoch_r */
     Edition( const std::string & version_r,
              const std::string & release_r,
              epoch_t epoch_r = noepoch );
+
     /** Dtor */
     ~Edition();
 
   public:
     /** Epoch */
     epoch_t epoch() const;
+
     /** Version */
     const std::string & version() const;
+
     /** Release */
     const std::string & release() const;
 
@@ -78,6 +108,9 @@ namespace zypp
     */
     static int compare( const Edition & lhs, const Edition & rhs );
 
+    /* Binary operator functor comparing Edition. */
+    struct Less;
+
   private:
     /** Hides implementation */
     struct Impl;
@@ -92,7 +125,6 @@ namespace zypp
 
   /** \name Comaprison based on epoch, version, and release. */
   //@{
-
   /** \relates Edition */
   inline bool operator==( const Edition & lhs, const Edition & rhs )
   { return Edition::compare( Rel::EQ, lhs, rhs ); }
@@ -116,9 +148,37 @@ namespace zypp
   /** \relates Edition */
   inline bool operator>=( const Edition & lhs, const Edition & rhs )
   { return Edition::compare( Rel::GE, lhs, rhs ); }
-
   //@}
 
+  ///////////////////////////////////////////////////////////////////
+  //
+  //   CLASS NAME : Edition::Less
+  //
+  /** Binary operator functor comparing Edition.
+   * Default order for std::container using Edition as key is based
+   * on <em>plain string comparison</em>. Use Less to compare, if
+   * real version comparison is desired.
+   * \code
+   * set<Edition> eset;
+   * eset.insert( Edition("1.0","") );
+   * eset.insert( Edition("1_0","") );
+   * // Now: eset.size() == 2
+   * \endcode
+   * \code
+   * set<Edition,Edition::Less> eset;
+   * eset.insert( Edition("1.0","") );
+   * eset.insert( Edition("1_0","") );
+   * // Now: eset.size() == 1
+   * \endcode
+  */
+  struct Edition::Less : public std::binary_function<Edition,Edition,bool>
+  {
+    /** \return <tt>lhs < rhs</tt> */
+    bool operator()(const Edition & lhs, const Edition & rhs ) const
+    { return lhs < rhs; }
+  };
+  ///////////////////////////////////////////////////////////////////
+
   /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
@@ -126,14 +186,17 @@ namespace zypp
 ///////////////////////////////////////////////////////////////////
 namespace std
 { /////////////////////////////////////////////////////////////////
-  /** \relates Edition Default order for std::container based on string value.*/
+
+  /** \relates Edition Default to lexicographical order in std::container.*/
   template<>
     inline bool less<zypp::Edition>::operator()( const zypp::Edition & lhs, const zypp::Edition & rhs ) const
     { return lhs.asString() < rhs.asString(); }
-  /** \relates Edition Equality for std::container classes based on string value. */
+
+  /** \relates Edition Lexicographical equal for std::container. */
   template<>
     inline bool equal_to<zypp::Edition>::operator()( const zypp::Edition & lhs, const zypp::Edition & rhs ) const
     { return lhs.asString() == rhs.asString(); }
+
   /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
index a2f1913..80b0d02 100644 (file)
@@ -92,8 +92,7 @@ namespace zypp
   */
   typedef std::string PackageGroup;
 
-  /**
-   */
+  /** Candidate for string unification? */
   typedef std::list<std::string> PackageKeywords;
 
   /** Class representing a Date (time_t). Basically store a time_t and offer
index ca3d26c..a9673c2 100644 (file)
@@ -38,11 +38,9 @@ namespace zypp
      * KindOf stores a \b lowercased version of a string and uses this as
      * identification.
      *
-     * \todo How to make doxygen show the related ==/!= operator
-     * for KindOf vs std::string comarison?
      * \todo Unify strings and associate numerical value for more
      * efficient comparison and use in \c switch.
-     * \todo Make lowercased/uppercased/... an option. First of all
+     * \todo Make lowercased/uppercased/etc an option. First of all
      * get rid of the string::toLower calls operator.
      * \todo Maybe collaboration with some sort of Registry.
     */
@@ -58,7 +56,7 @@ namespace zypp
         */
         explicit
         KindOf( const std::string & value_r )
-        : _value( string::toLower(value_r) )
+        : _value( str::toLower(value_r) )
         {}
         /** Dtor */
         ~KindOf()
@@ -74,49 +72,55 @@ namespace zypp
       };
     ///////////////////////////////////////////////////////////////////
 
-    /** \Relates KindOf stream output*/
+    //@{
+    /** \relates KindOf Stream output*/
     template<class _Tp>
       inline std::ostream & operator<<( std::ostream & str, const KindOf<_Tp> & obj )
       { return str << obj.asString(); }
+    //@}
 
     ///////////////////////////////////////////////////////////////////
 
-    /** \Relates KindOf */
+    //@{
+    /** \relates KindOf */
     template<class _Tp>
       inline bool operator==( const KindOf<_Tp> & lhs, const KindOf<_Tp> & rhs )
       { return lhs.asString() == rhs.asString(); }
 
-    /** \Relates KindOf */
+    /** \relates KindOf */
     template<class _Tp>
       inline bool operator==( const KindOf<_Tp> & lhs, const std::string & rhs )
-      { return lhs.asString() == string::toLower(rhs); }
+      { return lhs.asString() == str::toLower(rhs); }
 
-    /** \Relates KindOf */
+    /** \relates KindOf */
     template<class _Tp>
       inline bool operator==( const std::string & lhs, const KindOf<_Tp> & rhs )
-      { return string::toLower(lhs) == rhs.asString(); }
+      { return str::toLower(lhs) == rhs.asString(); }
+    //@}
 
-
-    /** \Relates KindOf */
+    //@{
+    /** \relates KindOf */
     template<class _Tp>
       inline bool operator!=( const KindOf<_Tp> & lhs, const KindOf<_Tp> & rhs )
       { return !( lhs == rhs ); }
 
-    /** \Relates KindOf */
+    /** \relates KindOf */
     template<class _Tp>
       inline bool operator!=( const KindOf<_Tp> & lhs, const std::string & rhs )
       { return !( lhs == rhs ); }
 
-    /** \Relates KindOf */
+    /** \relates KindOf */
     template<class _Tp>
       inline bool operator!=( const std::string & lhs, const KindOf<_Tp> & rhs )
       { return !( lhs == rhs ); }
+    //@}
 
-
-    /** \Relates KindOf For use in std::container. */
+    //@{
+    /** \relates KindOf Lexicographical order. */
     template<class _Tp>
       inline bool operator<( const KindOf<_Tp> & lhs, const KindOf<_Tp> & rhs )
       { return lhs.asString() < rhs.asString(); }
+    //@}
 
     /////////////////////////////////////////////////////////////////
   } // namespace base
index 6ae9a53..4252ffd 100644 (file)
@@ -34,9 +34,9 @@ namespace zypp
                                 const int    line_r )
       {
         return (level_r < 0 ? std::cout : std::cerr)
-               << string::form( "<%d> [%s] %s(%s):%d ",
-                                level_r, group_r,
-                                file_r, func_r, line_r );
+               << str::form( "<%d> [%s] %s(%s):%d ",
+                             level_r, group_r,
+                             file_r, func_r, line_r );
       }
 
       /////////////////////////////////////////////////////////////////
index acc23a3..24be02d 100644 (file)
 namespace zypp
 { /////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////
-  namespace base
+  namespace str
   { /////////////////////////////////////////////////////////////////
 
-    ///////////////////////////////////////////////////////////////////
-    namespace string
-    { /////////////////////////////////////////////////////////////////
-
-      /******************************************************************
-       **
-       **      FUNCTION NAME : form
-       **      FUNCTION TYPE : std::string
-      */
-      std::string form( const char * format, ... )
+    /******************************************************************
+     **
+     **      FUNCTION NAME : form
+     **      FUNCTION TYPE : std::string
+    */
+    std::string form( const char * format, ... )
+    {
+      struct SafeBuf
       {
-        struct SafeBuf
-        {
-          char * _buf;
-          SafeBuf() : _buf( 0 ) {}
-          ~SafeBuf() { if ( _buf ) free( _buf ); }
-          std::string asString() const
-          { return _buf ? std::string(_buf) : std::string(); }
-        };
-        SafeBuf safe;
+        char * _buf;
+        SafeBuf() : _buf( 0 ) {}
+        ~SafeBuf() { if ( _buf ) free( _buf ); }
+        std::string asString() const
+        { return _buf ? std::string(_buf) : std::string(); }
+      };
+      SafeBuf safe;
 
-        va_list ap;
-        va_start( ap, format );
-        vasprintf( &safe._buf, format, ap );
-        va_end( ap );
+      va_list ap;
+      va_start( ap, format );
+      vasprintf( &safe._buf, format, ap );
+      va_end( ap );
 
-        return safe.asString();
-      }
+      return safe.asString();
+    }
 
-      /******************************************************************
-       **
-       **      FUNCTION NAME : toLower
-       **      FUNCTION TYPE : std::string
-      */
-      std::string toLower( const std::string & s )
-      {
-        if ( s.empty() )
-          return s;
+    /******************************************************************
+     **
+     **      FUNCTION NAME : toLower
+     **      FUNCTION TYPE : std::string
+    */
+    std::string toLower( const std::string & s )
+    {
+      if ( s.empty() )
+        return s;
 
-        std::string ret( s );
-        for ( std::string::size_type i = 0; i < ret.length(); ++i ) {
+      std::string ret( s );
+      for ( std::string::size_type i = 0; i < ret.length(); ++i )
+        {
           if ( isupper( ret[i] ) )
             ret[i] = static_cast<char>(tolower( ret[i] ));
         }
-        return ret;
-      }
+      return ret;
+    }
 
-      /******************************************************************
-       **
-       **      FUNCTION NAME : toUpper
-       **      FUNCTION TYPE : std::string
-      */
-      std::string toUpper( const std::string & s )
-      {
-        if ( s.empty() )
-          return s;
+    /******************************************************************
+     **
+     **      FUNCTION NAME : toUpper
+     **      FUNCTION TYPE : std::string
+    */
+    std::string toUpper( const std::string & s )
+    {
+      if ( s.empty() )
+        return s;
 
-        std::string ret( s );
-        for ( std::string::size_type i = 0; i < ret.length(); ++i ) {
+      std::string ret( s );
+      for ( std::string::size_type i = 0; i < ret.length(); ++i )
+        {
           if ( islower( ret[i] ) )
             ret[i] = static_cast<char>(toupper( ret[i] ));
         }
-        return ret;
-      }
+      return ret;
+    }
 
 
     /////////////////////////////////////////////////////////////////
-    } // namespace string
-    ///////////////////////////////////////////////////////////////////
-
-    /////////////////////////////////////////////////////////////////
-  } // namespace base
+  } // namespace str
   ///////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////
 } // namespace zypp
index cae4a48..5683fe6 100644 (file)
 namespace zypp
 { /////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////
-  namespace base
+  namespace str
   { /////////////////////////////////////////////////////////////////
 
-    ///////////////////////////////////////////////////////////////////
-    namespace string
-    { /////////////////////////////////////////////////////////////////
+    /** Printf style construction of std::string. */
+    std::string form( const char * format, ... )
+    __attribute__ ((format (printf, 1, 2)));
 
-      /** Printf style construction of std::string. */
-      std::string form( const char * format, ... )
-      __attribute__ ((format (printf, 1, 2)));
+    /** Return lowercase version of \a s
+     * \todo improve
+    */
+    std::string toLower( const std::string & s );
 
-
-      /** Return lowercase version of \a s
-       * \todo improve
-      */
-      std::string toLower( const std::string & s );
-
-      /** Return uppercase version of \a s
-       * \todo improve
-      */
-      std::string toUpper( const std::string & s );
-
-      /////////////////////////////////////////////////////////////////
-    } // namespace string
-    ///////////////////////////////////////////////////////////////////
+    /** Return uppercase version of \a s
+     * \todo improve
+    */
+    std::string toUpper( const std::string & s );
 
     /////////////////////////////////////////////////////////////////
-  } // namespace base
+  } // namespace str
   ///////////////////////////////////////////////////////////////////
   /////////////////////////////////////////////////////////////////
 } // namespace zypp