Boost C++ 库

...世界上最受推崇和专业设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

Boost.Assert 库提供了几个可配置的诊断宏,它们在行为和目的上类似于标准宏 assert,后者定义于 <cassert> 中。

断言宏, <boost/assert.hpp>

BOOST_ASSERT

头文件 <boost/assert.hpp> 定义了宏 BOOST_ASSERT,它类似于标准 assert 宏,后者定义于 <cassert> 中。该宏旨在用于 Boost 库和用户代码。

  • 默认情况下,BOOST_ASSERT(expr) 展开为 assert(expr)

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_DISABLE_ASSERTS,则 BOOST_ASSERT(expr) 展开为 ((void)0),无论是否定义了宏 NDEBUG。这允许用户选择性地禁用 BOOST_ASSERT,而不会影响标准 assert 的定义。

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_ENABLE_ASSERT_HANDLER,则 BOOST_ASSERT(expr) 展开为

    (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr,
        BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))

    也就是说,它会评估 expr,如果为 false,则调用 ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)。无论是否定义了 NDEBUG,情况都是如此。

    boost::assertion_failed<boost/assert.hpp> 中声明为

    namespace boost
    {
    #if defined(BOOST_ASSERT_HANDLER_IS_NORETURN)
        BOOST_NORETURN
    #endif
        void assertion_failed(char const * expr, char const * function,
            char const * file, long line);
    }

    但它从未被定义。用户需要提供适当的定义。

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_ENABLE_ASSERT_DEBUG_HANDLER,则当定义了 NDEBUG 时,BOOST_ASSERT(expr) 展开为 ((void)0)。否则,行为就如同定义了 BOOST_ENABLE_ASSERT_HANDLER

<cassert> 一样,<boost/assert.hpp> 可以在单个翻译单元中多次包含。BOOST_ASSERT 将每次都如上所述重新定义。

BOOST_ASSERT_MSG

BOOST_ASSERT_MSG 类似于 BOOST_ASSERT,但它接受一个额外的参数,一个字符字面量,用于提供错误消息。

  • 默认情况下,BOOST_ASSERT_MSG(expr,msg) 展开为 assert((expr)&&(msg))

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_DISABLE_ASSERTS,则 BOOST_ASSERT_MSG(expr,msg) 展开为 ((void)0),无论是否定义了宏 NDEBUG

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_ENABLE_ASSERT_HANDLER,则 BOOST_ASSERT_MSG(expr,msg) 展开为

    (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr,
        msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))

    无论是否定义了 NDEBUG,情况都是如此。

    boost::assertion_failed_msg<boost/assert.hpp> 中声明为

    namespace boost
    {
    #if defined(BOOST_ASSERT_HANDLER_IS_NORETURN)
        BOOST_NORETURN
    #endif
        void assertion_failed_msg(char const * expr, char const * msg,
            char const * function, char const * file, long line);
    }

    但它从未被定义。用户需要提供适当的定义。

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_ENABLE_ASSERT_DEBUG_HANDLER,则当定义了 NDEBUG 时,BOOST_ASSERT_MSG(expr) 展开为 ((void)0)。否则,行为就如同定义了 BOOST_ENABLE_ASSERT_HANDLER

<cassert> 一样,<boost/assert.hpp> 可以在单个翻译单元中多次包含。BOOST_ASSERT_MSG 将每次都如上所述重新定义。

BOOST_VERIFY

BOOST_VERIFY 的行为与 BOOST_ASSERT 相同,但传递给 BOOST_VERIFY 的表达式始终会被评估。当断言的表达式具有期望的副作用时,这非常有用;当变量的唯一用途是在断言内部时,它还可以帮助抑制关于未使用变量的警告。

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_DISABLE_ASSERTS,则 BOOST_VERIFY(expr) 展开为 ((void)(expr))

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_ENABLE_ASSERT_HANDLER,则 BOOST_VERIFY(expr) 展开为 BOOST_ASSERT(expr)

  • 否则,当定义了 NDEBUG 时,BOOST_VERIFY(expr) 展开为 ((void)(expr));当未定义 NDEBUG 时,则展开为 BOOST_ASSERT(expr)

