1257 lines
33 KiB
C++
1257 lines
33 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_FANCY_O_STREAM_HPP
|
|
#define TEUCHOS_FANCY_O_STREAM_HPP
|
|
|
|
#include "Teuchos_RCP.hpp"
|
|
#include "Teuchos_GlobalMPISession.hpp"
|
|
#include "Teuchos_oblackholestream.hpp"
|
|
#include "Teuchos_as.hpp"
|
|
|
|
namespace Teuchos {
|
|
|
|
|
|
/** \brief Stream buffering class that performs the magic of indenting
|
|
* data sent to an std::ostream object.
|
|
*
|
|
* \ingroup teuchos_outputting_grp
|
|
*
|
|
* Note, this is not a user-level class. Users should use
|
|
* <tt>basic_FancyOStream</tt>.
|
|
*/
|
|
template<typename CharT, typename Traits>
|
|
class basic_FancyOStream_buf : public std::basic_streambuf<CharT,Traits>
|
|
{
|
|
public:
|
|
|
|
/** \brief . */
|
|
typedef CharT char_type;
|
|
/** \brief . */
|
|
typedef Traits traits_type;
|
|
/** \brief . */
|
|
typedef typename traits_type::int_type int_type;
|
|
/** \brief . */
|
|
typedef typename traits_type::pos_type pos_type;
|
|
/** \brief . */
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
/** \brief . */
|
|
basic_FancyOStream_buf(
|
|
const RCP<std::basic_ostream<char_type,traits_type> > &oStream
|
|
,const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
,const int startingTab
|
|
,const bool showLinePrefix
|
|
,const int maxLenLinePrefix
|
|
,const bool showTabCount
|
|
,const bool showProcRank
|
|
);
|
|
|
|
/** \brief . */
|
|
void initialize(
|
|
const RCP<std::basic_ostream<char_type,traits_type> > &oStream
|
|
,const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
,const int startingTab
|
|
,const bool showLinePrefix
|
|
,const int maxLenLinePrefix
|
|
,const bool showTabCount
|
|
,const bool showProcRank
|
|
);
|
|
|
|
/** \brief . */
|
|
RCP<std::basic_ostream<char_type,traits_type> > getOStream();
|
|
|
|
/** \brief . */
|
|
void setTabIndentStr(const std::basic_string<char_type,traits_type> &tabIndentStr);
|
|
|
|
/** \brief . */
|
|
const std::basic_string<char_type,traits_type>& getTabIndentStr() const;
|
|
|
|
/** \brief .*/
|
|
void setShowLinePrefix(const bool showLinePrefix);
|
|
|
|
/** \brief .*/
|
|
bool getShowLinePrefix() const;
|
|
|
|
/** \brief .*/
|
|
void setMaxLenLinePrefix(const int maxLenLinePrefix);
|
|
|
|
/** \brief .*/
|
|
int getMaxLenLinePrefix() const;
|
|
|
|
/** \brief . */
|
|
void setShowTabCount(const bool showTabCount);
|
|
|
|
/** \brief . */
|
|
bool getShowTabCount() const;
|
|
|
|
/** \brief . */
|
|
void setShowProcRank(const bool showProcRank);
|
|
|
|
/** \brief . */
|
|
bool getShowProcRank() const;
|
|
|
|
/** \brief .*/
|
|
void setProcRankAndSize( const int procRank, const int numProcs );
|
|
|
|
/** \brief .*/
|
|
int getProcRank() const;
|
|
|
|
/** \brief .*/
|
|
int getNumProcs() const;
|
|
|
|
/** \brief . */
|
|
void setOutputToRootOnly( const int rootRank );
|
|
|
|
/** \brief . */
|
|
int getOutputToRootOnly() const;
|
|
|
|
/** \brief . */
|
|
void pushTab(const int tabs);
|
|
|
|
/** \brief . */
|
|
int getNumCurrTabs() const;
|
|
|
|
/** \brief . */
|
|
void popTab();
|
|
|
|
/** \brief . */
|
|
void pushLinePrefix(
|
|
const std::basic_string<char_type,traits_type> &linePrefix
|
|
);
|
|
|
|
/** \brief . */
|
|
void popLinePrefix();
|
|
|
|
/** \brief . */
|
|
const std::basic_string<char_type,traits_type>& getTopLinePrefix() const;
|
|
|
|
/** \brief . */
|
|
void pushDisableTabbing();
|
|
|
|
/** \brief . */
|
|
void popDisableTabbing();
|
|
|
|
protected:
|
|
|
|
//! @name Protected overridden functions from std::basic_streambuf
|
|
//@{
|
|
|
|
/** \brief . */
|
|
std::streamsize xsputn(const char_type* s, std::streamsize n);
|
|
|
|
/** \brief . */
|
|
int_type overflow(int_type c);
|
|
|
|
#ifdef TEUCHOS_FANCY_OSTREAM_SHOW_ALL_CALLS
|
|
|
|
void imbue(const locale& l)
|
|
{
|
|
std::cerr << "\ncalled imbue()\n";
|
|
std::basic_streambuf<CharT,Traits>::imbue(l);
|
|
}
|
|
|
|
basic_streambuf<char_type,Traits>*
|
|
setbuf(char_type* s, streamsize n)
|
|
{
|
|
std::cerr << "\ncalled setbuf()\n";
|
|
return std::basic_streambuf<CharT,Traits>::setbuf(s,n);
|
|
}
|
|
|
|
pos_type
|
|
seekoff(off_type a, ios_base::seekdir b,ios_base::openmode c)
|
|
{
|
|
std::cerr << "\ncalled seekoff()\n";
|
|
return std::basic_streambuf<CharT,Traits>::seekoff(a,b,c);
|
|
}
|
|
|
|
pos_type
|
|
seekpos(pos_type a, ios_base::openmode b)
|
|
{
|
|
std::cerr << "\ncalled seekpos()\n";
|
|
return std::basic_streambuf<CharT,Traits>::seekpos(a,b);
|
|
}
|
|
|
|
int
|
|
sync()
|
|
{
|
|
std::cerr << "\ncalled sync()\n";
|
|
return std::basic_streambuf<CharT,Traits>::sync();
|
|
}
|
|
|
|
streamsize
|
|
showmanyc()
|
|
{
|
|
std::cerr << "\ncalled showmanyc()\n";
|
|
return std::basic_streambuf<CharT,Traits>::showmanyc();
|
|
}
|
|
|
|
streamsize
|
|
xsgetn(char_type* s, streamsize n)
|
|
{
|
|
std::cerr << "\ncalled xsgetn()\n";
|
|
return std::basic_streambuf<CharT,Traits>::xsgetn(s,n);
|
|
}
|
|
|
|
int_type
|
|
underflow()
|
|
{
|
|
std::cerr << "\ncalled underflow()\n";
|
|
return std::basic_streambuf<CharT,Traits>::underflow();
|
|
}
|
|
|
|
int_type
|
|
uflow()
|
|
{
|
|
std::cerr << "\ncalled uflow()\n";
|
|
return std::basic_streambuf<CharT,Traits>::uflow();
|
|
}
|
|
|
|
int_type
|
|
pbackfail(int_type c = traits_type::eof())
|
|
{
|
|
std::cerr << "\ncalled pbackfail()\n";
|
|
return std::basic_streambuf<CharT,Traits>::pbackfail(c);
|
|
}
|
|
|
|
#endif // TEUCHOS_FANCY_OSTREAM_SHOW_ALL_CALLS
|
|
|
|
//@}
|
|
|
|
private:
|
|
|
|
// ////////////////////////
|
|
// Private types
|
|
|
|
typedef std::basic_string<char_type,traits_type> string_t;
|
|
typedef std::deque<int> tabIndentStack_t;
|
|
typedef std::deque<string_t> linePrefixStack_t;
|
|
|
|
// ////////////////////////
|
|
// Private data members
|
|
|
|
RCP<std::basic_ostream<char_type,traits_type> > oStreamSet_;
|
|
RCP<std::basic_ostream<char_type,traits_type> > oStream_;
|
|
std::basic_string<char_type,traits_type> tabIndentStr_;
|
|
bool showLinePrefix_;
|
|
int maxLenLinePrefix_;
|
|
bool showTabCount_;
|
|
bool showProcRank_;
|
|
int rootRank_;
|
|
int procRank_;
|
|
int numProcs_;
|
|
int rankPrintWidth_;
|
|
|
|
RCP<std::ostringstream> lineOut_;
|
|
|
|
int tabIndent_;
|
|
tabIndentStack_t tabIndentStack_;
|
|
linePrefixStack_t linePrefixStack_;
|
|
int enableTabbingStack_;
|
|
|
|
bool wroteNewline_;
|
|
|
|
// ////////////////////////
|
|
// Private member functions
|
|
|
|
std::ostream& out();
|
|
|
|
void writeChars( const char_type s[], std::streamsize n );
|
|
|
|
void writeFrontMatter();
|
|
|
|
// Not defined and not to be called
|
|
basic_FancyOStream_buf();
|
|
basic_FancyOStream_buf(const basic_FancyOStream_buf<CharT,Traits>&);
|
|
basic_FancyOStream_buf<CharT,Traits> operator=(
|
|
const basic_FancyOStream_buf<CharT,Traits>&
|
|
);
|
|
|
|
};
|
|
|
|
/** \brief std::ostream subclass that performs the magic of indenting data
|
|
* sent to an std::ostream object among other things.
|
|
*
|
|
* Use the typedef <tt>FancyOStream</tt> for support for the <tt>char</tt>
|
|
* character type.
|
|
*
|
|
* Indentation of the stream is accomplished through creating
|
|
* <tt>basic_OSTab</tt> objects.
|
|
*
|
|
* In addition to indenting output, this stream object can also print various
|
|
* types of information at the beginning of each line. The type of information
|
|
* supported is:
|
|
* <ul>
|
|
* <li> Processor rank: Set using <tt>setShowProcRank()</tt>.
|
|
* <li> Line prefix name: Set using <tt>showLinePrefix()</tt> and <tt>OSTab::OSTab()</tt>.
|
|
* <li> Tab counts (useful for debugging): Set using <tt>setShowTabCount()</tt>.
|
|
* </ul>
|
|
*
|
|
* See <tt>FancyOutputting_test.cpp</tt> for examples of how this class is
|
|
* used and the output it generates.
|
|
*/
|
|
template <typename CharT, typename Traits = std::char_traits<CharT> >
|
|
class basic_FancyOStream : public std::basic_ostream<CharT, Traits>
|
|
{
|
|
public:
|
|
|
|
//! @name Public types
|
|
//@{
|
|
|
|
/** \brief . */
|
|
typedef CharT char_type;
|
|
/** \brief . */
|
|
typedef Traits traits_type;
|
|
/** \brief . */
|
|
typedef typename traits_type::int_type int_type;
|
|
/** \brief . */
|
|
typedef typename traits_type::pos_type pos_type;
|
|
/** \brief . */
|
|
typedef typename traits_type::off_type off_type;
|
|
/** \brief . */
|
|
|
|
/** \brief . */
|
|
typedef basic_FancyOStream_buf<CharT,Traits> streambuf_t;
|
|
/** \brief . */
|
|
typedef std::basic_ostream<char_type, traits_type> ostream_t;
|
|
|
|
//@}
|
|
|
|
//! @name Public client functions
|
|
//@{
|
|
|
|
/** \brief . */
|
|
explicit
|
|
basic_FancyOStream(
|
|
const RCP< std::basic_ostream<char_type,traits_type> > &oStream
|
|
,const std::basic_string<char_type,traits_type> &tabIndentStr = " "
|
|
,const int startingTab = 0
|
|
,const bool showLinePrefix = false
|
|
,const int maxLenLinePrefix = 10
|
|
,const bool showTabCount = false
|
|
,const bool showProcRank = false
|
|
);
|
|
|
|
/** \brief . */
|
|
void initialize(
|
|
const RCP< std::basic_ostream<char_type,traits_type> > &oStream
|
|
,const std::basic_string<char_type,traits_type> &tabIndentStr = " "
|
|
,const int startingTab = 0
|
|
,const bool showLinePrefix = false
|
|
,const int maxLenLinePrefix = 10
|
|
,const bool showTabCount = false
|
|
,const bool showProcRank = false
|
|
);
|
|
|
|
/** \brief. */
|
|
RCP<std::basic_ostream<char_type,traits_type> > getOStream();
|
|
|
|
/** \brief . */
|
|
basic_FancyOStream& setTabIndentStr(
|
|
const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
);
|
|
|
|
/** \brief. */
|
|
const std::basic_string<char_type,traits_type>& getTabIndentStr() const;
|
|
|
|
/** \brief Set if processor rank, line prefixes, and tab counts are shown or not .*/
|
|
basic_FancyOStream& setShowAllFrontMatter(const bool showAllFrontMatter);
|
|
|
|
/** \brief .*/
|
|
basic_FancyOStream& setShowLinePrefix(const bool showLinePrefix);
|
|
|
|
/** \brief .*/
|
|
basic_FancyOStream& setMaxLenLinePrefix(const int maxLenLinePrefix);
|
|
|
|
/** \brief . */
|
|
basic_FancyOStream& setShowTabCount(const bool showTabCount);
|
|
|
|
/** \brief . */
|
|
basic_FancyOStream& setShowProcRank(const bool showProcRank);
|
|
|
|
/** \brief . */
|
|
basic_FancyOStream& setProcRankAndSize( const int procRank, const int numProcs );
|
|
|
|
/** \brief . */
|
|
basic_FancyOStream& setOutputToRootOnly( const int rootRank );
|
|
|
|
/** \brief . */
|
|
int getOutputToRootOnly() const;
|
|
|
|
/** \brief . */
|
|
void copyAllOutputOptions(const basic_FancyOStream<CharT,Traits> &oStream);
|
|
|
|
//@}
|
|
|
|
//! @name Functions designed to be used by basic_OSTab
|
|
//@{
|
|
|
|
/** \brief . */
|
|
void pushTab(const int tabs = 1);
|
|
|
|
/** \brief . */
|
|
int getNumCurrTabs() const;
|
|
|
|
/** \brief . */
|
|
void popTab();
|
|
|
|
/** \brief . */
|
|
void pushLinePrefix(const std::basic_string<char_type,traits_type> &linePrefix);
|
|
|
|
/** \brief . */
|
|
void popLinePrefix();
|
|
|
|
/** \brief . */
|
|
const std::basic_string<char_type,traits_type>& getTopLinePrefix() const;
|
|
|
|
/** \brief . */
|
|
void pushDisableTabbing();
|
|
|
|
/** \brief . */
|
|
void popDisableTabbing();
|
|
|
|
//@}
|
|
|
|
private:
|
|
|
|
streambuf_t streambuf_;
|
|
|
|
// Not defined and not to be called
|
|
basic_FancyOStream();
|
|
basic_FancyOStream(const basic_FancyOStream<CharT,Traits>&);
|
|
basic_FancyOStream<CharT,Traits> operator=(const basic_FancyOStream<CharT,Traits>&);
|
|
|
|
};
|
|
/** \brief Dynamically allocate a FancyOStream and return it wrapped in an RCP
|
|
* object.
|
|
*
|
|
* \relates basic_FancyOStream
|
|
*/
|
|
template <typename CharT, typename Traits>
|
|
RCP<basic_FancyOStream<CharT,Traits> >
|
|
fancyOStream(
|
|
const RCP< std::basic_ostream<CharT,Traits> >& oStream,
|
|
const std::basic_string<CharT,Traits>& tabIndentStr = " ",
|
|
const int startingTab = 0,
|
|
const bool showLinePrefix = false,
|
|
const int maxLenLinePrefix = 10,
|
|
const bool showTabCount = false,
|
|
const bool showProcRank = false
|
|
)
|
|
{
|
|
return rcp(
|
|
new basic_FancyOStream<CharT,Traits>(
|
|
oStream,tabIndentStr,startingTab,showLinePrefix,
|
|
maxLenLinePrefix,showTabCount,showProcRank
|
|
)
|
|
);
|
|
}
|
|
|
|
/** \brief Get a FancyOStream from an std::ostream object.
|
|
*
|
|
* If the object already is a FancyOStream, then nothing has to be done.
|
|
* Otherwise, a temp FancyOStream is created for this purpose. If
|
|
* <tt>out.get()==NULL</tt> then <tt>return.get()==NULL</tt> on return also!
|
|
*
|
|
* \relates basic_FancyOStream
|
|
*/
|
|
template <typename CharT, typename Traits>
|
|
RCP<basic_FancyOStream<CharT,Traits> >
|
|
getFancyOStream( const RCP<std::basic_ostream<CharT,Traits> > &out )
|
|
{
|
|
if(out.get()==NULL)
|
|
return Teuchos::null;
|
|
RCP<basic_FancyOStream<CharT,Traits> >
|
|
fancyOut = rcp_dynamic_cast<basic_FancyOStream<CharT,Traits> >(out);
|
|
if(fancyOut.get())
|
|
return fancyOut;
|
|
return rcp(new basic_FancyOStream<CharT,Traits>(out));
|
|
}
|
|
|
|
/** \brief Tabbing class for helping to create formated, indented output for a
|
|
* <tt>basic_FancyOStream</tt> object.
|
|
*
|
|
* Use the typedef <tt>OSStream</tt> for support for the <tt>char</tt>
|
|
* character type.
|
|
*
|
|
* This class is used to create tab indents and set line prefix names for
|
|
* output that is generated by a <tt>basic_FancyOStream</tt> object.
|
|
*
|
|
* \relates basic_FancyOStream
|
|
*/
|
|
template <typename CharT, typename Traits = std::char_traits<CharT> >
|
|
class basic_OSTab
|
|
{
|
|
public:
|
|
|
|
/** \brief . */
|
|
static const int DISABLE_TABBING = -99999; // This magic number should be just fine!
|
|
/** \brief. */
|
|
basic_OSTab(
|
|
const RCP<basic_FancyOStream<CharT,Traits> > &fancyOStream
|
|
,const int tabs = 1
|
|
,const std::basic_string<CharT,Traits> linePrefix = ""
|
|
)
|
|
:fancyOStream_(fancyOStream)
|
|
,tabs_(tabs)
|
|
,linePrefix_(linePrefix)
|
|
{
|
|
updateState();
|
|
}
|
|
/** \brief. */
|
|
basic_OSTab(
|
|
const RCP<std::basic_ostream<CharT,Traits> > &oStream
|
|
,const int tabs = 1
|
|
,const std::basic_string<CharT,Traits> linePrefix = ""
|
|
)
|
|
:fancyOStream_(getFancyOStream(oStream))
|
|
,tabs_(tabs)
|
|
,linePrefix_(linePrefix)
|
|
{
|
|
updateState();
|
|
}
|
|
/** \brief Warning: Only call this constructor for stack-based object. */
|
|
basic_OSTab(
|
|
basic_FancyOStream<CharT,Traits> &fancyOStream
|
|
,const int tabs = 1
|
|
,const std::basic_string<CharT,Traits> linePrefix = ""
|
|
)
|
|
:fancyOStream_(rcp(&fancyOStream,false))
|
|
,tabs_(tabs)
|
|
,linePrefix_(linePrefix)
|
|
{
|
|
updateState();
|
|
}
|
|
/** \brief Warning: Only call this constructor for stack-based object. */
|
|
basic_OSTab(
|
|
std::basic_ostream<CharT,Traits> &oStream
|
|
,const int tabs = 1
|
|
,const std::basic_string<CharT,Traits> linePrefix = ""
|
|
)
|
|
:fancyOStream_(getFancyOStream(rcp(&oStream,false)))
|
|
,tabs_(tabs)
|
|
,linePrefix_(linePrefix)
|
|
{
|
|
updateState();
|
|
}
|
|
/** \brief. */
|
|
basic_OSTab( const basic_OSTab &osTab )
|
|
:fancyOStream_(osTab.fancyOStream_)
|
|
,tabs_(osTab.tabs_)
|
|
{
|
|
updateState();
|
|
}
|
|
/** \brief. */
|
|
~basic_OSTab()
|
|
{
|
|
if(fancyOStream_.get()) {
|
|
if(tabs_==DISABLE_TABBING)
|
|
fancyOStream_->popDisableTabbing();
|
|
else
|
|
fancyOStream_->popTab();
|
|
if(linePrefix_.length()) fancyOStream_->popLinePrefix();
|
|
}
|
|
}
|
|
/** \brief. */
|
|
basic_OSTab<CharT,Traits>& operator=( const basic_OSTab &osTab )
|
|
{
|
|
fancyOStream_ = osTab.fancyOStream_;
|
|
tabs_ = osTab.tabs_;
|
|
updateState();
|
|
return *this;
|
|
}
|
|
/** \brief. */
|
|
basic_OSTab<CharT,Traits>& incrTab(const int tabs = 1)
|
|
{
|
|
tabs_ += tabs;
|
|
if(fancyOStream_.get()) {
|
|
fancyOStream_->popTab();
|
|
fancyOStream_->pushTab(tabs_);
|
|
}
|
|
return *this;
|
|
}
|
|
/** \brief. */
|
|
basic_FancyOStream<CharT,Traits>& o() const
|
|
{
|
|
return *fancyOStream_;
|
|
}
|
|
/** \brief. */
|
|
basic_FancyOStream<CharT,Traits>* get() const
|
|
{
|
|
return fancyOStream_.get();
|
|
}
|
|
|
|
private:
|
|
|
|
RCP<basic_FancyOStream<CharT,Traits> > fancyOStream_;
|
|
int tabs_;
|
|
std::basic_string<CharT,Traits> linePrefix_;
|
|
|
|
void updateState()
|
|
{
|
|
if(fancyOStream_.get()) {
|
|
if(tabs_==DISABLE_TABBING)
|
|
fancyOStream_->pushDisableTabbing();
|
|
else
|
|
fancyOStream_->pushTab(tabs_);
|
|
if(linePrefix_.length()) fancyOStream_->pushLinePrefix(linePrefix_);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
/** \brief Create a tab for an RCP-wrapped <tt>basic_FancyOStream</tt> object
|
|
* to cause the indentation of all output automatically!.
|
|
*
|
|
* This function returns an RCP object to a <tt>basic_FancyOStream</tt> object
|
|
* that has its tab indented by one. If the input <tt>*out</tt> object is
|
|
* already a <tt>%basic_FancyOStream</tt> object, then that object is used as
|
|
* is. If the <tt>*out</tt> object is not a <tt>%basic_FancyOStream</tt>
|
|
* object, then a new <tt>%basic_FancyOStream</tt> object is created and its
|
|
* tab is set!"
|
|
*
|
|
* In any case, when the returned RCP object is destroyed, the tab will be
|
|
* removed automatically!
|
|
*
|
|
* \relates basic_FancyOStream
|
|
*/
|
|
template <typename CharT, typename Traits>
|
|
RCP<basic_FancyOStream<CharT,Traits> >
|
|
tab(
|
|
const RCP<basic_FancyOStream<CharT,Traits> > &out
|
|
,const int tabs = 1
|
|
,const std::basic_string<CharT,Traits> linePrefix = ""
|
|
)
|
|
{
|
|
if(out.get()==NULL)
|
|
return Teuchos::null;
|
|
RCP<basic_FancyOStream<CharT,Traits> >
|
|
fancyOut = rcp(&*out,false);
|
|
set_extra_data( out, "out", &fancyOut );
|
|
set_extra_data(
|
|
rcp(new basic_OSTab<CharT,Traits>(out,tabs,linePrefix))
|
|
,"OSTab"
|
|
,&fancyOut
|
|
,PRE_DESTROY
|
|
);
|
|
return fancyOut;
|
|
}
|
|
|
|
|
|
/** \brief Create a tab for an RCP-wrapped <tt>std:: std::ostream</tt> object
|
|
* to cause the indentation of all output automatically!.
|
|
*
|
|
* This function returns an RCP object to a <tt>basic_FancyOStream</tt> object
|
|
* that has its tab indented by one. If the input <tt>*out</tt> object is
|
|
* already a <tt>%basic_FancyOStream</tt> object, then that object is used as
|
|
* is. If the <tt>*out</tt> object is not a <tt>%basic_FancyOStream</tt>
|
|
* object, then a new <tt>%basic_FancyOStream</tt> object is created and its
|
|
* tab is set!"
|
|
*
|
|
* In any case, when the returned RCP object is destroyed, the tab will be
|
|
* removed automatically!
|
|
*
|
|
* \relates basic_FancyOStream
|
|
*/
|
|
template <typename CharT, typename Traits>
|
|
RCP<basic_FancyOStream<CharT,Traits> >
|
|
tab(
|
|
const RCP<std::basic_ostream<CharT,Traits> > &out
|
|
,const int tabs = 1
|
|
,const std::basic_string<CharT,Traits> linePrefix = ""
|
|
)
|
|
{
|
|
return tab(getFancyOStream(out),tabs,linePrefix);
|
|
}
|
|
|
|
// ///////////////////////////////
|
|
// Typedefs
|
|
|
|
/** \brief .
|
|
* \ingroup teuchos_outputting_grp
|
|
*/
|
|
typedef basic_FancyOStream<char> FancyOStream;
|
|
|
|
/** \brief .
|
|
* \ingroup teuchos_outputting_grp
|
|
*/
|
|
typedef basic_OSTab<char> OSTab;
|
|
|
|
/** \brief .
|
|
* \ingroup teuchos_outputting_grp
|
|
*/
|
|
#define TEUCHOS_OSTAB ::Teuchos::OSTab __localThisTab = this->getOSTab()
|
|
|
|
// ////////////////////////////////
|
|
// Defintions
|
|
|
|
//
|
|
// basic_FancyOStream_buf
|
|
//
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream_buf<CharT,Traits>::basic_FancyOStream_buf(
|
|
const RCP<std::basic_ostream<char_type,traits_type> > &oStream
|
|
,const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
,const int startingTab
|
|
,const bool showLinePrefix
|
|
,const int maxLenLinePrefix
|
|
,const bool showTabCount
|
|
,const bool showProcRank
|
|
)
|
|
{
|
|
this->initialize(oStream,tabIndentStr,startingTab,showLinePrefix,
|
|
maxLenLinePrefix,showTabCount,showProcRank);
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::initialize(
|
|
const RCP<std::basic_ostream<char_type,traits_type> > &oStream
|
|
,const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
,const int startingTab
|
|
,const bool showLinePrefix
|
|
,const int maxLenLinePrefix
|
|
,const bool showTabCount
|
|
,const bool showProcRank
|
|
)
|
|
{
|
|
oStreamSet_ = oStream;
|
|
oStream_ = oStream;
|
|
tabIndentStr_ = tabIndentStr;
|
|
showLinePrefix_ = showLinePrefix;
|
|
maxLenLinePrefix_ = maxLenLinePrefix;
|
|
showTabCount_ = showTabCount;
|
|
showProcRank_ = showProcRank;
|
|
rootRank_ = -1;
|
|
procRank_ = GlobalMPISession::getRank();
|
|
numProcs_ = GlobalMPISession::getNProc();
|
|
rankPrintWidth_ = int(std::log10(float(numProcs_)))+1;
|
|
tabIndent_ = startingTab;
|
|
tabIndentStack_.clear();
|
|
linePrefixStack_.clear();
|
|
wroteNewline_ = true;
|
|
enableTabbingStack_ = 0;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
RCP<std::basic_ostream<CharT,Traits> >
|
|
basic_FancyOStream_buf<CharT,Traits>::getOStream()
|
|
{
|
|
return oStreamSet_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::setTabIndentStr(
|
|
const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
)
|
|
{
|
|
tabIndentStr_ = tabIndentStr;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
const std::basic_string<CharT,Traits>&
|
|
basic_FancyOStream_buf<CharT,Traits>::getTabIndentStr() const
|
|
{
|
|
return tabIndentStr_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::setShowLinePrefix(const bool showLinePrefix)
|
|
{
|
|
showLinePrefix_ = showLinePrefix;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
bool basic_FancyOStream_buf<CharT,Traits>::getShowLinePrefix() const
|
|
{
|
|
return showLinePrefix_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::setMaxLenLinePrefix(const int maxLenLinePrefix)
|
|
{
|
|
TEST_FOR_EXCEPT( !(maxLenLinePrefix>=5) );
|
|
maxLenLinePrefix_ = maxLenLinePrefix;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
int basic_FancyOStream_buf<CharT,Traits>::getMaxLenLinePrefix() const
|
|
{
|
|
return maxLenLinePrefix_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::setShowTabCount(const bool showTabCount)
|
|
{
|
|
showTabCount_ = showTabCount;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
bool basic_FancyOStream_buf<CharT,Traits>::getShowTabCount() const
|
|
{
|
|
return showTabCount_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::setShowProcRank(const bool showProcRank)
|
|
{
|
|
showProcRank_ = showProcRank;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
bool basic_FancyOStream_buf<CharT,Traits>::getShowProcRank() const
|
|
{
|
|
return showProcRank_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::setProcRankAndSize(
|
|
const int procRank, const int numProcs
|
|
)
|
|
{
|
|
procRank_ = procRank;
|
|
numProcs_ = numProcs;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
int basic_FancyOStream_buf<CharT,Traits>::getProcRank() const
|
|
{
|
|
return procRank_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
int basic_FancyOStream_buf<CharT,Traits>::getNumProcs() const
|
|
{
|
|
return numProcs_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::setOutputToRootOnly(
|
|
const int rootRank
|
|
)
|
|
{
|
|
rootRank_ = rootRank;
|
|
if(rootRank >= 0) {
|
|
if(rootRank == procRank_)
|
|
oStream_ = oStreamSet_;
|
|
else
|
|
oStream_ = rcp(new oblackholestream());
|
|
// Only processor is being output to so there is no need for line
|
|
// batching!
|
|
lineOut_ = null;
|
|
}
|
|
else {
|
|
oStream_ = oStreamSet_;
|
|
// Output is being sent to all processors so we need line batching to
|
|
// insure that each line will be printed all together!
|
|
lineOut_ = rcp(new std::ostringstream());
|
|
}
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
int basic_FancyOStream_buf<CharT,Traits>::getOutputToRootOnly() const
|
|
{
|
|
return rootRank_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::pushTab(const int tabs)
|
|
{
|
|
if( tabIndent_ + tabs < 0 ) {
|
|
tabIndentStack_.push_back(-tabIndent_);
|
|
tabIndent_ = 0;
|
|
}
|
|
else {
|
|
tabIndentStack_.push_back(tabs);
|
|
tabIndent_ += tabs;
|
|
}
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
int basic_FancyOStream_buf<CharT,Traits>::getNumCurrTabs() const
|
|
{
|
|
return tabIndent_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::popTab()
|
|
{
|
|
tabIndent_ -= tabIndentStack_.back();
|
|
tabIndentStack_.pop_back();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::pushLinePrefix(
|
|
const std::basic_string<char_type,traits_type> &linePrefix
|
|
)
|
|
{
|
|
linePrefixStack_.push_back(linePrefix);
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::popLinePrefix()
|
|
{
|
|
linePrefixStack_.pop_back();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
const std::basic_string<CharT,Traits>&
|
|
basic_FancyOStream_buf<CharT,Traits>::getTopLinePrefix() const
|
|
{
|
|
return linePrefixStack_.back();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::pushDisableTabbing()
|
|
{
|
|
++enableTabbingStack_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::popDisableTabbing()
|
|
{
|
|
--enableTabbingStack_;
|
|
}
|
|
|
|
// protected
|
|
|
|
template<typename CharT, typename Traits>
|
|
std::streamsize basic_FancyOStream_buf<CharT,Traits>::xsputn(
|
|
const char_type* s, std::streamsize n
|
|
)
|
|
{
|
|
#ifdef TEUCHOS_FANCY_OSTREAM_SHOW_ALL_CALLS
|
|
std::cerr << "\ncalled xsputn()\n";
|
|
#endif
|
|
writeChars(s,n);
|
|
return n;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
typename basic_FancyOStream_buf<CharT,Traits>::int_type
|
|
basic_FancyOStream_buf<CharT,Traits>::overflow(int_type c)
|
|
{
|
|
#ifdef TEUCHOS_FANCY_OSTREAM_SHOW_ALL_CALLS
|
|
std::cerr << "\ncalled overflow()\n";
|
|
#endif
|
|
if(c != traits_type::eof()) {
|
|
const char_type cc[] = { traits_type::to_char_type(c) };
|
|
this->writeChars(cc,1);
|
|
}
|
|
return traits_type::not_eof(c);
|
|
//return std::basic_streambuf<CharT,Traits>::overflow(c);
|
|
}
|
|
|
|
// private
|
|
|
|
template<typename CharT, typename Traits>
|
|
std::ostream& basic_FancyOStream_buf<CharT,Traits>::out()
|
|
{
|
|
if(lineOut_.get())
|
|
return *lineOut_;
|
|
return *oStream_;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::writeChars(
|
|
const char_type s[], std::streamsize n
|
|
)
|
|
{
|
|
if(n == 0) return;
|
|
std::streamsize p = 0, first_p = 0;
|
|
bool done_outputting = false;
|
|
const char_type newline = '\n';
|
|
while( !done_outputting ) {
|
|
// Find the next newline
|
|
for( p = first_p; p < n; ++p ) {
|
|
if(s[p] == newline) {
|
|
break;
|
|
}
|
|
}
|
|
if(p == n) {
|
|
// We did not find a newline at the end!
|
|
--p;
|
|
done_outputting = true;
|
|
}
|
|
else if( p == n-1 && s[p] == newline ) {
|
|
// The last character in the std::string is a newline
|
|
done_outputting = true;
|
|
}
|
|
// Write the beginning of the line if we need to
|
|
if(wroteNewline_) {
|
|
writeFrontMatter();
|
|
wroteNewline_ = false;
|
|
}
|
|
// Write up to the newline or the end of the std::string
|
|
out().write(s+first_p,p-first_p+1);
|
|
if(s[p] == newline) {
|
|
wroteNewline_ = true;
|
|
if(lineOut_.get()) {
|
|
*oStream_ << lineOut_->str() << std::flush;
|
|
lineOut_->str("");
|
|
}
|
|
}
|
|
// Update for next search
|
|
if(!done_outputting)
|
|
first_p = p+1;
|
|
}
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream_buf<CharT,Traits>::writeFrontMatter()
|
|
{
|
|
bool didOutput = false;
|
|
std::ostream &out = this->out();
|
|
if(showProcRank_) {
|
|
out << "p=" << std::right << std::setw(rankPrintWidth_) << procRank_;
|
|
didOutput = true;
|
|
}
|
|
if(showLinePrefix_) {
|
|
if(didOutput)
|
|
out << ", ";
|
|
std::string currLinePrefix = "";
|
|
if ( linePrefixStack_.size() )
|
|
currLinePrefix = this->getTopLinePrefix();
|
|
const int localMaxLenLinePrefix =
|
|
TEUCHOS_MAX( as<int>(currLinePrefix.length()), maxLenLinePrefix_ );
|
|
out << std::left << std::setw(localMaxLenLinePrefix);
|
|
out << currLinePrefix;
|
|
didOutput = true;
|
|
}
|
|
if(showTabCount_) {
|
|
if(didOutput)
|
|
out << ", ";
|
|
out << "tabs=" << std::right << std::setw(2) << tabIndent_;
|
|
didOutput = true;
|
|
}
|
|
// ToDo: Add the Prefix name if asked
|
|
// ToDo: Add the processor number if asked
|
|
// ToDo: Add the number of indents if asked
|
|
if(didOutput) {
|
|
out << " |" << tabIndentStr_;
|
|
}
|
|
if(enableTabbingStack_==0) {
|
|
for( int i = 0; i < tabIndent_; ++i )
|
|
out << tabIndentStr_;
|
|
}
|
|
}
|
|
|
|
//
|
|
// basic_FancyOStream
|
|
//
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>::basic_FancyOStream(
|
|
const RCP< std::basic_ostream<char_type,traits_type> > &oStream
|
|
,const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
,const int startingTab
|
|
,const bool showLinePrefix
|
|
,const int maxLenLinePrefix
|
|
,const bool showTabCount
|
|
,const bool showProcRank
|
|
)
|
|
:ostream_t(NULL),
|
|
streambuf_(oStream,tabIndentStr,startingTab,showLinePrefix,
|
|
maxLenLinePrefix,showTabCount,showProcRank)
|
|
{
|
|
this->init(&streambuf_);
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream<CharT,Traits>::initialize(
|
|
const RCP< std::basic_ostream<char_type,traits_type> > &oStream
|
|
,const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
,const int startingTab
|
|
,const bool showLinePrefix
|
|
,const int maxLenLinePrefix
|
|
,const bool showTabCount
|
|
,const bool showProcRank
|
|
)
|
|
{
|
|
streambuf_.initialize(oStream,tabIndentStr,startingTab,
|
|
showLinePrefix,maxLenLinePrefix,showTabCount,showProcRank);
|
|
this->init(&streambuf_);
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
RCP<std::basic_ostream<CharT,Traits> >
|
|
basic_FancyOStream<CharT,Traits>::getOStream()
|
|
{
|
|
return streambuf_.getOStream();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::setTabIndentStr(
|
|
const std::basic_string<char_type,traits_type> &tabIndentStr
|
|
)
|
|
{
|
|
streambuf_.setTabIndentStr(tabIndentStr);
|
|
return *this;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
const std::basic_string<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::getTabIndentStr() const
|
|
{
|
|
return streambuf_.getTabIndentStr();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::setShowAllFrontMatter(
|
|
const bool showAllFrontMatter
|
|
)
|
|
{
|
|
streambuf_.setShowLinePrefix(showAllFrontMatter);
|
|
streambuf_.setShowTabCount(showAllFrontMatter);
|
|
streambuf_.setShowProcRank(showAllFrontMatter);
|
|
return *this;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::setShowLinePrefix(const bool showLinePrefix)
|
|
{
|
|
streambuf_.setShowLinePrefix(showLinePrefix);
|
|
return *this;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::setMaxLenLinePrefix(const int maxLenLinePrefix)
|
|
{
|
|
streambuf_.setMaxLenLinePrefix(maxLenLinePrefix);
|
|
return *this;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::setShowTabCount(const bool showTabCount)
|
|
{
|
|
streambuf_.setShowTabCount(showTabCount);
|
|
return *this;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::setShowProcRank(const bool showProcRank)
|
|
{
|
|
streambuf_.setShowProcRank(showProcRank);
|
|
return *this;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::setProcRankAndSize( const int procRank, const int numProcs )
|
|
{
|
|
streambuf_.setProcRankAndSize(procRank,numProcs);
|
|
return *this;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
basic_FancyOStream<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::setOutputToRootOnly( const int rootRank )
|
|
{
|
|
streambuf_.setOutputToRootOnly(rootRank);
|
|
return *this;
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
int basic_FancyOStream<CharT,Traits>::getOutputToRootOnly() const
|
|
{
|
|
return streambuf_.getOutputToRootOnly();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream<CharT,Traits>::copyAllOutputOptions( const basic_FancyOStream<CharT,Traits> &oStream )
|
|
{
|
|
//streambuf_.setTabIndentStr(oStream.streambuf_.getTabIndentStr());
|
|
streambuf_.setShowLinePrefix(oStream.streambuf_.getShowLinePrefix());
|
|
streambuf_.setMaxLenLinePrefix(oStream.streambuf_.getMaxLenLinePrefix());
|
|
streambuf_.setShowTabCount(oStream.streambuf_.getShowTabCount());
|
|
streambuf_.setShowProcRank(oStream.streambuf_.getShowProcRank());
|
|
streambuf_.setProcRankAndSize(oStream.streambuf_.getProcRank(),oStream.streambuf_.getNumProcs());
|
|
streambuf_.setOutputToRootOnly(oStream.streambuf_.getOutputToRootOnly());
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream<CharT,Traits>::pushTab(const int tabs)
|
|
{
|
|
streambuf_.pushTab(tabs);
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
int basic_FancyOStream<CharT,Traits>::getNumCurrTabs() const
|
|
{
|
|
return streambuf_.getNumCurrTabs();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream<CharT,Traits>::popTab()
|
|
{
|
|
streambuf_.popTab();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream<CharT,Traits>::pushLinePrefix(
|
|
const std::basic_string<char_type,traits_type> &linePrefix
|
|
)
|
|
{
|
|
streambuf_.pushLinePrefix(linePrefix);
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream<CharT,Traits>::popLinePrefix()
|
|
{
|
|
streambuf_.popLinePrefix();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
const std::basic_string<CharT,Traits>&
|
|
basic_FancyOStream<CharT,Traits>::getTopLinePrefix() const
|
|
{
|
|
return streambuf_.getTopLinePrefix();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream<CharT,Traits>::pushDisableTabbing()
|
|
{
|
|
streambuf_.pushDisableTabbing();
|
|
}
|
|
|
|
template<typename CharT, typename Traits>
|
|
void basic_FancyOStream<CharT,Traits>::popDisableTabbing()
|
|
{
|
|
return streambuf_.popDisableTabbing();
|
|
}
|
|
|
|
} // namespace Teuchos
|
|
|
|
#endif // TEUCHOS_FANCY_O_STREAM_HPP
|