Line data Source code
1 : //
2 : // Author: Vladimir Migashko <migashko@gmail.com>, (C) 2012
3 : //
4 : // Copyright: See COPYING file that comes with this distribution
5 : //
6 :
7 : #ifndef VSET_VTREE_ASPECT_AD_ERASE_ITERATOR_HPP
8 : #define VSET_VTREE_ASPECT_AD_ERASE_ITERATOR_HPP
9 :
10 : #include <vset/vtree/aspect/tags.hpp>
11 :
12 : #include <iostream>
13 :
14 : namespace vset{ namespace vtree{
15 :
16 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
17 :
18 29 : struct ad_erase_iterator
19 : {
20 : template<typename T>
21 : typename T::iterator
22 5 : operator()(T& t, typename T::const_iterator itr)
23 : {
24 5 : return this->operator ()(t, itr, true);
25 : }
26 :
27 : template<typename T>
28 : typename T::iterator
29 16857 : operator()(T& t, typename T::const_iterator itr, bool make_defrag) const
30 : {
31 : typedef typename T::iterator iterator;
32 : typedef typename iterator::difference_type difference_type;
33 : typedef typename T::container_type container_type;
34 : typedef typename container_type::iterator container_iterator;
35 :
36 16857 : if ( itr == t.end() )
37 1 : return iterator(t.get_container().end(), 0 );
38 :
39 16856 : difference_type offset = itr.get_position();
40 16856 : container_iterator cont_itr = t.get_container().erase( itr.get_source_iterator(), itr.get_source_iterator() );
41 16856 : if ( cont_itr == t.get_container().end() )
42 0 : return iterator( cont_itr, 0 );
43 :
44 33712 : cont_itr->second->erase(
45 16856 : cont_itr->second->cbegin() + offset,
46 : t.get_aspect().template get<_compare_>()
47 : );
48 :
49 16856 : if ( cont_itr->second->empty() )
50 : {
51 1 : t.get_allocator().deallocate(cont_itr->second, 1);
52 1 : t.get_container().erase( cont_itr++ );
53 1 : offset = 0;
54 : }
55 : else
56 : {
57 16855 : cont_itr = t.get_aspect().template get<_update_node_key_>()(t, cont_itr );
58 16855 : if ( offset == static_cast<difference_type>(cont_itr->second->size()) )
59 : {
60 8893 : offset=0;
61 8893 : ++cont_itr;
62 : }
63 : }
64 :
65 16856 : --t.get_aspect().template get<_size_>();
66 :
67 16856 : if( make_defrag )
68 : {
69 4 : t.get_aspect().template get<_defrag_container_>()(t, iterator(cont_itr, offset));
70 : }
71 :
72 16856 : return iterator(cont_itr, offset);
73 : }
74 : };
75 :
76 : #else
77 :
78 : struct ad_erase_iterator
79 : {
80 : template<typename T>
81 : typename T::iterator operator()(T& t, typename T::iterator itr)
82 : {
83 : return this->operator ()(t, itr, true);
84 : }
85 :
86 : template<typename T>
87 : typename T::iterator operator()(T& t, typename T::iterator itr, bool make_defrag)
88 : {
89 : typedef typename T::iterator iterator;
90 : typedef typename iterator::difference_type difference_type;
91 : typedef typename T::container_type container_type;
92 : typedef typename container_type::iterator container_iterator;
93 :
94 : if ( itr == t.end() )
95 : return iterator(t.get_container().end(), 0 );
96 :
97 : container_iterator cont_itr = itr.get_source_iterator();
98 : difference_type offset = itr.get_position();
99 :
100 : cont_itr->second->erase(
101 : cont_itr->second->begin() + itr.get_position(),
102 : t.get_aspect().template get<_compare_>()
103 : );
104 :
105 : if ( cont_itr->second->empty() )
106 : {
107 : t.get_allocator().deallocate(cont_itr->second, 1);
108 : t.get_container().erase( cont_itr++ );
109 : offset = 0;
110 : }
111 : else
112 : {
113 : cont_itr = t.get_aspect().template get<_update_node_key_>()(t, cont_itr );
114 : if ( offset == static_cast<difference_type>(cont_itr->second->size()) )
115 : {
116 : offset=0;
117 : ++cont_itr;
118 : }
119 : }
120 :
121 : --t.get_aspect().template get<_size_>();
122 :
123 : if( make_defrag )
124 : {
125 : t.get_aspect().template get<_defrag_container_>()(t, iterator(cont_itr, offset));
126 : }
127 :
128 : return iterator(cont_itr, offset);
129 : }
130 : };
131 :
132 : #endif
133 :
134 : }}
135 :
136 : #endif
|