annotate DEPENDENCIES/generic/include/boost/pending/container_traits.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 // (C) Copyright Jeremy Siek 2004
Chris@16 2 // (C) Copyright Thomas Claveirole 2010
Chris@16 3 // (C) Copyright Ignacy Gawedzki 2010
Chris@16 4 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 5 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 #ifndef BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
Chris@16 9 #define BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
Chris@16 10
Chris@16 11 // Sure would be nice to be able to forward declare these
Chris@16 12 // instead of pulling in all the headers. Too bad that
Chris@16 13 // is not legal. There ought to be a standard <stlfwd> header. -JGS
Chris@16 14
Chris@16 15 #include <boost/next_prior.hpp>
Chris@16 16
Chris@16 17 #include <algorithm> // for std::remove
Chris@16 18 #include <vector>
Chris@16 19 #include <list>
Chris@16 20 #include <map>
Chris@16 21 #include <set>
Chris@16 22 #include <boost/unordered_set.hpp>
Chris@16 23 #include <boost/unordered_map.hpp>
Chris@16 24
Chris@16 25 #if !defined BOOST_NO_SLIST
Chris@16 26 # ifdef BOOST_SLIST_HEADER
Chris@16 27 # include BOOST_SLIST_HEADER
Chris@16 28 # else
Chris@16 29 # include <slist>
Chris@16 30 # endif
Chris@16 31 #endif
Chris@16 32
Chris@16 33 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
Chris@16 34 // Stay out of the way of concept checking class templates
Chris@16 35 # define Container Container_
Chris@16 36 # define AssociativeContainer AssociativeContainer_
Chris@16 37 #endif
Chris@16 38
Chris@16 39 // The content of this file is in 'graph_detail' because otherwise
Chris@16 40 // there will be name clashes with
Chris@16 41 // sandbox/boost/sequence_algo/container_traits.hpp
Chris@16 42 // The 'detail' subnamespace will still cause problems.
Chris@16 43 namespace boost { namespace graph_detail {
Chris@16 44
Chris@16 45 //======================================================================
Chris@16 46 // Container Category Tags
Chris@16 47 //
Chris@16 48 // They use virtual inheritance because there are lots of
Chris@16 49 // inheritance diamonds.
Chris@16 50
Chris@16 51 struct container_tag { };
Chris@16 52 struct forward_container_tag : virtual public container_tag { };
Chris@16 53 struct reversible_container_tag : virtual public forward_container_tag { };
Chris@16 54 struct random_access_container_tag
Chris@16 55 : virtual public reversible_container_tag { };
Chris@16 56
Chris@16 57 struct sequence_tag : virtual public forward_container_tag { };
Chris@16 58
Chris@16 59 struct associative_container_tag : virtual public forward_container_tag { };
Chris@16 60
Chris@16 61 struct sorted_associative_container_tag
Chris@16 62 : virtual public associative_container_tag,
Chris@16 63 virtual public reversible_container_tag { };
Chris@16 64
Chris@16 65 struct front_insertion_sequence_tag : virtual public sequence_tag { };
Chris@16 66 struct back_insertion_sequence_tag : virtual public sequence_tag { };
Chris@16 67
Chris@16 68 struct unique_associative_container_tag
Chris@16 69 : virtual public associative_container_tag { };
Chris@16 70 struct multiple_associative_container_tag
Chris@16 71 : virtual public associative_container_tag { };
Chris@16 72 struct simple_associative_container_tag
Chris@16 73 : virtual public associative_container_tag { };
Chris@16 74 struct pair_associative_container_tag
Chris@16 75 : virtual public associative_container_tag { };
Chris@16 76
Chris@16 77
Chris@16 78 //======================================================================
Chris@16 79 // Iterator Stability Tags
Chris@16 80 //
Chris@16 81 // Do mutating operations such as insert/erase/resize invalidate all
Chris@16 82 // outstanding iterators?
Chris@16 83
Chris@16 84 struct stable_tag { };
Chris@16 85 struct unstable_tag { };
Chris@16 86
Chris@16 87 //======================================================================
Chris@16 88 // Container Traits Class and container_category() function
Chris@16 89
Chris@16 90 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 91 // don't use this unless there is partial specialization
Chris@16 92 template <class Container>
Chris@16 93 struct container_traits {
Chris@16 94 typedef typename Container::category category;
Chris@16 95 typedef typename Container::iterator_stability iterator_stability;
Chris@16 96 };
Chris@16 97 #endif
Chris@16 98
Chris@16 99 // Use this as a compile-time assertion that X is stable
Chris@16 100 inline void require_stable(stable_tag) { }
Chris@16 101
Chris@16 102 // std::vector
Chris@16 103 struct vector_tag :
Chris@16 104 virtual public random_access_container_tag,
Chris@16 105 virtual public back_insertion_sequence_tag { };
Chris@16 106
Chris@16 107 template <class T, class Alloc>
Chris@16 108 vector_tag container_category(const std::vector<T,Alloc>&)
Chris@16 109 { return vector_tag(); }
Chris@16 110
Chris@16 111 template <class T, class Alloc>
Chris@16 112 unstable_tag iterator_stability(const std::vector<T,Alloc>&)
Chris@16 113 { return unstable_tag(); }
Chris@16 114
Chris@16 115 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 116 template <class T, class Alloc>
Chris@16 117 struct container_traits< std::vector<T,Alloc> > {
Chris@16 118 typedef vector_tag category;
Chris@16 119 typedef unstable_tag iterator_stability;
Chris@16 120 };
Chris@16 121 #endif
Chris@16 122
Chris@16 123 // std::list
Chris@16 124 struct list_tag :
Chris@16 125 virtual public reversible_container_tag,
Chris@16 126 virtual public back_insertion_sequence_tag
Chris@16 127 // this causes problems for push_dispatch...
Chris@16 128 // virtual public front_insertion_sequence_tag
Chris@16 129 { };
Chris@16 130
Chris@16 131 template <class T, class Alloc>
Chris@16 132 list_tag container_category(const std::list<T,Alloc>&)
Chris@16 133 { return list_tag(); }
Chris@16 134
Chris@16 135 template <class T, class Alloc>
Chris@16 136 stable_tag iterator_stability(const std::list<T,Alloc>&)
Chris@16 137 { return stable_tag(); }
Chris@16 138
Chris@16 139 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 140 template <class T, class Alloc>
Chris@16 141 struct container_traits< std::list<T,Alloc> > {
Chris@16 142 typedef list_tag category;
Chris@16 143 typedef stable_tag iterator_stability;
Chris@16 144 };
Chris@16 145 #endif
Chris@16 146
Chris@16 147
Chris@16 148 // std::slist
Chris@16 149 #ifndef BOOST_NO_SLIST
Chris@16 150 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 151 template <class T, class Alloc>
Chris@16 152 struct container_traits<BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc> > {
Chris@16 153 typedef front_insertion_sequence_tag category;
Chris@16 154 typedef stable_tag iterator_stability;
Chris@16 155 };
Chris@16 156 #endif
Chris@16 157 template <class T, class Alloc>
Chris@16 158 front_insertion_sequence_tag container_category(
Chris@16 159 const BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc>&
Chris@16 160 )
Chris@16 161 { return front_insertion_sequence_tag(); }
Chris@16 162
Chris@16 163 template <class T, class Alloc>
Chris@16 164 stable_tag iterator_stability(
Chris@16 165 const BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc>&)
Chris@16 166 { return stable_tag(); }
Chris@16 167 #endif
Chris@16 168
Chris@16 169
Chris@16 170 // std::set
Chris@16 171 struct set_tag :
Chris@16 172 virtual public sorted_associative_container_tag,
Chris@16 173 virtual public simple_associative_container_tag,
Chris@16 174 virtual public unique_associative_container_tag
Chris@16 175 { };
Chris@16 176
Chris@16 177 template <class Key, class Cmp, class Alloc>
Chris@16 178 set_tag container_category(const std::set<Key,Cmp,Alloc>&)
Chris@16 179 { return set_tag(); }
Chris@16 180
Chris@16 181 template <class Key, class Cmp, class Alloc>
Chris@16 182 stable_tag iterator_stability(const std::set<Key,Cmp,Alloc>&)
Chris@16 183 { return stable_tag(); }
Chris@16 184
Chris@16 185 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 186 template <class Key, class Cmp, class Alloc>
Chris@16 187 struct container_traits< std::set<Key,Cmp,Alloc> > {
Chris@16 188 typedef set_tag category;
Chris@16 189 typedef stable_tag iterator_stability;
Chris@16 190 };
Chris@16 191 #endif
Chris@16 192
Chris@16 193 // std::multiset
Chris@16 194 struct multiset_tag :
Chris@16 195 virtual public sorted_associative_container_tag,
Chris@16 196 virtual public simple_associative_container_tag,
Chris@16 197 virtual public multiple_associative_container_tag
Chris@16 198 { };
Chris@16 199
Chris@16 200 template <class Key, class Cmp, class Alloc>
Chris@16 201 multiset_tag container_category(const std::multiset<Key,Cmp,Alloc>&)
Chris@16 202 { return multiset_tag(); }
Chris@16 203
Chris@16 204 template <class Key, class Cmp, class Alloc>
Chris@16 205 stable_tag iterator_stability(const std::multiset<Key,Cmp,Alloc>&)
Chris@16 206 { return stable_tag(); }
Chris@16 207
Chris@16 208 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 209 template <class Key, class Cmp, class Alloc>
Chris@16 210 struct container_traits< std::multiset<Key,Cmp,Alloc> > {
Chris@16 211 typedef multiset_tag category;
Chris@16 212 typedef stable_tag iterator_stability;
Chris@16 213 };
Chris@16 214 #endif
Chris@16 215
Chris@16 216 // deque
Chris@16 217
Chris@16 218 // std::map
Chris@16 219 struct map_tag :
Chris@16 220 virtual public sorted_associative_container_tag,
Chris@16 221 virtual public pair_associative_container_tag,
Chris@16 222 virtual public unique_associative_container_tag
Chris@16 223 { };
Chris@16 224
Chris@16 225 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 226 template <class Key, class T, class Cmp, class Alloc>
Chris@16 227 struct container_traits< std::map<Key,T,Cmp,Alloc> > {
Chris@16 228 typedef map_tag category;
Chris@16 229 typedef stable_tag iterator_stability;
Chris@16 230 };
Chris@16 231 #endif
Chris@16 232
Chris@16 233 template <class Key, class T, class Cmp, class Alloc>
Chris@16 234 map_tag container_category(const std::map<Key,T,Cmp,Alloc>&)
Chris@16 235 { return map_tag(); }
Chris@16 236
Chris@16 237 template <class Key, class T, class Cmp, class Alloc>
Chris@16 238 stable_tag iterator_stability(const std::map<Key,T,Cmp,Alloc>&)
Chris@16 239 { return stable_tag(); }
Chris@16 240
Chris@16 241 // std::multimap
Chris@16 242 struct multimap_tag :
Chris@16 243 virtual public sorted_associative_container_tag,
Chris@16 244 virtual public pair_associative_container_tag,
Chris@16 245 virtual public multiple_associative_container_tag
Chris@16 246 { };
Chris@16 247
Chris@16 248 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 249 template <class Key, class T, class Cmp, class Alloc>
Chris@16 250 struct container_traits< std::multimap<Key,T,Cmp,Alloc> > {
Chris@16 251 typedef multimap_tag category;
Chris@16 252 typedef stable_tag iterator_stability;
Chris@16 253 };
Chris@16 254 #endif
Chris@16 255
Chris@16 256 template <class Key, class T, class Cmp, class Alloc>
Chris@16 257 multimap_tag container_category(const std::multimap<Key,T,Cmp,Alloc>&)
Chris@16 258 { return multimap_tag(); }
Chris@16 259
Chris@16 260 template <class Key, class T, class Cmp, class Alloc>
Chris@16 261 stable_tag iterator_stability(const std::multimap<Key,T,Cmp,Alloc>&)
Chris@16 262 { return stable_tag(); }
Chris@16 263
Chris@16 264
Chris@16 265 // hash_set, hash_map
Chris@16 266
Chris@16 267 struct unordered_set_tag :
Chris@16 268 virtual public simple_associative_container_tag,
Chris@16 269 virtual public unique_associative_container_tag
Chris@16 270 { };
Chris@16 271
Chris@16 272 struct unordered_multiset_tag :
Chris@16 273 virtual public simple_associative_container_tag,
Chris@16 274 virtual public multiple_associative_container_tag
Chris@16 275 { };
Chris@16 276
Chris@16 277
Chris@16 278 struct unordered_map_tag :
Chris@16 279 virtual public pair_associative_container_tag,
Chris@16 280 virtual public unique_associative_container_tag
Chris@16 281 { };
Chris@16 282
Chris@16 283 struct unordered_multimap_tag :
Chris@16 284 virtual public pair_associative_container_tag,
Chris@16 285 virtual public multiple_associative_container_tag
Chris@16 286 { };
Chris@16 287
Chris@16 288
Chris@16 289 #ifndef BOOST_NO_HASH
Chris@16 290 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Chris@16 291 template <class Key, class Eq, class Hash, class Alloc>
Chris@16 292 struct container_traits< boost::unordered_set<Key,Eq,Hash,Alloc> > {
Chris@16 293 typedef unordered_set_tag category;
Chris@16 294 typedef unstable_tag iterator_stability;
Chris@16 295 };
Chris@16 296 template <class Key, class T, class Eq, class Hash, class Alloc>
Chris@16 297 struct container_traits< boost::unordered_map<Key,T,Eq,Hash,Alloc> > {
Chris@16 298 typedef unordered_map_tag category;
Chris@16 299 typedef unstable_tag iterator_stability;
Chris@16 300 };
Chris@16 301 template <class Key, class Eq, class Hash, class Alloc>
Chris@16 302 struct container_traits< boost::unordered_multiset<Key,Eq,Hash,Alloc> > {
Chris@16 303 typedef unordered_multiset_tag category;
Chris@16 304 typedef unstable_tag iterator_stability;
Chris@16 305 };
Chris@16 306 template <class Key, class T, class Eq, class Hash, class Alloc>
Chris@16 307 struct container_traits< boost::unordered_multimap<Key,T,Eq,Hash,Alloc> > {
Chris@16 308 typedef unordered_multimap_tag category;
Chris@16 309 typedef unstable_tag iterator_stability;
Chris@16 310 };
Chris@16 311 #endif
Chris@16 312 template <class Key, class Eq, class Hash, class Alloc>
Chris@16 313 unordered_set_tag
Chris@16 314 container_category(const boost::unordered_set<Key,Eq,Hash,Alloc>&)
Chris@16 315 { return unordered_set_tag(); }
Chris@16 316
Chris@16 317 template <class Key, class T, class Eq, class Hash, class Alloc>
Chris@16 318 unordered_map_tag
Chris@16 319 container_category(const boost::unordered_map<Key,T,Eq,Hash,Alloc>&)
Chris@16 320 { return unordered_map_tag(); }
Chris@16 321
Chris@16 322 template <class Key, class Eq, class Hash, class Alloc>
Chris@16 323 unstable_tag iterator_stability(const boost::unordered_set<Key,Eq,Hash,Alloc>&)
Chris@16 324 { return unstable_tag(); }
Chris@16 325
Chris@16 326 template <class Key, class T, class Eq, class Hash, class Alloc>
Chris@16 327 unstable_tag iterator_stability(const boost::unordered_map<Key,T,Eq,Hash,Alloc>&)
Chris@16 328 { return unstable_tag(); }
Chris@16 329 template <class Key, class Eq, class Hash, class Alloc>
Chris@16 330 unordered_multiset_tag
Chris@16 331 container_category(const boost::unordered_multiset<Key,Eq,Hash,Alloc>&)
Chris@16 332 { return unordered_multiset_tag(); }
Chris@16 333
Chris@16 334 template <class Key, class T, class Eq, class Hash, class Alloc>
Chris@16 335 unordered_multimap_tag
Chris@16 336 container_category(const boost::unordered_multimap<Key,T,Eq,Hash,Alloc>&)
Chris@16 337 { return unordered_multimap_tag(); }
Chris@16 338
Chris@16 339 template <class Key, class Eq, class Hash, class Alloc>
Chris@16 340 unstable_tag
Chris@16 341 iterator_stability(const boost::unordered_multiset<Key,Eq,Hash,Alloc>&)
Chris@16 342 { return unstable_tag(); }
Chris@16 343
Chris@16 344 template <class Key, class T, class Eq, class Hash, class Alloc>
Chris@16 345 unstable_tag
Chris@16 346 iterator_stability(const boost::unordered_multimap<Key,T,Eq,Hash,Alloc>&)
Chris@16 347 { return unstable_tag(); }
Chris@16 348 #endif
Chris@16 349
Chris@16 350
Chris@16 351
Chris@16 352 //===========================================================================
Chris@16 353 // Generalized Container Functions
Chris@16 354
Chris@16 355
Chris@16 356 // Erase
Chris@16 357 template <class Sequence, class T>
Chris@16 358 void erase_dispatch(Sequence& c, const T& x,
Chris@16 359 sequence_tag)
Chris@16 360 {
Chris@16 361 c.erase(std::remove(c.begin(), c.end(), x), c.end());
Chris@16 362 }
Chris@16 363
Chris@16 364 template <class AssociativeContainer, class T>
Chris@16 365 void erase_dispatch(AssociativeContainer& c, const T& x,
Chris@16 366 associative_container_tag)
Chris@16 367 {
Chris@16 368 c.erase(x);
Chris@16 369 }
Chris@16 370 template <class Container, class T>
Chris@16 371 void erase(Container& c, const T& x)
Chris@16 372 {
Chris@16 373 erase_dispatch(c, x, container_category(c));
Chris@16 374 }
Chris@16 375
Chris@16 376 // Erase If
Chris@16 377 template <class Sequence, class Predicate, class IteratorStability>
Chris@16 378 void erase_if_dispatch(Sequence& c, Predicate p,
Chris@16 379 sequence_tag, IteratorStability)
Chris@16 380 {
Chris@16 381 #if 0
Chris@16 382 c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
Chris@16 383 #else
Chris@16 384 if (! c.empty())
Chris@16 385 c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
Chris@16 386 #endif
Chris@16 387 }
Chris@16 388 template <class AssociativeContainer, class Predicate>
Chris@16 389 void erase_if_dispatch(AssociativeContainer& c, Predicate p,
Chris@16 390 associative_container_tag, stable_tag)
Chris@16 391 {
Chris@16 392 typename AssociativeContainer::iterator i, next;
Chris@16 393 for (i = next = c.begin(); next != c.end(); i = next) {
Chris@16 394 ++next;
Chris@16 395 if (p(*i))
Chris@16 396 c.erase(i);
Chris@16 397 }
Chris@16 398 }
Chris@16 399 template <class AssociativeContainer, class Predicate>
Chris@16 400 void erase_if_dispatch(AssociativeContainer& c, Predicate p,
Chris@16 401 associative_container_tag, unstable_tag)
Chris@16 402 {
Chris@16 403 // This method is really slow, so hopefully we won't have any
Chris@16 404 // associative containers with unstable iterators!
Chris@16 405 // Is there a better way to do this?
Chris@16 406 typename AssociativeContainer::iterator i;
Chris@16 407 typename AssociativeContainer::size_type n = c.size();
Chris@16 408 while (n--)
Chris@16 409 for (i = c.begin(); i != c.end(); ++i)
Chris@16 410 if (p(*i)) {
Chris@16 411 c.erase(i);
Chris@16 412 break;
Chris@16 413 }
Chris@16 414 }
Chris@16 415 template <class Container, class Predicate>
Chris@16 416 void erase_if(Container& c, Predicate p)
Chris@16 417 {
Chris@16 418 erase_if_dispatch(c, p, container_category(c), iterator_stability(c));
Chris@16 419 }
Chris@16 420
Chris@16 421 // Push
Chris@16 422 template <class Container, class T>
Chris@16 423 std::pair<typename Container::iterator, bool>
Chris@16 424 push_dispatch(Container& c, const T& v, back_insertion_sequence_tag)
Chris@16 425 {
Chris@16 426 c.push_back(v);
Chris@16 427 return std::make_pair(boost::prior(c.end()), true);
Chris@16 428 }
Chris@16 429
Chris@16 430 template <class Container, class T>
Chris@16 431 std::pair<typename Container::iterator, bool>
Chris@16 432 push_dispatch(Container& c, const T& v, front_insertion_sequence_tag)
Chris@16 433 {
Chris@16 434 c.push_front(v);
Chris@16 435 return std::make_pair(c.begin(), true);
Chris@16 436 }
Chris@16 437
Chris@16 438 template <class AssociativeContainer, class T>
Chris@16 439 std::pair<typename AssociativeContainer::iterator, bool>
Chris@16 440 push_dispatch(AssociativeContainer& c, const T& v,
Chris@16 441 unique_associative_container_tag)
Chris@16 442 {
Chris@16 443 return c.insert(v);
Chris@16 444 }
Chris@16 445
Chris@16 446 template <class AssociativeContainer, class T>
Chris@16 447 std::pair<typename AssociativeContainer::iterator, bool>
Chris@16 448 push_dispatch(AssociativeContainer& c, const T& v,
Chris@16 449 multiple_associative_container_tag)
Chris@16 450 {
Chris@16 451 return std::make_pair(c.insert(v), true);
Chris@16 452 }
Chris@16 453
Chris@16 454 template <class Container, class T>
Chris@16 455 std::pair<typename Container::iterator,bool>
Chris@16 456 push(Container& c, const T& v)
Chris@16 457 {
Chris@16 458 return push_dispatch(c, v, container_category(c));
Chris@16 459 }
Chris@16 460
Chris@16 461 // Find
Chris@16 462 template <class Container, class Value>
Chris@16 463 typename Container::iterator
Chris@16 464 find_dispatch(Container& c,
Chris@16 465 const Value& value,
Chris@16 466 container_tag)
Chris@16 467 {
Chris@16 468 return std::find(c.begin(), c.end(), value);
Chris@16 469 }
Chris@16 470
Chris@16 471 template <class AssociativeContainer, class Value>
Chris@16 472 typename AssociativeContainer::iterator
Chris@16 473 find_dispatch(AssociativeContainer& c,
Chris@16 474 const Value& value,
Chris@16 475 associative_container_tag)
Chris@16 476 {
Chris@16 477 return c.find(value);
Chris@16 478 }
Chris@16 479
Chris@16 480 template <class Container, class Value>
Chris@16 481 typename Container::iterator
Chris@16 482 find(Container& c,
Chris@16 483 const Value& value)
Chris@16 484 {
Chris@16 485 return find_dispatch(c, value,
Chris@16 486 graph_detail::container_category(c));
Chris@16 487 }
Chris@16 488
Chris@16 489 // Find (const versions)
Chris@16 490 template <class Container, class Value>
Chris@16 491 typename Container::const_iterator
Chris@16 492 find_dispatch(const Container& c,
Chris@16 493 const Value& value,
Chris@16 494 container_tag)
Chris@16 495 {
Chris@16 496 return std::find(c.begin(), c.end(), value);
Chris@16 497 }
Chris@16 498
Chris@16 499 template <class AssociativeContainer, class Value>
Chris@16 500 typename AssociativeContainer::const_iterator
Chris@16 501 find_dispatch(const AssociativeContainer& c,
Chris@16 502 const Value& value,
Chris@16 503 associative_container_tag)
Chris@16 504 {
Chris@16 505 return c.find(value);
Chris@16 506 }
Chris@16 507
Chris@16 508 template <class Container, class Value>
Chris@16 509 typename Container::const_iterator
Chris@16 510 find(const Container& c,
Chris@16 511 const Value& value)
Chris@16 512 {
Chris@16 513 return find_dispatch(c, value,
Chris@16 514 graph_detail::container_category(c));
Chris@16 515 }
Chris@16 516
Chris@16 517 // Equal range
Chris@16 518 #if 0
Chris@16 519 // Make the dispatch fail if c is not an Associative Container (and thus
Chris@16 520 // doesn't have equal_range unless it is sorted, which we cannot check
Chris@16 521 // statically and is not typically true for BGL's uses of this function).
Chris@16 522 template <class Container,
Chris@16 523 class LessThanComparable>
Chris@16 524 std::pair<typename Container::iterator, typename Container::iterator>
Chris@16 525 equal_range_dispatch(Container& c,
Chris@16 526 const LessThanComparable& value,
Chris@16 527 container_tag)
Chris@16 528 {
Chris@16 529 // c must be sorted for std::equal_range to behave properly.
Chris@16 530 return std::equal_range(c.begin(), c.end(), value);
Chris@16 531 }
Chris@16 532 #endif
Chris@16 533
Chris@16 534 template <class AssociativeContainer, class Value>
Chris@16 535 std::pair<typename AssociativeContainer::iterator,
Chris@16 536 typename AssociativeContainer::iterator>
Chris@16 537 equal_range_dispatch(AssociativeContainer& c,
Chris@16 538 const Value& value,
Chris@16 539 associative_container_tag)
Chris@16 540 {
Chris@16 541 return c.equal_range(value);
Chris@16 542 }
Chris@16 543
Chris@16 544 template <class Container, class Value>
Chris@16 545 std::pair<typename Container::iterator, typename Container::iterator>
Chris@16 546 equal_range(Container& c,
Chris@16 547 const Value& value)
Chris@16 548 {
Chris@16 549 return equal_range_dispatch(c, value,
Chris@16 550 graph_detail::container_category(c));
Chris@16 551 }
Chris@16 552
Chris@16 553 }} // namespace boost::graph_detail
Chris@16 554
Chris@16 555 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
Chris@16 556 // Stay out of the way of concept checking class templates
Chris@16 557 # undef Container
Chris@16 558 # undef AssociativeContainer
Chris@16 559 #endif
Chris@16 560
Chris@16 561 #endif // BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H