BOOST_VERIFY_MSG

BOOST_VERIFY_MSG 类似于 BOOST_VERIFY,但带有一个额外的参数,即错误消息。

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_DISABLE_ASSERTS,则 BOOST_VERIFY_MSG(expr,msg) 展开为 ((void)(expr))

  • 如果在包含 <boost/assert.hpp> 时定义了宏 BOOST_ENABLE_ASSERT_HANDLER,则 BOOST_VERIFY_MSG(expr,msg) 展开为 BOOST_ASSERT_MSG(expr,msg)

  • 否则,当定义了 NDEBUG 时,BOOST_VERIFY_MSG(expr,msg) 展开为 ((void)(expr));当未定义 NDEBUG 时,则展开为 BOOST_ASSERT_MSG(expr,msg)

BOOST_ASSERT_IS_VOID

BOOST_ASSERTBOOST_ASSERT_MSG 展开为 ((void)0) 时,会定义宏 BOOST_ASSERT_IS_VOID。其目的是避免编译和潜在地运行仅用于准备要在断言中使用的数据的代码。

void MyContainer::erase(iterator i)
{
// Some sanity checks, data must be ordered
#ifndef BOOST_ASSERT_IS_VOID

    if(i != c.begin()) {
        iterator prev = i;
        --prev;
        BOOST_ASSERT(*prev < *i);
    }
    else if(i != c.end()) {
        iterator next = i;
        ++next;
        BOOST_ASSERT(*i < *next);
    }

#endif

    this->erase_impl(i);
}
  • 默认情况下,如果定义了 NDEBUG,则会定义 BOOST_ASSERT_IS_VOID

  • 如果定义了宏 BOOST_DISABLE_ASSERTS,则始终定义 BOOST_ASSERT_IS_VOID

  • 如果定义了宏 BOOST_ENABLE_ASSERT_HANDLER,则永远不会定义 BOOST_ASSERT_IS_VOID

  • 如果定义了宏 BOOST_ENABLE_ASSERT_DEBUG_HANDLER,则当定义了 NDEBUG 时,会定义 BOOST_ASSERT_IS_VOID

当前函数宏, <boost/current_function.hpp>

BOOST_CURRENT_FUNCTION

头文件 <boost/current_function.hpp> 定义了一个宏 BOOST_CURRENT_FUNCTION,它类似于 C99 预定义的标识符 __func__

BOOST_CURRENT_FUNCTION 展开为字符串字面量,或当前函数本地的字符数组的名称,其中包含(如果可能,则为完全限定的)封闭函数的名称。如果没有封闭函数,则行为因编译器而异,但通常是编译错误。

某些编译器不提供获取当前封闭函数名称的方法。在这些编译器上,或者当定义了宏 BOOST_DISABLE_CURRENT_FUNCTION 时,BOOST_CURRENT_FUNCTION 展开为 "(unknown)"

BOOST_DISABLE_CURRENT_FUNCTION 解决了程序员希望出于安全原因从最终可执行文件中消除 BOOST_CURRENT_FUNCTION 生成的字符串字面量的情况。

源位置支持, <boost/assert/source_location.hpp>

描述

头文件 <boost/assert/source_location.hpp> 定义了 source_location 类,该类表示源位置并包含文件、行、函数和列信息。它类似于 C++20 中的 std::source_location,但仅需要 C++03。

BOOST_CURRENT_LOCATION 创建一个 source_location 对象,其中包含关于当前源位置的信息。它可以大致以与 std::source_location::current() 相同的方式使用,例如在函数默认参数的声明中

#include <boost/assert/source_location.hpp>
#include <iostream>

void f( boost::source_location const& loc = BOOST_CURRENT_LOCATION )
{
    std::cout << "f() called from: " << loc << std::endl;
}

int main()
{
    f();
}

此示例的输出因编译器和 C++ 标准级别而异,但通常是以下之一

f() called from: example.cpp:11:6 in function 'int main()'
f() called from: example.cpp:11:5 in function 'main'
f() called from: example.cpp:11 in function 'main'
f() called from: example.cpp:4

