spot  2.15.1
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 
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.1