Files
mlpack/fastlib/trilinos/include/Teuchos_VerboseObject.hpp
T

412 lines
12 KiB
C++

// @HEADER
// ***********************************************************************
//
// Teuchos: Common Tools Package
// Copyright (2004) Sandia Corporation
//
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
// license for use of this work by or on behalf of the U.S. Government.
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
//
// ***********************************************************************
// @HEADER
#ifndef TEUCHOS_VERBOSE_OBJECT_HPP
#define TEUCHOS_VERBOSE_OBJECT_HPP
#include "Teuchos_RCP.hpp"
#include "Teuchos_FancyOStream.hpp"
#include "Teuchos_VerbosityLevel.hpp"
namespace Teuchos {
/** \brief Non-templated base class for objects that can print their
* activities to a stream.
*
* \ingroup teuchos_outputting_grp
*
* Objects that derive from this interface print to a default class-owned
* (i.e. static) output stream object (set using <tt>setDefaultOStream()</tt>)
* or the output stream can be set on an object-by-object basis using
* <tt>setOStream()</tt>.
*
* The output stream type is <tt>FancyOStream</tt> which allows for automated
* indentation (using the <tt>OSTab</tt> class) and has other useful features.
*/
class VerboseObjectBase {
public:
//! @name Public static member functions
//@{
/** \brief Set the default output stream object.
*
* If this function is not called, then a default stream based on
* <tt>std::cout</tt> is used.
*/
static void setDefaultOStream( const RCP<FancyOStream> &defaultOStream );
/** \brief Get the default output stream object. */
static RCP<FancyOStream> getDefaultOStream();
//@}
//! @name Constructors/Initializers
//@{
/** \brief . */
virtual ~VerboseObjectBase() {}
/** \brief Calls <tt>initializeVerboseObject()</tt>.
*/
explicit
VerboseObjectBase(
const RCP<FancyOStream> &oStream = Teuchos::null
);
/** \brief Calls <tt>initializeVerboseObject()</tt>.
*/
virtual void initializeVerboseObjectBase(
const RCP<FancyOStream> &oStream = Teuchos::null
);
/** \brief The output stream for <tt>*this</tt> object.
*
* This function is supposed by called by general clients to set the output
* stream according to some general logic in the code.
*/
virtual const VerboseObjectBase& setOStream(
const RCP<FancyOStream> &oStream) const;
/** \brief Set the overriding the output stream for <tt>*this</tt> object.
*
* This function is supposed to be called by special clients that want to
* set the output stream in a way that will not be overridden by
* <tt>setOStream()</tt>.
*/
virtual const VerboseObjectBase& setOverridingOStream(
const RCP<FancyOStream> &oStream) const;
/** \brief Set line prefix name for this object */
virtual VerboseObjectBase& setLinePrefix(const std::string &linePrefix);
//@}
//! @name Query functions
//@{
/** \brief Return the output stream to be used for out for <tt>*this</tt>
* object.
*/
virtual RCP<FancyOStream> getOStream() const;
/** \brief Return the the overriding output stream if set.
*
* This is the output stream tthat will be returned from
* <tt>getOStream()</tt> regardless that stream is set by
* <tt>setOStream()</tt>.
*/
virtual RCP<FancyOStream> getOverridingOStream() const;
/** \brief Get the line prefix for this object */
virtual std::string getLinePrefix() const;
//@}
//! @name Utilities
//@{
/** \brief Create a tab object which sets the number of tabs and optionally the line prefix.
*
* \param tabs [in] The number of relative tabs to add (if <tt>tabs > 0</tt>) or remove (if <tt>tabs < 0</tt>).
* If <tt>tabs == OSTab::DISABLE_TABBING</tt> then tabbing will be turned off temporarily.
*
* \param linePrefix
* [in] Sets a line prefix that overrides <tt>this->getLinePrefix()</tt>.
*
* The side effects of these changes go away as soon as the returned
* <tt>OSTab</tt> object is destroyed at the end of the block of code.
*
* Returns <tt>OSTab( this->getOStream(), tabs, linePrefix.length() ? linePrefix : this->getLinePrefix() )</tt>
*/
virtual OSTab getOSTab(const int tabs = 1, const std::string &linePrefix = "") const;
//@}
protected:
/** \brief Function that is called whenever the verbosity state
* is updated.
*
* Subclasses can override this function to be informed whenever the
* verbosity state of <tt>*this</tt> object gets updated.
*
* The default implementation simply does nothing.
*/
virtual void informUpdatedVerbosityState() const;
private:
mutable RCP<FancyOStream> thisOStream_;
mutable RCP<FancyOStream> thisOverridingOStream_;
std::string thisLinePrefix_;
static RCP<FancyOStream>& privateDefaultOStream();
};
/** \brief Templated base class for objects that can print their activities to
* a stream and have a verbosity level.
*
* Objects that derive from this interface print to a default class-owned
* (i.e. static) output stream object (set using <tt>setDefaultOStream()</tt>)
* or the output stream can be set on an object-by-object basis using
* <tt>setOStream()</tt> . In addition, each object, by default, has a
* verbosity level that is shared by all objects (set using
* <tt>setDefaultVerbosityLevel()</tt>) or can be set on an object-by-object
* basis using <tt>setVerbLevel()</tt>.
*
* The output stream type is <tt>FancyOStream</tt> which allows for automated
* indentation (using the <tt>OSTab</tt> class) and has other useful features.
*
* Note that <tt>setOStream()</tt> and <tt>setVerbLevel()</tt> are actually
* decalared as <tt>const</tt> functions. This is to allow a client to
* temporarily change the stream and verbosity level. To do this saftely, use
* the class <tt>VerboseObjectTempState</tt> which will revert the output
* state after it is destroyed.
*/
template<class ObjectType>
class VerboseObject : virtual public VerboseObjectBase {
public:
//! @name Public static member functions
//@{
/** \brief Set the default verbosity level.
*
* If not called, then the default verbosity level is <tt>VERB_DEFAULT</tt>
*/
static void setDefaultVerbLevel( const EVerbosityLevel defaultVerbLevel);
/** \brief Get the default verbosity level. */
static EVerbosityLevel getDefaultVerbLevel();
//@}
//! @name Constructors/Initializers
//@{
/** \brief Calls <tt>initializeVerboseObject()</tt>.
*/
explicit
VerboseObject(
const EVerbosityLevel verbLevel = VERB_DEFAULT, // Note, this must be the same as the default value for defaultVerbLevel_
const RCP<FancyOStream> &oStream = Teuchos::null
);
/** \brief Calls <tt>initializeVerboseObject()</tt>.
*/
virtual void initializeVerboseObject(
const EVerbosityLevel verbLevel = VERB_DEFAULT, // Note, this must be the same as the default value for defaultVerbLevel_
const RCP<FancyOStream> &oStream = Teuchos::null
);
/** \brief Set the verbosity level for <tt>*this</tt> object.
*
*
* This function is supposed by called by general clients to set the output
* level according to some general logic in the code.
*/
virtual const VerboseObject& setVerbLevel(
const EVerbosityLevel verbLevel) const;
/** \brief Set the overriding verbosity level for <tt>*this</tt> object.
*
* This function is supposed to be called by special clients that want to
* set the output level in a way that will not be overridden by
* <tt>setOStream()</tt>.
*/
virtual const VerboseObject& setOverridingVerbLevel(
const EVerbosityLevel verbLevel) const;
//@}
//! @name Query functions
//@{
/** \brief Get the verbosity level */
virtual EVerbosityLevel getVerbLevel() const;
//@}
private:
mutable EVerbosityLevel thisVerbLevel_;
mutable EVerbosityLevel thisOverridingVerbLevel_;
static EVerbosityLevel& privateDefaultVerbLevel();
};
/** \brief Set and release a stream and verbosity level.
*
*/
template<class ObjectType>
class VerboseObjectTempState {
public:
/** \brief . */
VerboseObjectTempState(
const RCP<const VerboseObject<ObjectType> > &verboseObject,
const RCP<FancyOStream> &newOStream,
const EVerbosityLevel newVerbLevel
)
:verboseObject_(verboseObject)
{
if(verboseObject_.get()) {
oldOStream_ = verboseObject_->getOStream();
oldVerbLevel_ = verboseObject_->getVerbLevel();
verboseObject_->setOStream(newOStream);
verboseObject_->setVerbLevel(newVerbLevel);
}
}
/** \brief . */
~VerboseObjectTempState()
{
if(verboseObject_.get()) {
verboseObject_->setOStream(oldOStream_);
verboseObject_->setVerbLevel(oldVerbLevel_);
}
}
private:
RCP<const VerboseObject<ObjectType> > verboseObject_;
RCP<FancyOStream> oldOStream_;
EVerbosityLevel oldVerbLevel_;
// Not defined and not to be called
VerboseObjectTempState();
VerboseObjectTempState(const VerboseObjectTempState&);
VerboseObjectTempState& operator=(const VerboseObjectTempState&);
};
// //////////////////////////////////
// Template defintions
//
// VerboseObject
//
// Public static member functions
template<class ObjectType>
void VerboseObject<ObjectType>::setDefaultVerbLevel( const EVerbosityLevel defaultVerbLevel)
{
privateDefaultVerbLevel() = defaultVerbLevel;
}
template<class ObjectType>
EVerbosityLevel VerboseObject<ObjectType>::getDefaultVerbLevel()
{
return privateDefaultVerbLevel();
}
// Constructors/Initializers
template<class ObjectType>
VerboseObject<ObjectType>::VerboseObject(
const EVerbosityLevel verbLevel,
const RCP<FancyOStream> &oStream
)
: thisOverridingVerbLevel_(VERB_DEFAULT)
{
this->initializeVerboseObject(verbLevel,oStream);
}
template<class ObjectType>
void VerboseObject<ObjectType>::initializeVerboseObject(
const EVerbosityLevel verbLevel,
const RCP<FancyOStream> &oStream
)
{
thisVerbLevel_ = verbLevel;
this->initializeVerboseObjectBase(oStream);
}
template<class ObjectType>
const VerboseObject<ObjectType>&
VerboseObject<ObjectType>::setVerbLevel(const EVerbosityLevel verbLevel) const
{
thisVerbLevel_ = verbLevel;
informUpdatedVerbosityState();
return *this;
}
template<class ObjectType>
const VerboseObject<ObjectType>&
VerboseObject<ObjectType>::setOverridingVerbLevel(
const EVerbosityLevel verbLevel
) const
{
thisOverridingVerbLevel_ = verbLevel;
informUpdatedVerbosityState();
return *this;
}
// Query functions
template<class ObjectType>
EVerbosityLevel VerboseObject<ObjectType>::getVerbLevel() const
{
if (VERB_DEFAULT != thisOverridingVerbLevel_)
return thisOverridingVerbLevel_;
if (VERB_DEFAULT == thisVerbLevel_)
return getDefaultVerbLevel();
return thisVerbLevel_;
}
// Private static members
template<class ObjectType>
EVerbosityLevel& VerboseObject<ObjectType>::privateDefaultVerbLevel()
{
static EVerbosityLevel defaultVerbLevel = VERB_DEFAULT;
return defaultVerbLevel;
}
} // namespace Teuchos
#endif // TEUCHOS_VERBOSE_OBJECT_HPP