PSCF v1.1
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 }
220
221 /*
222 * Set this to be the parent of a child component.
223 */
225 {
226 param.setIndent(*this, next);
227 #ifdef UTIL_MPI
228 if (hasIoCommunicator()) {
230 }
231 #endif
232 }
233
234 /*
235 * Add a leaf ParamComponent to the format array.
236 */
238 {
239 list_.push_back(&param);
240 isLeaf_.push_back(isLeaf);
241 ++size_;
242 }
244 // ParamComposite object
245
246 /*
247 * Add a required ParamComposite node.
248 */
250 {
251 bool isLeaf = false;
252 setParent(child, next);
253 addComponent(child, isLeaf);
254 }
255
256 /*
257 * Add a required ParamComposite node, and call its readParam() method.
258 */
259 void
261 bool next)
262 {
263 addParamComposite(child, next);
264 child.readParam(in);
265 }
266
267 /*
268 * Add an optional ParamComposite, and call its readParamOptional method.
269 */
270 void
272 ParamComposite &child, bool next)
273 {
274 addParamComposite(child, next);
275 child.readParamOptional(in);
276 }
277
278 /*
279 * Add a required ParamComposite node and load its data from archive ar.
280 */
281 void
283 ParamComposite &child, bool next)
284 {
285 addParamComposite(child, next);
286 child.load(ar);
287 }
288
289 /*
290 * Add an optional ParamComposite node, and load data if isActive.
291 */
292 void
294 ParamComposite &child, bool next)
295 {
296 addParamComposite(child, next);
297 child.loadOptional(ar);
298 }
299
300 // Begin
301
302 /*
303 * Create and add a new Begin object.
304 */
305 Begin& ParamComposite::addBegin(const char *label)
306 {
307 Begin* ptr = new Begin(label);
308 setParent(*ptr, false);
309 addComponent(*ptr);
310 return *ptr;
311 }
312
313 /*
314 * Read the opening line of a ParamComposite.
315 */
316 Begin& ParamComposite::readBegin(std::istream &in, const char *label,
317 bool isRequired)
318 {
319 Begin* ptr = new Begin(label, isRequired);
320 setParent(*ptr, false);
321 ptr->readParam(in);
322 if (ptr->isActive()) {
323 addComponent(*ptr);
324 }
325 return *ptr;
326 }
327
328 // End
329
330 /*
331 * Create and add a new End object.
332 */
334 {
335 End* ptr = new End();
336 setParent(*ptr, false);
337 addComponent(*ptr);
338 return *ptr;
339 }
340
341 /*
342 * Read the closing bracket of a ParamComposite.
343 */
344 End& ParamComposite::readEnd(std::istream &in)
345 {
346 End* ptr = &addEnd();
347 ptr->readParam(in);
348 return *ptr;
349 }
350
351 // Blank
352
353 /*
354 * Create and add a new Blank object (a blank line).
355 */
357 {
358 Blank* ptr = new Blank();
359 setParent(*ptr);
360 addComponent(*ptr);
361 return *ptr;
362 }
363
364 /*
365 * Read a blank line.
366 */
368 {
369 Blank* ptr = &addBlank();
370 ptr->readParam(in);
371 return *ptr;
372 }
373
374 /*
375 * Set the class name string.
376 */
377 void ParamComposite::setClassName(const char * className)
378 { className_ = className; }
379
380 /*
381 * Set or unset the isActive flag.
382 */
383 void ParamComposite::setIsRequired(bool isRequired)
384 {
385 isRequired_ = isRequired;
386 if (isRequired_) {
387 isActive_ = true;
388 }
389 }
390
391 /*
392 * Set or unset the isActive flag.
393 */
394 void ParamComposite::setIsActive(bool isActive)
395 {
396 if (isRequired_ && !isActive) {
397 UTIL_THROW("Error: cannot be required but not active");
398 }
399 isActive_ = isActive;
400 }
401
402}
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
Saving archive for binary istream.
Saving / output archive for binary ostream.
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:57
MPI::Intracomm & ioCommunicator() const
Get the MPI communicator by reference.
Definition: MpiFileIo.h:105
bool isIoProcessor() const
Can this processor do file I/O ?
Definition: MpiFileIo.h:92
void setIoCommunicator(MPI::Intracomm &communicator)
Set the communicator.
Definition: MpiFileIo.cpp:36
bool hasIoCommunicator() const
Does this object have an associated MPI communicator?
Definition: MpiFileIo.h:99
Abstract base class for classes that input and ouput parameters to file.
std::string indent() const
Return indent string for this object (string of spaces).
void setIndent(const ParamComponent &parent, bool next=true)
Set indent level.
static bool echo()
Get echo parameter.
An object that can read multiple parameters from file.
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?
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:51
Utility classes for scientific computation.
Definition: accumulators.mod:1
void bcast< bool >(MPI::Intracomm &comm, bool &data, int root)
Explicit specialization of bcast for bool data.
Definition: MpiSendRecv.cpp:34