Lemma is an Electromagnetics API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ProgressBar.cpp 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include "ProgressBar.h"
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <sstream>
  5. #define LENGTH_OF_PROGRESS_BAR 55
  6. #define PERCENTAGE_BIN_SIZE (100.0/LENGTH_OF_PROGRESS_BAR)
  7. namespace
  8. {
  9. std::string generateProgressBar(unsigned int percentage)
  10. {
  11. const int progress = static_cast<int>(percentage/PERCENTAGE_BIN_SIZE);
  12. std::ostringstream ss;
  13. ss << " " << std::setw(3) << std::right << percentage << "% ";
  14. std::string bar("[" + std::string(LENGTH_OF_PROGRESS_BAR-2, ' ') + "]");
  15. unsigned int numberOfSymbols = std::min(
  16. std::max(0, progress - 1),
  17. LENGTH_OF_PROGRESS_BAR - 2);
  18. bar.replace(1, numberOfSymbols, std::string(numberOfSymbols, '|'));
  19. ss << bar;
  20. return ss.str();
  21. }
  22. }
  23. ProgressBar::ProgressBar(
  24. uint32_t expectedIterations, const std::string& initialMessage)
  25. : mTotalIterations(expectedIterations),
  26. mNumberOfTicks(0),
  27. mEnded(false)
  28. {
  29. std::cout << initialMessage << "\n";
  30. mLengthOfLastPrintedMessage = initialMessage.size();
  31. std::cout << generateProgressBar(0) << "\r" << std::flush;
  32. }
  33. ProgressBar::~ProgressBar()
  34. {
  35. endProgressBar();
  36. }
  37. void ProgressBar::operator++()
  38. {
  39. if (mEnded)
  40. {
  41. throw std::runtime_error(
  42. "Attempted to use progress bar after having terminated it");
  43. }
  44. mNumberOfTicks = std::min(mTotalIterations, mNumberOfTicks+1);
  45. const unsigned int percentage = static_cast<unsigned int>(
  46. mNumberOfTicks*100.0/mTotalIterations);
  47. std::cout << generateProgressBar(percentage) << "\r" << std::flush;
  48. }
  49. void ProgressBar::printNewMessage(const std::string& message)
  50. {
  51. if (mEnded)
  52. {
  53. throw std::runtime_error(
  54. "Attempted to use progress bar after having terminated it");
  55. }
  56. std::cout << "\r"
  57. << std::left
  58. << std::setw(LENGTH_OF_PROGRESS_BAR + 6)
  59. << message << "\n";
  60. mLengthOfLastPrintedMessage = message.size();
  61. const unsigned int percentage = static_cast<unsigned int>(
  62. mNumberOfTicks*100.0/mTotalIterations);
  63. std::cout << generateProgressBar(percentage) << "\r" << std::flush;
  64. }
  65. void ProgressBar::updateLastPrintedMessage(const std::string& message)
  66. {
  67. if (mEnded)
  68. {
  69. throw std::runtime_error(
  70. "Attempted to use progress bar after having terminated it");
  71. }
  72. std::cout << "\r\033[F"
  73. << std::left
  74. << std::setw(mLengthOfLastPrintedMessage)
  75. << message << "\n";
  76. mLengthOfLastPrintedMessage = message.size();
  77. }
  78. void ProgressBar::endProgressBar()
  79. {
  80. if (!mEnded)
  81. {
  82. std::cout << std::string(2, '\n');
  83. }
  84. mEnded = true;
  85. }