bucket_sorter.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. {
  25. template < class BucketType, class ValueType, class Bucket,
  26. class ValueIndexMap >
  27. class bucket_sorter
  28. {
  29. BOOST_CONCEPT_ASSERT(
  30. (ReadablePropertyMapConcept< ValueIndexMap, ValueType >));
  31. public:
  32. typedef BucketType bucket_type;
  33. typedef ValueType value_type;
  34. typedef typename std::vector< value_type >::size_type size_type;
  35. bucket_sorter(size_type _length, bucket_type _max_bucket,
  36. const Bucket& _bucket = Bucket(),
  37. const ValueIndexMap& _id = ValueIndexMap())
  38. : head(_max_bucket, invalid_value())
  39. , next(_length, invalid_value())
  40. , prev(_length, invalid_value())
  41. , id_to_value(_length)
  42. , bucket(_bucket)
  43. , id(_id)
  44. {
  45. }
  46. void remove(const value_type& x)
  47. {
  48. const size_type i = get(id, x);
  49. const size_type& next_node = next[i];
  50. const size_type& prev_node = prev[i];
  51. // check if i is the end of the bucket list
  52. if (next_node != invalid_value())
  53. prev[next_node] = prev_node;
  54. // check if i is the begin of the bucket list
  55. if (prev_node != invalid_value())
  56. next[prev_node] = next_node;
  57. else // need update head of current bucket list
  58. head[bucket[x]] = next_node;
  59. }
  60. void push(const value_type& x)
  61. {
  62. id_to_value[get(id, x)] = x;
  63. (*this)[bucket[x]].push(x);
  64. }
  65. void update(const value_type& x)
  66. {
  67. remove(x);
  68. (*this)[bucket[x]].push(x);
  69. }
  70. // private:
  71. // with KCC, the nested stack class is having access problems
  72. // despite the friend decl.
  73. static size_type invalid_value()
  74. {
  75. return (std::numeric_limits< size_type >::max)();
  76. }
  77. typedef typename std::vector< size_type >::iterator Iter;
  78. typedef typename std::vector< value_type >::iterator IndexValueMap;
  79. public:
  80. friend class stack;
  81. class stack
  82. {
  83. public:
  84. stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v,
  85. const ValueIndexMap& _id)
  86. : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id)
  87. {
  88. }
  89. // Avoid using default arg for ValueIndexMap so that the default
  90. // constructor of the ValueIndexMap is not required if not used.
  91. stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v)
  92. : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v)
  93. {
  94. }
  95. void push(const value_type& x)
  96. {
  97. const size_type new_head = get(id, x);
  98. const size_type current = head[bucket_id];
  99. if (current != invalid_value())
  100. prev[current] = new_head;
  101. prev[new_head] = invalid_value();
  102. next[new_head] = current;
  103. head[bucket_id] = new_head;
  104. }
  105. void pop()
  106. {
  107. size_type current = head[bucket_id];
  108. size_type next_node = next[current];
  109. head[bucket_id] = next_node;
  110. if (next_node != invalid_value())
  111. prev[next_node] = invalid_value();
  112. }
  113. value_type& top() { return value[head[bucket_id]]; }
  114. const value_type& top() const { return value[head[bucket_id]]; }
  115. bool empty() const { return head[bucket_id] == invalid_value(); }
  116. private:
  117. bucket_type bucket_id;
  118. Iter head;
  119. Iter next;
  120. Iter prev;
  121. IndexValueMap value;
  122. ValueIndexMap id;
  123. };
  124. stack operator[](const bucket_type& i)
  125. {
  126. assert(i < head.size());
  127. return stack(i, head.begin(), next.begin(), prev.begin(),
  128. id_to_value.begin(), id);
  129. }
  130. protected:
  131. std::vector< size_type > head;
  132. std::vector< size_type > next;
  133. std::vector< size_type > prev;
  134. std::vector< value_type > id_to_value;
  135. Bucket bucket;
  136. ValueIndexMap id;
  137. };
  138. }
  139. #endif