I need to create a debugging ofstream, which has the functionality as follows:
#define DEBUG true
int main() {
debug << "Hello World\n";
}
The output in the above case should be:Hello World
And for the following code-
#define DEBUG false
int main() {
debug << "Hello World\n";
}
The output should be empty.
Any suggestions how I should proceed.
With your usage I think debug needs to be macro as there is no other way to pick up the value of DEBUG. A simple definition would be this:
#define debug (debugstream << enable<DEBUG>)
extern std::ostream debugstream;
template <bool Enable>
std::ostream& enable(std::ostream& out) {
if (Enable) {
out.clear();
}
else {
out.setstate(std::ios_base::badbit);
}
return out;
}
std::ostream debugstream(std::cout.rdbuf()); // probably defined in a separate translation unit
The trick here is to enable/disable printing of the output using the stream's starte: no output is to be produced (by correctly written output operators) when the stream isn't in good state, I.e., if either std::ios_base::failbit or std::ios_base::badbit is set. This behaviour could be forced by setting/unsetting the stream buffer instead using rdbuf().
As I understand from your question, you wish for a separate debugging stream (in contrast to std::cout and std:cerr).
You could accomplish this by making a "null stream" that simply eats everything and does nothing.
If your compiler is clever enough then it should even remove most of this in the end.
class NullStream {};
template<typename T>
NullStream& operator<<(NullStream& s, T const &) { return s; }
NullStream& operator<<(NullStream& s, std::ostream&(std::ostream&)) { return s; }
Now based on your macro you decide whether to use the NullStream or an actual ostringstream.
#if DEBUG
std::ostringstream debug;
#else
NullStream debug;
#endif
Testing it like this:
debug << "Hello World\n";
debug << 12345 << "\n";
debug << "Test" << std::endl;
#if DEBUG
std::cout << "Debug:" << std::endl;
std::cout << debug.str() << std::endl;
#endif
If DEBUG is not 0 then that would yield:
Debug:
Hello World
12345
Test
Note that NullStream doesn't have any of std::ostream's functionality per se, so another solution could be to derive from std::ostream and discard any input it receives.
Related
I am trying to overload the stream operator as a diagnostic tool for various objects in my code. Ideally I would like to be able to modify the stream on the fly with those stream modifier flags, however these are very limited and I don't really want to sprinkle setVerbose flags in each of my objects. I ended up with the following rather poor but working solution
#include <iostream>
#include <string>
#include <vector>
struct StructA {
std::string mLongName;
std::string mShortName;
inline friend std::ostream& operator << (std::ostream& os, const StructA& rStruct) {
// I dont know how to use a generic verbose flag - so use this - very bad idea
// but perhaps the stackoverflow people can help out with a good suggestion
if (os.flags() & os.skipws) {
os << rStruct.mShortName << std::endl;
} else {
os << rStruct.mLongName << std::endl;
}
return os;
}
};
int main()
{
StructA test {"Verbose Name", "Short Name"};
std::cout << test << std::noskipws << test << test << std::skipws << test;
}
I created the above live example to demonstrate my point, and it prints the following output:
Short Name
Verbose Name
Verbose Name
Short Name
As you can see, I am using a totally inappropriate 'skipws' stream modifier flag as a poor man's 1 level verbose flag - that was just to show the in stream approach I was looking for without havnig to add a member object to each of my printable objects (all suggestions for better approaches would be welcome but I would like to minimize the changes to each of my printable objects - as I have quite a lot). Secondly the flag is persistent until reset later - some other stream flags only last for the next stream operator but I am not exactly sure how that works and thirdly
You can store custom state in your stream instance:
See it Live On Coliru
#include <iostream>
static int const index = std::ios_base::xalloc();
std::ostream& verbose(std::ostream& stream) {
stream.iword(index) = 1;
return stream;
}
std::ostream& noverbose(std::ostream& stream) {
stream.iword(index) = 0;
return stream;
}
struct StructA {
std::string mLongName;
std::string mShortName;
inline friend std::ostream& operator << (std::ostream& os, const StructA& rStruct) {
switch (os.iword(index)) {
case 1: return os << rStruct.mLongName;
case 0:
default: return os << rStruct.mShortName;
}
}
};
int main()
{
StructA a;
a.mLongName = "loooooooooooooooooooong names are tedious";
a.mShortName = "succinctness";
std::cout << a << '\n';
std::cout << verbose;
std::cout << a << '\n';
std::cout << noverbose;
std::cout << a << '\n';
}
Credits go to Dietmar Kühl's answer.
If you needed siginificant amounts of state/logic, you would have to look at imbue-ing a custom locale facet. His answer shows the basics of this approach too.
It seems you are in this case too reluctant to create an abstraction for some reason. Don't take this personally I only write this because I once was too hesitant to do that, but create abstractions. Create a Logger class based on iostream either by inheritance or containment which behavior you can modify. Let's say the logger has options like
enum {SHORT,VERBOSE,DEBUG};
Let this option be static so that it has application wide effect on all the instances. Really there only needs to be one instance perhaps?
I realize that all your printable objects need to support the various printing options in a consistent way, i.e. all need to have shortName and longName.
This question already has answers here:
C++ enable/disable debug messages of std::couts on the fly
(9 answers)
Closed 8 years ago.
Is there in C++ already some class which print to cout but can be off when some macro is not defined (for example DEBUG) ?
I can do like
#ifdef DEBUG
std::cout<<"some data"<<"new log<<"\n";
#endif
but is there already overridden operator<< so this be compressed on just one line
You can easily make your own:
namespace mystd
{
struct X {
template<typename T>
X& operator << (const T& x)
{
#ifdef DEBUG
std::cout << x;
#endif
return *this;
}
} cout;
}
and write
mystd::cout << " " << " ";
Simple answere: No, but you can implement this logic easily.
More advanced logging frameworks will actually define a bigger set of logging levels and decide to log based on the current level and the level of the message.
For an example you could take a look at the Poco framework: http://pocoproject.org/slides/110-Logging.pdf
They also offer an std::ostream wrapper around their logging framework
You could use std::ostream state flags to conditionally disable output. A corresponding use code look like this:
std::cout << log << "hello, ";
std::cout << "world\n";
The implementation which enables/disables output when using log could be something like the code below: log is actually constructing an objects which will disable the output if DEBUG is not defined when inserted into a stream by setting the stream flag std::ios_base::failbit. Its destructor will restore the stream state if the state got changed. Since a stream is used, you can also pass the stream object to a function and it will conditionally write output:
extern void f(std::ostream&);
f(std::cout << log);
Of course, the objects also work with other std::ostream objects, not just std::cout.
#ifndef SIMPLE_LOG
#define SIMPLE_LOG
#include <ostream>
class log_enabled
{
mutable std::ostream* stream;
mutable std::ios_base::iostate state;
bool logging;
public:
log_enabled(bool l)
: stream(0)
, state()
, logging(l) {
}
~log_enabled() {
if (stream) {
stream->clear(this->state);
}
}
std::ostream& setup(std::ostream& out) const {
if (!logging) {
this->stream = &out;
this->state = out.rdstate();
out.setstate(std::ios_base::failbit);
}
return out;
}
};
std::ostream& operator<< (std::ostream& out, log_enabled const& log) {
return log.setup(out);
}
# ifdef DEBUG
# define log log_enabled(true)
# else
# define log log_enabled(false)
# endif
#endif
EDIT: The code marked as "not working" was actually working. It was because of a syntax problems in my tests, not detected by the compiler. So the question is already solved, thank you.
C++ is not a language I use everyday, so it is possible that the solution is trivial.
About the context first. I use C++ to develop on a microcontroller (Arduino-based, AVR microcontroller), so I do not use the STL, printf-like functions, new/malloc should be avoided and C++ <string> too.
I have an object called Serial similar to the C++ cout iostream, to communicate with the microcontroller with a serial interface. I have overloaded the "<<" operator of the class from which Serial is an instance so I can do something like that:
Serial << "debug " << "value is " << 3 << endl;
// Whithout the << operator it would be:
Serial.print("debug ");
Serial.print("value is ");
Serial.println(3);
I would like to create a function (or a macro) that enables this kind of line only if debugging is enabled, and which automatically add the "debug" string and append the "endl" value at the end.
So something like that (warning, code does not work because "data" cannot expand as a whole C++ instruction):
#ifdef DEBUG
#define PRINT_DEBUG(data) do {Serial << "debug " << data << endl;} while(0)
#else
#define PRINT_DEBUG(data) do {} while(0)
#endif
// This code works
PRINT_DEBUG("hello world");
// This code does not work
int value1 = 3;
char * value2 = "this is a string";
PRINT_DEBUG("sensor1 value:" << value1 << " other sensor value " << value2);
This kind of function/macro would allow me to easily output strings on my serial interface with a specific "string protocol" without having to repeat the "debug" string at the start. It would also allow me to easily disable the print of debug message by not setting the DEBUG macro. I also have only one "#ifdef DEBUG" instead of several ones in my code.
I managed to do something like that with variadic arguments, but I hate this solution because it is dangerous to use (I do not want to specify the number of arguments), and I cannot mix different type of data:
void __rawSend(char * args, ...) {
Serial.print(args);
va_list paramList;
va_start (paramList, args);
while(true) {
char * next = va_arg(paramList, char*);
if (next == NULL) {
break;
}
Serial.print(" ");
Serial.print(next);
}
Serial.println();
va_end(paramList);
}
#ifdef DEBUG
#define printDebug(...) do {__rawSend(OUTPUT_DEBUG, __VA_ARGS__, NULL);} while(0)
#else
#define printDebug(...) do {} while(0)
#endif
int intValue = 1;
char * stringValue = "data";
// This works
printDebug("hello",stringValue);
// This does not works
printDebug("data is", intValue);
How can I do that? Is it possible with macros (while avoiding variadic arguments and mixing different kind of types)? Is there a better solution?
Sorry all, the code marked as "not working" does actually work. It was because of a syntax problems in my tests, not detected by the compiler.
Anyway, my solution can benefit other people working with Arduino, as I have seen solutions using printf or trying to recreate printf.
I used the "<<" operator coming from http://arduiniana.org/libraries/streaming/
I tend to avoid macros for this sort of things and use classes and static polymoprhism instead :
// Define different types providing a stream interface
struct DebugStream
{
template <typename T>
std::ostream & operator<< (const T & x) const {
return Serial << "debug " << x;
}
// This one is for stream manipulators
std::ostream & operator<< (std::ostream& (*x) (std::ostream&)) const {
return Serial << "debug " << x;
}
};
// This type also provides a stream-like interface but does nothing
struct NoStream
{
template <class T>
const NoStream & operator<< (const T & x) const {
return *this;
}
const NoStream & operator<< (std::ostream& (*x) (std::ostream&)) const {
return *this;
}
};
// Instanciate a debug object having one of the previously defined types
//
// Make sure to declare debug in a common .hxx file included everywhere else
// but to define it only once in a .cxx file.
#ifdef DEBUG
DebugStream debug;
#else
NoStream debug;
#endif
// Use it like you would use the Serial iostream
debug << "value is " << 3 << std::endl;
Since everything is inlined and exact types are known at compile-time, the compiler can optimize out all unnecessary operations on NoStream instances.
If I understand your problems correctly...
Looks to me like you need to overload operator<< for all types you're going to send to the debug interface.
The var args macro has to have a way to deduce the types of its arguments. The way you have it implemented it's expecting all C type strings. You'd be better off with printf or a library like fastformat.
If your operator<< is not returning a reference to the class that allows operator<< to be chained, you'll get errors like "I have the following error for the line "DEBUG("hello" << " " << "world");" : invalid operands of types 'const char [6]' and 'const char [2]' to binary 'operator<<' ". I do not believe DEBUG("hello" << " " << "world"); can be made to work. DEBUG( "hello", "world"); might work.
I want to define a class MyStream so that:
MyStream myStream;
myStream << 1 << 2 << 3 << std::endl << 5 << 6 << std::endl << 7 << 8 << std::endl;
gives output
[blah]123
[blah]56
[blah]78
Basically, I want a "[blah]" inserted at the front, then inserted after every non terminating std::endl?
The difficulty here is NOT the logic management, but detecting and overloading the handling of std::endl. Is there an elegant way to do this?
Thanks!
EDIT: I don't need advice on logic management. I need to know how to detect/overload printing of std::endl.
What you need to do is write your own stream buffer: When the stream buffer is flushed you output you prefix characters and the content of the stream.
The following works because std::endl causes the following.
Add '\n' to the stream.
Calls flush() on the stream
This calls pubsync() on the stream buffer.
This calls the virtual method sync()
Override this virtual method to do the work you want.
#include <iostream>
#include <sstream>
class MyStream: public std::ostream
{
// Write a stream buffer that prefixes each line with Plop
class MyStreamBuf: public std::stringbuf
{
std::ostream& output;
public:
MyStreamBuf(std::ostream& str)
:output(str)
{}
~MyStreamBuf() {
if (pbase() != pptr()) {
putOutput();
}
}
// When we sync the stream with the output.
// 1) Output Plop then the buffer
// 2) Reset the buffer
// 3) flush the actual output stream we are using.
virtual int sync() {
putOutput();
return 0;
}
void putOutput() {
// Called by destructor.
// destructor can not call virtual methods.
output << "[blah]" << str();
str("");
output.flush();
}
};
// My Stream just uses a version of my special buffer
MyStreamBuf buffer;
public:
MyStream(std::ostream& str)
:std::ostream(&buffer)
,buffer(str)
{
}
};
int main()
{
MyStream myStream(std::cout);
myStream << 1 << 2 << 3 << std::endl << 5 << 6 << std::endl << 7 << 8 << std::endl;
}
> ./a.out
[blah]123
[blah]56
[blah]78
>
Your overloaded operators of the MyStream class have to set a previous-printed-token-was-endl flag.
Then, if the next object is printed, the [blah] can be inserted in front of it.
std::endl is a function taking and returning a reference to std::ostream. To detect it was shifted into your stream, you have to overload the operator<< between your type and such a function:
MyStream& operator<<( std::ostream&(*f)(std::ostream&) )
{
std::cout << f;
if( f == std::endl )
{
_lastTokenWasEndl = true;
}
return *this;
}
Agreed with Neil on principle.
You want to change the behavior of the buffer, because that is the only way to extend iostreams. endl does this:
flush(__os.put(__os.widen('\n')));
widen returns a single character, so you can't put your string in there. put calls putc which is not a virtual function and only occasionally hooks to overflow. You can intercept at flush, which calls the buffer's sync. You would need to intercept and change all newline characters as they are overflowed or manually synced and convert them to your string.
Designing an override buffer class is troublesome because basic_streambuf expects direct access to its buffer memory. This prevents you from easily passing I/O requests to a preexisting basic_streambuf. You need to go out on a limb and suppose you know the stream buffer class, and derive from it. (cin and cout are not guaranteed to use basic_filebuf, far as I can tell.) Then, just add virtual overflow and sync. (See §27.5.2.4.5/3 and 27.5.2.4.2/7.) Performing the substitution may require additional space so be careful to allocate that ahead of time.
- OR -
Just declare a new endl in your own namespace, or better, a manipulator which isn't called endl at all!
I use function pointers. It sounds terrifying to people who aren't used to C, but it's a lot more efficient in most cases. Here's an example:
#include <iostream>
class Foo
{
public:
Foo& operator<<(const char* str) { std::cout << str; return *this; }
// If your compiler allows it, you can omit the "fun" from *fun below. It'll make it an anonymous parameter, though...
Foo& operator<<(std::ostream& (*fun)(std::ostream&)) { std::cout << std::endl; }
} foo;
int main(int argc,char **argv)
{
foo << "This is a test!" << std::endl;
return 0;
}
If you really want to you can check for the address of endl to confirm that you aren't getting some OTHER void/void function, but I don't think it's worth it in most cases. I hope that helps.
Instead of attempting to modify the behavior of std::endl, you should probably create a filtering streambuf to do the job. James Kanze has an example showing how to insert a timestamp at the beginning of each output line. It should require only minor modification to change that to whatever prefix you want on each line.
I had the same question, and I thought that Potatoswatter's second answer had merit: "Just declare a new endl in your own namespace, or better, a manipulator which isn't called endl at all!"
So I found out how to write a custom manipulator which is not hard at all:
#include <sstream>
#include <iostream>
class log_t : public std::ostringstream
{
public:
};
std::ostream& custom_endl(std::ostream& out)
{
log_t *log = dynamic_cast<log_t*>(&out);
if (log)
{
std::cout << "custom endl succeeded.\n";
}
out << std::endl;
return out;
}
std::ostream& custom_flush(std::ostream& out)
{
log_t *log = dynamic_cast<log_t*>(&out);
if (log)
{
std::cout << "custom flush succeeded.\n";
}
out << std::flush;
return out;
}
int main(int argc, char **argv)
{
log_t log;
log << "custom endl test" << custom_endl;
log << "custom flush test" << custom_flush;
std::cout << "Contents of log:\n" << log.str() << std::endl;
}
Here's the output:
custom endl succeeded.
custom flush succeeded.
Contents of log:
custom endl test
custom flush test
Here I've created two custom manipulators, one that handles endl and one that handles flush. You can add whatever processing you want to these two functions, since you have a pointer to the log_t object.
You can't change std::endl - as it's name suggests it is a part of the C++ Standard Library and its behaviour is fixed. You need to change the behaviour of the stream itself, when it receives an end of line . Personally, I would not have thought this worth the effort, but if you want to venture into this area I strongly recommend reading the book Standard C++ IOStreams & Locales.
I'm trying to implement my own qDebug() style debug-output stream, this is basically what I have so far:
struct debug
{
#if defined(DEBUG)
template<typename T>
std::ostream& operator<<(T const& a) const
{
std::cout << a;
return std::cout;
}
#else
template<typename T>
debug const& operator<<(T const&) const
{
return *this;
}
/* must handle manipulators (endl) separately:
* manipulators are functions that take a stream& as argument and return a
* stream&
*/
debug const& operator<<(std::ostream& (*manip)(std::ostream&)) const
{
// do nothing with the manipulator
return *this;
}
#endif
};
Typical usage:
debug() << "stuff" << "more stuff" << std::endl;
But I'd like not to have to add std::endl;
My question is basically, how can I tell when the return type of operator<< isn't going to be used by another operator<< (and so append endl)?
The only way I can think of to achieve anything like this would be to create a list of things to print with associated with each temporary object created by qDebug(), then to print everything, along with trailing newline (and I could do clever things like inserting spaces) in ~debug(), but obviously this is not ideal since I don't have a guarantee that the temporary object is going to be destroyed until the end of the scope (or do I?).
Something like this will do:
struct debug {
debug() {
}
~debug() {
std::cerr << m_SS.str() << std::endl;
}
public:
// accepts just about anything
template<class T>
debug &operator<<(const T &x) {
m_SS << x;
return *this;
}
private:
std::ostringstream m_SS;
};
Which should let you do things like this:
debug() << "hello world";
I've used a pattern like this combined with a lock to provide a stream like logging system which can guarantee that log entries are written atomically.
NOTE: untested code, but should work :-)
Qt uses a method similar to #Evan. See a version of qdebug.h for the implementation details, but they stream everything to an underlying text stream, and then flush the stream and an end-line on destruction of the temporary QDebug object returned by qDebug().
When you write that this is the typical usage:
debug() << "stuff" << "more stuff" << std::endl;
are you definitely planning to construct a debug object each time you use it? If so, you should be able to get the behavior you want by having the debug destructor add the newline:
~debug()
{
*this << std::endl;
... the rest of your destructor ...
}
That does mean you cannot do something like this:
// this won't output "line1" and "line2" on separate lines
debug d;
d << "line1";
d << "line2";
The stream insertion (<<) and extraction (>>) are supposed to be non-members.
My question is basically, how can I
tell when the return type of
operator<< isn't going to be used by
another operator<< (and so append
endl)?
You cannot. Create a member function to specially append this or append an endl once those chained calls are done with. Document your class well so that the clients know how to use it. That's your best bet.