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

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