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
-
Include the Napkin
header:
#include <iostream> // cout
#include <pstade/napkin.hpp>
void quick_start()
{
using namespace pstade;
-
Initialize ostream
:
napkin::ostream os(std::cout);
-
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 string
s 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";
)
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
12.2 Version 0.90.1
12.3 Version 0.90.2