
Hello, I have a suggestion over boost/progress.hpp. The class is very good. But I have a critic to announce. If we want to use the class to just keep an eye of the evolution of the process (we do not can just say we don't want a stream output (i'm right??)). I.E : to send the progress pourcentage to a graphical progress bar. So I purpose something like the following : A basic class to manage the evolution of a process. A class to display the evolution of the process that use the precedent one. It's possible I misunderstanding the progress_display class to tell it that we don't want stream output (example to feed a graphical progress bar). The body of the functions and classes will be something like : #include <iostream> #include <string> using namespace std; // CProgress --------------------------------------------------------// // CProgress manage the appropriate count_step of progress // Usage : // CProgress progress( COUNT ); // for(int i=0; i < COUNT; ++i, ++progress) //{ // ... //do something //} //-- you can access to internal data : // //cout<< "Count : " << my_progress_bar.count() << " pourcent " << my_progress_bar.count()/(float)my_progress_bar.expected_count()*100; class CProgress { public: explicit CProgress ( unsigned long expected_count=1 ) { restart ( expected_count ); } virtual void restart ( unsigned long expected_count ) // Effects: display appropriate scale // Postconditions: count()==0, expected_count()==expected_count { _count = _next_tic_count = _tic = 0; _expected_count = expected_count; if ( !_expected_count ) _expected_count = 1; // prevent divide by zero } // restart unsigned long operator+= ( unsigned long increment ) // Effects: Increment appropriate progress tic if needed. // Postconditions: count()== original count() + increment // Returns: count(). { if ( ( _count += increment ) >= _next_tic_count ) { inc_tic(); } return _count; } unsigned long operator++() { return operator+= ( 1 ); } //-- Accessor unsigned long count() const { return _count; } unsigned long expected_count() const { return _expected_count; } protected: unsigned long _count, _expected_count, _next_tic_count; unsigned int _tic; private: virtual void inc_tic() { _next_tic_count = static_cast<unsigned long> ( ( _tic/50.0 ) *_expected_count ); } // inc_tic }; // CProgress_display --------------------------------------------------------// // CProgress_display displays an appropriate indication of // progress at an appropriate place in an appropriate form. // Usage : // CProgress_display my_progress_bar( fileList.size() ); // for (list<string>::const_iterator it = fileList.begin(); it != fileList.end(); ++it, ++my_progress_bar) // the CProgress_display::operator++ take in charge the display of the progression (***) // { // const string & filename = *it; // ... // do something // } // //0% 10 20 30 40 50 60 70 80 90 100% //|----|----|----|----|----|----|----|----|----|----| //************************** ... class CProgress_display : public CProgress { public: explicit CProgress_display ( unsigned long expected_count, std::ostream & os = std::cout, const std::string & s1 = "\n", //leading strings const std::string & s2 = "", const std::string & s3 = "" ) // os is hint; implementation may ignore, particularly in embedded systems : m_os ( os ), m_s1 ( s1 ), m_s2 ( s2 ), m_s3 ( s3 ) { restart ( expected_count ); } void restart ( unsigned long expected_count ) // Effects: display appropriate scale // Postconditions: count()==0, expected_count()==expected_count { CLTU_Progress::restart ( expected_count ); //-- Initialize the base class m_os << m_s1 << "0% 10 20 30 40 50 60 70 80 90 100%\n" << m_s2 << "|----|----|----|----|----|----|----|----|----|----|" << std::endl // endl implies flush, which ensures display << m_s3; } // restart private: std::ostream & m_os; // may not be present in all imps // string is more general, safer than const char *, and efficiency or size are not issues const std::string m_s1, m_s2, m_s3; // formatting display void inc_tic() { // use of floating point ensures that both large and small counts // work correctly. static_cast<>() is also used several places // to suppress spurious compiler warnings. unsigned int tics_needed = static_cast<unsigned int> ( ( static_cast<double> ( _count ) /_expected_count ) *50.0 ); do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed ); _next_tic_count = static_cast<unsigned long> ( ( _tic/50.0 ) *_expected_count ); if ( _count == _expected_count ) { if ( _tic < 51 ) m_os << '*'; m_os << std::endl; } } // display_tic }; _________ I'm sure the community will be open to discuss about it. Talk to you, Best, Pierre