Add NamedValue<_Tp>: Simple value<>name mapping supporting aliases
authorMichael Andres <ma@suse.de>
Mon, 17 Dec 2012 10:42:55 +0000 (11:42 +0100)
committerMichael Andres <ma@suse.de>
Mon, 17 Dec 2012 12:32:07 +0000 (13:32 +0100)
zypp/CMakeLists.txt
zypp/base/NamedValue.h [new file with mode: 0644]

index 538a7c4883bda6378fd0d20619aef45c12e32eef..5b406ffe056fa4deaf4975b8402f2dacd512ae2f 100644 (file)
@@ -246,6 +246,7 @@ SET( zypp_base_HEADERS
   base/LogTools.h
   base/Logger.h
   base/Measure.h
+  base/NamedValue.h
   base/NonCopyable.h
   base/ProfilingFormater.h
   base/ProvideNumericId.h
diff --git a/zypp/base/NamedValue.h b/zypp/base/NamedValue.h
new file mode 100644 (file)
index 0000000..a07c8d5
--- /dev/null
@@ -0,0 +1,161 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/base/NamedValue.h
+ *
+*/
+#ifndef ZYPP_BASE_NAMEDVALUE_H
+#define ZYPP_BASE_NAMEDVALUE_H
+
+#include <stdexcept>
+#include <string>
+#include <map>
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{
+
+  ///////////////////////////////////////////////////////////////////
+  /// \class NamedValue<_Tp>
+  /// \brief Simple value<>name mapping supporting aliases.
+  /// \code
+  ///   enum Commands {
+  ///     CMD_1,
+  ///     CMD_2
+  ///   };
+  ///   NamedValue<Commands> clist;
+  ///   //     Value   | Name   | Alias...
+  ///   clist( CMD_1 ) | "cmd1";
+  ///   clist( CMD_2 ) | "cmd2" | "second";
+  ///
+  ///   std::string name( clist.getName( CMD_1 ) );
+  ///   Commands    cmd( clist.getValue( "second" ) );
+  /// \endcode
+  ///////////////////////////////////////////////////////////////////
+  template< class _Tp, const bool _WithAlias = true >
+  class NamedValue
+  {
+    typedef std::map< std::string, _Tp > NameMap;
+    typedef std::map< _Tp, std::string > ValueMap;
+
+  public:
+    /** Wheter not initialized (no (name,value) pair remembered) */
+    bool empty() const
+    { return( _nameMap.empty() && _valueMap.empty() ); }
+
+  public:
+    /** \name Get value for name or alias. */
+    //@{
+      /** Whether there is a \c value mapped for \a name_r.
+       */
+      bool haveValue( const std::string & name_r ) const
+      {
+       typename NameMap::const_iterator it( _nameMap.find( name_r ) );
+       return( it != _nameMap.end() );
+      }
+
+      /** Get value mapped for name or alias.
+       * \return \c true if name or alias was found.
+       */
+      bool getValue( const std::string & name_r, _Tp & value_r ) const
+      {
+       typename NameMap::const_iterator it( _nameMap.find( name_r ) );
+       if ( it == _nameMap.end() )
+         return false;
+       value_r = it->second;
+       return true;
+      }
+      /** \overload \throws std::out_of_range exception if \a name_r was not found. */
+      const _Tp & getValue( const std::string & name_r ) const
+      { return _nameMap.at( name_r ); }
+    //@}
+
+
+    /** \name Get name for value. */
+    //@{
+      /** Whether there is a \c name mapped for \a value_r.
+       */
+      bool haveName( const std::string & value_r ) const
+      {
+       typename ValueMap::const_iterator it( _valueMap.find( value_r ) );
+       return( it != _valueMap.end() );
+      }
+
+      /** Get name of value.
+       * \return \c true if name or alias was found.
+       */
+      bool getName( const _Tp & value_r, std::string & name_r ) const
+      {
+       typename ValueMap::const_iterator it( _valueMap.find( value_r ) );
+       if ( it == _valueMap.end() )
+         return false;
+       value_r = it->second;
+       return true;
+      }
+      /** \overload \throws std::out_of_range exception if \a value_r was not found. */
+      const std::string & getName( const _Tp & value_r ) const
+      { return _valueMap.at( value_r ); }
+    //@}
+
+  public:
+    /** \name Inserter
+     */
+    //@{
+      class _Inserter
+      {
+      public:
+       _Inserter( NamedValue & parent_r, const _Tp & value_r )
+       : _parent( &parent_r )
+       , _value( value_r )
+       {}
+       _Inserter & operator|( const std::string & name_r )
+       { _parent->insert( _value, name_r ); return *this; }
+      private:
+       NamedValue * _parent;
+       _Tp _value;
+      };
+
+      _Inserter operator()( const _Tp & value_r )
+      { return _Inserter( *this, value_r ); }
+    //@}
+
+    /** Remember name (1st call) or alias (subsequent calls).
+     * \return \C true if this is the 1st call for \a value_r.
+     * \throws std::logic_error if \a name_r is already used as name or alias.
+     * \throws std::logic_error if \c _WithAlias is \c false and a name for \a value_r is already defined.
+     */
+    bool insert( const _Tp & value_r, const std::string & name_r )
+    {
+      typename NameMap::const_iterator nit( _nameMap.find( name_r ) );
+      if ( nit != _nameMap.end() )     // duplicate name
+       throw std::logic_error( "NamedValue::insert name" );
+
+      typename ValueMap::const_iterator tit( _valueMap.find( value_r ) );
+      if ( tit != _valueMap.end() )    // duplicate value, i.e. an alias
+      {
+       if ( !_WithAlias )
+         throw std::logic_error( "NamedValue::insert alias" );
+
+       _nameMap[name_r] = value_r;
+       return false;
+      }
+      // here: 1st entry for value_r
+      _nameMap[name_r] = value_r;
+      _valueMap[value_r] = name_r;
+      return true;
+    }
+
+  private:
+    NameMap _nameMap;
+    ValueMap _valueMap;
+  };
+  ///////////////////////////////////////////////////////////////////
+
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_BASE_NAMEDVALUE_H