Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r74778 - in trunk: boost/timer libs/timer/doc libs/timer/src libs/timer/test
From: bdawes_at_[hidden]
Date: 2011-10-07 09:57:44


Author: bemandawes
Date: 2011-10-07 09:57:43 EDT (Fri, 07 Oct 2011)
New Revision: 74778
URL: http://svn.boost.org/trac/boost/changeset/74778

Log:
Change stop() to void return, supply auto_cpu_timer observers, change m_os to pointer to enable compiler generated operator=, change report() to no longer do stop() ... resume()
Text files modified:
   trunk/boost/timer/timer.hpp | 46 +++++++++++-------
   trunk/libs/timer/doc/cpu_timers.html | 100 +++++++++++++++++++++++++--------------
   trunk/libs/timer/src/auto_timers_construction.cpp | 6 +-
   trunk/libs/timer/src/cpu_timer.cpp | 11 ++--
   trunk/libs/timer/test/cpu_timer_test.cpp | 93 ++++++++++++++++++++++++++++++++++++
   5 files changed, 192 insertions(+), 64 deletions(-)

Modified: trunk/boost/timer/timer.hpp
==============================================================================
--- trunk/boost/timer/timer.hpp (original)
+++ trunk/boost/timer/timer.hpp 2011-10-07 09:57:43 EDT (Fri, 07 Oct 2011)
@@ -53,7 +53,7 @@
   const short default_places = 6;
 
   BOOST_TIMER_DECL
- std::string format(const cpu_times& times, short places, const std::string& fmt);
+ std::string format(const cpu_times& times, short places, const std::string& format);
 
   BOOST_TIMER_DECL
   std::string format(const cpu_times& times, short places = default_places);
@@ -68,20 +68,20 @@
     cpu_timer() { start(); }
 
     // observers
- bool is_stopped() const { return m_is_stopped; }
- cpu_times elapsed() const; // does not stop()
- std::string format(short places, const std::string& format) const
- { return ::boost::timer::format(elapsed(), places, format); }
- std::string format(short places = default_places) const
- { return ::boost::timer::format(elapsed(), places); }
+ bool is_stopped() const { return m_is_stopped; }
+ cpu_times elapsed() const; // does not stop()
+ std::string format(short places, const std::string& format) const
+ { return ::boost::timer::format(elapsed(), places, format); }
+ std::string format(short places = default_places) const
+ { return ::boost::timer::format(elapsed(), places); }
     // actions
- void start();
- const cpu_times& stop();
- void resume();
+ void start();
+ void stop();
+ void resume();
 
   private:
- cpu_times m_times;
- bool m_is_stopped;
+ cpu_times m_times;
+ bool m_is_stopped;
   };
 
 // auto_cpu_timer --------------------------------------------------------------------//
@@ -90,29 +90,39 @@
   {
   public:
 
- // Explicit defaults to std::cout are not supplied since such defaults would
- // require including <iostream>, with its high costs, even when the standard
- // streams are not actually used.
+ // Explicit defaults for os are not provided to avoid including <iostream>, which has
+ // high costs even when the standard streams are not actually used. Explicit defaults
+ // for format are not provided to avoid order-of-dynamic-initialization issues with a
+ // std::string.
 
     explicit auto_cpu_timer(short places = default_places); // #1
              auto_cpu_timer(short places, const std::string& format); // #2
     explicit auto_cpu_timer(const std::string& format); // #3
              auto_cpu_timer(std::ostream& os, short places,
                             const std::string& format) // #4
- : m_places(places), m_os(os), m_format(format)
+ : m_places(places), m_os(&os), m_format(format)
                                    { start(); }
     explicit auto_cpu_timer(std::ostream& os, short places = default_places); // #5
              auto_cpu_timer(std::ostream& os, const std::string& format) // #6
- : m_places(default_places), m_os(os), m_format(format)
+ : m_places(default_places), m_os(&os), m_format(format)
                                    { start(); }
 
    ~auto_cpu_timer();
 
+ // observers
+ // not particularly useful to users, but allow testing of constructor
+ // postconditions and ease specification of other functionality without resorting
+ // to "for exposition only" private members.
+ std::ostream& ostream() const { return *m_os; }
+ short places() const { return m_places; }
+ const std::string& format_string() const { return m_format; }
+
+ // actions
     void report();
 
   private:
     short m_places;
- std::ostream& m_os;
+ std::ostream* m_os; // stored as ptr so compiler can generate operator=
     std::string m_format;
   };
    

