Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / base / NamedValue.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/base/NamedValue.h
10  *
11 */
12 #ifndef ZYPP_BASE_NAMEDVALUE_H
13 #define ZYPP_BASE_NAMEDVALUE_H
14
15 #include <stdexcept>
16 #include <string>
17 #include <map>
18
19 ///////////////////////////////////////////////////////////////////
20 namespace zypp
21 {
22
23   ///////////////////////////////////////////////////////////////////
24   /// \class NamedValue<_Tp>
25   /// \brief Simple value<>name mapping supporting aliases.
26   /// \code
27   ///   enum Commands {
28   ///     CMD_1,
29   ///     CMD_2
30   ///   };
31   ///   NamedValue<Commands> clist;
32   ///   //     Value   | Name   | Alias...
33   ///   clist( CMD_1 ) | "cmd1";
34   ///   clist( CMD_2 ) | "cmd2" | "second";
35   ///
36   ///   std::string name( clist.getName( CMD_1 ) );
37   ///   Commands    cmd( clist.getValue( "second" ) );
38   /// \endcode
39   ///////////////////////////////////////////////////////////////////
40   template< class _Tp, const bool _WithAlias = true >
41   class NamedValue
42   {
43     typedef std::map< std::string, _Tp > NameMap;
44     typedef std::map< _Tp, std::string > ValueMap;
45
46   public:
47     /** Whether not initialized (no (name,value) pair remembered) */
48     bool empty() const
49     { return( _nameMap.empty() && _valueMap.empty() ); }
50
51   public:
52     /** \name Get value for name or alias. */
53     //@{
54       /** Whether there is a \c value mapped for \a name_r.
55        */
56       bool haveValue( const std::string & name_r ) const
57       {
58         typename NameMap::const_iterator it( _nameMap.find( name_r ) );
59         return( it != _nameMap.end() );
60       }
61
62       /** Get value mapped for name or alias.
63        * \return \c true if name or alias was found.
64        */
65       bool getValue( const std::string & name_r, _Tp & value_r ) const
66       {
67         typename NameMap::const_iterator it( _nameMap.find( name_r ) );
68         if ( it == _nameMap.end() )
69           return false;
70         value_r = it->second;
71         return true;
72       }
73       /** \overload \throws std::out_of_range exception if \a name_r was not found. */
74       const _Tp & getValue( const std::string & name_r ) const
75       { return _nameMap.at( name_r ); }
76     //@}
77
78
79     /** \name Get name for value. */
80     //@{
81       /** Whether there is a \c name mapped for \a value_r.
82        */
83       bool haveName( const std::string & value_r ) const
84       {
85         typename ValueMap::const_iterator it( _valueMap.find( value_r ) );
86         return( it != _valueMap.end() );
87       }
88
89       /** Get name of value.
90        * \return \c true if name or alias was found.
91        */
92       bool getName( const _Tp & value_r, std::string & name_r ) const
93       {
94         typename ValueMap::const_iterator it( _valueMap.find( value_r ) );
95         if ( it == _valueMap.end() )
96           return false;
97         value_r = it->second;
98         return true;
99       }
100       /** \overload \throws std::out_of_range exception if \a value_r was not found. */
101       const std::string & getName( const _Tp & value_r ) const
102       { return _valueMap.at( value_r ); }
103     //@}
104
105   public:
106     /** \name Inserter
107      */
108     //@{
109       class _Inserter
110       {
111       public:
112         _Inserter( NamedValue & parent_r, const _Tp & value_r )
113         : _parent( &parent_r )
114         , _value( value_r )
115         {}
116         _Inserter & operator|( const std::string & name_r )
117         { _parent->insert( _value, name_r ); return *this; }
118       private:
119         NamedValue * _parent;
120         _Tp _value;
121       };
122
123       _Inserter operator()( const _Tp & value_r )
124       { return _Inserter( *this, value_r ); }
125     //@}
126
127     /** Remember name (1st call) or alias (subsequent calls).
128      * \return \C true if this is the 1st call for \a value_r.
129      * \throws std::logic_error if \a name_r is already used as name or alias.
130      * \throws std::logic_error if \c _WithAlias is \c false and a name for \a value_r is already defined.
131      */
132     bool insert( const _Tp & value_r, const std::string & name_r )
133     {
134       typename NameMap::const_iterator nit( _nameMap.find( name_r ) );
135       if ( nit != _nameMap.end() )      // duplicate name
136         throw std::logic_error( "NamedValue::insert name" );
137
138       typename ValueMap::const_iterator tit( _valueMap.find( value_r ) );
139       if ( tit != _valueMap.end() )     // duplicate value, i.e. an alias
140       {
141         if ( !_WithAlias )
142           throw std::logic_error( "NamedValue::insert alias" );
143
144         _nameMap[name_r] = value_r;
145         return false;
146       }
147       // here: 1st entry for value_r
148       _nameMap[name_r] = value_r;
149       _valueMap[value_r] = name_r;
150       return true;
151     }
152
153   private:
154     NameMap _nameMap;
155     ValueMap _valueMap;
156   };
157   ///////////////////////////////////////////////////////////////////
158
159 } // namespace zypp
160 ///////////////////////////////////////////////////////////////////
161 #endif // ZYPP_BASE_NAMEDVALUE_H