3

I have a function that uses progress_display to show a loading bar. I would like to be able to be able to disable the output for testing. The loading bar prints the second it is inititialized, and if I initialize it in an if statement, I get an error from calling ++loading_bar; from another if statement.

I was wondering if I could disable it by initializing it with my own stream that does nothing, but I have no idea how I would make this.

#include <boost/progress.hpp>
int myfuntion(bool silent)
{
  int computations = 100;
  boost::progress_display loading_bar(computations);
  ++loading_bar;
}
Galadude
  • 253
  • 1
  • 3
  • 11
  • 1
    IMHO this calls for [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection). i.e. have two implementations of some progress logging interface (one dummy, one using `boost::progress_display`) and pass an appropriate one as a parameter. – Dan Mašek May 17 '17 at 21:05

1 Answers1

2

You must pass an object derived from std::ostream in the constructor and the progress_display stores a reference, so it is not possible to change it afterwards.

As you say, you can create your own object that controls the output, but it must comply:

  • It must derive from std::ostream.
  • It must have the same time duration that the progress_display.

You may find more information here about the derivation from std::ostream. Based on the link, you may define the following struct;

struct Output : std::ostream, std::streambuf
{
    Output(bool enabled) : std::ostream(this), m_enabled(enabled) {}

    int overflow(int c)  {
        if(m_enabled) std::cout.put(c);
        return 0;
    }

    bool m_enabled;
};

Now, this struct can enable/disable the output from its constructor if you declare the progress_display as:

// Visible progress
Output out_enabled(true);
boost::progress_display loading_bar_visible(computations, out_enabled);

// Invisible progress
Output out_disabled(false);
boost::progress_display loading_bar_invisible(computations, out_disabled);
Community
  • 1
  • 1
J. Calleja
  • 4,855
  • 2
  • 33
  • 54
  • I had to add an additional `std::cout.flush();` after `put` to get this to work properly. – jodag Mar 31 '20 at 23:34