PSCF v1.3
ParamComposite.cpp
1/*
2* Util Package - C++ Utilities for Scientific Computation
3*
4* Copyright 2010 - 2017, The Regents of the University of Minnesota
5* Distributed under the terms of the GNU General Public License.
6*/
7
8#include "ParamComposite.h" // class header
9#include "Begin.h"
10#include "End.h"
11#include "Blank.h"
12#include <util/global.h>
13
14#include <cstdio>
15#include <cstring>
16
17namespace Util
18{
19
20 /*
21 * Default Constructor.
22 */
25 list_(),
26 isLeaf_(),
27 size_(0),
28 className_("ParamComposite"),
29 isRequired_(true),
30 isActive_(true)
31 {}
32
33 /*
34 * Constructor.
35 */
38 list_(),
39 isLeaf_(),
40 size_(0),
41 className_("ParamComposite"),
42 isRequired_(true),
43 isActive_(true)
44 {
45 if (capacity <= 0 ) {
46 UTIL_THROW("Attempt to reserve capacity <= 0");
47 }
48 list_.reserve(capacity);
49 isLeaf_.reserve(capacity);
50 }
51
52 /*
53 * Copy constructor.
54 */
56 : ParamComponent(other),
57 list_(),
58 isLeaf_(),
59 size_(0),
60 className_(other.className_),
61 isRequired_(true),
62 isActive_(true)
63 {}
64
65 /*
66 * Destructor.
67 */
69 {
70 if (size_ > 0) {
71 for (int i=0; i < size_; ++i) {
72 if (isLeaf_[i]) {
73 delete list_[i];
74 }
75 /* Only delete Parameter, Begin, End & Blank leaf objects.
76 * Do NOT delete node objects here. These are instances of
77 * of subclasses of ParamComposite that are never created
78 * by this object, and so should not be destroyed by this
79 * object.
80 */
81 }
82 }
83 }
84
85 /*
86 * Read required parameter block, including begin and end.
87 */
88 void ParamComposite::readParam(std::istream &in)
89 {
90 assert(className_.size() > 0);
91 isRequired_ = true;
92 isActive_ = true;
93 readBegin(in, className_.c_str());
95 readEnd(in);
96 }
97
98 /*
99 * Read optional parameter block, including begin and end.
100 */
102 {
103 assert(className_.size() > 0);
104 isRequired_ = false;
105 isActive_ = false;
106 Begin* beginPtr = &readBegin(in, className_.c_str(), isRequired_);
107 if (beginPtr->isActive()) {
108 readParameters(in);
109 readEnd(in);
110 isActive_ = true;
111 } else {
112 delete beginPtr;
113 }
114 }
115
116 /*
117 * Default writeParam implementation.
118 */
119 void ParamComposite::writeParam(std::ostream &out) const
120 {
121 if (isActive_) {
122 for (int i=0; i < size_; ++i) {
123 list_[i]->writeParam(out);
124 }
125 }
126 }
127
128 /*
129 * Default load implementation, adds begin and end.
130 */
132 {
133 assert(className_.size() > 0);
134 Begin* beginPtr = &addBegin(className_.c_str());
135 if (ParamComponent::echo()) {
136 if (isIoProcessor()) {
137 beginPtr->writeParam(Log::file());
138 }
139 }
140 loadParameters(ar);
141 End* endPtr = &addEnd();
142 if (ParamComponent::echo()) {
143 if (isIoProcessor()) {
144 endPtr->writeParam(Log::file());
145 }
146 }
147 }
148
149 /*
150 * Optionally load this object.
151 */
153 {
154 // Load and broadcast isActive_ flag
155 if (isIoProcessor()) {
156 ar & isActive_;
157 if (!isActive_) {
158 if (ParamComponent::echo()) {
159 Log::file() << indent()
160 << className() << "{ [absent] }"
161 << std::endl;
162 }
163 }
164 } else {
165 #ifdef UTIL_MPI
166 if (!hasIoCommunicator()) {
167 UTIL_THROW("Error: not isIoProcessor and not hasIoCommunicator");
168 }
169 #else
170 UTIL_THROW("Error: not isIoProcessor and no MPI");
171 #endif
172 }
173 #ifdef UTIL_MPI
174 if (hasIoCommunicator()) {
175 bcast<bool>(ioCommunicator(), isActive_, 0);
176 }
177 #endif
178
179 // Load object data iff isActive_
180 if (isActive_) {
181 load(ar);
182 }
183 }
184
185 /*
186 * Default save implementation.
187 */
189 {
190 for (int i=0; i < size_; ++i) {
191 list_[i]->save(ar);
192 }
193 }
194
195 /*
196 * Save this optional ParamComposite.
197 */
199 {
200 ar & isActive_;
201 if (isActive_) {
202 save(ar);
203 }
204 }
205
206 /*
207 * Reset list to empty state.
208 */
210 {
211 for (int i=0; i < size_; ++i) {
212 if (isLeaf_[i]) {
213 delete list_[i];
214 } else {
215 list_[i]->resetParam();
216 }
217 }
218 size_ = 0;
219 list_.clear();
220 isLeaf_.clear();
221 }
222
223 /*
224 * Set this to be the parent of a child component.
225 */
227 {
228 param.setIndent(*this, next);
229 #ifdef UTIL_MPI
230 if (hasIoCommunicator()) {
231 param.setIoCommunicator(ioCommunicator());
232 }
233 #endif
234 }
235
236 /*
237 * Add a leaf ParamComponent to the format array.
238 */
240 {
241 list_.push_back(&param);
242 isLeaf_.push_back(isLeaf);
243 ++size_;
244 }
245
246 // ParamComposite object
247
248 /*
249 * Add a required ParamComposite node.
250 */
252 {
253 bool isLeaf = false;
254 setParent(child, next);
255 addComponent(child, isLeaf);
256 }
257
258 /*
259 * Add a required ParamComposite node, and call its readParam() method.
260 */
261 void
263 bool next)
264 {
265 addParamComposite(child, next);
266 child.readParam(in);
267 }
268
269 /*
270 * Add an optional ParamComposite, and call its readParamOptional method.
271 */
272 void
274 ParamComposite &child, bool next)
275 {
276 addParamComposite(child, next);
277 child.readParamOptional(in);
278 }
279
280 /*
281 * Add a required ParamComposite node and load its data from archive ar.
282 */
283 void
285 ParamComposite &child, bool next)
286 {
287 addParamComposite(child, next);
288 child.load(ar);
289 }
290
291 /*
292 * Add an optional ParamComposite node, and load data if isActive.
293 */
294 void
296 ParamComposite &child, bool next)
297 {
298 addParamComposite(child, next);
299 child.loadOptional(ar);
300 }
301
302 // Begin
303
304 /*
305 * Create and add a new Begin object.
306 */
307 Begin& ParamComposite::addBegin(const char *label)
308 {
309 Begin* ptr = new Begin(label);
310 setParent(*ptr, false);
311 addComponent(*ptr);
312 return *ptr;
313 }
314
315 /*
316 * Read the opening line of a ParamComposite.
317 */
318 Begin& ParamComposite::readBegin(std::istream &in, const char *label,
319 bool isRequired)
320 {
321 Begin* ptr = new Begin(label, isRequired);
322 setParent(*ptr, false);
323 ptr->readParam(in);
324 if (ptr->isActive()) {
325 addComponent(*ptr);
326 }
327 return *ptr;
328 }
329
330 // End
331
332 /*
333 * Create and add a new End object.
334 */
336 {
337 End* ptr = new End();
338 setParent(*ptr, false);
339 addComponent(*ptr);
340 return *ptr;
341 }
342
343 /*
344 * Read the closing bracket of a ParamComposite.
345 */
346 End& ParamComposite::readEnd(std::istream &in)
347 {
348 End* ptr = &addEnd();
349 ptr->readParam(in);
350 return *ptr;
351 }
352
353 // Blank
354
355 /*
356 * Create and add a new Blank object (a blank line).
357 */
359 {
360 Blank* ptr = new Blank();
361 setParent(*ptr);
362 addComponent(*ptr);
363 return *ptr;
364 }
365
366 /*
367 * Read a blank line.
368 */
370 {
371 Blank* ptr = &addBlank();
372 ptr->readParam(in);
373 return *ptr;
374 }
375
376 /*
377 * Set the class name string.
378 */
380 { className_ = className; }
381
382 /*
383 * Set or unset the isActive flag.
384 */
386 {
387 isRequired_ = isRequired;
388 if (isRequired_) {
389 isActive_ = true;
390 }
391 }
392
393 /*
394 * Set or unset the isActive flag.
395 */
397 {
398 if (isRequired_ && !isActive) {
399 UTIL_THROW("Error: cannot be required but not active");
400 }
401 isActive_ = isActive;
402 }
403
404}
Beginning line of a composite parameter block.
Definition Begin.h:25
bool isActive() const
Is this an active element (has it been read from file)?
Definition Begin.h:84
virtual void readParam(std::istream &in)
Read the opening line.
Definition Begin.cpp:33
virtual void writeParam(std::ostream &out) const
Write the opening line.
Definition Begin.cpp:80
An empty line within a parameter file.
Definition Blank.h:25
virtual void readParam(std::istream &in)
Read a blank line.
Definition Blank.cpp:23
End bracket of a ParamComposite parameter block.
Definition End.h:25
virtual void writeParam(std::ostream &out) const
Write the closing bracket.
Definition End.cpp:43
virtual void readParam(std::istream &in)
Read the closing bracket.
Definition End.cpp:30
static std::ostream & file()
Get log ostream by reference.
Definition Log.cpp:59
bool isIoProcessor() const
Can this processor do file I/O ?
Definition MpiFileIo.h:94
std::string indent() const
Return indent string for this object (string of spaces).
ParamComponent()
Constructor.
void setIndent(const ParamComponent &parent, bool next=true)
Set indent level.
static bool echo()
Get echo parameter.
virtual void load(Serializable::IArchive &ar)
Load all parameters from an input archive.
virtual void loadOptional(Serializable::IArchive &ar)
Load an optional ParamComposite.
virtual void readParameters(std::istream &in)
Read the body of parameter block, without begin and end lines.
Begin & readBegin(std::istream &in, const char *label, bool isRequired=true)
Add and read a class label and opening bracket.
void addParamComposite(ParamComposite &child, bool next=true)
Add a child ParamComposite object to the format array.
void saveOptional(Serializable::OArchive &ar)
Saves isActive flag, and then calls save() iff isActive is true.
void setClassName(const char *className)
Set class name string.
void setIsRequired(bool isRequired)
Set or unset the isActive flag.
void resetParam()
Resets ParamComposite to its empty state.
virtual ~ParamComposite()
Virtual destructor.
virtual void save(Serializable::OArchive &ar)
Saves all parameters to an archive.
Begin & addBegin(const char *label)
Add a Begin object representing a class name and bracket.
void setIsActive(bool isActive)
Set or unset the isActive flag.
virtual void writeParam(std::ostream &out) const
Write all parameters to an output stream.
void loadParamComposite(Serializable::IArchive &ar, ParamComposite &child, bool next=true)
Add and load a required child ParamComposite.
virtual void readParam(std::istream &in)
Read the parameter file block.
Blank & addBlank()
Create and add a new Blank object, representing a blank line.
bool isActive() const
Is this parameter active?
End & addEnd()
Add a closing bracket.
ParamComposite()
Constructor.
std::string className() const
Get class name string.
void loadParamCompositeOptional(Serializable::IArchive &ar, ParamComposite &child, bool next=true)
Add and load an optional child ParamComposite if isActive.
Blank & readBlank(std::istream &in)
Add and read a new Blank object, representing a blank line.
void readParamComposite(std::istream &in, ParamComposite &child, bool next=true)
Add and read a required child ParamComposite.
virtual void readParamOptional(std::istream &in)
Read optional parameter file block.
void readParamCompositeOptional(std::istream &in, ParamComposite &child, bool next=true)
Add and attempt to read an optional child ParamComposite.
End & readEnd(std::istream &in)
Add and read the closing bracket.
void setParent(ParamComponent &param, bool next=true)
Set this to the parent of a child component.
virtual void loadParameters(Serializable::IArchive &ar)
Load state from archive, without adding Begin and End lines.
void addComponent(ParamComponent &param, bool isLeaf=true)
Add a new ParamComponent object to the format array.
bool isRequired() const
Is this ParamComposite required in the input file?
BinaryFileIArchive IArchive
Type of input archive used by load method.
BinaryFileOArchive OArchive
Type of output archive used by save method.
File containing preprocessor macros for error handling.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition global.h:49
Utility classes for scientific computation.