aboutsummaryrefslogtreecommitdiff
path: root/gfsm/gfsm/src/libgfsm/gfsmArcIter.h
blob: ff96994e3ef1ffa1d577a4f4f5d74daf65a31944 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

/*=============================================================================*\
 * File: gfsmArcIter.h
 * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
 * Description: finite state machine library: arc iterators
 *
 * Copyright (c) 2004-2007 Bryan Jurish.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *=============================================================================*/

/** \file gfsmArcIter.h
 *  \brief Iterate over outgoing arcs of an automaton state.
 */

#ifndef _GFSM_ARCITER_H
#define _GFSM_ARCITER_H

#include <gfsmAutomaton.h>

/*======================================================================
 * Types: Arc iterators
 */
/// Abstract type for arc iterators
typedef struct {
  gfsmAutomaton *fsm;    /**< fsm holding these arcs */
  gfsmState     *state;  /**< state holding these arcs */
  gfsmArcList   *arcs;   /**< pointer to node for current arc */
} gfsmArcIter;

/*======================================================================
 * Methods: Arc iterators: open/close
 */
///\name Arc Iterators: Constructors etc.
//@{
/** Open a ::gfsmArcIter \a aip for the outgoing arcs from state with ID \a qid in the automaton \a fsm.
 *  \param aip Pointer to the ::gfsmArcIter to be opened; assumed to be already allocated
 *  \param fsm Automaton containing the state whose outgoing arcs are to be opened
 *  \param qid ID of the state whose outgoing arcs are to be opened
 *
 *  \note
 *   \li Arc iterators may be silently invalidated by destructive operations
 *   \li The arc iterator should be closed with gfsm_arciter_close() when it is no longer needed.
 *   \li Caller is responsible for allocation and freeing of \a *aip.
 */
GFSM_INLINE
void gfsm_arciter_open(gfsmArcIter *aip, gfsmAutomaton *fsm, gfsmStateId stateid);

/** "Open" an arc iterator for the outgoing arcs from a state pointer into \a fsm
 *  \deprecated prefer gfsm_arciter_open()
 */
GFSM_INLINE
void gfsm_arciter_open_ptr(gfsmArcIter *aip, gfsmAutomaton *fsm, gfsmState *stateptr);

/** Close a ::gfsmArcIter \a aip if already opened, otherwise does nothing.
 *  \param aip The ::gfsmArcIter to be closed.
 *  \note
 *   \li If multiple copies of a ::gfsmArcIter exist, only one needs to be closed.
 *   \li Currently does nothing useful; in future versions this function may
 *       be required to free temporary allocations, etc.
 */
GFSM_INLINE
void gfsm_arciter_close(gfsmArcIter *aip);

/** Copy positional data from \a src to \a dst.
 * \param src The ::gfsmArcIter from which to copy positional data
 * \param dst The ::gfsmArcIter to which positional data is to be written
 * \note
 *  \li Only the position pointed to should be copied by this method,
 *      and not the underlying data.
 *  \li If you use this method to copy ::gfsmArcIter positions,
 *      you should subsequently call gfsm_arciter_close() on only
 *      \e one of them!
 */
GFSM_INLINE
gfsmArcIter *gfsm_arciter_copy(gfsmArcIter *dst, const gfsmArcIter *src);

/* Create and return a new (shallow) copy of a ::gfsmArcIter.
 * \param src The ::gfsmArcIter whose positional data is to be duplicated.
 * \note
 *  \li Only the position pointed to should be copied by this method,
 *      and not the underlying data.
 *  \li If you use this method to copy ::gfsmArcIter positions,
 *      you should subsequently call gfsm_arciter_close() on only
 *      \e one of them!
 */
GFSM_INLINE
gfsmArcIter *gfsm_arciter_clone(const gfsmArcIter *src);

//@}

/*======================================================================
 * Methods: Arc iterators: Accessors
 */
///\name Arc Iterators: Accessors
//@{

/** Check validity of a ::gfsmArcIter* \a aip.
 *  \param aip The ::gfsmArcIter whose status is to be queried.
 *  \returns a true value if \a aip is considered valid, FALSE otherwise.
 */
