progress_timer
progress_timer继承自timer,拥有timer的所有功能,不同的是,会在析构时自动输出时间,省去了timer手动调用elapsed()的工作。
头文件:<boost/progress.hpp>
using namespace boost;
progress_timer源码:
#include <boost/timer.hpp>
#include <boost/noncopyable.hpp>
#include <boost/cstdint.hpp> // for uintmax_t
#include <iostream> // for ostream, cout, etc
#include <string> // for string
class progress_timer : public timer, private noncopyable
{
public:
//explict 用来声明构造函数不允许被隐式转换
//初始化列表,可以用来初始化私有变量,也可以指明调用父类的那个构造函数
explict progress_timer(std::ostream &os = std::cout)
:timer(),noncopyable(),m_os(os)
{
}
//effective c++,不要让析构抛出异常,自己在析构中捕获异常
~progress_timer()
{
try
{
std::istream::fmtflags old_flags = m_os.setf(std::istream::fixed,std::istream::floatfield)
//将精度默认为小数点后两位,如果需要重新定义小数点位数,则需重写该类,在此将对应的精度值传入
std::streamsize old_prec = m_os.precision( 2 );
m_os << elapsed() << " s\n" // "s" is System International d'Unites std << std::endl;
//恢复流状态
m_os.flags( old_flags );
m_os.precision( old_prec );
}
catch(...)
{
//捕获所有异常,不进行处理
}
}
private:
std::ostream m_os;
};
//将拷贝构造和赋值运算删除
class noncopyable
{
protected:
BOOST_CONSTEXPR noncopyable() = default;
~noncopyable() = default;
private:
noncopyable( const noncopyable& ) = delete;
noncopyable& operator=( const noncopyable& ) = delete;
};
调用方法
#include <iostream>
#include <windows.h>
#include <boost/progress.hpp>
#include <string>
using namespace std;
using namespace boost;
int main()
{
{
progress_timer t;
Sleep(2000);
}
{
progress_timer t;
Sleep(3000);
}
return 0;
}
progress_diplay
progress_display可以再控制台上显示程序的执行进度。
//代码分析:当调用opertor+=或者++使,会增加对应的*
class progress_display : private noncopyable
{
public:
explicit progress_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
: noncopyable(), 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_
{
_count = _next_tic_count = _tic = 0;
_expected_count = expected_count_;
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;
if ( !_expected_count ) _expected_count = 1; // prevent divide by zero
} // restart
unsigned long operator+=( unsigned long increment )
// Effects: Display appropriate progress tic if needed.
// Postconditions: count()== original count() + increment
// Returns: count().
{
if ( (_count += increment) >= _next_tic_count ) { display_tic(); }
return _count;
}
unsigned long operator++() { return operator+=( 1 ); }
unsigned long count() const { return _count; }
unsigned long expected_count() const { return _expected_count; }
private:
std::ostream & m_os; // may not be present in all imps
const std::string m_s1; // string is more general, safer than
const std::string m_s2; // const char *, and efficiency or size are
const std::string m_s3; // not issues
unsigned long _count, _expected_count, _next_tic_count;
unsigned int _tic;
void display_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)
/ static_cast<double>(_expected_count)) * 50.0);
do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed );
_next_tic_count =
static_cast<unsigned long>((_tic/50.0) * static_cast<double>(_expected_count));
if ( _count == _expected_count ) {
if ( _tic < 51 ) m_os << '*';
m_os << std::endl;
}
} // display_tic
#include <iostream>
#include <windows.h>
#include <boost/progress.hpp>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
using namespace boost;
int main()
{
vector<string> v(100);
ofstream fs("./test.txt");
//声明一个progress_display对象,基数是v的大小
progress_display pd(v.size());
vector<string>::iterator pos;
for (pos = v.begin();pos != v.end();++pos)
{
fs << *pos << endl;
Sleep(500);
++pd;
}
return 0;
}