Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Napkin

0.00/5 (No votes)
12 Mar 2006 1  
A simple logging library using generic object to streams

1 Introduction

Napkin is the simple header-only logging library which provides generic reference-like type to output devices:

napkin::ostream os;

os.reset(std::cout);
os << "to cout:" << 1 << '\n';

os.reset(std::wcout);
os << "to wcout";

std::ofstream fout("log.txt");
os.reset(fout);
os << "to file:" << 3.14;

std::stringstream sout;
os.reset(sout);
os << "to string stream:" << 'x';

os.reset(napkin::dout);
os << "to debugger:" << sout.str();

os.reset(napkin::nout);
os << "to trash box";

std::vector<char> vout;
os.reset(vout);
os << "to sequence";

std::string strout;
os.reset(strout);
os << "to string";

All the types, functions and objects are defined in namespace pstade::napkin.

2 Requirements

3 Tested Under

  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET Version 7.1
  • GCC 3.4.4

4 Quick Start

  1. Include the Napkin header:

    #include <iostream> // cout
    
    #include <pstade/napkin.hpp>
    
    
    void quick_start()
    {
        using namespace pstade;

  2. Initialize ostream:

        napkin::ostream os(std::cout);

  3. Call operator<<:

        os << "hello, napkin";
    }

5 Basic Concepts

5.1 String

A String is a null-terminated const char *.

5.2 String Outputable

A StringOutputable is any out that either of the following expression is valid:

out << psz;
pstade_napkin_output(out, psz, ov);

where psz is a String and ov is a pstade::overload object. It is not surprising that many types conforms to this simple concept; even afxDump.

5.3 Wide String

A WideString is a null-terminated const wchar_t *.

5.4 Wide String Outputable

A WideStringOutputable is any out that either of the following expression is valid:

out << psz;
pstade_napkin_output(out, psz, ov);

where psz is a Wide String and ov is a pstade::overload object.

5.5 Output Streamable

This concept comes from Boost.LexicalCast; an OutputStreamable is any type that operator<< defined that takes a std::ostream or std::wostream object on the left hand side and an instance of the argument type on the right. That means if you have already defined operator<< of your class, Napkin can work with it.

6 Classes

6.1 ostream

ostream is the generic reference-like type to String Outputable objects. The valid expressions are:

ostream os(StringOutputableObject);
os.reset(StringOutputableObject);
os << OutputStreamableObject;
os << OutputStreamableObject0 << OutputStreamableObject1 << ... << 
                        OutputStreamableObjectN;

where os is a ostream object.

ostream also conforms to Default Constructible and Assignable:

using namespace pstade;

napkin::ostream os1(std::cout);
os1 << "constructor style\n";

napkin::ostream os2;
os2.reset(std::cout);
os2 << "reset style\n";

napkin::ostream os3 = os2;
os3 << "copy\n";

napkin::ostream os4;
os4.reset(os3);
os4 << "os3 is StringOutputable.\n";

Note that ostream is of course a model of String Outputable, because a String is Output Streamable by definition.

6.2 wostream

wostream is the generic reference-like type to Wide String Outputable objects. The valid expressions are:

wostream os(WideStringOutputableObject);
os.reset(WideStringOutputableObject);
os << OutputStreamableObject;
os << OutputStreamableObject0 << OutputStreamableObject1 << ... << 
                        OutputStreamableObjectN;

where os is a wostream object. The usage is the same as above.

7 Predefined String Outputables

7.1 nout

nout is the object that conforms to both String Outputable and Wide String Outputable. nout throws out all the inputs, which is usable if you want to temporarily turn off a logging.

7.2 dout

dout is the object that conforms to both String Outputable and Wide String Outputable. dout outputs strings by using ::OutputDebugString. This works only under Windows, so that you must explicitly include the header <pstade/napkin/dout.hpp>.

7.3 Standard Containers

Napkin customizes the standard Back Insertion Sequences by using the second valid expression of String Outputable or Wide String Outputable concept. If seq::value_type is convertible to char, the seq is a model ofString Outputable, and if seq::value_type is convertible to wchar_t, the seq is a model of Wide String Outputable, where seq is a type Back Insertion Sequence.

8 Define Your String Outputable

As an example, let's look into dout type definition:

struct dout_type
{
    void operator<<(const TCHAR *psz)
    {
        ::OutputDebugString(psz);
    }
};

Pretty simple.

9 Remove Side-effects

Though Napkin provides nout, you might want to remove all the side-effects under the release compilation. An easy solution is maybe something like:

#include <pstade/debug.hpp>

#include <pstade/protect.hpp>


void remove_side_effects()
{
    using namespace std;
    using namespace pstade;

    PSTADE_DEBUG( napkin::ostream os; )

    PSTADE_DEBUG(
        os.reset(cout);
        os << "Removed under release compilation\n";
    )

    // When you need comma out of ()

    PSTADE_DEBUG(
        PSTADE_PROTECT(( basic_ofstream< char, char_traits<char> > )) 
                            fout("debug.log");
        os.reset(fout);
        os << "'#if !defined(NDEBUG)' is much easier!";
    )
}

PSTADE_DEBUG disappears under the release compilation. PSTADE_PROTECT works only if the argument is a type.

10 Points of Interest

As mentioned above, String Outputable concept is simple. You can chain, broadcast or add time information anyway you like. Napkin could be a building block of your logging strategy.

Regardless of its flexibility, Napkin's implementation is very small. Napkin only makes use of Boost.LexicalCast, which makes use of std::stringstream.

11 References

12 Release Notes

12.1 Version 0.90.0

  • Initial version released

12.2 Version 0.90.1

12.3 Version 0.90.2

  • Removed pointer style

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here