spot 2.16
Loading...
Searching...
No Matches
adjlist.hh
1// -*- coding: utf-8 -*-
2// Copyright (C) by the Spot authors, see the AUTHORS file for details.
3//
4// This file is part of Spot, a model checking library.
5//
6// Spot is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 3 of the License, or
9// (at your option) any later version.
10//
11// Spot is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14// License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19#pragma once
20
21#include <spot/misc/common.hh>
22#include <spot/misc/_config.h>
23
24#include <vector>
25#include <iterator>
26#include <cstddef>
27#include <spot/graph/graph.hh>
28
29namespace spot
30{
39 template<class State_Data>
40 class SPOT_API adjlist
41 {
42 private:
43 // Edge structure in a linked list format
44 struct edge
45 {
46 unsigned dst;
47 // index of next edge, or 0.
48 unsigned next_index;
49 };
50
51 struct state_storage: public internal::boxed_label<State_Data>
52 {
53 unsigned first_edge = 0;
54
55#ifndef SWIG
56 template <typename... Args,
57 typename = typename std::enable_if<
58 !internal::first_is_base_of<state_storage,
59 Args...>::value>::type>
60 state_storage(Args&&... args)
61 noexcept(std::is_nothrow_constructible
62 <internal::boxed_label<State_Data>, Args...>::value)
63 : internal::boxed_label<State_Data>{std::forward<Args>(args)...}
64 {
65 }
66#endif
67 };
68
69 std::vector<edge> edges_;
70 std::vector<state_storage> states_;
71
72 public:
77 adjlist(unsigned max_states = 10, unsigned max_trans = 0)
78 {
79 states_.reserve(max_states);
80 if (max_trans == 0)
81 max_trans = max_states * 2;
82 edges_.reserve(max_trans + 1);
83 // Add a dummy edge at index 0 to simplify later comparisons.
84 // When next_index == 0, there is no successor.
85 edges_.push_back({-1U, 0U});
86 }
87
90 template <typename... Args>
91 unsigned new_state(Args&&... args)
92 {
93 unsigned s = states_.size();
94 states_.emplace_back(std::forward<Args>(args)...);
95 return s;
96 }
97
102 template <typename... Args>
103 unsigned new_states(unsigned n, Args&&... args)
104 {
105 unsigned s = states_.size();
106 states_.reserve(s + n);
107 while (n--)
108 states_.emplace_back(std::forward<Args>(args)...);
109 return s;
110 }
111
113 typename internal::boxed_label<State_Data>::data_t&
114 state_data(unsigned s)
115 {
116 return states_[s].data();
117 }
118
120 const typename internal::boxed_label<State_Data>::data_t&
121 state_data(unsigned s) const
122 {
123 return states_[s].data();
124 }
125
129 void new_edge(unsigned src, unsigned dst)
130 {
131 unsigned pos = edges_.size();
132 state_storage& ss = states_[src];
133 edges_.emplace_back(edge{dst, ss.first_edge});
134 ss.first_edge = pos;
135 }
136
139 {
140 private:
141 const adjlist* graph;
142 unsigned edge_index;
143
144 public:
145 // Iterator traits
147 using iterator_category = std::input_iterator_tag;
148 using value_type = unsigned;
149 using difference_type = std::ptrdiff_t;
150 using pointer = const unsigned*;
151 using reference = const unsigned&;
152
154 successor_iterator(const adjlist* g, unsigned idx)
155 : graph(g), edge_index(idx)
156 {
157 }
158
160 int operator*() const
161 {
162 return graph->edges_[edge_index].dst;
163 }
164
167 edge_index = graph->edges_[edge_index].next_index;
168 return *this;
169 }
170
173 successor_iterator tmp = *this;
174 ++(*this);
175 return tmp;
176 }
177
179 friend bool operator==(const successor_iterator& iter, std::nullptr_t)
180 {
181 return iter.edge_index == 0;
182 }
183
185 friend bool operator==(std::nullptr_t, const successor_iterator& iter)
186 {
187 return iter.edge_index == 0;
188 }
189
191 friend bool operator!=(const successor_iterator& iter, std::nullptr_t)
192 {
193 return iter.edge_index != 0;
194 }
195
197 friend bool operator!=(std::nullptr_t, const successor_iterator& iter)
198 {
199 return iter.edge_index != 0;
200 }
201 };
202
205 {
206 private:
207 const adjlist* graph;
208 unsigned state;
209
210 public:
212 successor_range(const adjlist* g, unsigned s)
213 : graph(g), state(s)
214 {
215 }
216
219 {
220 SPOT_ASSERT(state < graph->states_.size());
221 return successor_iterator(graph, graph->states_[state].first_edge);
222 }
223
225 std::nullptr_t end() const
226 {
227 return nullptr;
228 }
229 };
230
232 successor_range out(unsigned state) const
233 {
234 return successor_range(this, state);
235 }
236
238 unsigned num_states() const
239 {
240 return states_.size();
241 }
242
244 unsigned num_edges() const
245 {
246 return edges_.size() - 1;
247 }
248 };
249}
Iterator for traversing successors of a state.
Definition adjlist.hh:139
friend bool operator!=(const successor_iterator &iter, std::nullptr_t)
Return true iff iter is not past the end.
Definition adjlist.hh:191
std::input_iterator_tag iterator_category
Standard iterator type alias.
Definition adjlist.hh:147
int operator*() const
Dereference: return destination state.
Definition adjlist.hh:160
std::ptrdiff_t difference_type
Standard iterator type alias.
Definition adjlist.hh:149
const unsigned & reference
Standard iterator type alias.
Definition adjlist.hh:151
const unsigned * pointer
Standard iterator type alias.
Definition adjlist.hh:150
friend bool operator==(std::nullptr_t, const successor_iterator &iter)
Return true iff iter is past the end.
Definition adjlist.hh:185
successor_iterator operator++(int)
Post-increment: advance to next successor.
Definition adjlist.hh:172
successor_iterator & operator++()
Pre-increment: advance to next successor.
Definition adjlist.hh:166
friend bool operator!=(std::nullptr_t, const successor_iterator &iter)
Return true iff iter is not past the end.
Definition adjlist.hh:197
friend bool operator==(const successor_iterator &iter, std::nullptr_t)
Return true iff iter is past the end.
Definition adjlist.hh:179
unsigned value_type
Standard iterator type alias.
Definition adjlist.hh:148
successor_iterator(const adjlist *g, unsigned idx)
Construct an iterator over successors of state at idx in graph g.
Definition adjlist.hh:154
Range wrapper for successor iteration.
Definition adjlist.hh:205
successor_range(const adjlist *g, unsigned s)
Construct range over successors of state s in g.
Definition adjlist.hh:212
std::nullptr_t end() const
Return past-the-end sentinel.
Definition adjlist.hh:225
successor_iterator begin() const
Return iterator to first successor.
Definition adjlist.hh:218
A compact adjacency list representation for directed graphs.
Definition adjlist.hh:41
internal::boxed_label< State_Data >::data_t & state_data(unsigned s)
Return the state data for state s.
Definition adjlist.hh:114
unsigned new_state(Args &&... args)
Create a new state with given data.
Definition adjlist.hh:91
unsigned num_edges() const
Return the number of edges.
Definition adjlist.hh:244
const internal::boxed_label< State_Data >::data_t & state_data(unsigned s) const
Return the state data for state s.
Definition adjlist.hh:121
unsigned new_states(unsigned n, Args &&... args)
Create multiple new states with the same data.
Definition adjlist.hh:103
unsigned num_states() const
Return the number of states.
Definition adjlist.hh:238
successor_range out(unsigned state) const
Return successor range for state.
Definition adjlist.hh:232
adjlist(unsigned max_states=10, unsigned max_trans=0)
Constructor for adjacency list.
Definition adjlist.hh:77
void new_edge(unsigned src, unsigned dst)
Add a new edge between two states.
Definition adjlist.hh:129
Abstract class for states.
Definition twa.hh:49
@ U
until
Definition automata.hh:26

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Fri Feb 27 2015 10:00:07 for spot by doxygen 1.9.8