2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
21 #include <type_traits>
27 #include <boost/dynamic_bitset.hpp>
31 //////////////////////////////////////////////////////////////////////
34 * Encapsulates a unique priority queue of an integer type, where elements in
35 * the queue are ids less than some universe size.
37 * This is useful for dataflow worklists, where we want to visit blocks with
38 * lower (or higher) ids before blocks with higher (or lower) ids, but also
39 * don't want to schedule something that's already scheduled. By default this
40 * returns lower ids first (note that this is returning things that are larger
41 * according to its Compare function, like std::priority_queue).
43 template<class T
, class Compare
= std::greater
<T
>>
44 struct dataflow_worklist
{
46 std::is_integral
<T
>::value
&& std::is_unsigned
<T
>::value
,
47 "dataflow_worklist requires an unsigned integer type"
50 explicit dataflow_worklist(T universe_size
)
51 : m_set(universe_size
)
55 auto r
= std::vector
<T
>{};
56 r
.reserve(universe_size
);
62 // We have to manually implement move, because boost::dynamic_bitset doesn't
63 // support it (at the time of this writing).
64 dataflow_worklist(dataflow_worklist
&& o
) noexcept
65 : dataflow_worklist(0)
70 dataflow_worklist
& operator=(dataflow_worklist
&& o
) noexcept
{
71 dataflow_worklist
tmp(std::move(o
));
76 void swap(dataflow_worklist
& o
) {
82 bool empty() const { return m_q
.empty(); }
83 T
top() { assert(!empty()); return m_q
.top(); }
87 assert(m_set
.test(t
));
94 * Enqueue t. Returns true iff the item was newly inserted.
97 assert(t
< m_set
.size());
98 if (m_set
[t
]) return false;
105 boost::dynamic_bitset
<> m_set
;
106 std::priority_queue
<T
,std::vector
<T
>,Compare
> m_q
;
109 //////////////////////////////////////////////////////////////////////