GFSM_INLINE
gboolean gfsm_arciter_ok(const gfsmArcIter *aip);

/** Position the ::gfsmArcIter \a aip to the next available outgoing arc for which it was opened.
 *  \param aip The ::gfsmArcIter to be incremented.
 */
GFSM_INLINE
void gfsm_arciter_next(gfsmArcIter *aip);

/** Reset an arc iterator to the first outgoing arc for which it was initially opened.
 *  \param aip the ::gfsmArcIter to be reset
 */
GFSM_INLINE
void gfsm_arciter_reset(gfsmArcIter *aip);

/** Get current arc associated with a :gfsmArcIter, or NULL if none is available.
 *  \param aip The ::gfsmArcIter to be 'dereferenced'.
 *  \returns A pointer to the current ::gfsmArc 'pointed to' by \a aip, or NULL if
 *           no more arcs are available.
 *  \note
 *   \li In future versions, a ::gfsmAutomaton implementation will be free to return
 *       a dynamically generated arc here: there is no general
 *       guarantee that modifications to the ::gfsmArc returned by this
 *       function will be propagated to the underlying ::gfsmAutomaton.
 *   \li It is expected to remain the case that for the default automaton implementation class,
 *       the arcs returned by this function should be modifiable in-place.
 */
GFSM_INLINE
gfsmArc *gfsm_arciter_arc(const gfsmArcIter *aip);

/** Remove the arc referred to by a ::gfsmArcIter \a aip from the associated ::gfsmAutomaton,
 *  and position \aip to the next available arc, if any.
 *  \param aip The ::gfsmArcIter whose 'current' arc is to be removed.
 */
GFSM_INLINE
void gfsm_arciter_remove(gfsmArcIter *aip);


/** Position an arc-iterator to the current or next arc with lower label \a lo.
 *  \param aip The ::gfsmArcIter to reposition
 *  \param lo  Lower arc label to seek
 *  \note
 *    Currently just wraps gfsm_arciter_ok(), gfsm_arciter_next() and gfsm_arciter_arc()
 *    in a linear search from the current position.
 */
void gfsm_arciter_seek_lower(gfsmArcIter *aip, gfsmLabelVal lo);

/** Position an arc-iterator to the current or next arc with upper label \a hi.
 *  \param aip The ::gfsmArcIter to reposition
 *  \param lo  Upper arc label to seek
 *  \note
 *    Currently just wraps gfsm_arciter_ok(), gfsm_arciter_next() and gfsm_arciter_arc()
 *    in a linear search from the current position.
 */
void gfsm_arciter_seek_upper(gfsmArcIter *aip, gfsmLabelVal hi);

/** Position an arc-iterator to the current or next arc with lower label \a lo and upper label \a hi.
 *  If either \a lo or \a hi is ::gfsmNoLabel, no matching will be performed on the corresponding arc label(s).
 *  \param aip The ::gfsmArcIter to reposition
 *  \param lo  Lower arc label to seek, or ::gfsmNoLabel to ignore lower labels
 *  \param hi  Upper arc label to seek, or ::gfsmNoLabel to ignore upper labels
 *  \note
 *    Default implementation wraps gfsm_arciter_ok(), gfsm_arciter_next() and gfsm_arciter_arc()
 *    in a linear search from the current position.
 */
void gfsm_arciter_seek_both(gfsmArcIter *aip, gfsmLabelVal lo, gfsmLabelVal hi);

/// Typedef for user-seek functions
typedef gboolean (*gfsmArcIterSeekFunc) (gfsmArcIter *aip, gpointer data);

/** Position an arc-iterator to the next arc for which (*seekfunc)(arciter,data) returns TRUE.
 *  \note
 *    Just wraps gfsm_arciter_ok() and gfsm_arciter_next()
 *    in a linear search from the current position.
 */
void gfsm_arciter_seek_user(gfsmArcIter *aip,
			    gfsmArcIterSeekFunc seekfunc,
			    gpointer data);


//@}

//-- inline definitions
#ifdef GFSM_INLINE_ENABLED
# include <gfsmArcIter.hi>
#endif

#endif /* _GFSM_ARCITER_H */