如果您想声明一个抛出异常的函数,以便调用者的源位置附加到抛出的异常,这将非常有用

BOOST_NORETURN BOOST_NOINLINE void throw_invalid_argument(
    char const* message,
    boost::source_location const& loc = BOOST_CURRENT_LOCATION )
{
    boost::throw_exception( std::invalid_argument( message ), loc );
}

现在您可以在 at 的实现中使用此辅助函数来指示索引超出范围

T& my_class::at( size_t i )
{
    if( i >= size() ) throw_invalid_argument( "index out of range" );
    return data()[ i ];
}

这将把 at 中调用 throw_invalid_argument 的行的源位置附加到抛出的异常。

请注意,如果改为在 throw_invalid_argument 中使用 BOOST_THROW_EXCEPTION,则位置将是 throw_invalid_argument 的位置,而不是其调用者的位置。

概要

namespace boost
{

struct source_location
{
    constexpr source_location() noexcept;
    constexpr source_location( char const* file, uint_least32_t line,
      char const* function, uint_least32_t column = 0 ) noexcept;
    constexpr source_location( std::source_location const& loc ) noexcept;

    constexpr char const* file_name() const noexcept;
    constexpr char const* function_name() const noexcept;
    constexpr uint_least32_t line() const noexcept;
    constexpr uint_least32_t column() const noexcept;

    std::string to_string() const;
};

template<class E, class T>
  std::basic_ostream<E, T> &
    operator<<( std::basic_ostream<E, T> & os, source_location const & loc );

} // namespace boost

#define BOOST_CURRENT_LOCATION /* see below */

source_location

constexpr source_location() noexcept;
效果

构造一个 source_location 对象,其中 file_name()function_name() 返回 ""line()column() 返回 0

constexpr source_location( char const* file, uint_least32_t line,
  char const* function, uint_least32_t column = 0 ) noexcept;
效果

构造一个 source_location 对象,其中 file_name() 返回 filefunction_name() 返回 functionline() 返回 line 参数,column() 返回 column 参数。

constexpr source_location( std::source_location const& loc ) noexcept;
效果

构造一个 source_location 对象,其中 file_name() 返回 loc.file_name()function_name() 返回 loc.function_name()line() 返回 loc.line()column() 返回 loc.column()

to_string

std::string to_string() const;
返回值

*this 的字符串表示形式。

operator<<

template<class E, class T>
  std::basic_ostream<E, T> &
    operator<<( std::basic_ostream<E, T> & os, source_location const & loc );
效果

os << loc.to_string().

返回值

os.

BOOST_CURRENT_LOCATION

当定义了 BOOST_DISABLE_CURRENT_LOCATION 时,BOOST_CURRENT_LOCATION 的定义为

#define BOOST_CURRENT_LOCATION ::boost::source_location()

这允许生成不包含识别信息的可执行文件,以出于安全原因。

否则,BOOST_CURRENT_LOCATION 定义为大致等同于

#define BOOST_CURRENT_LOCATION \
    ::boost::source_location(::std::source_location::current())

修订历史

1.88.0 版本的更改

  • 当定义了 BOOST_ASSERT_HANDLER_IS_NORETURN 时,boost::assertion_failedboost::assertion_failed_msg 被声明为 BOOST_NORETURN

1.79.0 版本的更改

  • source_location().file_name()source_location().function_name() 现在返回 "" 而不是 "(unknown)"

  • 添加了从 std::source_location 构造 source_location 的构造函数。

  • 更改了 BOOST_CURRENT_LOCATION 以更紧密地匹配 std::source_location::current() 的行为,例如可在顶层或作为默认函数参数使用。

1.78.0 版本的更改

  • 添加了 source_location::to_string

1.73.0 版本的更改

  • 添加了 source_location

本文档是

  • 版权所有 2002, 2007, 2014, 2017, 2019-2022 Peter Dimov

  • 版权所有 2011 Beman Dawes

  • 版权所有 2015 Ion Gaztañaga

  • 根据 Boost 软件许可,版本 1.0 分发。