File indexing completed on 2025-01-18 09:43:31
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
0009 #define BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
0010
0011
0012
0013
0014
0015 #include <boost/next_prior.hpp>
0016
0017 #include <algorithm> // for std::remove
0018 #include <utility>
0019 #include <vector>
0020 #include <list>
0021 #include <map>
0022 #include <set>
0023 #include <boost/unordered_set.hpp>
0024 #include <boost/unordered_map.hpp>
0025
0026 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET
0027 #include <unordered_set>
0028 #endif
0029
0030 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP
0031 #include <unordered_map>
0032 #endif
0033
0034 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0035 #define BOOST_PENDING_FWD_TYPE(type) const type&
0036 #define BOOST_PENDING_FWD_VALUE(type, var) (var)
0037 #else
0038 #define BOOST_PENDING_FWD_TYPE(type) type&&
0039 #define BOOST_PENDING_FWD_VALUE(type, var) (std::forward< type >((var)))
0040 #endif
0041
0042
0043
0044
0045
0046 namespace boost
0047 {
0048 namespace graph_detail
0049 {
0050
0051
0052
0053
0054
0055
0056
0057 struct container_tag
0058 {
0059 };
0060 struct forward_container_tag : virtual public container_tag
0061 {
0062 };
0063 struct reversible_container_tag : virtual public forward_container_tag
0064 {
0065 };
0066 struct random_access_container_tag : virtual public reversible_container_tag
0067 {
0068 };
0069
0070 struct sequence_tag : virtual public forward_container_tag
0071 {
0072 };
0073
0074 struct associative_container_tag : virtual public forward_container_tag
0075 {
0076 };
0077
0078 struct sorted_associative_container_tag
0079 : virtual public associative_container_tag,
0080 virtual public reversible_container_tag
0081 {
0082 };
0083
0084 struct front_insertion_sequence_tag : virtual public sequence_tag
0085 {
0086 };
0087 struct back_insertion_sequence_tag : virtual public sequence_tag
0088 {
0089 };
0090
0091 struct unique_associative_container_tag
0092 : virtual public associative_container_tag
0093 {
0094 };
0095 struct multiple_associative_container_tag
0096 : virtual public associative_container_tag
0097 {
0098 };
0099 struct simple_associative_container_tag
0100 : virtual public associative_container_tag
0101 {
0102 };
0103 struct pair_associative_container_tag
0104 : virtual public associative_container_tag
0105 {
0106 };
0107
0108
0109
0110
0111
0112
0113
0114 struct stable_tag
0115 {
0116 };
0117 struct unstable_tag
0118 {
0119 };
0120
0121
0122
0123
0124
0125 template < class Container > struct container_traits
0126 {
0127 typedef typename Container::category category;
0128 typedef typename Container::iterator_stability iterator_stability;
0129 };
0130
0131
0132 inline void require_stable(stable_tag) {}
0133
0134
0135 struct vector_tag : virtual public random_access_container_tag,
0136 virtual public back_insertion_sequence_tag
0137 {
0138 };
0139
0140 template < class T, class Alloc >
0141 vector_tag container_category(const std::vector< T, Alloc >&)
0142 {
0143 return vector_tag();
0144 }
0145
0146 template < class T, class Alloc >
0147 unstable_tag iterator_stability(const std::vector< T, Alloc >&)
0148 {
0149 return unstable_tag();
0150 }
0151
0152 template < class T, class Alloc >
0153 struct container_traits< std::vector< T, Alloc > >
0154 {
0155 typedef vector_tag category;
0156 typedef unstable_tag iterator_stability;
0157 };
0158
0159
0160 struct list_tag : virtual public reversible_container_tag,
0161 virtual public back_insertion_sequence_tag
0162
0163
0164 {
0165 };
0166
0167 template < class T, class Alloc >
0168 list_tag container_category(const std::list< T, Alloc >&)
0169 {
0170 return list_tag();
0171 }
0172
0173 template < class T, class Alloc >
0174 stable_tag iterator_stability(const std::list< T, Alloc >&)
0175 {
0176 return stable_tag();
0177 }
0178
0179 template < class T, class Alloc >
0180 struct container_traits< std::list< T, Alloc > >
0181 {
0182 typedef list_tag category;
0183 typedef stable_tag iterator_stability;
0184 };
0185
0186
0187 struct set_tag : virtual public sorted_associative_container_tag,
0188 virtual public simple_associative_container_tag,
0189 virtual public unique_associative_container_tag
0190 {
0191 };
0192
0193 template < class Key, class Cmp, class Alloc >
0194 set_tag container_category(const std::set< Key, Cmp, Alloc >&)
0195 {
0196 return set_tag();
0197 }
0198
0199 template < class Key, class Cmp, class Alloc >
0200 stable_tag iterator_stability(const std::set< Key, Cmp, Alloc >&)
0201 {
0202 return stable_tag();
0203 }
0204
0205 template < class Key, class Cmp, class Alloc >
0206 struct container_traits< std::set< Key, Cmp, Alloc > >
0207 {
0208 typedef set_tag category;
0209 typedef stable_tag iterator_stability;
0210 };
0211
0212
0213 struct multiset_tag : virtual public sorted_associative_container_tag,
0214 virtual public simple_associative_container_tag,
0215 virtual public multiple_associative_container_tag
0216 {
0217 };
0218
0219 template < class Key, class Cmp, class Alloc >
0220 multiset_tag container_category(const std::multiset< Key, Cmp, Alloc >&)
0221 {
0222 return multiset_tag();
0223 }
0224
0225 template < class Key, class Cmp, class Alloc >
0226 stable_tag iterator_stability(const std::multiset< Key, Cmp, Alloc >&)
0227 {
0228 return stable_tag();
0229 }
0230
0231 template < class Key, class Cmp, class Alloc >
0232 struct container_traits< std::multiset< Key, Cmp, Alloc > >
0233 {
0234 typedef multiset_tag category;
0235 typedef stable_tag iterator_stability;
0236 };
0237
0238
0239
0240
0241 struct map_tag : virtual public sorted_associative_container_tag,
0242 virtual public pair_associative_container_tag,
0243 virtual public unique_associative_container_tag
0244 {
0245 };
0246
0247 template < class Key, class T, class Cmp, class Alloc >
0248 struct container_traits< std::map< Key, T, Cmp, Alloc > >
0249 {
0250 typedef map_tag category;
0251 typedef stable_tag iterator_stability;
0252 };
0253
0254 template < class Key, class T, class Cmp, class Alloc >
0255 map_tag container_category(const std::map< Key, T, Cmp, Alloc >&)
0256 {
0257 return map_tag();
0258 }
0259
0260 template < class Key, class T, class Cmp, class Alloc >
0261 stable_tag iterator_stability(const std::map< Key, T, Cmp, Alloc >&)
0262 {
0263 return stable_tag();
0264 }
0265
0266
0267 struct multimap_tag : virtual public sorted_associative_container_tag,
0268 virtual public pair_associative_container_tag,
0269 virtual public multiple_associative_container_tag
0270 {
0271 };
0272
0273 template < class Key, class T, class Cmp, class Alloc >
0274 struct container_traits< std::multimap< Key, T, Cmp, Alloc > >
0275 {
0276 typedef multimap_tag category;
0277 typedef stable_tag iterator_stability;
0278 };
0279
0280 template < class Key, class T, class Cmp, class Alloc >
0281 multimap_tag container_category(const std::multimap< Key, T, Cmp, Alloc >&)
0282 {
0283 return multimap_tag();
0284 }
0285
0286 template < class Key, class T, class Cmp, class Alloc >
0287 stable_tag iterator_stability(const std::multimap< Key, T, Cmp, Alloc >&)
0288 {
0289 return stable_tag();
0290 }
0291
0292
0293
0294 struct unordered_set_tag : virtual public simple_associative_container_tag,
0295 virtual public unique_associative_container_tag
0296 {
0297 };
0298
0299 struct unordered_multiset_tag
0300 : virtual public simple_associative_container_tag,
0301 virtual public multiple_associative_container_tag
0302 {
0303 };
0304
0305 struct unordered_map_tag : virtual public pair_associative_container_tag,
0306 virtual public unique_associative_container_tag
0307 {
0308 };
0309
0310 struct unordered_multimap_tag
0311 : virtual public pair_associative_container_tag,
0312 virtual public multiple_associative_container_tag
0313 {
0314 };
0315
0316 template < class Key, class Eq, class Hash, class Alloc >
0317 struct container_traits< boost::unordered_set< Key, Eq, Hash, Alloc > >
0318 {
0319 typedef unordered_set_tag category;
0320 typedef unstable_tag iterator_stability;
0321 };
0322 template < class Key, class T, class Eq, class Hash, class Alloc >
0323 struct container_traits< boost::unordered_map< Key, T, Eq, Hash, Alloc > >
0324 {
0325 typedef unordered_map_tag category;
0326 typedef unstable_tag iterator_stability;
0327 };
0328 template < class Key, class Eq, class Hash, class Alloc >
0329 struct container_traits< boost::unordered_multiset< Key, Eq, Hash, Alloc > >
0330 {
0331 typedef unordered_multiset_tag category;
0332 typedef unstable_tag iterator_stability;
0333 };
0334 template < class Key, class T, class Eq, class Hash, class Alloc >
0335 struct container_traits<
0336 boost::unordered_multimap< Key, T, Eq, Hash, Alloc > >
0337 {
0338 typedef unordered_multimap_tag category;
0339 typedef unstable_tag iterator_stability;
0340 };
0341
0342 template < class Key, class Eq, class Hash, class Alloc >
0343 unordered_set_tag container_category(
0344 const boost::unordered_set< Key, Eq, Hash, Alloc >&)
0345 {
0346 return unordered_set_tag();
0347 }
0348
0349 template < class Key, class T, class Eq, class Hash, class Alloc >
0350 unordered_map_tag container_category(
0351 const boost::unordered_map< Key, T, Eq, Hash, Alloc >&)
0352 {
0353 return unordered_map_tag();
0354 }
0355
0356 template < class Key, class Eq, class Hash, class Alloc >
0357 unstable_tag iterator_stability(
0358 const boost::unordered_set< Key, Eq, Hash, Alloc >&)
0359 {
0360 return unstable_tag();
0361 }
0362
0363 template < class Key, class T, class Eq, class Hash, class Alloc >
0364 unstable_tag iterator_stability(
0365 const boost::unordered_map< Key, T, Eq, Hash, Alloc >&)
0366 {
0367 return unstable_tag();
0368 }
0369 template < class Key, class Eq, class Hash, class Alloc >
0370 unordered_multiset_tag container_category(
0371 const boost::unordered_multiset< Key, Eq, Hash, Alloc >&)
0372 {
0373 return unordered_multiset_tag();
0374 }
0375
0376 template < class Key, class T, class Eq, class Hash, class Alloc >
0377 unordered_multimap_tag container_category(
0378 const boost::unordered_multimap< Key, T, Eq, Hash, Alloc >&)
0379 {
0380 return unordered_multimap_tag();
0381 }
0382
0383 template < class Key, class Eq, class Hash, class Alloc >
0384 unstable_tag iterator_stability(
0385 const boost::unordered_multiset< Key, Eq, Hash, Alloc >&)
0386 {
0387 return unstable_tag();
0388 }
0389
0390 template < class Key, class T, class Eq, class Hash, class Alloc >
0391 unstable_tag iterator_stability(
0392 const boost::unordered_multimap< Key, T, Eq, Hash, Alloc >&)
0393 {
0394 return unstable_tag();
0395 }
0396
0397 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET
0398 template < class Key, class Eq, class Hash, class Alloc >
0399 struct container_traits< std::unordered_set< Key, Eq, Hash, Alloc > >
0400 {
0401 typedef unordered_set_tag category;
0402 typedef unstable_tag iterator_stability;
0403 };
0404 #endif
0405 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP
0406 template < class Key, class T, class Eq, class Hash, class Alloc >
0407 struct container_traits< std::unordered_map< Key, T, Eq, Hash, Alloc > >
0408 {
0409 typedef unordered_map_tag category;
0410 typedef unstable_tag iterator_stability;
0411 };
0412 #endif
0413 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET
0414 template < class Key, class Eq, class Hash, class Alloc >
0415 struct container_traits< std::unordered_multiset< Key, Eq, Hash, Alloc > >
0416 {
0417 typedef unordered_multiset_tag category;
0418 typedef unstable_tag iterator_stability;
0419 };
0420 #endif
0421 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP
0422 template < class Key, class T, class Eq, class Hash, class Alloc >
0423 struct container_traits<
0424 std::unordered_multimap< Key, T, Eq, Hash, Alloc > >
0425 {
0426 typedef unordered_multimap_tag category;
0427 typedef unstable_tag iterator_stability;
0428 };
0429 #endif
0430 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET
0431 template < class Key, class Eq, class Hash, class Alloc >
0432 unordered_set_tag container_category(
0433 const std::unordered_set< Key, Eq, Hash, Alloc >&)
0434 {
0435 return unordered_set_tag();
0436 }
0437 #endif
0438
0439 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP
0440 template < class Key, class T, class Eq, class Hash, class Alloc >
0441 unordered_map_tag container_category(
0442 const std::unordered_map< Key, T, Eq, Hash, Alloc >&)
0443 {
0444 return unordered_map_tag();
0445 }
0446 #endif
0447
0448 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET
0449 template < class Key, class Eq, class Hash, class Alloc >
0450 unstable_tag iterator_stability(
0451 const std::unordered_set< Key, Eq, Hash, Alloc >&)
0452 {
0453 return unstable_tag();
0454 }
0455 #endif
0456
0457 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP
0458 template < class Key, class T, class Eq, class Hash, class Alloc >
0459 unstable_tag iterator_stability(
0460 const std::unordered_map< Key, T, Eq, Hash, Alloc >&)
0461 {
0462 return unstable_tag();
0463 }
0464 #endif
0465 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET
0466 template < class Key, class Eq, class Hash, class Alloc >
0467 unordered_multiset_tag container_category(
0468 const std::unordered_multiset< Key, Eq, Hash, Alloc >&)
0469 {
0470 return unordered_multiset_tag();
0471 }
0472 #endif
0473
0474 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP
0475 template < class Key, class T, class Eq, class Hash, class Alloc >
0476 unordered_multimap_tag container_category(
0477 const std::unordered_multimap< Key, T, Eq, Hash, Alloc >&)
0478 {
0479 return unordered_multimap_tag();
0480 }
0481 #endif
0482
0483 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET
0484 template < class Key, class Eq, class Hash, class Alloc >
0485 unstable_tag iterator_stability(
0486 const std::unordered_multiset< Key, Eq, Hash, Alloc >&)
0487 {
0488 return unstable_tag();
0489 }
0490 #endif
0491
0492 #ifndef BOOST_NO_CXX11_HDR_UNORDERED_MAP
0493 template < class Key, class T, class Eq, class Hash, class Alloc >
0494 unstable_tag iterator_stability(
0495 const std::unordered_multimap< Key, T, Eq, Hash, Alloc >&)
0496 {
0497 return unstable_tag();
0498 }
0499 #endif
0500
0501
0502
0503
0504
0505 template < class Sequence, class T >
0506 void erase_dispatch(Sequence& c, const T& x, sequence_tag)
0507 {
0508 c.erase(std::remove(c.begin(), c.end(), x), c.end());
0509 }
0510
0511 template < class AssociativeContainer, class T >
0512 void erase_dispatch(
0513 AssociativeContainer& c, const T& x, associative_container_tag)
0514 {
0515 c.erase(x);
0516 }
0517 template < class Container, class T > void erase(Container& c, const T& x)
0518 {
0519 erase_dispatch(c, x, container_category(c));
0520 }
0521
0522
0523 template < class Sequence, class Predicate, class IteratorStability >
0524 void erase_if_dispatch(
0525 Sequence& c, Predicate p, sequence_tag, IteratorStability)
0526 {
0527 #if 0
0528 c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
0529 #else
0530 if (!c.empty())
0531 c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
0532 #endif
0533 }
0534 template < class AssociativeContainer, class Predicate >
0535 void erase_if_dispatch(AssociativeContainer& c, Predicate p,
0536 associative_container_tag, stable_tag)
0537 {
0538 typename AssociativeContainer::iterator i, next;
0539 for (i = next = c.begin(); next != c.end(); i = next)
0540 {
0541 ++next;
0542 if (p(*i))
0543 c.erase(i);
0544 }
0545 }
0546 template < class AssociativeContainer, class Predicate >
0547 void erase_if_dispatch(AssociativeContainer& c, Predicate p,
0548 associative_container_tag, unstable_tag)
0549 {
0550
0551
0552
0553 typename AssociativeContainer::iterator i;
0554 typename AssociativeContainer::size_type n = c.size();
0555 while (n--)
0556 for (i = c.begin(); i != c.end(); ++i)
0557 if (p(*i))
0558 {
0559 c.erase(i);
0560 break;
0561 }
0562 }
0563 template < class Container, class Predicate >
0564 void erase_if(Container& c, Predicate p)
0565 {
0566 erase_if_dispatch(c, p, container_category(c), iterator_stability(c));
0567 }
0568
0569
0570 template < class Container, class T >
0571 std::pair< typename Container::iterator, bool > push_dispatch(
0572 Container& c, BOOST_PENDING_FWD_TYPE(T) v, back_insertion_sequence_tag)
0573 {
0574 c.push_back(BOOST_PENDING_FWD_VALUE(T, v));
0575 return std::make_pair(boost::prior(c.end()), true);
0576 }
0577
0578 template < class Container, class T >
0579 std::pair< typename Container::iterator, bool > push_dispatch(
0580 Container& c, BOOST_PENDING_FWD_TYPE(T) v, front_insertion_sequence_tag)
0581 {
0582 c.push_front(BOOST_PENDING_FWD_VALUE(T, v));
0583 return std::make_pair(c.begin(), true);
0584 }
0585
0586 template < class AssociativeContainer, class T >
0587 std::pair< typename AssociativeContainer::iterator, bool > push_dispatch(
0588 AssociativeContainer& c, BOOST_PENDING_FWD_TYPE(T) v,
0589 unique_associative_container_tag)
0590 {
0591 return c.insert(BOOST_PENDING_FWD_VALUE(T, v));
0592 }
0593
0594 template < class AssociativeContainer, class T >
0595 std::pair< typename AssociativeContainer::iterator, bool > push_dispatch(
0596 AssociativeContainer& c, BOOST_PENDING_FWD_TYPE(T) v,
0597 multiple_associative_container_tag)
0598 {
0599 return std::make_pair(c.insert(BOOST_PENDING_FWD_VALUE(T, v)), true);
0600 }
0601
0602 template < class Container, class T >
0603 std::pair< typename Container::iterator, bool > push(
0604 Container& c, BOOST_PENDING_FWD_TYPE(T) v)
0605 {
0606 return push_dispatch(
0607 c, BOOST_PENDING_FWD_VALUE(T, v), container_category(c));
0608 }
0609
0610
0611 template < class Container, class Value >
0612 typename Container::iterator find_dispatch(
0613 Container& c, const Value& value, container_tag)
0614 {
0615 return std::find(c.begin(), c.end(), value);
0616 }
0617
0618 template < class AssociativeContainer, class Value >
0619 typename AssociativeContainer::iterator find_dispatch(
0620 AssociativeContainer& c, const Value& value, associative_container_tag)
0621 {
0622 return c.find(value);
0623 }
0624
0625 template < class Container, class Value >
0626 typename Container::iterator find(Container& c, const Value& value)
0627 {
0628 return find_dispatch(c, value, graph_detail::container_category(c));
0629 }
0630
0631
0632 template < class Container, class Value >
0633 typename Container::const_iterator find_dispatch(
0634 const Container& c, const Value& value, container_tag)
0635 {
0636 return std::find(c.begin(), c.end(), value);
0637 }
0638
0639 template < class AssociativeContainer, class Value >
0640 typename AssociativeContainer::const_iterator find_dispatch(
0641 const AssociativeContainer& c, const Value& value,
0642 associative_container_tag)
0643 {
0644 return c.find(value);
0645 }
0646
0647 template < class Container, class Value >
0648 typename Container::const_iterator find(
0649 const Container& c, const Value& value)
0650 {
0651 return find_dispatch(c, value, graph_detail::container_category(c));
0652 }
0653
0654
0655 #if 0
0656
0657
0658
0659 template <class Container,
0660 class LessThanComparable>
0661 std::pair<typename Container::iterator, typename Container::iterator>
0662 equal_range_dispatch(Container& c,
0663 const LessThanComparable& value,
0664 container_tag)
0665 {
0666
0667 return std::equal_range(c.begin(), c.end(), value);
0668 }
0669 #endif
0670
0671 template < class AssociativeContainer, class Value >
0672 std::pair< typename AssociativeContainer::iterator,
0673 typename AssociativeContainer::iterator >
0674 equal_range_dispatch(
0675 AssociativeContainer& c, const Value& value, associative_container_tag)
0676 {
0677 return c.equal_range(value);
0678 }
0679
0680 template < class Container, class Value >
0681 std::pair< typename Container::iterator, typename Container::iterator >
0682 equal_range(Container& c, const Value& value)
0683 {
0684 return equal_range_dispatch(
0685 c, value, graph_detail::container_category(c));
0686 }
0687
0688 }
0689 }
0690
0691 #undef BOOST_PENDING_FWD_TYPE
0692 #undef BOOST_PENDING_FWD_VALUE
0693
0694 #endif