spot 2.15
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
101 template <typename... Args>
102 unsigned new_states(unsigned n, Args&&... args)
103 {
104 unsigned s = states_.size();
105 states_.reserve(s + n);
106 while (n--)
107 states_.emplace_back(std::forward<Args>(args)...);
108 return s;
109 }
110
111 typename internal::boxed_label<State_Data>::data_t&
112 state_data(unsigned s)
113 {
114 return states_[s].data();
115 }
116
117 const typename internal::boxed_label<State_Data>::data_t&
118 state_data(unsigned s) const
119 {
120 return states_[s].data();
121 }
122
126 void new_edge(unsigned src, unsigned dst)
127 {
128 unsigned pos = edges_.size();
129 state_storage& ss = states_[src];
130 edges_.emplace_back(edge{dst, ss.first_edge});
131 ss.first_edge = pos;
132 }
133
136 {
137 private:
138 const adjlist* graph;
139 unsigned edge_index;
140
141 public:
142 // Iterator traits
143 using iterator_category = std::input_iterator_tag;
144 using value_type = unsigned;
145 using difference_type = std::ptrdiff_t;
146 using pointer = const unsigned*;
147 using reference = const unsigned&;
148
149 successor_iterator(const adjlist* g, unsigned idx)
150 : graph(g), edge_index(idx)
151 {
152 }
153
154 int operator*() const
155 {
156 return graph->edges_[edge_index].dst;
157 }
158
159 successor_iterator& operator++() {
160 edge_index = graph->edges_[edge_index].next_index;
161 return *this;
162 }
163
164 successor_iterator operator++(int) {
165 successor_iterator tmp = *this;
166 ++(*this);
167 return tmp;
168 }
169
170 friend bool operator==(const successor_iterator& iter, std::nullptr_t)
171 {
172 return iter.edge_index == 0;
173 }
174
175 friend bool operator==(std::nullptr_t, const successor_iterator& iter)
176 {
177 return iter.edge_index == 0;
178 }
179
180 friend bool operator!=(const successor_iterator& iter, std::nullptr_t)
181 {
182 return iter.edge_index != 0;
183 }
184
185 friend bool operator!=(std::nullptr_t, const successor_iterator& iter)
186 {
187 return iter.edge_index != 0;
188 }
189 };
190
193 {
194 private:
195 const adjlist* graph;
196 unsigned state;
197
198 public:
199 successor_range(const adjlist* g, unsigned s)
200 : graph(g), state(s)
201 {
202 }
203
204 successor_iterator begin() const
205 {
206 unsigned first_edge = (state < graph->states_.size()) ?
207 graph->states_[state].first_edge : 0;
208 return successor_iterator(graph, first_edge);
209 }
210
211 std::nullptr_t end() const
212 {
213 return nullptr;
214 }
215 };
216
217 successor_range out(unsigned state) const
218 {
219 return successor_range(this, state);
220 }
221
222 unsigned num_states() const
223 {
224 return states_.size();
225 }
226
227 unsigned num_edges() const
228 {
229 return edges_.size() - 1;
230 }
231 };
232}
Iterator for traversing successors of a state.
Definition adjlist.hh:136
Range wrapper for successor iteration.
Definition adjlist.hh:193
A compact adjacency list representation for directed graphs.
Definition adjlist.hh:41
unsigned new_state(Args &&... args)
Create a new state with given data.
Definition adjlist.hh:91
unsigned new_states(unsigned n, Args &&... args)
Create multiple new states with the same data.
Definition adjlist.hh:102
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:126
Abstract class for states.
Definition twa.hh:47
@ 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