1 // boost progress.hpp header file ------------------------------------------//
3 // Copyright Beman Dawes 1994-99. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/timer for documentation.
10 // 1 Dec 01 Add leading progress display strings (suggested by Toon Knapen)
11 // 20 May 01 Introduce several static_casts<> to eliminate warning messages
12 // (Fixed by Beman, reported by Herve Bronnimann)
13 // 12 Jan 01 Change to inline implementation to allow use without library
14 // builds. See docs for more rationale. (Beman Dawes)
15 // 22 Jul 99 Name changed to .hpp
16 // 16 Jul 99 Second beta
17 // 6 Jul 99 Initial boost version
19 #ifndef BOOST_PROGRESS_HPP
20 #define BOOST_PROGRESS_HPP
22 #include <boost/timer.hpp>
23 #include <boost/utility.hpp> // for noncopyable
24 #include <boost/cstdint.hpp> // for uintmax_t
25 #include <iostream> // for ostream, cout, etc
26 #include <string> // for string
30 // progress_timer ----------------------------------------------------------//
32 // A progress_timer behaves like a timer except that the destructor displays
33 // an elapsed time message at an appropriate place in an appropriate form.
35 class progress_timer
: public timer
, private noncopyable
39 explicit progress_timer( std::ostream
& os
= std::cout
)
40 // os is hint; implementation may ignore, particularly in embedded systems
44 // A) Throwing an exception from a destructor is a Bad Thing.
45 // B) The progress_timer destructor does output which may throw.
46 // C) A progress_timer is usually not critical to the application.
47 // Therefore, wrap the I/O in a try block, catch and ignore all exceptions.
50 // use istream instead of ios_base to workaround GNU problem (Greg Chicares)
51 std::istream::fmtflags old_flags
= m_os
.setf( std::istream::fixed
,
52 std::istream::floatfield
);
53 std::streamsize old_prec
= m_os
.precision( 2 );
54 m_os
<< elapsed() << " s\n" // "s" is System International d'Unites std
56 m_os
.flags( old_flags
);
57 m_os
.precision( old_prec
);
60 catch (...) {} // eat any exceptions
68 // progress_display --------------------------------------------------------//
70 // progress_display displays an appropriate indication of
71 // progress at an appropriate place in an appropriate form.
73 // NOTE: (Jan 12, 2001) Tried to change unsigned long to boost::uintmax_t, but
74 // found some compilers couldn't handle the required conversion to double.
75 // Reverted to unsigned long until the compilers catch up.
77 class progress_display
: private noncopyable
80 explicit progress_display( unsigned long expected_count_
,
81 std::ostream
& os
= std::cout
,
82 const std::string
& s1
= "\n", //leading strings
83 const std::string
& s2
= "",
84 const std::string
& s3
= "" )
85 // os is hint; implementation may ignore, particularly in embedded systems
86 : m_os(os
), m_s1(s1
), m_s2(s2
), m_s3(s3
) { restart(expected_count_
); }
88 void restart( unsigned long expected_count_
)
89 // Effects: display appropriate scale
90 // Postconditions: count()==0, expected_count()==expected_count_
92 _count
= _next_tic_count
= _tic
= 0;
93 _expected_count
= expected_count_
;
95 m_os
<< m_s1
<< "0% 10 20 30 40 50 60 70 80 90 100%\n"
96 << m_s2
<< "|----|----|----|----|----|----|----|----|----|----|"
97 << std::endl
// endl implies flush, which ensures display
99 if ( !_expected_count
) _expected_count
= 1; // prevent divide by zero
102 unsigned long operator+=( unsigned long increment
)
103 // Effects: Display appropriate progress tic if needed.
104 // Postconditions: count()== original count() + increment
107 if ( (_count
+= increment
) >= _next_tic_count
) { display_tic(); }
111 unsigned long operator++() { return operator+=( 1 ); }
112 unsigned long count() const { return _count
; }
113 unsigned long expected_count() const { return _expected_count
; }
116 std::ostream
& m_os
; // may not be present in all imps
117 const std::string m_s1
; // string is more general, safer than
118 const std::string m_s2
; // const char *, and efficiency or size are
119 const std::string m_s3
; // not issues
121 unsigned long _count
, _expected_count
, _next_tic_count
;
125 // use of floating point ensures that both large and small counts
126 // work correctly. static_cast<>() is also used several places
127 // to suppress spurious compiler warnings.
128 unsigned int tics_needed
=
129 static_cast<unsigned int>(
130 (static_cast<double>(_count
)/_expected_count
)*50.0 );
131 do { m_os
<< '*' << std::flush
; } while ( ++_tic
< tics_needed
);
133 static_cast<unsigned long>((_tic
/50.0)*_expected_count
);
134 if ( _count
== _expected_count
) {
135 if ( _tic
< 51 ) m_os
<< '*';
143 #endif // BOOST_PROGRESS_HPP