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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_DATAFLOW_WORKLIST_H_
17 #define incl_HPHP_DATAFLOW_WORKLIST_H_
22 #include <type_traits>
28 #include <boost/dynamic_bitset.hpp>
32 //////////////////////////////////////////////////////////////////////
35 * Encapsulates a unique priority queue of an integer type, where elements in
36 * the queue are ids less than some universe size.
38 * This is useful for dataflow worklists, where we want to visit blocks with
39 * lower (or higher) ids before blocks with higher (or lower) ids, but also
40 * don't want to schedule something that's already scheduled. By default this
41 * returns lower ids first (note that this is returning things that are larger
42 * according to its Compare function, like std::priority_queue).
44 template<class T
, class Compare
= std::greater
<T
>>
45 struct dataflow_worklist
{
47 std::is_integral
<T
>::value
&& std::is_unsigned
<T
>::value
,
48 "dataflow_worklist requires an unsigned integer type"
51 explicit dataflow_worklist(T universe_size
)
52 : m_set(universe_size
)
56 auto r
= std::vector
<T
>{};
57 r
.reserve(universe_size
);
63 // We have to manually implement move, because boost::dynamic_bitset doesn't
64 // support it (at the time of this writing).
65 dataflow_worklist(dataflow_worklist
&& o
) noexcept
66 : dataflow_worklist(0)
71 dataflow_worklist
& operator=(dataflow_worklist
&& o
) noexcept
{
72 dataflow_worklist
tmp(std::move(o
));
77 void swap(dataflow_worklist
& o
) {
83 bool empty() const { return m_q
.empty(); }
84 T
top() { assert(!empty()); return m_q
.top(); }
88 assert(m_set
.test(t
));
95 * Enqueue t. Returns true iff the item was newly inserted.
98 assert(t
< m_set
.size());
99 if (m_set
[t
]) return false;
106 boost::dynamic_bitset
<> m_set
;
107 std::priority_queue
<T
,std::vector
<T
>,Compare
> m_q
;
110 //////////////////////////////////////////////////////////////////////