From: bangerth Date: Tue, 23 Apr 2013 01:20:15 +0000 (+0000) Subject: Patch by Fahad Alrashed: Provide additional member functions for LogStream. X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=96a3d402d3f3bde95e0751575ada6c9b239e8706;p=dealii-svn.git Patch by Fahad Alrashed: Provide additional member functions for LogStream. git-svn-id: https://svn.dealii.org/trunk@29361 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index 992cfe9e07..2c16962a81 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -111,6 +111,13 @@ this function.
    +
  1. New: LogStream now has member functions LogStream::width, +LogStream::precision and LogStream::flags that make it look more +like normal objects of type std::ostream. +
    +(Fahad Alrashed, 2013/04/22) +
  2. +
  3. New: SparseDirectUMFPACK has long had the ability to work with BlockSparseMatrix objects, but couldn't deal with BlockVector objects. This is now fixed. diff --git a/deal.II/include/deal.II/base/logstream.h b/deal.II/include/deal.II/base/logstream.h index 789a920a0c..5a6166acb6 100644 --- a/deal.II/include/deal.II/base/logstream.h +++ b/deal.II/include/deal.II/base/logstream.h @@ -329,6 +329,30 @@ public: void threshold_float(const float t); + /** + * set the precision for the underlying stream and returns the + * previous stream precision. This fuction mimics + * http://www.cplusplus.com/reference/ios/ios_base/precision/ + */ + std::streamsize precision (const std::streamsize prec); + + + /** + * set the width for the underlying stream and returns the + * previous stream width. This fuction mimics + * http://www.cplusplus.com/reference/ios/ios_base/width/ + */ + std::streamsize width (const std::streamsize wide); + + + /** + * set the flags for the underlying stream and returns the + * previous stream flags. This fuction mimics + * http://www.cplusplus.com/reference/ios/ios_base/flags/ + */ + std::ios::fmtflags flags(const std::ios::fmtflags f); + + /** * Output a constant something through this stream. */ @@ -507,6 +531,27 @@ private: */ bool at_newline; + /** + * The flags used to modify how + * the stream returned by get_stream() is used. + */ + std::ios_base::fmtflags stream_flags; + + /** + * The minimum width of characters + * used to represent a number. Used by width() to + * change the stream return by get_stream() + */ + std::streamsize stream_width; + + /** + * The maximum width of characters + * used to represent a floating point number. + * Used by precision() to + * change the stream return by get_stream() + */ + std::streamsize stream_precision; + /** * Print head of line. This prints optional time information and the * contents of the prefix stack. @@ -520,7 +565,6 @@ private: */ std::ostringstream &get_stream() { - outstreams.get().setf(std::ios::showpoint | std::ios::left); return outstreams.get(); } @@ -541,8 +585,22 @@ inline LogStream & LogStream::operator<< (const T &t) { - // print to the internal stringstream: - get_stream() << t; + // save the state of the output stream + std::ostringstream &stream = get_stream(); + + const std::ios::fmtflags old_flags = stream.flags(stream_flags); + const unsigned int old_precision = stream.precision (stream_precision); + const unsigned int old_width = stream.width (stream_width); + + // print to the internal stringstream, using the flags we have just set for + // the stream object: + stream << t; + + // reset output format to whatever it was before + stream.flags (old_flags); + stream.precision(old_precision); + stream.width(old_width); + return *this; } @@ -552,16 +610,27 @@ inline LogStream & LogStream::operator<< (const double t) { + // save the state of out stream + std::ostringstream &stream = get_stream(); + const std::ios::fmtflags old_flags = stream.flags(stream_flags); + const unsigned int old_precision = stream.precision (stream_precision); + const unsigned int old_width = stream.width (stream_width); + // we have to make sure that we don't catch NaN's and +-Inf's with the // test, because for these denormals all comparisons are always false. // thus, for a NaN, both t<=0 and t>=0 are false at the same time, which // can't be said for any other number if (! (t<=0) && !(t>=0)) - get_stream() << t; + stream << t; else if (std::fabs(t) < double_threshold) - get_stream() << '0'; + stream << '0'; else - get_stream() << t*(1.+offset); + stream << t*(1.+offset); + + // reset output format + stream.flags (old_flags); + stream.precision(old_precision); + stream.width(old_width); return *this; } @@ -572,16 +641,27 @@ inline LogStream & LogStream::operator<< (const float t) { + // save the state of out stream + std::ostringstream &stream = get_stream(); + const std::ios::fmtflags old_flags = stream.flags(stream_flags); + const unsigned int old_precision = stream.precision (stream_precision); + const unsigned int old_width = stream.width (stream_width); + // we have to make sure that we don't catch NaN's and +-Inf's with the // test, because for these denormals all comparisons are always false. // thus, for a NaN, both t<=0 and t>=0 are false at the same time, which // can't be said for any other number if (! (t<=0) && !(t>=0)) - get_stream() << t; + stream << t; else if (std::fabs(t) < float_threshold) - get_stream() << '0'; + stream << '0'; else - get_stream() << t*(1.+offset); + stream << t*(1.+offset); + + // reset output format + stream.flags (old_flags); + stream.precision(old_precision); + stream.width(old_width); return *this; } diff --git a/tests/base/log_precision.cc b/tests/base/log_precision.cc new file mode 100644 index 0000000000..068a339307 --- /dev/null +++ b/tests/base/log_precision.cc @@ -0,0 +1,42 @@ +//---------------------------- log_precision.cc --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2005, 2006, 2007, 2013 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- log_precision.cc --------------------------- + +// test that we can set the precision of LogStream objects + +#include "../tests.h" +#include +#include +#include +#include + +int main () +{ + std::ofstream logfile("log_precision/output"); + deallog << std::setprecision(3); + deallog.attach(logfile); + deallog.depth_console(0); + deallog.threshold_double(1.e-10); + + deallog << numbers::PI << std::endl; + + // test with a different precision + deallog.precision(12); + deallog << numbers::PI << std::endl; + + // ensure that the precision of the underlying file stream object remained + // unchanged + deallog.get_file_stream() << numbers::PI << std::endl; + + return 0; +} + diff --git a/tests/base/log_precision/cmp/generic b/tests/base/log_precision/cmp/generic new file mode 100644 index 0000000000..7313b85ec8 --- /dev/null +++ b/tests/base/log_precision/cmp/generic @@ -0,0 +1,4 @@ + +DEAL::3.14159 +DEAL::3.14159265359 +3.14159 diff --git a/tests/base/log_width.cc b/tests/base/log_width.cc new file mode 100644 index 0000000000..24c3324ea9 --- /dev/null +++ b/tests/base/log_width.cc @@ -0,0 +1,42 @@ +//---------------------------- log_width.cc --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2005, 2006, 2007, 2013 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- log_width.cc --------------------------- + +// test that we can set the width of LogStream objects + +#include "../tests.h" +#include +#include +#include +#include + +int main () +{ + std::ofstream logfile("log_width/output"); + deallog << std::setprecision(3); + deallog.attach(logfile); + deallog.depth_console(0); + deallog.threshold_double(1.e-10); + + deallog << numbers::PI*2 << 42 << std::endl; + + // test with a different width + deallog.width(18); + deallog << numbers::PI*2 << 42 << std::endl; + + // ensure that the width of the underlying file stream object remained + // unchanged + deallog.get_file_stream() << numbers::PI*2 << 42 << std::endl; + + return 0; +} + diff --git a/tests/base/log_width/cmp/generic b/tests/base/log_width/cmp/generic new file mode 100644 index 0000000000..06c9981eaf --- /dev/null +++ b/tests/base/log_width/cmp/generic @@ -0,0 +1,4 @@ + +DEAL::6.2831942 +DEAL::6.28319 42 +6.2831942