FE
0.16.1
Fast, Effecient FrontEnds
Toggle main menu visibility
Loading...
Searching...
No Matches
worklist.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <cstddef>
4
5
#include <ranges>
6
#include <stack>
7
#include <type_traits>
8
#include <utility>
9
10
#include "
fe/container.h
"
11
#include "
fe/vector.h
"
12
13
namespace
fe
{
14
15
/// A FIFO queue over a Vector.
16
/// Popped elements stay in place until they make up half of the storage, so `pop` is amortized constant.
17
template
<
class
T,
size_t
N = Default_Inlined_Size<T>>
18
class
VectorQueue
{
19
public
:
20
using
value_type
= T;
21
22
bool
empty
()
const
{
return
head_ == vec_.size(); }
23
size_t
size
()
const
{
return
vec_.size() - head_; }
24
25
T&
front
() {
return
vec_[head_]; }
26
const
T&
front
()
const
{
return
vec_[head_]; }
27
T&
back
() {
return
vec_.back(); }
28
const
T&
back
()
const
{
return
vec_.back(); }
29
30
void
push
(
const
T& val) { vec_.push_back(val); }
31
void
push
(T&& val) { vec_.push_back(std::move(val)); }
32
template
<
class
... Args>
33
decltype
(
auto
)
emplace
(Args&&... args) {
34
return
vec_.emplace_back(std::forward<Args>(args)...);
35
}
36
37
void
pop
() {
38
if
(++head_ == vec_.size()) {
39
vec_.clear();
40
head_ = 0;
41
}
else
if
(head_ >= 2 * N && 2 * head_ >= vec_.size()) {
42
vec_.erase(vec_.begin(), vec_.begin() + head_);
43
head_ = 0;
44
}
45
}
46
47
private
:
48
Vector<T, N>
vec_;
49
size_t
head_ = 0;
50
};
51
52
/// A worklist that pushes each element at most once.
53
/// @p Set remembers what has already been pushed and may be a reference to share it with the caller.
54
/// Use it through the BFSWorklist/DFSWorklist aliases.
55
template
<
class
Set,
class
C>
56
class
Worklist
{
57
public
:
58
using
T
=
typename
std::remove_reference_t<Set>::value_type;
59
static_assert
(std::is_same_v<T, typename C::value_type>);
60
61
/// @name Constructors
62
///@{
63
Worklist
() =
default
;
64
explicit
Worklist
(Set set)
65
: done_(
std
::forward<Set>(set)) {}
66
Worklist
(std::initializer_list<T> init) {
push
(init); }
67
///@}
68
69
/// @name push
70
///@{
71
bool
push
(
T
val) {
72
if
(done_.emplace(val).second) {
73
c_.emplace(std::move(val));
74
return
true
;
75
}
76
return
false
;
77
}
78
template
<std::ranges::input_range R>
79
void
push
(R&& r) {
80
for
(
auto
&& val : r)
81
push
(val);
82
}
83
///@}
84
85
/// @name Access
86
///@{
87
bool
empty
()
const
{
return
c_.empty(); }
88
size_t
size
()
const
{
return
c_.size(); }
89
T
pop
() {
return
fe::pop
(c_); }
90
91
T
&
front
()
requires
Queuelike
<C> {
return
c_.front(); }
92
const
T
&
front
() const requires
Queuelike
<C> {
return
c_.front(); }
93
T
&
back
()
requires
Queuelike
<C> {
return
c_.back(); }
94
const
T
&
back
() const requires
Queuelike
<C> {
return
c_.back(); }
95
T
&
top
()
requires
Stacklike
<C> {
return
c_.top(); }
96
const
T
&
top
() const requires
Stacklike
<C> {
return
c_.top(); }
97
///@}
98
99
void
clear
() {
100
done_.clear();
101
c_ = {};
102
}
103
104
private
:
105
Set done_;
106
C c_;
107
};
108
109
namespace
detail {
110
template
<
class
Set>
111
using
WorklistElem =
typename
std::remove_reference_t<Set>::value_type;
112
}
113
114
template
<
class
Set>
115
using
BFSWorklist
=
Worklist<Set, VectorQueue<detail::WorklistElem<Set>
>>;
116
template
<
class
Set>
117
using
DFSWorklist
=
Worklist<Set, std::stack<detail::WorklistElem<Set>
,
Vector<detail::WorklistElem<Set>
>>>;
118
119
}
// namespace fe
fe::VectorQueue
A FIFO queue over a Vector.
Definition
worklist.h:18
fe::VectorQueue::push
void push(const T &val)
Definition
worklist.h:30
fe::VectorQueue::value_type
T value_type
Definition
worklist.h:20
fe::VectorQueue::empty
bool empty() const
Definition
worklist.h:22
fe::VectorQueue::front
T & front()
Definition
worklist.h:25
fe::VectorQueue::back
const T & back() const
Definition
worklist.h:28
fe::VectorQueue::emplace
decltype(auto) emplace(Args &&... args)
Definition
worklist.h:33
fe::VectorQueue::front
const T & front() const
Definition
worklist.h:26
fe::VectorQueue::size
size_t size() const
Definition
worklist.h:23
fe::VectorQueue::back
T & back()
Definition
worklist.h:27
fe::VectorQueue::pop
void pop()
Definition
worklist.h:37
fe::VectorQueue::push
void push(T &&val)
Definition
worklist.h:31
fe::Vector
This is a thin wrapper for ankerl::svector<T, N, A> which is a drop-in replacement for std::vector<T,...
Definition
vector.h:25
fe::Worklist
A worklist that pushes each element at most once.
Definition
worklist.h:56
fe::Worklist::size
size_t size() const
Definition
worklist.h:88
fe::Worklist::push
bool push(T val)
Definition
worklist.h:71
fe::Worklist::top
const T & top() const
Definition
worklist.h:96
fe::Worklist::Worklist
Worklist()=default
fe::Worklist::back
const T & back() const
Definition
worklist.h:94
fe::Worklist::front
T & front()
Definition
worklist.h:91
fe::Worklist::Worklist
Worklist(std::initializer_list< T > init)
Definition
worklist.h:66
fe::Worklist::clear
void clear()
Definition
worklist.h:99
fe::Worklist::T
typename std::remove_reference_t< Set >::value_type T
Definition
worklist.h:58
fe::Worklist::Worklist
Worklist(Set set)
Definition
worklist.h:64
fe::Worklist::top
T & top()
Definition
worklist.h:95
fe::Worklist::push
void push(R &&r)
Definition
worklist.h:79
fe::Worklist::empty
bool empty() const
Definition
worklist.h:87
fe::Worklist::pop
T pop()
Definition
worklist.h:89
fe::Worklist::front
const T & front() const
Definition
worklist.h:92
fe::Worklist::back
T & back()
Definition
worklist.h:93
fe::Queuelike
Something which behaves like std::queue.
Definition
container.h:19
fe::Stacklike
Something which behaves like std::stack or std::priority_queue.
Definition
container.h:12
container.h
fe
Definition
algo.h:17
fe::pop
S::value_type pop(S &s)
Definition
container.h:27
fe::DFSWorklist
Worklist< Set, std::stack< detail::WorklistElem< Set >, Vector< detail::WorklistElem< Set > > > > DFSWorklist
Definition
worklist.h:117
fe::BFSWorklist
Worklist< Set, VectorQueue< detail::WorklistElem< Set > > > BFSWorklist
Definition
worklist.h:115
std
Definition
span.h:150
vector.h
fe
worklist.h
Generated by
1.18.0