Online Book Reader

Home Category

Professional C__ - Marc Gregoire [459]

By Root 1209 0

// from the vector to the output stream.

//

// operator<< must print the entries in order. If the buffer has wrapped,

// the earliest entry is one past the most recent entry, which is the entry

// indicated by mNext. So first print from entry mNext to the end.

//

// Then (even if the buffer hasn't wrapped) print from the beginning to mNext-1.

ostream& operator<<(ostream& ostr, const RingBuffer& rb)

{

if (rb.mWrapped) {

// If the buffer has wrapped, print the elements from

// the earliest entry to the end.

copy(rb.mEntries.begin() + rb.mNext, rb.mEntries.end(),

ostream_iterator(ostr, "\n"));

}

// Now, print up to the most recent entry.

// Go up to begin() + mNext because the range is not inclusive on the

// right side.

copy(rb.mEntries.begin(), rb.mEntries.begin() + rb.mNext,

ostream_iterator(ostr, "\n"));

return ostr;

}

Code snippet from RingBuffer\RingBuffer.cpp

Using the Ring Buffer

In order to use the ring buffer, you can declare an object and start adding messages to it. When you want to print the buffer, just use operator<< to print it to the appropriate ostream. Here is the earlier start-time debug mode program modified to show use of a ring buffer instead:

RingBuffer debugBuf;

class ComplicatedClass

{

public:

ComplicatedClass() {}

};

class UserCommand

{

public:

UserCommand() {}

};

ostream& operator<<(ostream& ostr, const ComplicatedClass& src);

ostream& operator<<(ostream& ostr, const UserCommand& src);

UserCommand getNextCommand(ComplicatedClass* obj);

void processUserCommand(UserCommand& cmd);

void trickyFunction(ComplicatedClass* obj) throw(exception);

int main(int argc, char* argv[])

{

// Print the command-line arguments.

for (int i = 0; i < argc; i++) {

debugBuf.addEntry(argv[i]);

}

ComplicatedClass obj;

trickyFunction(&obj);

// Print the current contents of the debug buffer to cout.

cout << debugBuf;

return 0;

}

ostream& operator<<(ostream& ostr, const ComplicatedClass& src)

{

ostr << "ComplicatedClass";

return ostr;

}

ostream& operator<<(ostream& ostr, const UserCommand& src)

{

ostr << "UserCommand";

return ostr;

}

UserCommand getNextCommand(ComplicatedClass* obj)

{

UserCommand cmd;

return cmd;

}

void processUserCommand(UserCommand& cmd)

{

// Details omitted for brevity

}

void trickyFunction(ComplicatedClass* obj) throw(exception)

{

// Trace log the values with which this function starts.

ostringstream ostr;

ostr << __func__ << "(): given argument: " << *obj;

debugBuf.addEntry(ostr.str());

for (size_t i = 0; i < 100; ++i) {

UserCommand cmd = getNextCommand(obj);

ostringstream ostr;

ostr << __func__ << "(): retrieved cmd " << cmd;

debugBuf.addEntry(ostr.str());

try {

processUserCommand(cmd);

} catch (const exception& e) {

string msg = __func__;

msg += "(): received exception from processUserCommand():";

msg += e.what();

debugBuf.addEntry(msg);

throw;

}

}

}

Code snippet from RingBuffer\RingBufferTest.cpp

Note that this interface to the ring buffer sometimes requires you to construct strings by using ostringstreams or string concatenation before adding entries to the buffer. The following section explains how you can avoid this.

Ring Buffer with Variadic Function Template

To avoid the need to use ostringstreams or string concatenation, you can use the C++11 variadic function template feature, discussed in Chapter 20. The new RingBuffer definition is as follows. Comments have been removed to save space.

class RingBuffer

{

public:

RingBuffer(size_t numEntries = kDefaultNumEntries,

ostream* ostr = nullptr);

virtual ~RingBuffer();

template

void addEntry(const Args&... args)

{

ostringstream os;

addEntryHelper(os, args...);

addStringEntry(os.str());

}

friend ostream& operator<<(ostream& ostr, const RingBuffer& rb);

ostream* setOutput(ostream* newOstr);

protected:

vector mEntries;

ostream* mOstr;

size_t mNumEntries, mNext;

bool mWrapped;

static const size_t kDefaultNumEntries = 500;

template

void addEntryHelper(ostringstream& os, const

Return Main Page Previous Page Next Page

®Online Book Reader