update doc
[platform/upstream/libzypp.git] / doc / autoinclude / CodeSnippets.doc
1 /** \page CodeSnippets Code Snippets
2
3 \section for_
4   If you prefer using iterator in a \c for loop, but dislike to figure out
5   the exact type of the iterator, you may find the  \c for_ macro convenient:
6   \code
7     #include "zypp/base/Easy.h"
8
9     for_( it, pool.byIdentBegin( kind, name ),
10               pool.byIdentEnd( kind, name ) )
11     {
12       PoolItem copy = *it;
13     }
14   \endcode
15   instead of:
16   \code
17     for ( ResPool::byIdent_iterator it = pool.byIdentBegin( kind, name ),
18           end = pool.byIdentEnd( kind, name );
19           it != end, ++it )
20     {
21       PoolItem copy = *it;
22     }
23   \endcode
24
25 \section erase erase elements from containers
26   \verbatim
27   // //////////////////////////////////////////////////////////////////////
28   // Avoid buggy code, that tries to erase elements, matching a
29   // certain property from containers. Example:
30   //
31   //  for (ResStore::iterator it = store.begin(); it != store.end(); ++it)
32   //  {
33   //    _pool.erase(*it);
34   //  }
35   //
36   // Problem: Removing an element from a container invalidates (at least)
37   //          all iterators pointing to it. Thus after erasing *it, it is
38   //          no longer valid. ++it has UNDEFINED BEHAVIOUR.
39
40   // //////////////////////////////////////////////////////////////////////
41   // Loop based algorithms (differs depending on the kind of container)
42   // =====================
43   // //////////////////////////////////////////////////////////////////////
44
45   // //////////////////////////////////////////////////////////////////////
46   // Sequential container (vector string deque list): erase returns
47   // a valid iterator to the next element.
48   // //////////////////////////////////////////////////////////////////////
49
50     SeqContainer c;
51     for ( SeqContainer::iterator it = c.begin(); it != c.end(); /**/ )
52       {
53         if ( toBeRemoved( *it ) )
54           {
55             it = c.erase( it ); // valid next-iterator returned
56           }
57         else
58           ++it;
59       }
60
61
62   // //////////////////////////////////////////////////////////////////////
63   // Associative container (maps sets): erase returns void, but we can use
64   // postfix increment, as ONLY iterators to the eased object get invalid:
65   // //////////////////////////////////////////////////////////////////////
66
67     AssocContainer c;
68     for ( AssocContainer::iterator it = c.begin(); it != c.end(); /**/ )
69       {
70         if ( toBeRemoved( *it ) )
71           {
72             c.erase( it++ ); // postfix! Incrementing before erase
73           }
74         else
75           ++it;
76       }
77
78
79   // //////////////////////////////////////////////////////////////////////
80   // stl algorithms
81   // ==============
82   //
83   // In case toBeRemoved above is actually a function/functor.
84   // //////////////////////////////////////////////////////////////////////
85
86
87   // //////////////////////////////////////////////////////////////////////
88   // Sequential container (vector string deque): stl::remove_if,
89   // does not erase elements, they are just moved to the containers
90   // end, and an iterator to the 1st item to be 'removed' is returned.
91   // //////////////////////////////////////////////////////////////////////
92
93     SeqContainer c;
94     c.erase( stl::remove_if( c.begin(), c.end(), toBeRemoved ),
95             c.end() );
96
97
98   // //////////////////////////////////////////////////////////////////////
99   // Sequential container (list): The above works too, but list has a
100   // builtin remove/remove_if which is more efficient.
101   // //////////////////////////////////////////////////////////////////////
102
103     list c;
104     c.remove_if( toBeRemoved );
105
106
107   // //////////////////////////////////////////////////////////////////////
108   // Associative container (maps sets): Actually the loop above is the most
109   // efficient solution. There is an algorithm based solution, but it requires
110   // copying all elements not to be removed ;(
111   // //////////////////////////////////////////////////////////////////////
112
113     AssocContainer c;
114
115     AssocContainer keepItems;
116     stl::remove_copy_if( c.begin(), c.end(),
117                         stl::inserter( keepItems, keepItems.end() ),
118                         toBeRemoved );
119     c.swap( keepItems );
120   \endverbatim
121
122 */