Advertisement
575

8 - progressbar

575
Apr 22nd, 2023
865
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.69 KB | None | 0 0
  1. #pragma once
  2. #ifndef __PROGRESSBAR_HPP
  3. #define __PROGRESSBAR_HPP
  4.  
  5. #include <iostream>
  6. #include <ostream>
  7. #include <string>
  8. #include <stdexcept>
  9.  
  10. class progressbar {
  11.  
  12. public:
  13.     // default destructor
  14.     ~progressbar() = default;
  15.  
  16.     // delete everything else
  17.     progressbar(progressbar const&) = delete;
  18.     progressbar& operator=(progressbar const&) = delete;
  19.     progressbar(progressbar&&) = delete;
  20.     progressbar& operator=(progressbar&&) = delete;
  21.  
  22.     // default constructor, must call set_niter later
  23.     inline progressbar();
  24.     inline progressbar(int n, bool showbar = true, std::ostream& out = std::cerr);
  25.  
  26.     // reset bar to use it again
  27.     inline void reset();
  28.     // set number of loop iterations
  29.     inline void set_niter(int iter);
  30.     // chose your style
  31.     inline void set_done_char(const std::string& sym) { done_char = sym; }
  32.     inline void set_todo_char(const std::string& sym) { todo_char = sym; }
  33.     inline void set_opening_bracket_char(const std::string& sym) { opening_bracket_char = sym; }
  34.     inline void set_closing_bracket_char(const std::string& sym) { closing_bracket_char = sym; }
  35.     // to show only the percentage
  36.     inline void show_bar(bool flag = true) { do_show_bar = flag; }
  37.     // set the output stream
  38.     inline void set_output_stream(const std::ostream& stream) { output.rdbuf(stream.rdbuf()); }
  39.     // main function
  40.     inline void update();
  41.  
  42. private:
  43.     int progress;
  44.     int n_cycles;
  45.     int last_perc;
  46.     bool do_show_bar;
  47.     bool update_is_called;
  48.  
  49.     std::string done_char;
  50.     std::string todo_char;
  51.     std::string opening_bracket_char;
  52.     std::string closing_bracket_char;
  53.  
  54.     std::ostream& output;
  55. };
  56.  
  57. inline progressbar::progressbar() :
  58.     progress(0),
  59.     n_cycles(0),
  60.     last_perc(0),
  61.     do_show_bar(true),
  62.     update_is_called(false),
  63.     done_char("#"),
  64.     todo_char(" "),
  65.     opening_bracket_char("["),
  66.     closing_bracket_char("]"),
  67.     output(std::cerr) {}
  68.  
  69. inline progressbar::progressbar(int n, bool showbar, std::ostream& out) :
  70.     progress(0),
  71.     n_cycles(n),
  72.     last_perc(0),
  73.     do_show_bar(showbar),
  74.     update_is_called(false),
  75.     done_char("#"),
  76.     todo_char(" "),
  77.     opening_bracket_char("["),
  78.     closing_bracket_char("]"),
  79.     output(out) {}
  80.  
  81. inline void progressbar::reset() {
  82.     progress = 0,
  83.         update_is_called = false;
  84.     last_perc = 0;
  85.     return;
  86. }
  87.  
  88. inline void progressbar::set_niter(int niter) {
  89.     if (niter <= 0) throw std::invalid_argument(
  90.         "progressbar::set_niter: number of iterations null or negative");
  91.     n_cycles = niter;
  92.     return;
  93. }
  94.  
  95. inline void progressbar::update() {
  96.  
  97.     if (n_cycles == 0) throw std::runtime_error(
  98.         "progressbar::update: number of cycles not set");
  99.  
  100.     if (!update_is_called) {
  101.         if (do_show_bar == true) {
  102.             output << opening_bracket_char;
  103.             for (int _ = 0; _ < 50; _++) output << todo_char;
  104.             output << closing_bracket_char << " 0%";
  105.         }
  106.         else output << "0%";
  107.     }
  108.     update_is_called = true;
  109.  
  110.     int perc = 0;
  111.  
  112.     // compute percentage, if did not change, do nothing and return
  113.     perc = progress * 100. / (n_cycles - 1);
  114.     if (perc < last_perc) return;
  115.  
  116.     // update percentage each unit
  117.     if (perc == last_perc + 1) {
  118.         // erase the correct  number of characters
  119.         if (perc <= 10)                output << "\b\b" << perc << '%';
  120.         else if (perc > 10 and perc < 100) output << "\b\b\b" << perc << '%';
  121.         else if (perc == 100)               output << "\b\b\b" << perc << '%';
  122.     }
  123.     if (do_show_bar == true) {
  124.         // update bar every ten units
  125.         if (perc % 2 == 0) {
  126.             // erase closing bracket
  127.             output << std::string(closing_bracket_char.size(), '\b');
  128.             // erase trailing percentage characters
  129.             if (perc < 10)               output << "\b\b\b";
  130.             else if (perc >= 10 && perc < 100) output << "\b\b\b\b";
  131.             else if (perc == 100)              output << "\b\b\b\b\b";
  132.  
  133.             // erase 'todo_char'
  134.             for (int j = 0; j < 50 - (perc - 1) / 2; ++j) {
  135.                 output << std::string(todo_char.size(), '\b');
  136.             }
  137.  
  138.             // add one additional 'done_char'
  139.             if (perc == 0) output << todo_char;
  140.             else           output << done_char;
  141.  
  142.             // refill with 'todo_char'
  143.             for (int j = 0; j < 50 - (perc - 1) / 2 - 1; ++j) output << todo_char;
  144.  
  145.             // readd trailing percentage characters
  146.             output << closing_bracket_char << ' ' << perc << '%';
  147.         }
  148.     }
  149.     last_perc = perc;
  150.     ++progress;
  151.     output << std::flush;
  152.  
  153.     return;
  154. }
  155.  
  156. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement