]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // boost progress.hpp header file ------------------------------------------// |
2 | ||
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) | |
6 | ||
7 | // See http://www.boost.org/libs/timer for documentation. | |
8 | ||
9 | // Revision History | |
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 | |
18 | ||
19 | #ifndef BOOST_PROGRESS_HPP | |
20 | #define BOOST_PROGRESS_HPP | |
21 | ||
22 | #include <boost/timer.hpp> | |
23 | #include <boost/noncopyable.hpp> | |
24 | #include <boost/cstdint.hpp> // for uintmax_t | |
25 | #include <iostream> // for ostream, cout, etc | |
26 | #include <string> // for string | |
27 | ||
28 | namespace boost { | |
29 | ||
30 | // progress_timer ----------------------------------------------------------// | |
31 | ||
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. | |
34 | ||
35 | class progress_timer : public timer, private noncopyable | |
36 | { | |
37 | ||
38 | public: | |
39 | explicit progress_timer( std::ostream & os = std::cout ) | |
40 | // os is hint; implementation may ignore, particularly in embedded systems | |
41 | : timer(), noncopyable(), m_os(os) {} | |
42 | ~progress_timer() | |
43 | { | |
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. | |
48 | try | |
49 | { | |
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 | |
55 | << std::endl; | |
56 | m_os.flags( old_flags ); | |
57 | m_os.precision( old_prec ); | |
58 | } | |
59 | ||
60 | catch (...) {} // eat any exceptions | |
61 | } // ~progress_timer | |
62 | ||
63 | private: | |
64 | std::ostream & m_os; | |
65 | }; | |
66 | ||
67 | ||
68 | // progress_display --------------------------------------------------------// | |
69 | ||
70 | // progress_display displays an appropriate indication of | |
71 | // progress at an appropriate place in an appropriate form. | |
72 | ||
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. | |
76 | ||
77 | class progress_display : private noncopyable | |
78 | { | |
79 | public: | |
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 | : noncopyable(), m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count_); } | |
87 | ||
88 | void restart( unsigned long expected_count_ ) | |
89 | // Effects: display appropriate scale | |
90 | // Postconditions: count()==0, expected_count()==expected_count_ | |
91 | { | |
92 | _count = _next_tic_count = _tic = 0; | |
93 | _expected_count = expected_count_; | |
94 | ||
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 | |
98 | << m_s3; | |
99 | if ( !_expected_count ) _expected_count = 1; // prevent divide by zero | |
100 | } // restart | |
101 | ||
102 | unsigned long operator+=( unsigned long increment ) | |
103 | // Effects: Display appropriate progress tic if needed. | |
104 | // Postconditions: count()== original count() + increment | |
105 | // Returns: count(). | |
106 | { | |
107 | if ( (_count += increment) >= _next_tic_count ) { display_tic(); } | |
108 | return _count; | |
109 | } | |
110 | ||
111 | unsigned long operator++() { return operator+=( 1 ); } | |
112 | unsigned long count() const { return _count; } | |
113 | unsigned long expected_count() const { return _expected_count; } | |
114 | ||
115 | private: | |
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 | |
120 | ||
121 | unsigned long _count, _expected_count, _next_tic_count; | |
122 | unsigned int _tic; | |
123 | void display_tic() | |
124 | { | |
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 = static_cast<unsigned int>((static_cast<double>(_count) | |
129 | / static_cast<double>(_expected_count)) * 50.0); | |
130 | do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed ); | |
131 | _next_tic_count = | |
132 | static_cast<unsigned long>((_tic/50.0) * static_cast<double>(_expected_count)); | |
133 | if ( _count == _expected_count ) { | |
134 | if ( _tic < 51 ) m_os << '*'; | |
135 | m_os << std::endl; | |
136 | } | |
137 | } // display_tic | |
138 | }; | |
139 | ||
140 | } // namespace boost | |
141 | ||
142 | #endif // BOOST_PROGRESS_HPP |