bucket_sorter.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. //=======================================================================
  3. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  4. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //=======================================================================
  10. //
  11. //
  12. // Revision History:
  13. // 13 June 2001: Changed some names for clarity. (Jeremy Siek)
  14. // 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
  15. //
  16. #ifndef BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP
  17. #define BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP
  18. #include <vector>
  19. #include <cassert>
  20. #include <boost/limits.hpp>
  21. #include <boost/concept/assert.hpp>
  22. #include <boost/property_map/property_map.hpp>
  23. namespace boost {
  24. template <class BucketType, class ValueType, class Bucket,
  25. class ValueIndexMap>
  26. class bucket_sorter {
  27. BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<ValueIndexMap, ValueType> ));
  28. public:
  29. typedef BucketType bucket_type;
  30. typedef ValueType value_type;
  31. typedef typename std::vector<value_type>::size_type size_type;
  32. bucket_sorter(size_type _length, bucket_type _max_bucket,
  33. const Bucket& _bucket = Bucket(),
  34. const ValueIndexMap& _id = ValueIndexMap())
  35. : head(_max_bucket, invalid_value()),
  36. next(_length, invalid_value()),
  37. prev(_length, invalid_value()),
  38. id_to_value(_length),
  39. bucket(_bucket), id(_id) { }
  40. void remove(const value_type& x) {
  41. const size_type i = get(id, x);
  42. const size_type& next_node = next[i];
  43. const size_type& prev_node = prev[i];
  44. //check if i is the end of the bucket list
  45. if ( next_node != invalid_value() )
  46. prev[next_node] = prev_node;
  47. //check if i is the begin of the bucket list
  48. if ( prev_node != invalid_value() )
  49. next[prev_node] = next_node;
  50. else //need update head of current bucket list
  51. head[ bucket[x] ] = next_node;
  52. }
  53. void push(const value_type& x) {
  54. id_to_value[get(id, x)] = x;
  55. (*this)[bucket[x]].push(x);
  56. }
  57. void update(const value_type& x) {
  58. remove(x);
  59. (*this)[bucket[x]].push(x);
  60. }
  61. // private:
  62. // with KCC, the nested stack class is having access problems
  63. // despite the friend decl.
  64. static size_type invalid_value() {
  65. return (std::numeric_limits<size_type>::max)();
  66. }
  67. typedef typename std::vector<size_type>::iterator Iter;
  68. typedef typename std::vector<value_type>::iterator IndexValueMap;
  69. public:
  70. friend class stack;
  71. class stack {
  72. public:
  73. stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v,
  74. const ValueIndexMap& _id)
  75. : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id) {}
  76. // Avoid using default arg for ValueIndexMap so that the default
  77. // constructor of the ValueIndexMap is not required if not used.
  78. stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v)
  79. : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v) {}
  80. void push(const value_type& x) {
  81. const size_type new_head = get(id, x);
  82. const size_type current = head[bucket_id];
  83. if ( current != invalid_value() )
  84. prev[current] = new_head;
  85. prev[new_head] = invalid_value();
  86. next[new_head] = current;
  87. head[bucket_id] = new_head;
  88. }
  89. void pop() {
  90. size_type current = head[bucket_id];
  91. size_type next_node = next[current];
  92. head[bucket_id] = next_node;
  93. if ( next_node != invalid_value() )
  94. prev[next_node] = invalid_value();
  95. }
  96. value_type& top() { return value[ head[bucket_id] ]; }
  97. const value_type& top() const { return value[ head[bucket_id] ]; }
  98. bool empty() const { return head[bucket_id] == invalid_value(); }
  99. private:
  100. bucket_type bucket_id;
  101. Iter head;
  102. Iter next;
  103. Iter prev;
  104. IndexValueMap value;
  105. ValueIndexMap id;
  106. };
  107. stack operator[](const bucket_type& i) {
  108. assert(i < head.size());
  109. return stack(i, head.begin(), next.begin(), prev.begin(),
  110. id_to_value.begin(), id);
  111. }
  112. protected:
  113. std::vector<size_type> head;
  114. std::vector<size_type> next;
  115. std::vector<size_type> prev;
  116. std::vector<value_type> id_to_value;
  117. Bucket bucket;
  118. ValueIndexMap id;
  119. };
  120. }
  121. #endif