1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/output.h,v 1.65 2017/05/29 17:50:43 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  * ACKNOWLEDGEMENTS:
33  * Support for output with NetCDF is based on a contribution
34  * by Patrick Rix <patrick.rix@online.de>
35  */
36 
37 /* gestore dell'output */
38 
39 #ifndef OUTPUT_H
40 #define OUTPUT_H
41 
42 /* se #define DEBUG_COUT l'output avviene su cout anziche' nei files */
43 
44 #include <iostream>
45 #include <iomanip>
46 #include <fstream>
47 #include <vector>
48 #include <typeinfo>
49 
50 #ifdef USE_NETCDF
51 #if defined(HAVE_NETCDFCPP_H)
52 #include <netcdfcpp.h>
53 #elif defined(HAVE_NETCDF_H)
54 #include <netcdf.h>
55 #endif
56 #endif /* USE_NETCDF */
57 
58 #include "myassert.h"
59 #include "except.h"
60 #include "solman.h"
61 #include "filename.h"
62 
63 /* OutputHandler - begin */
64 
65 class OutputHandler : public FileName {
66 public:
67 	enum OutFiles {
68 		UNKNOWN			= -1,
69 		FIRSTFILE		= 0,
70 		OUTPUT			= 0,	//  0
71 		STRNODES,
72 		ELECTRIC,
73 		ABSTRACT,
74 		INERTIA,
75 		JOINTS,				//  5
76 		FORCES,
77 		BEAMS,
78 		ROTORS,
79 		RESTART,
80 		RESTARTXSOL,			// 10
81 		AERODYNAMIC,
82 		HYDRAULIC,
83 		PRESNODES,
84 		LOADABLE,
85 		GENELS,				// 15
86 		PARTITION,
87 		AEROMODALS,
88 		REFERENCEFRAMES,
89 		LOG,
90 		AIRPROPS,			// 20
91 		PARAMETERS,
92 		EXTERNALS,
93 		MODAL,
94 		NETCDF,
95 		THERMALNODES,			// 25
96 		THERMALELEMENTS,
97 		PLATES,
98 		GRAVITY,
99 		DOFSTATS,
100 		DRIVECALLERS,			// 30
101 		TRACES,
102 		EIGENANALYSIS,			// NOTE: ALWAYS LAST!
103 		LASTFILE			// 33
104 	};
105 
106 private:
107 	long currentStep;
108 
109 public:
SetCurrentStep(long Step)110 	inline void SetCurrentStep(long Step) {
111 		currentStep = Step;
112 	};
IncCurrentStep(void)113 	inline void IncCurrentStep(void) {
114 		currentStep++;
115 	};
GetCurrentStep(void)116        	inline long GetCurrentStep(void) const {
117 		return currentStep;
118 	};
119 
120 private:
121 
122 	// flag values
123 	enum {
124 		OUTPUT_NONE			= 0x00U,
125 		OUTPUT_USE_DEFAULT_PRECISION	= 0x01U,
126 		OUTPUT_USE_SCIENTIFIC		= 0x02U,
127 
128 		OUTPUT_MAY_USE_TEXT		= 0x10U,
129 		OUTPUT_USE_TEXT			= 0x20U,
130 		OUTPUT_MAY_USE_NETCDF		= 0x40U,
131 		OUTPUT_USE_NETCDF		= 0x80U,
132 
133 		LAST
134 	};
135 
136 	/* Aggiungere qui i files che si desidera avere a disposizione */
137 	struct {
138 		std::ofstream*	pof;
139 		unsigned	flags;
140 	} OutData[LASTFILE];
141 
142 	// NetCDF dimensions and global attributes related to the binary file
143 #ifdef USE_NETCDF
144 	const NcDim *m_DimTime;
145 	const NcDim *m_DimV1;
146 	const NcDim *m_DimV3;
147 	NcFile *m_pBinFile;   /* ! one ! binary NetCDF data file */
148 #endif /* USE_NETCDF */
149 
150 	/* handlers to streams */
151 	std::ofstream ofOutput;      		/*  0 */
152 	std::ofstream ofStrNodes;
153 	std::ofstream ofElectric;
154 	std::ofstream ofAbstract;
155 	std::ofstream ofInertia;
156 	std::ofstream ofJoints;      		/*  5 */
157 	std::ofstream ofForces;
158 	std::ofstream ofBeams;
159 	std::ofstream ofRotors;
160 	std::ofstream ofRestart;
161 	std::ofstream ofRestartXSol; 		/* 10 */
162 	std::ofstream ofAerodynamic;
163 	std::ofstream ofHydraulic;
164 	std::ofstream ofPresNodes;
165 	std::ofstream ofLoadable;
166 	std::ofstream ofGenels;			/* 15 */
167 	std::ofstream ofPartition;
168 	std::ofstream ofAeroModals;
169 	std::ofstream ofReferenceFrames;	/* 20 */
170 	std::ofstream ofLog;
171 	std::ofstream ofAirProps;
172 	std::ofstream ofParameters;
173 	std::ofstream ofExternals;
174 	std::ofstream ofModal;			/* 25 */
175 	std::ofstream ofThermalNodes;
176 	std::ofstream ofThermalElements;
177 	std::ofstream ofPlates;
178 	std::ofstream ofGravity;
179 	std::ofstream ofDofStats;		/* 30 */
180 	std::ofstream ofDriveCallers;
181 	std::ofstream ofTraces;
182 	std::ofstream ofEigenanalysis;
183 
184 	int iCurrWidth;
185 	int iCurrPrecision;
186 	int nCurrRestartFile;
187 
188 	// private because we know we're using valid out index
189 	bool IsOpen(int out) const;
190 	bool UseDefaultPrecision(int out) const;
191 	bool UseScientific(int out) const;
192 
193 	bool UseText(int out) const;
194 	bool UseNetCDF(int out) const;
195 
196 	// Pseudo-constructor
197 	void OutputHandler_int(void);
198 
199 public:
200 	OutputHandler(void);
201 
202 	OutputHandler(const char* sFName, int iExtNum = -1);
203 
204 	void Init(const char* sFName, int iExtNum = -1);
205 
206 	virtual ~OutputHandler(void);
207 
208 	/* Aggiungere qui le funzioni che aprono i singoli stream */
209 	bool Open(const OutputHandler::OutFiles out);
210 
211 	/* Overload for eigenanalysis text output */
212 	bool Open(const int out, const std::string& postfix);
213 	bool IsOpen(const OutputHandler::OutFiles out) const;
214 	bool UseDefaultPrecision(const OutputHandler::OutFiles out) const;
215 	bool UseScientific(const OutputHandler::OutFiles out) const;
216 
217 	void SetText(const OutputHandler::OutFiles out);
218 	void ClearText(void);
219 	void ClearText(const OutputHandler::OutFiles out);
220 	bool UseText(const OutputHandler::OutFiles out) const;
221 
222 	void SetNetCDF(const OutputHandler::OutFiles out);
223 	void ClearNetCDF(void);
224 	void ClearNetCDF(const OutputHandler::OutFiles out);
225 	bool UseNetCDF(const OutputHandler::OutFiles out) const;
226 
227 	bool Close(const OutputHandler::OutFiles out);
228 
229 	bool OutputOpen(void);
230 	bool RestartOpen(bool openResXSol = false);
231 
232 	bool PartitionOpen(void);
233 	bool LogOpen(void);
234 
235 	/* Aggiungere qui le funzioni che ritornano gli stream desiderati */
236 	inline std::ostream& Get(const OutputHandler::OutFiles f);
237 
238 	inline std::ostream& Output(void) const;
239 	inline std::ostream& StrNodes(void) const;
240 	inline std::ostream& Electric(void) const;
241 	inline std::ostream& Abstract(void) const;
242 	inline std::ostream& Inertia(void) const;
243 	inline std::ostream& Joints(void) const;
244 	inline std::ostream& Forces(void) const;
245 	inline std::ostream& Beams(void) const;
246 	inline std::ostream& Rotors(void) const;
247 	inline std::ostream& Restart(void) const;
248 	inline std::ostream& RestartXSol(void) const;
249 	inline std::ostream& Aerodynamic(void) const;
250 	inline std::ostream& Hydraulic(void) const;
251 	inline std::ostream& PresNodes(void) const;
252 	inline std::ostream& Loadable(void) const;
253 	inline std::ostream& Genels(void) const;
254 	inline std::ostream& Partition(void) const;
255 	inline std::ostream& AeroModals(void) const;
256 	inline std::ostream& ReferenceFrames(void) const;
257 	inline std::ostream& Log(void) const;
258 	inline std::ostream& AirProps(void) const;
259 	inline std::ostream& Parameters(void) const;
260 	inline std::ostream& Externals(void) const;
261 	inline std::ostream& Modal(void) const;
262 	inline std::ostream& ThermalNodes(void) const;
263 	inline std::ostream& ThermalElements(void) const;
264 	inline std::ostream& Plates(void) const;
265 	inline std::ostream& Gravity(void) const;
266 	inline std::ostream& DofStats(void) const;
267 	inline std::ostream& DriveCallers(void) const;
268 	inline std::ostream& Traces(void) const;
269 	inline std::ostream& Eigenanalysis(void) const;
270 
271 	inline int iW(void) const;
272 	inline int iP(void) const;
273 
274 	void SetWidth(int iNewWidth);
275 	void SetPrecision(int iNewPrecision);
276 	void SetExceptions(std::ios::iostate flags);
277 
278 #ifdef USE_NETCDF
279 	inline NcFile* pGetBinFile(void) const;
280 
281 	struct AttrVal {
282 		std::string attr;
283 		std::string val;
AttrValAttrVal284 		AttrVal(void) { NO_OP; };
AttrValAttrVal285 		AttrVal(const std::string& attr, const std::string& val) : attr(attr), val(val) { NO_OP; };
286 	};
287 
288 	typedef std::vector<OutputHandler::AttrVal> AttrValVec;
289 	typedef std::vector<const NcDim *> NcDimVec;
290 
291 	const NcDim *
292 	CreateDim(const std::string& name, integer size = -1);
293 
294 	const NcDim *
295 	GetDim(const std::string& name) const;
296 
297 	inline const NcDim* DimTime(void) const;
298 	inline const NcDim* DimV1(void) const;
299 	inline const NcDim* DimV3(void) const;
300 
301 	NcVar *
302 	CreateVar(const std::string& name, NcType type,
303 		const AttrValVec& attrs, const NcDimVec& dims);
304 
305 	NcVar *
306 	CreateVar(const std::string& name, const std::string& type);
307 
308 	template <class T>
309 	NcVar *
310 	CreateVar(const std::string& name,
311 		const std::string& units, const std::string& description);
312 
313 	NcVar *
314 	CreateRotationVar(const std::string& name_prefix,
315 		const std::string& name_postfix,
316 		OrientationDescription od,
317 		const std::string& description);
318 #endif /* USE_NETCDF */
319 }; /* End class OutputHandler */
320 
321 #ifdef USE_NETCDF
322 template <class T>
323 NcVar *
CreateVar(const std::string & name,const std::string & units,const std::string & description)324 OutputHandler::CreateVar(const std::string& name,
325 	const std::string& units, const std::string& description)
326 {
327 	AttrValVec attrs(3);
328 	NcDimVec dims(1);
329 
330 	attrs[0] = AttrVal("units", units);
331 	attrs[2] = AttrVal("description", description);
332 	dims[0] = DimTime();
333 
334 	NcType type;
335 	if (typeid(T) == typeid(integer)) {
336 		attrs[1] = AttrVal("type", "integer");
337 		type = ncLong;
338 
339 	} else if (typeid(T) == typeid(doublereal)) {
340 		attrs[1] = AttrVal("type", "doublereal");
341 		type = ncDouble;
342 
343 	} else if (typeid(T) == typeid(Vec3)) {
344 		attrs[1] = AttrVal("type", "Vec3");
345 		dims.resize(2);
346 		dims[1] = DimV3();
347 		type = ncDouble;
348 
349 	} else {
350 		throw ErrGeneric(MBDYN_EXCEPT_ARGS);
351 	}
352 
353 	return CreateVar(name, type, attrs, dims);
354 }
355 
356 inline NcFile *
pGetBinFile(void)357 OutputHandler::pGetBinFile(void) const
358 {
359 	return m_pBinFile;
360 }
361 
362 inline const NcDim *
DimTime(void)363 OutputHandler::DimTime(void) const
364 {
365 	return m_DimTime;
366 }
367 
368 inline const NcDim *
DimV1(void)369 OutputHandler::DimV1(void) const
370 {
371 	return m_DimV1;
372 }
373 
374 inline const NcDim *
DimV3(void)375 OutputHandler::DimV3(void) const
376 {
377 	return m_DimV3;
378 }
379 #endif /* USE_NETCDF */
380 
381 inline std::ostream&
Get(const OutputHandler::OutFiles f)382 OutputHandler::Get(const OutputHandler::OutFiles f)
383 {
384 	ASSERT(f > -1 && f < LASTFILE);
385 	ASSERT(IsOpen(f));
386 	return *(OutData[f].pof);
387 }
388 
389 inline std::ostream&
Output(void)390 OutputHandler::Output(void) const
391 {
392 #ifdef DEBUG_COUT
393 	return const_cast<std::ostream &>(cout);
394 #else
395 	ASSERT(IsOpen(OUTPUT));
396 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofOutput));
397 #endif
398 }
399 
400 inline std::ostream&
StrNodes(void)401 OutputHandler::StrNodes(void) const
402 {
403 	ASSERT(IsOpen(STRNODES));
404 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofStrNodes));
405 }
406 
407 inline std::ostream&
Electric(void)408 OutputHandler::Electric(void) const
409 {
410 	ASSERT(IsOpen(ELECTRIC));
411 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofElectric));
412 }
413 
414 inline std::ostream&
ThermalNodes(void)415 OutputHandler::ThermalNodes(void) const
416 {
417 	ASSERT(IsOpen(THERMALNODES));
418 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofThermalNodes));
419 }
420 
421 inline std::ostream&
ThermalElements(void)422 OutputHandler::ThermalElements(void) const
423 {
424 	ASSERT(IsOpen(THERMALELEMENTS));
425 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofThermalElements));
426 }
427 
428 inline std::ostream&
Abstract(void)429 OutputHandler::Abstract(void) const
430 {
431 	ASSERT(IsOpen(ABSTRACT));
432 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofAbstract));
433 }
434 
435 inline std::ostream&
Inertia(void)436 OutputHandler::Inertia(void) const
437 {
438 	ASSERT(IsOpen(INERTIA));
439 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofInertia));
440 }
441 
442 inline std::ostream&
Joints(void)443 OutputHandler::Joints(void) const
444 {
445 	ASSERT(IsOpen(JOINTS));
446 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofJoints));
447 }
448 
449 inline std::ostream&
Forces(void)450 OutputHandler::Forces(void) const
451 {
452 	ASSERT(IsOpen(FORCES));
453 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofForces));
454 }
455 
456 inline std::ostream&
Beams(void)457 OutputHandler::Beams(void) const
458 {
459 	ASSERT(IsOpen(BEAMS));
460 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofBeams));
461 }
462 
463 inline std::ostream&
Rotors(void)464 OutputHandler::Rotors(void) const
465 {
466 	ASSERT(IsOpen(ROTORS));
467 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofRotors));
468 }
469 
470 inline std::ostream&
Restart(void)471 OutputHandler::Restart(void) const
472 {
473 	ASSERT(IsOpen(RESTART));
474 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofRestart));
475 }
476 
477 inline std::ostream&
RestartXSol(void)478 OutputHandler::RestartXSol(void) const
479 {
480 	ASSERT(IsOpen(RESTART));
481 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofRestartXSol));
482 }
483 
484 inline std::ostream&
Aerodynamic(void)485 OutputHandler::Aerodynamic(void) const
486 {
487 	ASSERT(IsOpen(AERODYNAMIC));
488 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofAerodynamic));
489 }
490 
491 inline std::ostream&
Hydraulic(void)492 OutputHandler::Hydraulic(void) const
493 {
494 	ASSERT(IsOpen(HYDRAULIC));
495 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofHydraulic));
496 }
497 
498 inline std::ostream&
PresNodes(void)499 OutputHandler::PresNodes(void) const
500 {
501 	ASSERT(IsOpen(PRESNODES));
502 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofPresNodes));
503 }
504 
505 inline std::ostream&
Loadable(void)506 OutputHandler::Loadable(void) const
507 {
508 	ASSERT(IsOpen(LOADABLE));
509 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofLoadable));
510 }
511 
512 inline std::ostream&
Genels(void)513 OutputHandler::Genels(void) const
514 {
515 	ASSERT(IsOpen(GENELS));
516 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofGenels));
517 }
518 
519 inline std::ostream&
Partition(void)520 OutputHandler::Partition(void) const
521 {
522 	ASSERT(IsOpen(PARTITION));
523 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofPartition));
524 }
525 
526 inline std::ostream&
AeroModals(void)527 OutputHandler::AeroModals(void) const
528 {
529 	ASSERT(IsOpen(AEROMODALS));
530 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofAeroModals));
531 }
532 
533 inline std::ostream&
ReferenceFrames(void)534 OutputHandler::ReferenceFrames(void) const
535 {
536 	ASSERT(IsOpen(REFERENCEFRAMES));
537 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofReferenceFrames));
538 }
539 
540 inline std::ostream&
Log(void)541 OutputHandler::Log(void) const
542 {
543 #ifdef DEBUG_COUT
544 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(cout));
545 #else
546 	ASSERT(IsOpen(LOG));
547 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofLog));
548 #endif
549 }
550 
551 inline std::ostream&
AirProps(void)552 OutputHandler::AirProps(void) const
553 {
554 	ASSERT(IsOpen(AIRPROPS));
555 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofAirProps));
556 }
557 
558 inline std::ostream&
Parameters(void)559 OutputHandler::Parameters(void) const
560 {
561 	ASSERT(IsOpen(PARAMETERS));
562 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofParameters));
563 }
564 
565 inline std::ostream&
Externals(void)566 OutputHandler::Externals(void) const
567 {
568 	ASSERT(IsOpen(EXTERNALS));
569 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofExternals));
570 }
571 
572 inline std::ostream&
Modal(void)573 OutputHandler::Modal(void) const
574 {
575 	ASSERT(IsOpen(MODAL));
576 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofModal));
577 }
578 
579 inline std::ostream&
Plates(void)580 OutputHandler::Plates(void) const
581 {
582 	ASSERT(IsOpen(PLATES));
583 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofPlates));
584 }
585 
586 inline std::ostream&
Gravity(void)587 OutputHandler::Gravity(void) const
588 {
589 	ASSERT(IsOpen(GRAVITY));
590 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofGravity));
591 }
592 
593 inline std::ostream&
DofStats(void)594 OutputHandler::DofStats(void) const
595 {
596 	ASSERT(IsOpen(DOFSTATS));
597 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofDofStats));
598 }
599 
600 inline std::ostream&
DriveCallers(void)601 OutputHandler::DriveCallers(void) const
602 {
603 	ASSERT(IsOpen(DRIVECALLERS));
604 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofDriveCallers));
605 }
606 
607 inline std::ostream&
Traces(void)608 OutputHandler::Traces(void) const
609 {
610 	ASSERT(IsOpen(TRACES));
611 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofTraces));
612 }
613 
614 inline std::ostream&
Eigenanalysis(void)615 OutputHandler::Eigenanalysis(void) const
616 {
617 	ASSERT(IsOpen(EIGENANALYSIS));
618 	return const_cast<std::ostream &>(dynamic_cast<const std::ostream &>(ofEigenanalysis));
619 }
620 
621 
622 inline int
iW(void)623 OutputHandler::iW(void) const
624 {
625 	return iCurrWidth;
626 }
627 
628 inline int
iP(void)629 OutputHandler::iP(void) const
630 {
631 	return iCurrPrecision;
632 }
633 
634 /* OutputHandler - end */
635 
636 
637 /* ToBeOutput - begin */
638 
639 const flag fDefaultOut = 1;
640 
641 class ToBeOutput {
642 public:
643 	enum {
644 		OUTPUT = 0x1U,
645 
646 		// use OUTPUT_MASK to isolate public output flags
647 		OUTPUT_MASK = 0xFU,
648 
649 		// reserve values up to OUTPUT_PRIVATE for public use;
650 		// reserved output flags can start from OUTPUT_PRIVATE up
651 		OUTPUT_PRIVATE = 0x10U,
652 
653 		// use OUTPUT_PRIVATE_MASK to isolate private output flags
654 		OUTPUT_PRIVATE_MASK = ~OUTPUT_MASK
655 	};
656 
657 protected:
658 	flag fOutput;
659 
660 public:
661 	ToBeOutput(flag fOut = fDefaultOut);
662 	virtual ~ToBeOutput(void);
663 
664 	virtual void OutputPrepare(OutputHandler &OH);
665 
666 	/* Regular output */
667 	virtual void Output(OutputHandler& OH) const;
668 
669 	/* Output of perturbed solution (modes ...) */
670 	virtual void Output(OutputHandler& OH,
671 	const VectorHandler& X, const VectorHandler& XP) const;
672 
673 	virtual flag fToBeOutput(void) const;
674 	virtual bool bToBeOutput(void) const;
675 	virtual void SetOutputFlag(flag f = flag(1));
676 };
677 
678 /* ToBeOutput - end */
679 
680 class Traceable {
681 public:
682 	enum {
683 		TRACE 				= 0x01U,
684 		TRACE_PUBLIC_MASK	= 0x0FU,
685 		TRACE_PRIVATE		= 0x10U,
686 		TRACE_PRIVATE_MASK	= ~TRACE_PUBLIC_MASK
687 	};
688 
689 	Traceable(flag fTrace = 0);
690 	virtual ~Traceable(void);
691 
692 	virtual void Trace(OutputHandler& OH) const=0;
693 	virtual flag fToBeTraced(void) const;
694 	virtual void SetTraceFlag(flag f = TRACE);
695 
696 private:
697 	flag fTrace;
698 };
699 
700 #endif /* OUTPUT_H */
701