spot  2.16
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 
29 namespace 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
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 past the end.
Definition: adjlist.hh:185
successor_iterator operator++(int)
Post-increment: advance to next successor.
Definition: adjlist.hh:172
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
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
internal::boxed_label< State_Data >::data_t & state_data(unsigned s)
Return the state data for state s.
Definition: adjlist.hh:114
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.1