$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] [Progress]
From: Pierre (pmoulon_at_[hidden])
Date: 2009-07-15 10:02:06
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