williamr@2
|
1 |
//
|
williamr@2
|
2 |
// Boost.Pointer Container
|
williamr@2
|
3 |
//
|
williamr@2
|
4 |
// Copyright Thorsten Ottosen 2003-2005. Use, modification and
|
williamr@2
|
5 |
// distribution is subject to the Boost Software License, Version
|
williamr@2
|
6 |
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
williamr@2
|
7 |
// http://www.boost.org/LICENSE_1_0.txt)
|
williamr@2
|
8 |
//
|
williamr@2
|
9 |
// For more information, see http://www.boost.org/libs/ptr_container/
|
williamr@2
|
10 |
//
|
williamr@2
|
11 |
|
williamr@2
|
12 |
|
williamr@2
|
13 |
#ifndef BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP
|
williamr@2
|
14 |
#define BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP
|
williamr@2
|
15 |
|
williamr@2
|
16 |
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
williamr@2
|
17 |
# pragma once
|
williamr@2
|
18 |
#endif
|
williamr@2
|
19 |
|
williamr@2
|
20 |
#include <boost/ptr_container/detail/reversible_ptr_container.hpp>
|
williamr@2
|
21 |
|
williamr@2
|
22 |
namespace boost
|
williamr@2
|
23 |
{
|
williamr@2
|
24 |
|
williamr@2
|
25 |
namespace ptr_container_detail
|
williamr@2
|
26 |
{
|
williamr@2
|
27 |
template
|
williamr@2
|
28 |
<
|
williamr@2
|
29 |
class Config,
|
williamr@2
|
30 |
class CloneAllocator
|
williamr@2
|
31 |
>
|
williamr@2
|
32 |
class associative_ptr_container :
|
williamr@2
|
33 |
public reversible_ptr_container<Config,CloneAllocator>
|
williamr@2
|
34 |
{
|
williamr@2
|
35 |
typedef reversible_ptr_container<Config,CloneAllocator>
|
williamr@2
|
36 |
base_type;
|
williamr@2
|
37 |
|
williamr@2
|
38 |
typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter
|
williamr@2
|
39 |
scoped_deleter;
|
williamr@2
|
40 |
|
williamr@2
|
41 |
public: // typedefs
|
williamr@2
|
42 |
typedef BOOST_DEDUCED_TYPENAME Config::key_type
|
williamr@2
|
43 |
key_type;
|
williamr@2
|
44 |
typedef BOOST_DEDUCED_TYPENAME Config::key_compare
|
williamr@2
|
45 |
key_compare;
|
williamr@2
|
46 |
typedef BOOST_DEDUCED_TYPENAME Config::value_compare
|
williamr@2
|
47 |
value_compare;
|
williamr@2
|
48 |
typedef BOOST_DEDUCED_TYPENAME Config::iterator
|
williamr@2
|
49 |
iterator;
|
williamr@2
|
50 |
typedef BOOST_DEDUCED_TYPENAME Config::const_iterator
|
williamr@2
|
51 |
const_iterator;
|
williamr@2
|
52 |
typedef BOOST_DEDUCED_TYPENAME base_type::size_type
|
williamr@2
|
53 |
size_type;
|
williamr@2
|
54 |
|
williamr@2
|
55 |
public: // foundation
|
williamr@2
|
56 |
|
williamr@2
|
57 |
template< class Compare, class Allocator >
|
williamr@2
|
58 |
associative_ptr_container( const Compare& comp,
|
williamr@2
|
59 |
const Allocator& a )
|
williamr@2
|
60 |
: base_type( comp, a )
|
williamr@2
|
61 |
{ }
|
williamr@2
|
62 |
|
williamr@2
|
63 |
template< class InputIterator, class Compare, class Allocator >
|
williamr@2
|
64 |
associative_ptr_container( InputIterator first, InputIterator last,
|
williamr@2
|
65 |
const Compare& comp,
|
williamr@2
|
66 |
const Allocator& a )
|
williamr@2
|
67 |
: base_type( first, last, comp, a )
|
williamr@2
|
68 |
{ }
|
williamr@2
|
69 |
|
williamr@2
|
70 |
template< class PtrContainer >
|
williamr@2
|
71 |
associative_ptr_container( std::auto_ptr<PtrContainer> r )
|
williamr@2
|
72 |
: base_type( r, key_compare() )
|
williamr@2
|
73 |
{ }
|
williamr@2
|
74 |
|
williamr@2
|
75 |
template< class PtrContainer >
|
williamr@2
|
76 |
void operator=( std::auto_ptr<PtrContainer> r )
|
williamr@2
|
77 |
{
|
williamr@2
|
78 |
base_type::operator=( r );
|
williamr@2
|
79 |
}
|
williamr@2
|
80 |
|
williamr@2
|
81 |
public: // associative container interface
|
williamr@2
|
82 |
key_compare key_comp() const
|
williamr@2
|
83 |
{
|
williamr@2
|
84 |
return this->c_private().key_comp();
|
williamr@2
|
85 |
}
|
williamr@2
|
86 |
|
williamr@2
|
87 |
value_compare value_comp() const
|
williamr@2
|
88 |
{
|
williamr@2
|
89 |
return this->c_private().value_comp();
|
williamr@2
|
90 |
}
|
williamr@2
|
91 |
|
williamr@2
|
92 |
iterator erase( iterator before ) // nothrow
|
williamr@2
|
93 |
{
|
williamr@2
|
94 |
BOOST_ASSERT( !this->empty() );
|
williamr@2
|
95 |
BOOST_ASSERT( before != this->end() );
|
williamr@2
|
96 |
|
williamr@2
|
97 |
this->remove( before ); // nothrow
|
williamr@2
|
98 |
iterator res( before ); // nothrow
|
williamr@2
|
99 |
++res; // nothrow
|
williamr@2
|
100 |
this->c_private().erase( before.base() ); // nothrow
|
williamr@2
|
101 |
return res; // nothrow
|
williamr@2
|
102 |
}
|
williamr@2
|
103 |
|
williamr@2
|
104 |
size_type erase( const key_type& x ) // nothrow
|
williamr@2
|
105 |
{
|
williamr@2
|
106 |
iterator i( this->c_private().find( x ) ); // nothrow
|
williamr@2
|
107 |
if( i == this->end() ) // nothrow
|
williamr@2
|
108 |
return 0u; // nothrow
|
williamr@2
|
109 |
this->remove( i ); // nothrow
|
williamr@2
|
110 |
return this->c_private().erase( x ); // nothrow
|
williamr@2
|
111 |
}
|
williamr@2
|
112 |
|
williamr@2
|
113 |
iterator erase( iterator first,
|
williamr@2
|
114 |
iterator last ) // nothrow
|
williamr@2
|
115 |
{
|
williamr@2
|
116 |
iterator res( last ); // nothrow
|
williamr@2
|
117 |
if( res != this->end() )
|
williamr@2
|
118 |
++res; // nothrow
|
williamr@2
|
119 |
|
williamr@2
|
120 |
this->remove( first, last ); // nothrow
|
williamr@2
|
121 |
this->c_private().erase( first.base(), last.base() );// nothrow
|
williamr@2
|
122 |
return res; // nothrow
|
williamr@2
|
123 |
}
|
williamr@2
|
124 |
|
williamr@2
|
125 |
protected:
|
williamr@2
|
126 |
|
williamr@2
|
127 |
template< class AssociatePtrCont >
|
williamr@2
|
128 |
void multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object,
|
williamr@2
|
129 |
AssociatePtrCont& from ) // strong
|
williamr@2
|
130 |
{
|
williamr@2
|
131 |
BOOST_ASSERT( (void*)&from != (void*)this );
|
williamr@2
|
132 |
BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" );
|
williamr@2
|
133 |
|
williamr@2
|
134 |
this->c_private().insert( *object.base() ); // strong
|
williamr@2
|
135 |
from.c_private().erase( object.base() ); // nothrow
|
williamr@2
|
136 |
}
|
williamr@2
|
137 |
|
williamr@2
|
138 |
template< class AssociatePtrCont >
|
williamr@2
|
139 |
size_type multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first,
|
williamr@2
|
140 |
BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last,
|
williamr@2
|
141 |
AssociatePtrCont& from ) // basic
|
williamr@2
|
142 |
{
|
williamr@2
|
143 |
BOOST_ASSERT( (void*)&from != (void*)this );
|
williamr@2
|
144 |
BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" );
|
williamr@2
|
145 |
|
williamr@2
|
146 |
size_type res = 0;
|
williamr@2
|
147 |
for( ; first != last; )
|
williamr@2
|
148 |
{
|
williamr@2
|
149 |
BOOST_ASSERT( first != from.end() );
|
williamr@2
|
150 |
this->c_private().insert( *first.base() ); // strong
|
williamr@2
|
151 |
BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator
|
williamr@2
|
152 |
to_delete( first );
|
williamr@2
|
153 |
++first;
|
williamr@2
|
154 |
from.c_private().erase( to_delete.base() ); // nothrow
|
williamr@2
|
155 |
++res;
|
williamr@2
|
156 |
}
|
williamr@2
|
157 |
|
williamr@2
|
158 |
return res;
|
williamr@2
|
159 |
}
|
williamr@2
|
160 |
|
williamr@2
|
161 |
template< class AssociatePtrCont >
|
williamr@2
|
162 |
bool single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object,
|
williamr@2
|
163 |
AssociatePtrCont& from ) // strong
|
williamr@2
|
164 |
{
|
williamr@2
|
165 |
BOOST_ASSERT( (void*)&from != (void*)this );
|
williamr@2
|
166 |
BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" );
|
williamr@2
|
167 |
|
williamr@2
|
168 |
std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> p =
|
williamr@2
|
169 |
this->c_private().insert( *object.base() ); // strong
|
williamr@2
|
170 |
if( p.second )
|
williamr@2
|
171 |
from.c_private().erase( object.base() ); // nothrow
|
williamr@2
|
172 |
|
williamr@2
|
173 |
return p.second;
|
williamr@2
|
174 |
}
|
williamr@2
|
175 |
|
williamr@2
|
176 |
template< class AssociatePtrCont >
|
williamr@2
|
177 |
size_type single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first,
|
williamr@2
|
178 |
BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last,
|
williamr@2
|
179 |
AssociatePtrCont& from ) // basic
|
williamr@2
|
180 |
{
|
williamr@2
|
181 |
BOOST_ASSERT( (void*)&from != (void*)this );
|
williamr@2
|
182 |
BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" );
|
williamr@2
|
183 |
|
williamr@2
|
184 |
size_type res = 0;
|
williamr@2
|
185 |
for( ; first != last; )
|
williamr@2
|
186 |
{
|
williamr@2
|
187 |
BOOST_ASSERT( first != from.end() );
|
williamr@2
|
188 |
std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> p =
|
williamr@2
|
189 |
this->c_private().insert( *first.base() ); // strong
|
williamr@2
|
190 |
BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator
|
williamr@2
|
191 |
to_delete( first );
|
williamr@2
|
192 |
++first;
|
williamr@2
|
193 |
if( p.second )
|
williamr@2
|
194 |
{
|
williamr@2
|
195 |
from.c_private().erase( to_delete.base() ); // nothrow
|
williamr@2
|
196 |
++res;
|
williamr@2
|
197 |
}
|
williamr@2
|
198 |
}
|
williamr@2
|
199 |
return res;
|
williamr@2
|
200 |
}
|
williamr@2
|
201 |
|
williamr@2
|
202 |
}; // class 'associative_ptr_container'
|
williamr@2
|
203 |
|
williamr@2
|
204 |
} // namespace 'ptr_container_detail'
|
williamr@2
|
205 |
|
williamr@2
|
206 |
} // namespace 'boost'
|
williamr@2
|
207 |
|
williamr@2
|
208 |
|
williamr@2
|
209 |
#endif
|