00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00045 #ifndef VALUE_TYPE_ADAPTER_HPP
00046 #define VALUE_TYPE_ADAPTER_HPP
00047
00048 #include <ext/pb_assoc/detail/value_type_adapter/ref_pair.hpp>
00049 #include <ext/pb_assoc/detail/assoc_cntnr_base.hpp>
00050 #include <ext/pb_assoc/detail/value_type_adapter/invalidation_guarantee_selector.hpp>
00051 #include <ext/pb_assoc/detail/type_utils.hpp>
00052 #include <utility>
00053 #include <algorithm>
00054 #include <tr1/type_traits>
00055
00056 namespace pb_assoc
00057 {
00058
00059 namespace detail
00060 {
00061
00062 #define PB_ASSOC_STATIC_ASSERT(UNIQUE, E) \
00063 typedef \
00064 pb_assoc::detail::static_assert_dummy_class< \
00065 sizeof(pb_assoc::detail::static_assert<(bool)(E)>)> \
00066 UNIQUE##static_assert_type
00067
00068 #define PB_ASSOC_CLASS_T_DEC \
00069 template< \
00070 typename Key, \
00071 typename Data, \
00072 class DS_Tag, \
00073 class Policy_Tl, \
00074 class Allocator, \
00075 int Mapping_Level>
00076
00077 #define PB_ASSOC_CLASS_C_DEC \
00078 value_type_adapter< \
00079 Key, \
00080 Data, \
00081 DS_Tag, \
00082 Policy_Tl, \
00083 Allocator, \
00084 Mapping_Level>
00085
00086 #define PB_ASSOC_BASE_C_DEC \
00087 cond_type< \
00088 Mapping_Level != 1, \
00089 value_type_adapter< \
00090 Key, \
00091 Data, \
00092 DS_Tag, \
00093 Policy_Tl, \
00094 Allocator, \
00095 Mapping_Level - 1>, \
00096 typename assoc_cntnr_base< \
00097 Key, \
00098 Data, \
00099 DS_Tag, \
00100 Policy_Tl, \
00101 Allocator>::type>::type
00102
00103 template<typename Key,
00104 typename Data,
00105 class DS_Tag,
00106 class Policy_Tl,
00107 class Allocator,
00108 int Mapping_Level>
00109 struct value_type_adapter : public PB_ASSOC_BASE_C_DEC
00110 {
00111
00112 private:
00113 typedef typename PB_ASSOC_BASE_C_DEC my_base;
00114
00115 typedef typename my_base::data_type my_base_data_type;
00116
00117 enum
00118 {
00119 same_alloc_type =
00120 is_same_type<
00121 typename my_base::allocator::template rebind<
00122 char>::other,
00123 typename my_base_data_type::allocator::template rebind<
00124 char>::other>::value
00125 };
00126
00127 PB_ASSOC_STATIC_ASSERT(wrong_level, Mapping_Level > 0);
00128
00129 PB_ASSOC_STATIC_ASSERT(must_be_same_alloc, same_alloc_type);
00130
00131 #include <ext/pb_assoc/detail/value_type_adapter/value_type_traits.hpp>
00132 #include <ext/pb_assoc/detail/value_type_adapter/it_value_type_traits.hpp>
00133
00134 typedef
00135 it_value_type_traits_<
00136 typename base_it_key_type<
00137 my_base,
00138 Mapping_Level == 1>::type,
00139 typename my_base_data_type::const_key_reference,
00140 typename cond_type<
00141 is_same_type<
00142 typename my_base_data_type::data_type,
00143 null_data_type>::value,
00144 null_data_type,
00145 typename my_base_data_type::data_reference>::type,
00146 typename my_base_data_type::reference,
00147 typename my_base::allocator>
00148 it_value_type_traits_t;
00149
00150 #include <ext/pb_assoc/detail/value_type_adapter/iterator.hpp>
00151
00152 typedef
00153 value_type_traits_<
00154 typename my_base::key_type,
00155 typename my_base_data_type::key_type,
00156 typename my_base_data_type::data_type,
00157 typename my_base::allocator>
00158 value_type_traits_t;
00159
00160 enum
00161 {
00162 has_data =
00163 !is_same_type<
00164 typename my_base_data_type::data_type,
00165 null_data_type>::value
00166 };
00167
00168 public:
00169
00170 typedef typename Allocator::size_type size_type;
00171
00172 typedef typename Allocator::difference_type difference_type;
00173
00174 typedef typename my_base::allocator allocator;
00175
00176 typedef typename it_value_type_traits_t::key_type it_key_type;
00177
00178 typedef
00179 std::pair<
00180 typename my_base::key_type,
00181 typename my_base_data_type::key_type>
00182 key_type;
00183
00184 typedef
00185 typename allocator::template rebind<
00186 key_type>::other::reference
00187 key_reference;
00188
00189 typedef
00190 typename allocator::template rebind<
00191 key_type>::other::const_reference
00192 const_key_reference;
00193
00194 typedef
00195 typename allocator::template rebind<
00196 key_type>::other::pointer
00197 key_pointer;
00198
00199 typedef
00200 typename allocator::template rebind<
00201 key_type>::other::const_pointer
00202 const_key_pointer;
00203
00204 typedef typename my_base_data_type::data_type data_type;
00205
00206 typedef
00207 typename allocator::template rebind<
00208 data_type>::other::reference
00209 data_reference;
00210
00211 typedef
00212 typename allocator::template rebind<
00213 data_type>::other::const_reference
00214 const_data_reference;
00215
00216 typedef
00217 typename allocator::template rebind<
00218 data_type>::other::pointer
00219 data_pointer;
00220
00221 typedef
00222 typename allocator::template rebind<
00223 data_type>::other::const_pointer
00224 const_data_pointer;
00225
00226 typedef typename value_type_traits_t::value_type value_type;
00227
00228 typedef typename value_type_traits_t::reference reference;
00229
00230 typedef typename value_type_traits_t::const_reference const_reference;
00231
00232 typedef typename value_type_traits_t::pointer pointer;
00233
00234 typedef typename value_type_traits_t::const_pointer const_pointer;
00235
00236 typedef
00237 it_<
00238 typename my_base::const_find_iterator,
00239 typename my_base_data_type::const_find_iterator,
00240 has_data,
00241 true>
00242 const_find_iterator;
00243
00244 typedef
00245 it_<
00246 typename my_base::find_iterator,
00247 typename my_base_data_type::find_iterator,
00248 has_data,
00249 false>
00250 find_iterator;
00251
00252 typedef
00253 it_<
00254 typename my_base::const_iterator,
00255 typename my_base_data_type::const_iterator,
00256 has_data,
00257 true>
00258 const_iterator;
00259
00260 typedef
00261 it_<
00262 typename my_base::iterator,
00263 typename my_base_data_type::iterator,
00264 has_data,
00265 false>
00266 iterator;
00267
00268 enum
00269 {
00270 mapping_level = mapping_level_imp<
00271 typename my_base::given_data_type>::value -1
00272 };
00273
00274
00275
00276 typedef compound_ds_tag ds_category;
00277
00278 typedef
00279 typename cond_type<
00280 mapping_level == 1,
00281 typename cond_type<
00282 has_data,
00283 data_enabled_ms_tag,
00284 basic_ms_tag>::type,
00285 compound_data_enabled_ms_tag>::type
00286 ms_category;
00287
00288 typedef
00289 typename cond_type<
00290 Mapping_Level == 1,
00291 DS_Tag,
00292 compound_ds_tag>::type
00293 effective_base_ds_tag;
00294
00295 typedef ds_traits< my_base_data_type> base_data_ds_traits;
00296
00297 enum
00298 {
00299 erase_can_throw =
00300 base_data_ds_traits::erase_can_throw
00301 };
00302
00303 enum
00304 {
00305 order_preserving =
00306 order_preserving_imp<
00307 my_base,
00308 effective_base_ds_tag>::value&&
00309 base_data_ds_traits::order_preserving
00310 };
00311
00312 enum
00313 {
00314 erase_iterators =
00315 base_data_ds_traits::erase_iterators
00316 };
00317
00318 typedef
00319 typename ig_sel<
00320 typename invalidation_guarantee_imp<
00321 my_base,
00322 effective_base_ds_tag>::type,
00323 typename ds_traits<
00324 my_base_data_type>::invalidation_guarantee>::type
00325 invalidation_guarantee;
00326
00327 enum
00328 {
00329 reverse_iteration =
00330 reverse_iteration_imp<
00331 my_base,
00332 effective_base_ds_tag>::value&&
00333 base_data_ds_traits::reverse_iteration
00334 };
00335
00336 enum
00337 {
00338 split_join = false
00339 };
00340
00341 protected:
00342 typedef typename my_base_data_type::data_pointer erase_imp_ret_t;
00343
00344 private:
00345 inline const_key_reference
00346 extract_key_imp(const_reference r_val, int_to_type<true>)
00347 {
00348 return (r_val.first);
00349 }
00350
00351 inline const_key_reference
00352 extract_key_imp(const_reference r_val, int_to_type<false>)
00353 {
00354 return (r_val);
00355 }
00356
00357 inline it_key_type
00358 extract_key_imp(typename iterator::const_reference r_val, int_to_type<true>)
00359 {
00360 return (r_val.first);
00361 }
00362
00363 inline it_key_type
00364 extract_key_imp(typename iterator::const_reference r_val, int_to_type<false>)
00365 {
00366 return (r_val);
00367 }
00368
00369 public:
00370
00371 inline size_type
00372 size() const
00373 {
00374 return (std::distance(begin(), end()));
00375 }
00376
00377 inline size_type
00378 max_size() const
00379 {
00380 return (my_base::max_size());
00381 }
00382
00383 inline bool
00384 empty() const
00385 {
00386 return (size() == 0);
00387 }
00388
00389 inline static const_key_reference
00390 extract_key(const_reference r_val)
00391 {
00392 return (extract_key_imp(
00393 r_val,
00394 int_to_type<has_data>()));
00395 }
00396
00397 inline it_key_type
00398 extract_key(typename iterator::const_reference r_val)
00399 {
00400 return (extract_key_imp(
00401 r_val,
00402 int_to_type<has_data>()));
00403 }
00404
00405 inline std::pair<
00406 find_iterator,
00407 bool>
00408 insert(const_reference r_val)
00409 {
00410 typedef std::pair< typename my_base::find_iterator, bool> base_ins_ret;
00411
00412
00413 }
00414
00415 inline data_reference
00416 operator[](const_key_reference r_key)
00417 {
00418 return (subscript_imp(r_key));
00419 }
00420
00421 inline const_find_iterator
00422 find(const_key_reference r_key) const
00423 {
00424 typename my_base::const_find_iterator it = my_base::find(r_key.first);
00425
00426 if (it == my_base::end())
00427 return (end());
00428
00429 typename my_base_data_type::const_find_iterator sec_it =
00430 it->second.find(r_key.second);
00431
00432 if (sec_it == it->second.end())
00433 return (end());
00434
00435 return (const_find_iterator(it, sec_it));
00436 }
00437
00438 inline find_iterator
00439 find(const_key_reference r_key)
00440 {
00441 typename my_base::find_iterator it = my_base::find(r_key.first);
00442
00443 if (it == my_base::end())
00444 return (end());
00445
00446 typename my_base_data_type::find_iterator sec_it =
00447 it->second.find(r_key.second);
00448
00449 if (sec_it == it->second.end())
00450 return (end());
00451
00452 return (find_iterator(it, my_base::end(), sec_it));
00453 }
00454
00455 inline const_data_reference
00456 operator[](const_key_reference r_key) const
00457 {
00458 return (my_base::operator[](r_key.first).operator[](r_key.second));
00459 }
00460
00461 inline size_type
00462 erase(const_key_reference r_key)
00463 {
00464 typename my_base::find_iterator it =
00465 my_base::find(r_key.first);
00466
00467 if (it == my_base::end())
00468 return (0);
00469
00470 if (it->second.find(r_key.second) == it->second.end())
00471 return (0);
00472
00473 it->second.erase(r_key.second);
00474
00475 return (1);
00476 }
00477
00478 #include <ext/pb_assoc/detail/value_type_adapter/erase_if_pred.hpp>
00479
00480 template<class Pred>
00481 inline size_type
00482 erase_if(Pred prd)
00483 {
00484 typename my_base::iterator it = my_base::begin();
00485
00486 typename my_base::iterator end_it = my_base::end();
00487
00488 size_type ersd = 0;
00489
00490
00491
00492 while (it != end_it)
00493 {
00494 if (it->second.empty() == false)
00495 {
00496 erase_if_pred<Pred> p(prd, it);
00497
00498 ersd += it->second.erase_if(p);
00499 }
00500
00501 ++it;
00502 }
00503
00504 return (ersd);
00505 }
00506
00507 void
00508 clear()
00509 {
00510 typename my_base::iterator it = my_base::begin();
00511
00512 typename my_base::iterator end_it = my_base::end();
00513
00514 while (it != end_it)
00515 it->second.clear();
00516 }
00517
00518 inline const_iterator
00519 begin() const
00520 {
00521 typename my_base::const_iterator it = my_base::begin();
00522
00523 while (it != my_base::end()&& it->second.size() == 0)
00524 ++it;
00525
00526 if (it == my_base::end())
00527 return (end());
00528
00529 return (const_iterator(it, my_base::end(), it->second.begin()));
00530 }
00531
00532 inline iterator
00533 begin()
00534 {
00535 typename my_base::iterator it = my_base::begin();
00536
00537 while (it != my_base::end()&& it->second.size() == 0)
00538 ++it;
00539
00540 if (it == my_base::end())
00541 return (end());
00542
00543 return (iterator(it, my_base::end(), it->second.begin()));
00544 }
00545
00546 inline const_iterator
00547 end() const
00548 {
00549 return (const_iterator(my_base::end(), my_base::end()));
00550 }
00551
00552 inline iterator
00553 end()
00554 {
00555 return (iterator(my_base::end(), my_base::end()));
00556 }
00557
00558 protected:
00559
00560 virtual
00561 ~value_type_adapter()
00562 { }
00563
00564 #define PB_ASSOC_CLASS_NAME value_type_adapter
00565
00566 #define PB_ASSOC_DIRECT_BASE_C_DEC PB_ASSOC_BASE_C_DEC
00567
00568 #define PB_ASSOC_DIRECT_BASE_CAST_C_DEC \
00569 typename PB_ASSOC_DIRECT_BASE_C_DEC
00570
00571 #include <ext/pb_assoc/detail/constructors_destructor_fn_imps.hpp>
00572
00573 #undef PB_ASSOC_CLASS_NAME
00574
00575 #undef PB_ASSOC_DIRECT_BASE_C_DEC
00576
00577 #undef PB_ASSOC_DIRECT_BASE_CAST_C_DEC
00578
00579 data_reference
00580 subscript_imp(const_key_reference r_key)
00581 {
00582 return (my_base::subscript_imp(r_key.first)[r_key.second]);
00583 }
00584
00585 private:
00586 value_type_adapter&
00587 operator=(const value_type_adapter& r_other);
00588 };
00589
00590 #undef PB_ASSOC_CLASS_T_DEC
00591
00592 #undef PB_ASSOC_CLASS_C_DEC
00593
00594 #undef PB_ASSOC_BASE_C_DEC
00595
00596 }
00597
00598 }
00599
00600 #endif // #ifndef VALUE_TYPE_ADAPTER_HPP
00601