Modified: trunk/libs/timer/doc/cpu_timers.html
==============================================================================
--- trunk/libs/timer/doc/cpu_timers.html (original)
+++ trunk/libs/timer/doc/cpu_timers.html 2011-10-07 09:57:43 EDT (Fri, 07 Oct 2011)
@@ -64,13 +64,15 @@
       <a href="#Class-cpu_timer">Class <code>cpu_timer</code></a><br>
       &nbsp;&nbsp;<code>&nbsp; cpu_timer</code><a href="#cpu_timer-constructors">
 constructors, destructor</a><br>
- &nbsp;&nbsp;<code>&nbsp; cpu_timer</code><a href="#cpu_timer-observers">
+ &nbsp;&nbsp;&nbsp; &nbsp;<code>cpu_timer</code><a href="#cpu_timer-observers">
 observers</a><br>
       &nbsp;&nbsp;<code>&nbsp; cpu_timer</code><a href="#cpu_timer-actions">
 actions</a><br>
       &nbsp; Class auto_cpu_timer<br>
       &nbsp;&nbsp;&nbsp;<code> auto_cpu_timer</code> constructors<br>
       &nbsp;&nbsp;&nbsp;<code> auto_cpu_timer</code> destructor<br>
+&nbsp;&nbsp;&nbsp;&nbsp; <a href="#auto_cpu_timer-observers"><code>
+ auto_cpu_timer</code> observers</a><br>
       &nbsp;&nbsp;&nbsp;<code> auto_cpu_timer</code> actions<br>
       <a href="#Timer-accuracy">Timer accuracy</a><br>
 &nbsp; Resolution<br>
@@ -348,38 +350,34 @@
     {
     public:
 
- // constructor, destructor
+ // constructor
       <a href="#cpu_timer-ctor">cpu_timer</a>() noexcept;
- ~cpu_timer() noexcept {}
-
- // compiler generated
+
+ // compiler generated; shown for exposition only
+ ~cpu_timer() noexcept = default;
       cpu_timer(const cpu_timer&amp;) = default;
- cpu_timer&amp; operator=(const cpu_timer&amp;) = default;
+ cpu_timer&amp; operator=(const cpu_timer&amp;) = default;
 
       // observers
- bool is_stopped() const noexcept;
- cpu_times elapsed() const noexcept;
- std::string format(int places, const std::string&amp; format) const;
- std::string format(int places = default_places) const;
+ bool is_stopped() const noexcept;
+ cpu_times elapsed() const noexcept;
+ std::string format(int places, const std::string&amp; format) const;
+ std::string format(int places = default_places) const;
 
       // actions
- void start() noexcept;
- const cpu_times&amp; stop() noexcept;
- void resume() noexcept;
+ void start() noexcept;
+ void stop() noexcept;
+ void resume() noexcept;
     };</pre>
     </td>
   </tr>
 </table>
-<h3><a name="cpu_timer-constructors"><code>cpu_timer</code> constructor</a>, destructor</h3>
+<h3><a name="cpu_timer-constructors"><code>cpu_timer</code> constructor</a></h3>
 <pre><span style="background-color: #D7EEFF"><a name="cpu_timer-ctor">cpu_timer</a>() noexcept;</span></pre>
 <blockquote>
   <p><i>Effects:</i> Constructs an object of type <code>
   cpu_timer</code>. Calls<code> start()</code>.</p>
 </blockquote>
-<pre><span style="background-color: #D7EEFF">~<a name="cpu_timer-dtor">cpu_timer</a>() noexcept {}</span></pre>
-<blockquote>
- <p><i>Effects:</i> None</p>
-</blockquote>
 <h3><a name="cpu_timer-observers"><code>cpu_timer</code>
 observers</a></h3>
 <pre><span style="background-color: #D7EEFF">bool</span><span style="background-color: #D7EEFF"> <a name="is_stopped">is_stopped</a>() const noexcept;</span></pre>
@@ -417,7 +415,7 @@
 <p><i>Postconditions:</i> <code>!is_stopped()</code>.</p>
 
 </blockquote>
-<pre><span style="background-color: #D7EEFF">cpu_times</span><span style="background-color: #D7EEFF"> <a name="stop">stop</a>() noexcept;</span></pre>
+<pre><span style="background-color: #D7EEFF">void <a name="stop">stop</a>() noexcept;</span></pre>
 <blockquote>
 
 <p><i>Effects:</i> If <code>!is_stopped()</code>, stores the difference between
@@ -427,8 +425,6 @@
 
 <p><i>Postconditions:</i> <code>is_stopped()</code>.</p>
 
