Napkin






4.38/5 (4投票s)
2006年3月12日
3分钟阅读

39974

82
一个简单的日志库,使用通用对象到流。
1 引言
Napkin
是一个简单的仅头文件日志库,它提供通用的类引用类型来输出到设备。
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";
所有类型、函数和对象都定义在 `pstade::napkin` 命名空间下。
2 需求
- Boost C++ Libraries Version 1.33.1 或更高版本(无需编译)
- P-Stade C++ Libraries Version 0.97.3 或更高版本(无需编译,优先级高于 Boost 头文件)
3 测试环境
- Microsoft Visual C++ 2005 Express Edition
- Microsoft Visual C++ .NET 7.1 版
- GCC 3.4.4
4 快速入门
-
包含 `Napkin` 头文件
#include <iostream> // cout #include <pstade/napkin.hpp> void quick_start() { using namespace pstade;
-
初始化 `ostream`
napkin::ostream os(std::cout);
-
调用 `<<` 操作符
os << "hello, napkin"; }
5 基本概念
5.1 字符串 (String)
`String` 是一个以 `null` 结尾的 `const char *`。
5.2 可字符串输出 (String Outputable)
`StringOutputable` 是任何满足以下任一表达式有效的 `out`:
out << psz;
pstade_napkin_output(out, psz, ov);
其中 `psz` 是一个 `String`,`ov` 是一个 `pstade::overload` 对象。许多类型都符合这个简单的概念,包括 `afxDump`,这并不令人意外。
5.3 宽字符串 (Wide String)
`WideString` 是一个以 `null` 结尾的 `const wchar_t *`。
5.4 可宽字符串输出 (Wide String Outputable)
`WideStringOutputable` 是任何满足以下任一表达式有效的 `out`:
out << psz;
pstade_napkin_output(out, psz, ov);
其中 `psz` 是一个 `Wide String`,`ov` 是一个 `pstade::overload` 对象。
5.5 可输出流 (Output Streamable)
这个概念来自 Boost.LexicalCast;`OutputStreamable` 是任何类型,对其定义了 `<<` 操作符,该操作符的左侧为 `std::ostream` 或 `std::wostream` 对象,右侧为该类型的一个实例。这意味着,如果您已经为您定义的类重载了 `<<` 操作符,`Napkin` 就能与其一起工作。
6 类
6.1 ostream
`ostream` 是指向 `String Outputable` 对象的通用类引用类型。有效的表达式有:
ostream os(StringOutputableObject);
os.reset(StringOutputableObject);
os << OutputStreamableObject;
os << OutputStreamableObject0 << OutputStreamableObject1 << ... <<
OutputStreamableObjectN;
其中 `os` 是一个 `ostream` 对象。
`ostream` 也符合 默认可构造 (Default Constructible) 和 可赋值 (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";
请注意,`ostream` 本身也是 `String Outputable` 的一个模型,因为 `String` 按定义就是 `Output Streamable` 的。
6.2 wostream
`wostream` 是指向 `Wide String Outputable` 对象的通用类引用类型。有效的表达式有:
wostream os(WideStringOutputableObject);
os.reset(WideStringOutputableObject);
os << OutputStreamableObject;
os << OutputStreamableObject0 << OutputStreamableObject1 << ... <<
OutputStreamableObjectN;
其中 `os` 是一个 `wostream` 对象。用法与上面相同。
7 预定义的可字符串输出对象
7.1 nout
`nout` 是一个同时符合 `String Outputable` 和 `Wide String Outputable` 的对象。`nout` 会丢弃所有输入,如果您想暂时禁用日志记录,可以使用它。
7.2 dout
`dout` 是一个同时符合 `String Outputable` 和 `Wide String Outputable` 的对象。`dout` 使用 `::OutputDebugString` 输出 `string`。这仅在 Windows 下有效,因此您必须显式包含头文件 `<pstade/napkin/dout.hpp>`。
7.3 标准容器
`Napkin` 通过使用 `String Outputable` 或 `Wide String Outputable` 概念的第二个有效表达式,来自定义标准 后向插入序列 (Back Insertion Sequence) 。如果 `seq::value_type` 可以转换为 `char`,则 `seq` 是 `String Outputable` 的一个模型;如果 `seq::value_type` 可以转换为 `wchar_t`,则 `seq` 是 `Wide String Outputable` 的一个模型,其中 `seq` 是一个 后向插入序列 类型。
8 定义您自己的可字符串输出对象
例如,让我们看看 `dout` 的类型定义:
struct dout_type
{
void operator<<(const TCHAR *psz)
{
::OutputDebugString(psz);
}
};
非常简单。
9 移除副作用
虽然 `Napkin` 提供了 `nout`,但您可能希望在发布版本编译时移除所有副作用。一个简单的解决方案可能是这样的:
#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` 在发布编译时会消失。`PSTADE_PROTECT` 仅在参数是类型时才起作用。
10 关注点
如上所述,`String Outputable` 概念非常简单。您可以链接、广播或添加时间信息。 `Napkin` 可以作为您日志记录策略的一个构建块。
尽管 `Napkin` 具有灵活性,但其实现非常小巧。 `Napkin` 只使用了 Boost.LexicalCast,而后者又使用了 `std::stringstream`。
11 参考
12 发行说明
12.1 版本 0.90.0
- 首次发布
12.2 版本 0.90.1
- 支持标准 后向插入序列 作为 `String Outputable`
- 扩展了 `String Outputable` 概念
- 移除了 `wnew`
12.3 版本 0.90.2
- 移除了指针风格