#include <glibmm.h>
namespace
{
class ThreadProgress
{
public:
  explicit ThreadProgress(int id);
  virtual ~ThreadProgress();
  int  id() const;
  void join();
  bool unfinished() const;
private:
  enum { ITERATIONS = 100 };
  
  
  
  int                 id_;
  unsigned int        progress_;
  void progress_increment();
  void thread_function();
};
{
public:
  Application();
  virtual ~Application();
  void run();
private:
  void launch_threads();
  void on_progress_finished(ThreadProgress* thread_progress);
};
template <class T>
{
public:
  void operator()(T ptr) const { delete ptr; }
};
ThreadProgress::ThreadProgress(int id)
:
  thread_   (0),
  id_       (id),
  progress_ (0)
{
  
  signal_increment_.connect(
sigc::mem_fun(*
this, &ThreadProgress::progress_increment));
}
ThreadProgress::~ThreadProgress()
{
  
  g_return_if_fail(thread_ == 0);
}
int ThreadProgress::id() const
{
  return id_;
}
void ThreadProgress::launch()
{
  
}
void ThreadProgress::join()
{
  thread_->join();
  thread_ = 0;
}
bool ThreadProgress::unfinished() const
{
  return (progress_ < ITERATIONS);
}
{
  return signal_finished_;
}
void ThreadProgress::progress_increment()
{
  ++progress_;
  std::cout << 
"Thread " << id_ << 
": " << progress_ << 
'%' << 
std::endl;
 
  if (progress_ >= ITERATIONS)
    signal_finished_();
}
void ThreadProgress::thread_function()
{
  for (int i = 0; i < ITERATIONS; ++i)
  {
    
    signal_increment_();
  }
}
Application::Application()
:
  progress_threads_ (5)
{
  try
  {
    {
      ThreadProgress *const progress = new ThreadProgress(i + 1);
      progress_threads_[i] = progress;
      progress->signal_finished().connect(
          sigc::bind<1>(
sigc::mem_fun(*
this, &Application::on_progress_finished), progress));
    }
  }
  catch (...)
  {
    
    
    std::for_each(progress_threads_.begin(), progress_threads_.end(),
 
                  DeletePtr<ThreadProgress*>());
    throw;
  }
}
Application::~Application()
{
  std::for_each(progress_threads_.begin(), progress_threads_.end(),
                DeletePtr<ThreadProgress*>());
}
void Application::run()
{
  
  main_loop_->run();
}
void Application::launch_threads()
{
  std::cout << "Launching " << progress_threads_.size() << " threads:" << std::endl;
  std::for_each(progress_threads_.begin(), progress_threads_.end(),
}
void Application::on_progress_finished(ThreadProgress* thread_progress)
{
  thread_progress->join();
  std::cout << "Thread " << thread_progress->id() << ": finished." << std::endl;
  
  if (
std::find_if(progress_threads_.begin(), progress_threads_.end(),
 
                   std::mem_fun(&ThreadProgress::unfinished)) == progress_threads_.end())
 
  {
    main_loop_->quit();
  }
}
} 
int main(int, char**)
{
  Application application;
  application.run();
  return 0;
}