cfl_basevector.cpp
Go to the documentation of this file.
1/** @file cfl_basevector.cpp @brief */
2
3/* FAU Discrete Event Systems Library (libfaudes)
4
5 Copyright (C) 2006 Bernd Opitz
6 Copyright (C) 2007, 2025 Thomas Moor
7 Exclusive copyright is granted to Klaus Schmidt
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#include "cfl_basevector.h"
24#include "cfl_nameset.h"
25
26namespace faudes {
27
28// local debugging
29//#undef FD_DC
30//#define FD_DC(a) FD_WARN(a)
31
32/*
33******************************************************************************************
34******************************************************************************************
35******************************************************************************************
36
37Implementation of TBaseVector
38
39******************************************************************************************
40******************************************************************************************
41******************************************************************************************
42*/
43
44// faudes type std
45FAUDES_TYPE_IMPLEMENTATION(Void,vBaseVector,ExtType)
46
47
48// vBaseVector()
50 ExtType()
51{
52 FD_DC("vBaseVector(" << this << ")::vBaseVector()");
53 // fix base member defaults
54 mObjectName="Vector";
55 mElementTagDef="Element";
56}
57
58
59// vBaseVector(filename)
60vBaseVector::vBaseVector(const std::string& rFileName, const std::string& rLabel) :
61 ExtType()
62{
63 FD_DC("vBaseVector(" << this << ")::vBaseVector()");
64 // fix base member defaults
65 mObjectName="Vector";
66 mElementTagDef="Element";
67 // do read;
68 Read(rFileName,rLabel);
69}
70
71
72// vBaseVector(rOtherSet)
74 ExtType()
75{
76 FD_DC("vBaseVector(" << this << ")::vBaseVector(rOtherVector " << &rOtherVector << "): copy construct");
77 DoAssign(rOtherVector);
78}
79
80// destructor
82 FD_DC("vBaseVector(" << this << ")::~vBaseVector()");
83 // delete entries
84 for(Position pos=0; pos<mVector.size(); pos++)
85 if(mVector[pos].mMine) delete mVector[pos].pElement;
86 // done
87 FD_DC("vBaseVector(" << this << ")::~vBaseVector(): done");
88}
89
90
91// element prototype
92const Type* vBaseVector::Elementp(void) const {
93 static Type proto;
94 return &proto;
95}
96
97// element prototype
98const Type& vBaseVector::Element(void) const {
99 return *Elementp();
100}
101
102// element factory
104 return Element().New();
105}
106
107// test element type
108bool vBaseVector::ElementTry(const Type& rElement) const {
109 return Elementp()->Cast(&rElement)!=NULL;
110}
111
112// assignment (here, we know the type to match)
113void vBaseVector::DoAssign(const vBaseVector& rSourceVector) {
114 FD_DC("vBaseVector(" << this << ")::DoAssign(rOtherVector " << &rSourceVector << ")");
115 // bail out on selfref
116 if(this==&rSourceVector) return;
117 // virtual clear
118 Clear();
119 // care about base
120 mObjectName=rSourceVector.mObjectName;
121 mElementTagDef=rSourceVector.mObjectName;
122 // allocate
123 mVector.resize(rSourceVector.Size());
124 // copy entries (incl name)
125 for(Position pos=0; pos<mVector.size(); pos++) {
126 mVector[pos].pElement = rSourceVector.mVector[pos].pElement->Copy();
127 mVector[pos].pElement->Name(rSourceVector.mVector[pos].pElement->Name());
128 mVector[pos].mMine=true;
129 mVector[pos].mFileName="";
130 }
131 // done
132 FD_DC("vBaseVector(" << this << ")::DoAssign(rOtherVector " << &rSourceVector << "): done");
133}
134
135// assignment (here, we know the type to match)
137 FD_DC("vBaseVector(" << this << ")::AssignByReference(rOtherVector " << &rSourceVector << ")");
138 // bail out on selfref
139 if(this==&rSourceVector) return;
140 // virtual clear
141 Clear();
142 // care about base
143 mObjectName=rSourceVector.mObjectName;
144 mElementTagDef=rSourceVector.mObjectName;
145 // allocate
146 mVector.resize(rSourceVector.Size());
147 // copy entries (incl name)
148 for(Position pos=0; pos<mVector.size(); pos++) {
149 mVector[pos].pElement = rSourceVector.mVector[pos].pElement;
150 mVector[pos].mMine=false;
151 mVector[pos].mFileName="";
152 }
153 // done
154 FD_DC("vBaseVector(" << this << ")::AssignByReference(rOtherVector " << &rSourceVector << "): done");
155}
156
157// clear
159 // delete entries
160 for(Position pos=0; pos<mVector.size(); pos++) {
161 if(mVector[pos].mMine) delete mVector[pos].pElement;
162 }
163 // resize
164 mVector.resize(0);
165}
166
167// Test equality
168bool vBaseVector::DoEqual(const vBaseVector& rOther) const {
169 FD_DC("vBaseVector(" << this << ")::DoEqual()");
170 if(Size()!=rOther.Size()) return false;
171 Position p=0;
172 for(;p<Size();++p) {
173 bool eq= At(p).Equal(rOther.At(p));
174 FD_DF("vBaseVector(" << this << ")::DoEqual(): " << p << ": " << eq);
175 if(!eq) return false;
176 }
177 return true;
178}
179
180// Size()
182 return (Idx) mVector.size();
183}
184
185// Size(idx)
187 FD_DC("vBaseVector(" << this << ")::Size(..): from " << mVector.size() << " to " << len);
188 // record
189 Position olen=mVector.size();
190 // delete
191 for(Position pos=len; pos<olen; pos++)
192 if(mVector[pos].mMine) delete mVector[pos].pElement;
193 // allocate
194 mVector.resize(len);
195 // initialize
196 for(Position pos=olen; pos < len; pos++) {
197 mVector[pos].pElement = NewElement();
198 mVector[pos].mMine=true;
199 mVector[pos].mFileName = "";
200 }
201 // done
202 FD_DC("vBaseVector(" << this << ")::Size(..): done");
203}
204
205
206// Default config
207bool vBaseVector::IsDefault(void) const {
208 return mVector.empty();
209}
210
211// Empty()
212bool vBaseVector::Empty(void) const {
213 return mVector.empty();
214}
215
216// At()
217const Type& vBaseVector::At(const Position& pos) const {
218#ifdef FAUDES_CHECKED
219 if(pos >= mVector.size()) {
220 std::stringstream errstr;
221 errstr << "index out of range" << std::endl;
222 throw Exception("vBaseVector::At", errstr.str(), 62);
223 }
224#endif
225 return *mVector[pos].pElement;
226}
227
228// At()
230#ifdef FAUDES_CHECKED
231 if(pos >= mVector.size()) {
232 std::stringstream errstr;
233 errstr << "index out of range" << std::endl;
234 throw Exception("vBaseVector::At", errstr.str(), 62);
235 }
236#endif
237 return *mVector[pos].pElement;
238}
239
240
241
242// replace (copy)
243void vBaseVector::Replace(const Position& pos, const Type& rElem) {
244#ifdef FAUDES_CHECKED
245 if(pos >= mVector.size()) {
246 std::stringstream errstr;
247 errstr << "index out of range" << std::endl;
248 throw Exception("vBaseVector::At", errstr.str(), 62);
249 }
250#endif
251 if(!ElementTry(rElem)) {
252 std::stringstream errstr;
253 errstr << "cannot cast element " << std::endl;
254 throw Exception("vBaseVector::Replace(pos,elem)", errstr.str(), 63);
255 }
256 iterator pit=mVector.begin()+pos;
257 if(pit->mMine) delete pit->pElement;
258 pit->pElement=rElem.Copy();
259 pit->mMine=true;
260 pit->mFileName="";
261}
262
263// replace (take)
264void vBaseVector::Replace(const Position& pos, Type* pElem) {
265#ifdef FAUDES_CHECKED
266 if(pos >= mVector.size()) {
267 std::stringstream errstr;
268 errstr << "index out of range" << std::endl;
269 throw Exception("vBaseVector::At", errstr.str(), 62);
270 }
271#endif
272 if(!ElementTry(*pElem)) {
273 std::stringstream errstr;
274 errstr << "cannot cast element " << std::endl;
275 throw Exception("vBaseVector::Replace(pos,elem)", errstr.str(), 63);
276 }
277 iterator pit=mVector.begin()+pos;
278 if(pit->mMine) delete pit->pElement;
279 pit->pElement=pElem;
280 pit->mMine=false;
281 pit->mFileName="";
282}
283
284// replace (file)
285void vBaseVector::Replace(const Position& pos, const std::string& rFileName) {
286#ifdef FAUDES_CHECKED
287 if(pos >= mVector.size()) {
288 std::stringstream errstr;
289 errstr << "index out of range" << std::endl;
290 throw Exception("vBaseVector::At", errstr.str(), 62);
291 }
292#endif
293 iterator pit=mVector.begin()+pos;
294 if(pit->mMine) delete pit->pElement;
295 pit->pElement = NewElement();
296 pit->mMine=true;
297 pit->pElement->Read(rFileName);
298 pit->mFileName=rFileName;
299}
300
301// erase
302void vBaseVector::Erase(const Position& pos) {
303#ifdef FAUDES_CHECKED
304 if(pos >= mVector.size()) {
305 std::stringstream errstr;
306 errstr << "index out of range" << std::endl;
307 throw Exception("vBaseVector::At", errstr.str(), 62);
308 }
309#endif
310 iterator pit=mVector.begin()+pos;
311 if(pit->mMine) delete pit->pElement;
312 mVector.erase(pit);
313}
314
315
316// insert (copy)
317void vBaseVector::Insert(const Position& pos, const Type& rElem) {
318#ifdef FAUDES_CHECKED
319 if(pos > mVector.size()) {
320 std::stringstream errstr;
321 errstr << "index out of range" << std::endl;
322 throw Exception("vBaseVector::At", errstr.str(), 62);
323 }
324#endif
325 if(!ElementTry(rElem)) {
326 std::stringstream errstr;
327 errstr << "cannot cast element " << std::endl;
328 throw Exception("vBaseVector::Insert(pos,elem)", errstr.str(), 63);
329 }
330 ElementRecord elem;
331 elem.pElement = rElem.Copy();
332 elem.mMine=true;
333 elem.mFileName="";
334 iterator pit=mVector.begin()+pos;
335 mVector.insert(pit,elem);
336}
337
338// insert (take)
339void vBaseVector::Insert(const Position& pos, Type* pElem) {
340#ifdef FAUDES_CHECKED
341 if(pos > mVector.size()) {
342 std::stringstream errstr;
343 errstr << "index out of range" << std::endl;
344 throw Exception("vBaseVector::At", errstr.str(), 62);
345 }
346#endif
347 if(!ElementTry(*pElem)) {
348 std::stringstream errstr;
349 errstr << "cannot cast element " << std::endl;
350 throw Exception("vBaseVector::Insert(pos,elem)", errstr.str(), 63);
351 }
352 ElementRecord elem;
353 elem.pElement = pElem;
354 elem.mMine=false;
355 elem.mFileName="";
356 iterator pit=mVector.begin()+pos;
357 mVector.insert(pit,elem);
358}
359
360// insert (file)
361void vBaseVector::Insert(const Position& pos, const std::string& rFileName) {
362#ifdef FAUDES_CHECKED
363 if(pos > mVector.size()) {
364 std::stringstream errstr;
365 errstr << "index out of range" << std::endl;
366 throw Exception("vBaseVector::At", errstr.str(), 62);
367 }
368#endif
369 ElementRecord elem;
370 elem.pElement =NewElement();
371 elem.mMine=true;
372 elem.pElement->Read(rFileName);
373 elem.mFileName=rFileName;
374 iterator pit=mVector.begin()+pos;
375 mVector.insert(pit,elem);
376}
377
378
379// append (copy)
380void vBaseVector::PushBack(const Type& rElem) {
381 if(!ElementTry(rElem)) {
382 std::stringstream errstr;
383 errstr << "cannot cast element " << std::endl;
384 throw Exception("vBaseVector::PushBack(elem)", errstr.str(), 63);
385 }
386 ElementRecord elem;
387 elem.pElement = rElem.Copy();
388 elem.mMine=true;
389 elem.mFileName="";
390 mVector.push_back(elem);
391}
392
393// append (take)
395 if(!ElementTry(*pElem)) {
396 std::stringstream errstr;
397 errstr << "cannot cast element " << std::endl;
398 throw Exception("vBaseVector::PushBack(elem)", errstr.str(), 63);
399 }
400 ElementRecord elem;
401 elem.pElement = pElem;
402 elem.mMine=false;
403 elem.mFileName="";
404 mVector.push_back(elem);
405}
406
407// append (file)
408 void vBaseVector::PushBack(const std::string& rFileName) {
409 ElementRecord elem;
410 elem.pElement = NewElement();
411 elem.mMine=true;
412 elem.pElement->Read(rFileName);
413 elem.mFileName=rFileName;
414 mVector.push_back(elem);
415}
416
417
418// append (copy)
419void vBaseVector::Append(const Type& rElem) {
420 PushBack(rElem);
421}
422
423// append (take)
425 PushBack(pElem);
426}
427
428// append (file)
429void vBaseVector::Append(const std::string& rFileName) {
430 PushBack(rFileName);
431}
432
433
434// find
436 if(!ElementTry(rElem)) {
437 std::stringstream errstr;
438 errstr << "cannot cast element " << std::endl;
439 throw Exception("vBaseVector::Find(elem)", errstr.str(), 63);
440 }
441 Position pos=0;
442 for(;pos<Size();++pos) {
443 if(rElem.Equal(At(pos))) return pos;
444 }
445 return Size();
446}
447
448// consilidate
450 Position i=0;
451 Position j=0;
452 while(i<Size()) {
453 j=i+1;
454 while(j<Size()) {
455 if(mVector[i].pElement->Equal(*mVector[j].pElement))
456 Erase(j);
457 else
458 ++j;
459 }
460 ++i;
461 }
462}
463
464// FilenameAt()
465const std::string& vBaseVector::FilenameAt(const Position& pos) const {
466#ifdef FAUDES_CHECKED
467 if(pos >= mVector.size()) {
468 std::stringstream errstr;
469 errstr << "index out of range" << std::endl;
470 throw Exception("vBaseVector::FilenameAt", errstr.str(), 62);
471 }
472#endif
473 return mVector[pos].mFileName;
474}
475
476// FilenameAt()
477void vBaseVector::FilenameAt(const Position& pos, const std::string& rFileName) {
478#ifdef FAUDES_CHECKED
479 if(pos >= mVector.size()) {
480 std::stringstream errstr;
481 errstr << "index out of range" << std::endl;
482 throw Exception("vBaseVector::FilenameAt", errstr.str(), 62);
483 }
484#endif
485 mVector[pos].mFileName = rFileName;
486}
487
488// take ownership
490 iterator pit=mVector.begin();
491 for(;pit!=mVector.end();++pit) {
492 if(pit->mMine) continue;
493 pit->pElement=pit->pElement->Copy();
494 pit->mMine=true;
495 }
496}
497
498// take ownership
500 iterator pit=mVector.begin();
501 for(;pit!=mVector.end();++pit)
502 pit->mMine=true;
503}
504
505// DoWrite(tw, label, context)
506void vBaseVector::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
507 // figure whether we write individual files
508 bool ifiles=rTw.FileMode();
509 for(Position pos=0; pos<mVector.size() && ifiles; pos++)
510 if(mVector[pos].mFileName=="") ifiles=false;
511 // extract base directory
512 std::string dirname="";
513 if(rTw.FileMode())
514 dirname = ExtractDirectory(rTw.FileName());
515 // have a section
516 Token btag=XBeginTag(rLabel,"Vector");
517 FD_DC("vBaseVector(" << this << ")::DoWrite(..): #" << Size());
518 rTw.Write(btag);
519 // loop entries
520 std::string etstr=ElementTag();
521 for(Position pos=0; pos<mVector.size(); pos++) {
522 // just stream tokens
523 if(!ifiles) {
524 mVector[pos].pElement->Write(rTw,etstr,pContext);
525 continue;
526 }
527 // write individual files
528 std::string filename= ExtractFilename(mVector[pos].mFileName);
529 rTw.WriteString(filename);
530 mVector[pos].pElement->Write(PrependPath(dirname,filename),"",pContext);
531 }
532 rTw.WriteEnd(btag.StringValue());
533}
534
535
536// DoXWrite(tw, label, context)
537void vBaseVector::DoXWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
538 // figure whether we write individual files
539 bool ifiles=rTw.FileMode();
540 for(Position pos=0; pos<mVector.size() && ifiles; pos++)
541 if(mVector[pos].mFileName=="") ifiles=false;
542 // extract base directory
543 std::string dirname="";
544 if(rTw.FileMode())
545 dirname = ExtractDirectory(rTw.FileName());
546 // have a section
547 Token btag=XBeginTag(rLabel,"Vector");
548 FD_DC("vBaseVector(" << this << ")::DoWrite(..): #" << Size());
549 rTw.Write(btag);
550 // loop entries
551 std::string etstr=ElementTag();
552 for(Position pos=0; pos<mVector.size(); pos++) {
553 // just stream tokens
554 if(!ifiles) {
555 mVector[pos].pElement->XWrite(rTw,etstr,pContext);
556 continue;
557 }
558 // write individual files
559 std::string filename= ExtractFilename(mVector[pos].mFileName);
560 rTw.WriteString(filename); // << should we have a tag?
561 mVector[pos].pElement->XWrite(PrependPath(dirname,filename),"",pContext);
562 }
563 rTw.WriteEnd(btag.StringValue());
564}
565
566// DoDWrite(tw,rLabel,context)
567void vBaseVector::DoDWrite(TokenWriter& rTw,const std::string& rLabel, const Type* pContext) const {
568 // have a section
569 Token btag=XBeginTag(rLabel,"Vector");
570 FD_DC("vBaseVector(" << this << ")::DoWrite(..): #" << Size());
571 rTw.Write(btag);
572 for(Position pos=0; pos<mVector.size(); pos++) {
573 mVector[pos].pElement->DWrite(rTw,"",pContext);
574 }
575 rTw.WriteEnd(btag.StringValue());
576}
577
578
579// DoSWrite(tw)
581 FD_DC("vBaseVector(" << this << ")::DoSWrite(..)");
582 rTw.WriteComment(" Vector Size: "+ ToStringInteger(Size()));
583 for(Position pos=0; pos<mVector.size(); pos++) {
584 rTw.WriteComment(" Vector Entry " + ToStringInteger(pos));
585 mVector[pos].pElement->SWrite(rTw);
586 }
587 rTw.WriteComment("");
588}
589
590
591// DoRead(rTr, rLabel, pContext)
592void vBaseVector::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
593 // set up defaults
594 std::string label=rLabel;
595 std::string ftype=TypeName();
596 std::string etstr=ElementTag();
597 std::string etype=ElementType();;
598 // figure section
599 Token token;
600 if(label=="") {
601 rTr.Peek(token);
602 if(token.Type()==Token::Begin) label=token.StringValue();
603 }
604 if(label=="") label=ftype;
605 Name(label);
606 rTr.ReadBegin(label,token);
607 // fill my entries from token stream
608 while(!rTr.Eos(label)){
609 //peek token
610 rTr.Peek(token);
611 // if Token is a String we assume its the name of a file containing an element
612 if(token.Type()==Token::String) {
613 //read Token
614 rTr.Get(token);
615 // read relative filename
616 std::string filename = token.StringValue();
617 // build up path to base-file
618 std::string dirname;
619 if(rTr.SourceMode()==TokenReader::File) dirname = ExtractDirectory(rTr.FileName());
620 //build up path to specified file
621 std::string path = dirname.append(filename);
622 //insert device
623 Insert(mVector.size(),path);
624 continue;
625 }
626 // if its not a file it has to be an entry
627 else if(token.Type()==Token::Begin) {
628 // prepare
629 Type* elemp = NewElement();
630 // read entry
631 elemp->Read(rTr,etstr,pContext);
632 // insert to vector
633 Insert(mVector.size(),elemp);
634 // fix ownership
635 (--mVector.end())->mMine=true;
636 continue;
638 // token mismatch
639 std::stringstream errstr;
640 errstr << "token mismatch" << std::endl;
641 throw Exception("vBaseVector::At", errstr.str(), 50);
642 }
643 // done
644 rTr.ReadEnd(label);
645}
646
647
648
649
650} // namespace faudes
651
Class TBaseVector.
#define FD_DC(message)
#define FD_DF(message)
Classes NameSet, TaNameSet.
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
Definition cfl_types.h:958
std::string mObjectName
Definition cfl_types.h:1231
virtual const std::string & ElementType(void) const
virtual const std::string & ElementTag(void) const
const std::string & Name(void) const
virtual const std::string & TypeName(void) const
bool Eos(const std::string &rLabel)
void ReadEnd(const std::string &rLabel)
void ReadBegin(const std::string &rLabel)
bool Get(Token &token)
bool Peek(Token &token)
std::string FileName(void) const
Mode SourceMode(void) const
std::string FileName(void) const
void WriteComment(const std::string &rComment)
void Write(Token &rToken)
void WriteString(const std::string &rString)
bool FileMode(void) const
void WriteEnd(const std::string &rLabel)
const std::string & StringValue(void) const
@ Begin
<label> (begin of section)
Definition cfl_token.h:84
@ String
any string, space separated or quoted, must start with a letter
Definition cfl_token.h:86
TokenType Type(void) const
virtual Token XBeginTag(const std::string &rLabel="", const std::string &rFallbackLabel="") const
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
virtual Type * New(void) const
Definition cfl_types.cpp:54
virtual Type * Copy(void) const
Definition cfl_types.cpp:60
virtual bool Equal(const Type &rOther) const
Definition cfl_types.cpp:89
virtual const Type * Cast(const Type *pOther) const
Definition cfl_types.cpp:66
virtual Position Find(const Type &rElem)
virtual void DoSWrite(TokenWriter &rTw) const
void FilenameAt(const Position &pos, const std::string &rFileName)
virtual ~vBaseVector(void)
virtual Type * NewElement(void)
virtual const Type & At(const Position &pos) const
bool Empty(void) const
virtual const Type & Element(void) const
virtual void EraseDoublets(void)
virtual void Insert(const Position &pos, const Type &rElem)
bool IsDefault(void) const
void AssignByReference(vBaseVector &rSourceVector)
std::string mElementTagDef
virtual const Type * Elementp(void) const
virtual bool ElementTry(const Type &rElement) const
virtual void Erase(const Position &pos)
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
virtual void Append(const Type &rElem)
virtual void DoDWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
virtual void DoXWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
virtual void PushBack(const Type &rElem)
virtual void Replace(const Position &pos, const Type &rElem)
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
void DoAssign(const vBaseVector &rSourceVector)
std::vector< ElementRecord >::iterator iterator
virtual void Clear(void)
std::vector< ElementRecord > mVector
bool DoEqual(const vBaseVector &rOther) const
uint32_t Idx
std::string ExtractDirectory(const std::string &rFullPath)
std::string PrependPath(const std::string &rLeft, const std::string &rRight)
std::string ExtractFilename(const std::string &rFullPath)
std::string ToStringInteger(Int number)
Definition cfl_utils.cpp:43

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen