Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / Capabilities.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/Capabilities.h
10  *
11 */
12 #ifndef ZYPP_SAT_CAPABILITIES_H
13 #define ZYPP_SAT_CAPABILITIES_H
14
15 #include <iosfwd>
16
17 #include "zypp/base/DefaultIntegral.h"
18 #include "zypp/sat/detail/PoolMember.h"
19 #include "zypp/Capability.h"
20
21 ///////////////////////////////////////////////////////////////////
22 namespace zypp
23 { /////////////////////////////////////////////////////////////////
24
25   ///////////////////////////////////////////////////////////////////
26   //
27   //    CLASS NAME : Capabilities
28   //
29   /** Container of \ref Capability (currently read only).
30    *
31    * \note libsolv dependency lists may include internal ids
32    * which must be skipped on iteration or size calculation
33    * (\see \ref detail::isDepMarkerId).
34    */
35   class Capabilities
36   {
37     public:
38       typedef Capability value_type;
39       typedef unsigned   size_type;
40
41       enum Mode { SKIP_TO_INTERNAL };
42
43     public:
44       /** Default ctor */
45       Capabilities()
46       : _begin( 0 )
47       {}
48
49       /** Ctor from Id pointer (friend \ref Solvable). */
50       explicit
51       Capabilities( const sat::detail::IdType * base_r )
52       : _begin( base_r )
53       {}
54
55       /** Ctor from Id pointer (friend \ref Solvable).
56        * Jump behind skip_r (e.g. behind prereqMarker).
57        */
58       Capabilities( const sat::detail::IdType * base_r, sat::detail::IdType skip_r );
59
60     public:
61       /** Whether the container is empty. */
62       bool empty() const
63       { return ! ( _begin && *_begin ); }
64
65       /** Number of capabilities inside. */
66       size_type size() const;
67
68     public:
69       class const_iterator;
70
71       /** Iterator pointing to the first \ref Capability. */
72       const_iterator begin() const;
73
74       /** Iterator pointing behind the last \ref Capability. */
75       const_iterator end() const;
76
77   public:
78     /** Return whether \a lhs matches at least one capability in set. */
79     bool matches( const Capability & lhs ) const;
80
81     private:
82       const sat::detail::IdType * _begin;
83   };
84   ///////////////////////////////////////////////////////////////////
85
86   /** \relates Capabilities Stream output */
87   std::ostream & operator<<( std::ostream & str, const Capabilities & obj );
88
89   ///////////////////////////////////////////////////////////////////
90   //
91   //    CLASS NAME : Capabilities::const_iterator
92   //
93   /** \ref Capabilities iterator.
94    */
95   class Capabilities::const_iterator : public boost::iterator_adaptor<
96         const_iterator                   // Derived
97       , const sat::detail::IdType *      // Base
98       , const Capability                 // Value
99       , boost::forward_traversal_tag     // CategoryOrTraversal
100       , const Capability                 // Reference
101       >
102   {
103     public:
104       const_iterator()
105       : const_iterator::iterator_adaptor_( 0 )
106       {}
107
108       explicit const_iterator( const sat::detail::IdType * _idx )
109       : const_iterator::iterator_adaptor_( _idx )
110       {
111         if ( base_reference() && sat::detail::isDepMarkerId( *base_reference() ) )
112         {
113           _tagged = true;
114           ++base_reference();
115         }
116       }
117
118     public:
119       /** Return \c true if the \ref Capability is \c tagged.
120        * The meaning of \c tagged depends on the kind of dependency you
121        * are processing. It is a hint that the iteratir skipped some
122        * internal marker, indicating that subsequent cabailities have
123        * a special property. Within a \ref Solvables requirements e.g.
124        * the pre-requirements are tagged.
125        * \code
126        * Capabilities req( solvable.requires() );
127        * for_( it, req.begin(), req.end() )
128        * {
129        *   if ( it.tagged() )
130        *     cout << *it << " (is prereq)" << endl;
131        *   else
132        *     cout << *it << endl;
133        * }
134        * \endcode
135       */
136       bool tagged() const { return _tagged; }
137
138     private:
139       friend class boost::iterator_core_access;
140
141       reference dereference() const
142       { return ( base() ) ? Capability( *base() ) : Capability::Null; }
143
144       template <class OtherDerived, class OtherIterator, class V, class C, class R, class D>
145       bool equal( const boost::iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> & rhs ) const
146       { // NULL pointer is eqal pointer to Id 0
147         return ( base() == rhs.base() // includes both NULL...
148                  || ( !rhs.base() && !*base()     )
149                  || ( !base()     && !*rhs.base() ) );
150       }
151
152       void increment()
153       { // jump over libsolvs internal ids.
154         if ( sat::detail::isDepMarkerId( *(++base_reference()) ) )
155         {
156           _tagged = true;
157           ++base_reference();
158         }
159       }
160
161     private:
162       DefaultIntegral<bool,false> _tagged;
163   };
164   ///////////////////////////////////////////////////////////////////
165
166   inline Capabilities::const_iterator Capabilities::begin() const
167   { return const_iterator( _begin ); }
168
169   inline Capabilities::const_iterator Capabilities::end() const
170   { return const_iterator( 0 ); }
171
172   inline bool Capabilities::matches( const Capability & lhs ) const
173   {
174     for ( const Capability & rhs : *this )
175       if ( lhs.matches( rhs ) == CapMatch::yes )
176         return true;
177     return false;
178   }
179   /////////////////////////////////////////////////////////////////
180 } // namespace zypp
181 ///////////////////////////////////////////////////////////////////
182 #endif // ZYPP_SAT_CAPABILITIES_H