-<p><i>Returns:</i> The stored times.</p>
-
 </blockquote>
 <pre><span style="background-color: #D7EEFF">void <a name="resume">resume</a>() noexcept;</span></pre>
 <blockquote>
@@ -464,10 +460,17 @@
 
      <a href="#auto_cpu_timer-destructor">~auto_cpu_timer</a>() noexcept;
 
- cpu_timer(const cpu_timer&amp;) = default;
- cpu_timer&amp; operator=(const cpu_timer&amp;) = default;
+ // compiler generated special member functions
+ auto_cpu_timer(const auto_cpu_timer&amp;) = default;
+ auto_cpu_timer&amp; operator=(const auto_cpu_timer&amp;) = default;
+
+ // observers
+ std::ostream&amp; ostream() const noexcept;
+ short places() const noexcept;
+ const std::string&amp; format_string() const noexcept;
 
- void report();
+ // actions
+ void report();
     };</pre>
     </td>
   </tr>
@@ -486,32 +489,57 @@
 </span></pre>
 <blockquote>
   <p><i>Effects:</i> Constructs an object of type <code>
- auto_cpu_timer</code>, storing <code>os</code>, <code>places</code>, and <code>
- format</code>. For the overloads without a <code>format</code>
-argument, the default format is stored as the
- <code>format</code>. For the overloads without an <code>os</code>
-argument, std::cout is stored as the <code>os</code>.</p>
+ auto_cpu_timer</code> and stores the ostream, places, and format string data
+ needed to establish the postconditions.</p>
+ <p><i>Postconditions:</i></p>
+ <ul>
+ <li>For overloads with an <code>os</code> argument, <code>ostream() == os</code>.
+ Otherwise <code>ostream() == std::cout</code>.</li>
+ <li><code>places() == places</code>.</li>
+ <li>For overloads with a <code>format</code> argument, <code>format_string()
+ == format</code>. Otherwise <code>format_string() == std::cout</code></li>
+ </ul>
 </blockquote>
 <h3><a name="auto_cpu_timer-destructor"><code>auto_cpu_timer</code> destructor</a></h3>
 <pre><span style="background-color: #D7EEFF">~</span><span style="background-color: #D7EEFF">auto_cpu_timer</span><span style="background-color: #D7EEFF">() noexcept;</span></pre>
 <blockquote>
-<p dir="ltr"><i>Effects: </i>If <code>!is_stopped()</code>, <a href="#report">
-report()</a>. Otherwise, no effects.</p>
+<p dir="ltr"><i>Effects: </i>If <code>!is_stopped()</code>, stop(), <a href="#report">
+report()</a>.</p>
 <p dir="ltr">[<i>Note:</i> Because the function is <code>noexcept</code>,
 implementation requires a try/catch or equivalent to ensure no exception
 escapes. <i>--end note</i>]</p>
 </blockquote>
+<h3><a name="auto_cpu_timer-observers">auto_cpu_timer observers</a></h3>
+<p>The observers allow testing of constructor postconditions and specification
+of other functionality without resorting to &quot;for exposition only&quot; private
+members.</p>
+<pre><span style="background-color: #D7EEFF">std::ostream&amp; <a name="ostream">ostream</a>() const noexcept;</span></pre>
+<blockquote>
+ <p><i>Returns:</i> The ostream stored by construction or subsequent copy
+ assignment.</p>
+</blockquote>
+<pre><span style="background-color: #D7EEFF">short <a name="places">places</a>() const noexcept;</span></pre>
+<blockquote>
+ <p><i>Returns:</i> The places stored by construction or subsequent copy
+ assignment.</p>
+</blockquote>
+<pre><span style="background-color: #D7EEFF">const std::string&amp; <a name="format_string">format_string</a>() const noexcept;</span></pre>
+<blockquote>
+ <p><i>Returns:</i> The format string stored by construction or subsequent copy
+ assignment.</p>
+</blockquote>
 <h3><a name="auto_cpu_timer-actions"><code>auto_cpu_timer</code> actions</a></h3>
 <pre><span style="background-color: #D7EEFF">void <a name="report">report</a>();</span></pre>
 <blockquote>
   <p><i>Effects: </i>As if:</p>
   <blockquote>
- <pre>m_os &lt;&lt; timer::format(stop(), m_places, m_format);
-resume();</pre>
+ <pre>ostream() &lt;&lt; timer::format(elapsed(), places(), format_string());</pre>
   </blockquote>
 
