From df6bfb842abd7598e7c81a6da5d2f9d3f8b42414 Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Mon, 17 Dec 2012 11:42:55 +0100 Subject: [PATCH] Add NamedValue<_Tp>: Simple value<>name mapping supporting aliases --- zypp/CMakeLists.txt | 1 + zypp/base/NamedValue.h | 161 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 zypp/base/NamedValue.h diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt index 538a7c488..5b406ffe0 100644 --- a/zypp/CMakeLists.txt +++ b/zypp/CMakeLists.txt @@ -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 index 000000000..a07c8d5a4 --- /dev/null +++ b/zypp/base/NamedValue.h @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/base/NamedValue.h + * +*/ +#ifndef ZYPP_BASE_NAMEDVALUE_H +#define ZYPP_BASE_NAMEDVALUE_H + +#include +#include +#include + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ + + /////////////////////////////////////////////////////////////////// + /// \class NamedValue<_Tp> + /// \brief Simple value<>name mapping supporting aliases. + /// \code + /// enum Commands { + /// CMD_1, + /// CMD_2 + /// }; + /// NamedValue 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 -- 2.34.1