00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #ifndef TEUCHOS_VERBOSE_OBJECT_HPP 00030 #define TEUCHOS_VERBOSE_OBJECT_HPP 00031 00032 #include "Teuchos_RCP.hpp" 00033 #include "Teuchos_FancyOStream.hpp" 00034 #include "Teuchos_VerbosityLevel.hpp" 00035 00036 00037 namespace Teuchos { 00038 00039 00053 class VerboseObjectBase { 00054 public: 00055 00057 00058 00064 static void setDefaultOStream( const RCP<FancyOStream> &defaultOStream ); 00065 00067 static RCP<FancyOStream> getDefaultOStream(); 00068 00070 00072 00073 00075 virtual ~VerboseObjectBase() {} 00076 00079 explicit 00080 VerboseObjectBase( 00081 const RCP<FancyOStream> &oStream = Teuchos::null 00082 ); 00083 00086 virtual void initializeVerboseObjectBase( 00087 const RCP<FancyOStream> &oStream = Teuchos::null 00088 ); 00089 00095 virtual const VerboseObjectBase& setOStream( 00096 const RCP<FancyOStream> &oStream) const; 00097 00104 virtual const VerboseObjectBase& setOverridingOStream( 00105 const RCP<FancyOStream> &oStream) const; 00106 00108 virtual VerboseObjectBase& setLinePrefix(const std::string &linePrefix); 00109 00111 00113 00114 00118 virtual RCP<FancyOStream> getOStream() const; 00119 00126 virtual RCP<FancyOStream> getOverridingOStream() const; 00127 00129 virtual std::string getLinePrefix() const; 00130 00132 00134 00135 00149 virtual OSTab getOSTab(const int tabs = 1, const std::string &linePrefix = "") const; 00150 00152 00153 protected: 00154 00163 virtual void informUpdatedVerbosityState() const; 00164 00165 private: 00166 00167 mutable RCP<FancyOStream> thisOStream_; 00168 mutable RCP<FancyOStream> thisOverridingOStream_; 00169 std::string thisLinePrefix_; 00170 00171 static RCP<FancyOStream>& privateDefaultOStream(); 00172 00173 }; 00174 00175 00196 template<class ObjectType> 00197 class VerboseObject : virtual public VerboseObjectBase { 00198 public: 00199 00201 00202 00207 static void setDefaultVerbLevel( const EVerbosityLevel defaultVerbLevel); 00208 00210 static EVerbosityLevel getDefaultVerbLevel(); 00211 00213 00215 00216 00219 explicit 00220 VerboseObject( 00221 const EVerbosityLevel verbLevel = VERB_DEFAULT, // Note, this must be the same as the default value for defaultVerbLevel_ 00222 const RCP<FancyOStream> &oStream = Teuchos::null 00223 ); 00224 00227 virtual void initializeVerboseObject( 00228 const EVerbosityLevel verbLevel = VERB_DEFAULT, // Note, this must be the same as the default value for defaultVerbLevel_ 00229 const RCP<FancyOStream> &oStream = Teuchos::null 00230 ); 00231 00238 virtual const VerboseObject& setVerbLevel( 00239 const EVerbosityLevel verbLevel) const; 00240 00247 virtual const VerboseObject& setOverridingVerbLevel( 00248 const EVerbosityLevel verbLevel) const; 00249 00251 00253 00254 00256 virtual EVerbosityLevel getVerbLevel() const; 00257 00259 00260 private: 00261 00262 mutable EVerbosityLevel thisVerbLevel_; 00263 mutable EVerbosityLevel thisOverridingVerbLevel_; 00264 00265 static EVerbosityLevel& privateDefaultVerbLevel(); 00266 00267 }; 00268 00269 00273 template<class ObjectType> 00274 class VerboseObjectTempState { 00275 public: 00277 VerboseObjectTempState( 00278 const RCP<const VerboseObject<ObjectType> > &verboseObject, 00279 const RCP<FancyOStream> &newOStream, 00280 const EVerbosityLevel newVerbLevel 00281 ) 00282 :verboseObject_(verboseObject) 00283 { 00284 if(verboseObject_.get()) { 00285 oldOStream_ = verboseObject_->getOStream(); 00286 oldVerbLevel_ = verboseObject_->getVerbLevel(); 00287 verboseObject_->setOStream(newOStream); 00288 verboseObject_->setVerbLevel(newVerbLevel); 00289 } 00290 } 00292 ~VerboseObjectTempState() 00293 { 00294 if(verboseObject_.get()) { 00295 verboseObject_->setOStream(oldOStream_); 00296 verboseObject_->setVerbLevel(oldVerbLevel_); 00297 } 00298 } 00299 private: 00300 RCP<const VerboseObject<ObjectType> > verboseObject_; 00301 RCP<FancyOStream> oldOStream_; 00302 EVerbosityLevel oldVerbLevel_; 00303 // Not defined and not to be called 00304 VerboseObjectTempState(); 00305 VerboseObjectTempState(const VerboseObjectTempState&); 00306 VerboseObjectTempState& operator=(const VerboseObjectTempState&); 00307 }; 00308 00309 00310 // ////////////////////////////////// 00311 // Template defintions 00312 00313 00314 // 00315 // VerboseObject 00316 // 00317 00318 00319 // Public static member functions 00320 00321 00322 template<class ObjectType> 00323 void VerboseObject<ObjectType>::setDefaultVerbLevel( const EVerbosityLevel defaultVerbLevel) 00324 { 00325 privateDefaultVerbLevel() = defaultVerbLevel; 00326 } 00327 00328 00329 template<class ObjectType> 00330 EVerbosityLevel VerboseObject<ObjectType>::getDefaultVerbLevel() 00331 { 00332 return privateDefaultVerbLevel(); 00333 } 00334 00335 00336 // Constructors/Initializers 00337 00338 00339 template<class ObjectType> 00340 VerboseObject<ObjectType>::VerboseObject( 00341 const EVerbosityLevel verbLevel, 00342 const RCP<FancyOStream> &oStream 00343 ) 00344 : thisOverridingVerbLevel_(VERB_DEFAULT) 00345 { 00346 this->initializeVerboseObject(verbLevel,oStream); 00347 } 00348 00349 00350 template<class ObjectType> 00351 void VerboseObject<ObjectType>::initializeVerboseObject( 00352 const EVerbosityLevel verbLevel, 00353 const RCP<FancyOStream> &oStream 00354 ) 00355 { 00356 thisVerbLevel_ = verbLevel; 00357 this->initializeVerboseObjectBase(oStream); 00358 } 00359 00360 00361 template<class ObjectType> 00362 const VerboseObject<ObjectType>& 00363 VerboseObject<ObjectType>::setVerbLevel(const EVerbosityLevel verbLevel) const 00364 { 00365 thisVerbLevel_ = verbLevel; 00366 informUpdatedVerbosityState(); 00367 return *this; 00368 } 00369 00370 00371 template<class ObjectType> 00372 const VerboseObject<ObjectType>& 00373 VerboseObject<ObjectType>::setOverridingVerbLevel( 00374 const EVerbosityLevel verbLevel 00375 ) const 00376 { 00377 thisOverridingVerbLevel_ = verbLevel; 00378 informUpdatedVerbosityState(); 00379 return *this; 00380 } 00381 00382 00383 // Query functions 00384 00385 00386 template<class ObjectType> 00387 EVerbosityLevel VerboseObject<ObjectType>::getVerbLevel() const 00388 { 00389 if (VERB_DEFAULT != thisOverridingVerbLevel_) 00390 return thisOverridingVerbLevel_; 00391 if (VERB_DEFAULT == thisVerbLevel_) 00392 return getDefaultVerbLevel(); 00393 return thisVerbLevel_; 00394 } 00395 00396 00397 // Private static members 00398 00399 00400 template<class ObjectType> 00401 EVerbosityLevel& VerboseObject<ObjectType>::privateDefaultVerbLevel() 00402 { 00403 static EVerbosityLevel defaultVerbLevel = VERB_DEFAULT; 00404 return defaultVerbLevel; 00405 } 00406 00407 00408 } // namespace Teuchos 00409 00410 00411 #endif // TEUCHOS_VERBOSE_OBJECT_HPP