- <p>[<i>Note:</i> <code>stop()</code> is called because doing I/O while the
- timer is running might produce misleading results. <i>--end note</i>]</p>
+ <p>[<i>Note: </i>It may be desirable to call <code>stop()</code> before
+ calling <code>report()</code> because doing I/O while the
+ timer is running might produce misleading results. <code>resume()</code> may
+ be called afterwards to continue timing. <i>--end note</i>]</p>
 
 </blockquote>
 
@@ -645,7 +673,7 @@
 
 <hr>
 <p><font size="2">Revised:
-<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->06 October 2011<!--webbot bot="Timestamp" endspan i-checksum="32189" --></font></p>
+<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->07 October 2011<!--webbot bot="Timestamp" endspan i-checksum="32191" --></font></p>
 <p><font size="2">© Copyright Beman Dawes, 2006<br>
 © Copyright Beman Dawes and Robert Stewart, 2011</font></p>
 <p><font size="2">Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt</font></p>

Modified: trunk/libs/timer/src/auto_timers_construction.cpp
==============================================================================
--- trunk/libs/timer/src/auto_timers_construction.cpp (original)
+++ trunk/libs/timer/src/auto_timers_construction.cpp 2011-10-07 09:57:43 EDT (Fri, 07 Oct 2011)
@@ -34,13 +34,13 @@
   namespace timer
   {
     auto_cpu_timer::auto_cpu_timer(short places) // #1
- : m_places(places), m_os(std::cout), m_format(default_fmt) { start(); }
+ : m_places(places), m_os(&std::cout), m_format(default_fmt) { start(); }
 
     auto_cpu_timer::auto_cpu_timer(short places, const std::string& format) // #2
- : m_places(places), m_os(std::cout), m_format(format) { start(); }
+ : m_places(places), m_os(&std::cout), m_format(format) { start(); }
 
     auto_cpu_timer::auto_cpu_timer(const std::string& format) // #3
- : m_places(default_places), m_os(std::cout), m_format(format) { start(); }
+ : m_places(default_places), m_os(&std::cout), m_format(format) { start(); }
 
   } // namespace timer
 } // namespace boost

Modified: trunk/libs/timer/src/cpu_timer.cpp
==============================================================================
--- trunk/libs/timer/src/cpu_timer.cpp (original)
+++ trunk/libs/timer/src/cpu_timer.cpp 2011-10-07 09:57:43 EDT (Fri, 07 Oct 2011)
@@ -191,10 +191,10 @@
       get_cpu_times(m_times);
     }
 
- const cpu_times& cpu_timer::stop()
+ void cpu_timer::stop()
     {
       if (is_stopped())
- return m_times;
+ return;
       m_is_stopped = true;
       
       cpu_times current;
@@ -202,7 +202,6 @@
       m_times.wall = (current.wall - m_times.wall);
       m_times.user = (current.user - m_times.user);
       m_times.system = (current.system - m_times.system);
- return m_times;
     }
 
     cpu_times cpu_timer::elapsed() const
@@ -232,21 +231,21 @@
     // auto_cpu_timer ----------------------------------------------------------------//
 
     auto_cpu_timer::auto_cpu_timer(std::ostream& os, short places) // #5
