Boost Development Guide-4.12utility

utility

The utility library is not a Boost library with a unified theme, but contains several small but useful tools.

The noncopyable.swap introduced at the beginning of this chapter was once classified in the utility library (now it belongs to the core library). In addition, utility also includes many other utility classes, such as base_from_member, compressed_pair, checked_delete, etc.

BOOST_BINARY

BOOST_BINARY provides a set of macros for implementing simple binary constant representation, which is similar to the usage of binary literal "0bxxx" in the C++14 standard.

The definition of BOOST_BINARY is located in <boost/utility/binary.hpp>, and can also be included indirectly through <boost/utility.hpp>, that is:

#include<boost/utility/binary.hpp> //或者
#include<boost/utility.hpp>

It uses the boost.preprocessor preprocessing metaprogramming tool to expand one or more groups of 01 numbers into an octal number at compile time. Each number group needs to be separated by a space, and each group can hold 1 to 8 0/1 numbers.

What needs special attention here is that the length of the number group must not exceed 8. Due to the limitation of preprocessor macro expansion, if the nesting level is too deep, it will fail to compile and a lot of errors will be reported.

cout << hex << showbase;
cout << BOOST_BINARY(0110) << endl;
cout << BOOST_BINARY(0110 1101) << endl;
cout << BOOST_BINARY(10110110 01) << endl;
cout << bitset<5>(BOOST_BINARY(0110)) << endl;

In addition to the most basic and versatile BOOST_BINARY macro, this component also contains macros in the form BOOST_BINARY_XX, where xx is a standard integer extension, such as u (unsigned int), UL (unsigned long), etc., to support specific integer types. The place. For example, the macro corresponding to long long is BOOST_BINARY_LL.

cout << BOOST_BINARY_UL(101 1001) << endl;
long long x = BOOST_BINARY_LL(1101);
cout << x << endl;

The BOOST_BINARY macro provides a good initialization operation method, which is particularly useful in certain situations where bitwise operations are required, such as using std::bitset. Moreover, the BOOST_BINARY macros are expanded at compile time without any runtime overhead.

BOOST_CURRENT_FUNCTION

The GCC compiler defines some extended macros in addition to C89's __FILE__ and __LINE__. The __PRETTY_FUNCTION__ macro can represent the function name. Compilers such as VC and Intel C also define similar macros, while the C99 standard The __func__ macro is defined to achieve the same functionality.

The BOOST_CURRENT_FUNCTION macro uses a workaround to supplement this function for C++, making it more portable.

usage

In order to use the BOOST_CURRENT_FUNCTION macro, you need to include <boost/current_function.hpp>, that is

#include<boost/current_fuction.hpp>

Just use the BOOST_CURRENT_FUNCTION macro in your code to get the name of the peripheral function containing the macro, which appears as a compile-time string containing the complete function declaration. If the BOOST_CURRENT_FUNCTION macro is not within the scope of any function, the behavior varies from compiler to compiler.

double func()
{
    
    
	cout << BOOST_CURRENT_FUNCTION << endl;
	return 0.0;
}

string str = BOOST_CURRENT_FUNCTION;      //错误用法,不能用在函数作用域外

int main()
{
    
    
	cout << str << endl;
	cout << __FUNCTION__ << endl;
	cout << BOOST_CURRENT_FUNCTION << endl;
	func();
}

After the program is compiled using GCC, the running results are as follows:

top level
main
int main()
double func()

Implementation principle

Readers may be surprised by the strange magic of the BOOST_CURRENT_FUNCTION macro. In fact, the BOOST_CURRENT_FUNCTION macro is not mysterious. Its implementation code is actually quite simple, just defining the compiler-specific macro as BOOST_CURRENT_FUNCTION for various compilers, so its capabilities are completely dependent on the compiler.

For example for GCC, BOOST_CURRENT_FUNCTION is:

#define BOOST_CURRENT_FUCTION __PRETTY_FUNCTION__

Although the function and implementation of BOOST_CURRENT_FUNCTION are very simple, it does provide a general solution for displaying function names, which is very useful when throwing exceptions or outputting diagnostic logs.

code example

Compiled with LLVM-clang-cl

#include <bitset>
#include <iostream>
using namespace std;

#include <boost/utility.hpp>

//
void case1()
{
    
    
	cout << hex << showbase;
	cout << BOOST_BINARY(0110) << endl;
	cout << BOOST_BINARY(0110 1101) << endl;
	cout << BOOST_BINARY(10110110 01) << endl;
	cout << bitset<5>(BOOST_BINARY(0110)) << endl;

	cout << BOOST_BINARY_UL(101 1001) << endl;
	long long x = BOOST_BINARY_LL(1101);
	cout << x << endl;

}

//
#include <boost/current_function.hpp>

double func()
{
    
    
	cout << BOOST_CURRENT_FUNCTION << endl;
	return 0.0;
}

string str = BOOST_CURRENT_FUNCTION;      //错误用法,不能用在函数作用域外

void case2()
{
    
    
	cout << str << endl;
	cout << __FUNCTION__ << endl;
	cout << BOOST_CURRENT_FUNCTION << endl;
	func();
}

//

int main()
{
    
    
	case1();
	case2();
}

Insert image description here

Supongo que te gusta

Origin blog.csdn.net/qq_36314864/article/details/132557429
Recomendado
Clasificación