MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
veciter.h
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/libraries/libmbutil/veciter.h,v 1.39 2017/01/12 14:44:05 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 /* Iteratore per vettori */
33 
34 
35 #ifndef VECITER_H
36 #define VECITER_H
37 
38 #ifdef USE_MULTITHREAD
39 #include <signal.h>
40 #include "ac/spinlock.h"
41 #endif /* USE_MULTITHREAD */
42 
43 #include "myassert.h"
44 
45 /* GetFirst ritorna true ed assegna a TReturn il primo item del vettore.
46  * Si assume che il vettore contenga almeno un termine;
47  * GetNext ritorna true ed assegna a TReturn il termine successivo se esiste,
48  * altrimenti ritorna false e l'assegnamento a TReturn e' unpredictable. */
49 
50 
51 template <class T>
52 class Iter {
53 public:
54  virtual ~Iter(void) { NO_OP; };
55  virtual bool bGetFirst(T& TReturn) const = 0;
56  virtual bool bGetNext(T& TReturn) const = 0;
57 };
58 
59 template<class T>
60 class VecIter : public Iter<T> {
61 protected:
62  mutable T* pStart;
63  mutable T* pCount;
64  unsigned iSize;
65 
66 public:
67  VecIter(void) : pStart(0), pCount(0), iSize(0) { NO_OP; };
68  VecIter(const T* p, unsigned i) : pStart(p), pCount(p), iSize(i)
69  {
70  ASSERT(pStart != 0);
71  ASSERT(iSize > 0);
72  };
73 
74  virtual ~VecIter(void)
75  {
76  NO_OP;
77  };
78 
79  void Init(const T* p, unsigned i)
80  {
81  ASSERT(p != NULL);
82  ASSERT(i > 0);
83 
84  pStart = pCount = const_cast<T *>(p);
85  iSize = i;
86  };
87 
88  inline bool bGetFirst(T& TReturn) const
89  {
90  ASSERT(pStart != NULL);
91  ASSERT(iSize > 0);
92 
93  if (pStart == NULL) {
94  return false;
95  }
96 
97  pCount = pStart;
98  TReturn = *pStart;
99 
100  return true;
101  };
102 
103  inline bool bGetCurr(T& TReturn) const
104  {
105  ASSERT(pStart != NULL);
106  ASSERT(iSize > 0);
107  ASSERT(pCount >= pStart);
108 
109  if (pCount == pStart + iSize) {
110  return false;
111  }
112 
113  TReturn = *pCount;
114 
115  return true;
116  };
117 
118  inline bool bGetNext(T& TReturn) const
119  {
120  ASSERT(pStart != NULL);
121  ASSERT(iSize > 0);
122  ASSERT(pCount >= pStart);
123 
124  ++pCount;
125  if (pCount == pStart + iSize) {
126  return false;
127  }
128 
129  TReturn = *pCount;
130 
131  return true;
132  };
133 };
134 
135 #ifdef USE_MULTITHREAD
136 /*
137  * The user's class must inherit from InUse to be used by the MT_VecIter
138  * the user must reset the inuse flag by using SetInUse() before
139  * concurrently iterating over the array; the iterator provides a
140  * helper routine for this; provide it is called only once and not
141  * concurrently.
142  */
143 class InUse {
144 private:
145  mutable volatile AO_TS_t inuse;
146 
147 public:
148  InUse(void) : inuse(AO_TS_INITIALIZER) { NO_OP; };
149  virtual ~InUse(void) { NO_OP; };
150 
151  inline bool bIsInUse(void) const
152  {
153  /*
154  * If inuse is...
155  * true: leave it as is; return false
156  * false: make it true; return true
157  */
158  /* FIXME: make it portable */
159 
160  return (mbdyn_test_and_set(&inuse) == AO_TS_CLEAR);
161  };
162  inline void ReSetInUse() { AO_CLEAR(&inuse); };
163 };
164 
165 /* #define DEBUG_VECITER */
166 
167 template<class T>
168 class MT_VecIter : public VecIter<T> {
169 protected:
170 #ifdef DEBUG_VECITER
171  mutable unsigned iCount;
172 #endif /* DEBUG_VECITER */
173 
174 public:
175  MT_VecIter(void) : VecIter<T>() { NO_OP; };
176  MT_VecIter(const T* p, unsigned i) : VecIter<T>(p, i)
177  {
178  NO_OP;
179  };
180 
181  virtual ~MT_VecIter(void)
182  {
183  NO_OP;
184  };
185 
186  /* NOTE: it must be called only once */
187  void ResetAccessData(void)
188  {
189  ASSERT(VecIter<T>::pStart != NULL);
191 
192  for (unsigned i = 0; i < VecIter<T>::iSize; i++) {
193  VecIter<T>::pStart[i]->ReSetInUse();
194  }
195  }
196 
197  inline bool bGetFirst(T& TReturn) const
198  {
199  ASSERT(VecIter<T>::pStart != NULL);
201 
202 #ifdef DEBUG_VECITER
203  iCount = 0;
204 #endif /* DEBUG_VECITER */
205 
207 
208  return bGetNext(TReturn);
209  };
210 
211  inline bool bGetCurr(T& TReturn) const
212  {
213  ASSERT(VecIter<T>::pStart != NULL);
217 
219  return false;
220  }
221 
222  TReturn = *VecIter<T>::pCount;
223  /* NOTE: of course, by definition it's already in use */
224 
225  return true;
226  };
227 
228  inline bool bGetNext(T& TReturn) const
229  {
230  ASSERT(VecIter<T>::pStart != NULL);
234 
235  for (VecIter<T>::pCount++;
237  VecIter<T>::pCount++) {
238  if ((*VecIter<T>::pCount)->bIsInUse()) {
239  TReturn = *VecIter<T>::pCount;
240 #ifdef DEBUG_VECITER
241  iCount++;
242 #endif /* DEBUG_VECITER */
243  return true;
244  }
245  }
246 
247 #ifdef DEBUG_VECITER
248  silent_cerr("[" << pthread_self() << "]: total=" << iCount
249  << std::endl);
250 #endif /* DEBUG_VECITER */
251  return false;
252  };
253 };
254 
255 #endif /* USE_MULTITHREAD */
256 
257 #endif /* VECITER_H */
virtual bool bGetNext(T &TReturn) const =0
bool bGetNext(T &TReturn) const
Definition: veciter.h:118
virtual bool bGetFirst(T &TReturn) const =0
#define NO_OP
Definition: myassert.h:74
virtual ~VecIter(void)
Definition: veciter.h:74
T * pStart
Definition: veciter.h:62
VecIter(void)
Definition: veciter.h:67
#define ASSERT(expression)
Definition: colamd.c:977
Definition: veciter.h:52
virtual ~Iter(void)
Definition: veciter.h:54
bool bGetCurr(T &TReturn) const
Definition: veciter.h:103
T * pCount
Definition: veciter.h:63
void Init(const T *p, unsigned i)
Definition: veciter.h:79
bool bGetFirst(T &TReturn) const
Definition: veciter.h:88
VecIter(const T *p, unsigned i)
Definition: veciter.h:68
unsigned iSize
Definition: veciter.h:64