- : m_places(places), m_os(os), m_format(default_fmt)
+ : m_places(places), m_os(&os), m_format(default_fmt)
     {
       start();
     }
 
     void auto_cpu_timer::report()
     {
- show_time(stop(), m_os, m_format, m_places);
- resume();
+ show_time(elapsed(), ostream(), format_string(), places());
     }
 
     auto_cpu_timer::~auto_cpu_timer()
     {
       if (!is_stopped())
       {
+ stop(); // the sooner we stop(), the better
         try
         {
           report();

Modified: trunk/libs/timer/test/cpu_timer_test.cpp
==============================================================================
--- trunk/libs/timer/test/cpu_timer_test.cpp (original)
+++ trunk/libs/timer/test/cpu_timer_test.cpp 2011-10-07 09:57:43 EDT (Fri, 07 Oct 2011)
@@ -18,6 +18,7 @@
 using std::string;
 using std::cout;
 using std::endl;
+using boost::timer::default_places;
 using boost::timer::nanosecond_type;
 using boost::timer::cpu_times;
 using boost::timer::format;
@@ -26,9 +27,98 @@
 
 namespace
 {
+ void unit_test()
+ {
+ cout << "unit test..." << endl;
+
+ string default_format(" %ws wall, %us user + %ss system = %ts CPU (%p%)\n");
+
+ // each constructor
+ auto_cpu_timer t1;
+ BOOST_TEST(!t1.is_stopped());
+ BOOST_TEST(&t1.ostream() == &cout);
+ BOOST_TEST_EQ(t1.places(), default_places);
+ BOOST_TEST_EQ(t1.format_string(), default_format);
+ t1.stop();
+ BOOST_TEST(t1.is_stopped());
+ auto_cpu_timer t1a(t1);
+ BOOST_TEST(t1a.is_stopped());
+ BOOST_TEST_EQ(t1a.elapsed().wall, t1.elapsed().wall);
+ BOOST_TEST_EQ(t1a.elapsed().user, t1.elapsed().user);
+ BOOST_TEST_EQ(t1a.elapsed().system, t1.elapsed().system);
+ BOOST_TEST(&t1a.ostream() == &cout);
+ BOOST_TEST_EQ(t1a.places(), default_places);
+ BOOST_TEST_EQ(t1a.format_string(), default_format);
+
+ auto_cpu_timer t1b;
+ BOOST_TEST(!t1b.is_stopped());
+ t1b = t1;
+ BOOST_TEST(t1b.is_stopped());
+ BOOST_TEST_EQ(t1b.elapsed().wall, t1.elapsed().wall);
+ BOOST_TEST_EQ(t1b.elapsed().user, t1.elapsed().user);
+ BOOST_TEST_EQ(t1b.elapsed().system, t1.elapsed().system);
+ BOOST_TEST(&t1b.ostream() == &cout);
+ BOOST_TEST_EQ(t1b.places(), default_places);
+ BOOST_TEST_EQ(t1b.format_string(), default_format);
+
+ auto_cpu_timer t2(1);
+ BOOST_TEST(!t2.is_stopped());
+ BOOST_TEST(&t2.ostream() == &cout);
+ BOOST_TEST_EQ(t2.places(), 1);
+ BOOST_TEST_EQ(t2.format_string(), default_format);
+
+ auto_cpu_timer t3("foo");
+ BOOST_TEST(!t3.is_stopped());
+ BOOST_TEST(&t3.ostream() == &cout);
+ BOOST_TEST_EQ(t3.places(), default_places);
+ BOOST_TEST_EQ(t3.format_string(), string("foo"));
+
+ auto_cpu_timer t4(1, "foo");
+ BOOST_TEST(!t4.is_stopped());
+ BOOST_TEST(&t4.ostream() == &cout);
+ BOOST_TEST_EQ(t4.places(), 1);
+ BOOST_TEST_EQ(t4.format_string(), string("foo"));
+
+ auto_cpu_timer t5(std::cerr);
+ BOOST_TEST(!t5.is_stopped());
+ BOOST_TEST(&t5.ostream() == &std::cerr);
+ BOOST_TEST_EQ(t5.places(), default_places);
+ BOOST_TEST_EQ(t5.format_string(), default_format);
+
+ auto_cpu_timer t6(std::cerr, 1);
+ BOOST_TEST(!t6.is_stopped());
+ BOOST_TEST(&t6.ostream() == &std::cerr);
+ BOOST_TEST_EQ(t6.places(), 1);
+ BOOST_TEST_EQ(t6.format_string(), default_format);
+
+ auto_cpu_timer t7(std::cerr, "foo");
+ BOOST_TEST(!t7.is_stopped());
+ BOOST_TEST(&t7.ostream() == &std::cerr);
+ BOOST_TEST_EQ(t7.places(), default_places);
+ BOOST_TEST_EQ(t7.format_string(), string("foo"));
+
+ auto_cpu_timer t8(std::cerr, 1, "foo");
+ BOOST_TEST(!t8.is_stopped());
+ BOOST_TEST(&t8.ostream() == &std::cerr);
+ BOOST_TEST_EQ(t8.places(), 1);
+ BOOST_TEST_EQ(t8.format_string(), string("foo"));
+
+ t1.stop();
+ t1a.stop();
+ t1b.stop();
+ t2.stop();
+ t3.stop();
+ t4.stop();
+ t5.stop();
+ t6.stop();
+ t7.stop();
+ t8.stop();
+
+ cout << " unit test complete\n";
+ }
+
   void format_test()
   {
- cout << "format test..." << endl;
 
     cpu_times times;
     times.wall = 5123456789LL;
@@ -125,6 +215,7 @@
 {
   cout << "---------- timer_test ----------\n";
 
+ unit_test();
   format_test();
   std_c_consistency_test();
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk