65.9K
CodeProject 正在变化。 阅读更多。
Home

Napkin

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (4投票s)

2006年3月12日

3分钟阅读

viewsIcon

39974

downloadIcon

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 需求

3 测试环境

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

4 快速入门

  1. 包含 `Napkin` 头文件

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

  2. 初始化 `ostream`

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

  3. 调用 `<<` 操作符

        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

  • 移除了指针风格
© . All rights reserved.