![]() |
Home | Libraries | People | FAQ | More |
The header <boost/core/lightweight_test.hpp>
is a lightweight test framework. It's useful for writing Boost regression
tests for components that are dependencies of Boost.Test.
When using lightweight_test.hpp
,
do not forget to return
boost::report_errors()
from main
.
#define BOOST_TEST(expression) /*unspecified*/ #define BOOST_TEST_NOT(expression) /*unspecified*/ #define BOOST_ERROR(message) /*unspecified*/ #define BOOST_TEST_EQ(expr1, expr2) /*unspecified*/ #define BOOST_TEST_NE(expr1, expr2) /*unspecified*/ #define BOOST_TEST_CSTR_EQ(expr1, expr2) /*unspecified*/ #define BOOST_TEST_CSTR_NE(expr1, expr2) /*unspecified*/ #define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2) /* unspecified */ #define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) /* unspecified */ #define BOOST_TEST_THROWS(expr, excep) /*unspecified*/ namespace boost { int report_errors(); }
BOOST_TEST(expression)
If expression is false increases the error count and outputs a message
containing expression
.
BOOST_TEST_NOT(expression)
If expression is true increases the error count and outputs a message containing
!(expression)
.
BOOST_TEST_EQ(expr1, expr2)
If expr1 !=
expr2
increases the error count
and outputs a message containing both expressions.
BOOST_TEST_NE(expr1, expr2)
If expr1 ==
expr2
increases the error count
and outputs a message containing both expressions.
BOOST_TEST_CSTR_EQ(expr1, expr2)
Specialization of BOOST_TEST_EQ which interprets expr1 and expr2 as pointers
to null-terminated byte strings (C strings). If std::strcmp(expr1, expr2) != 0
,
increase the error count and output a message containing both expressions.
BOOST_TEST_CSTR_NE(expr1, expr2)
Specialization of BOOST_TEST_NE which interprets expr1 and expr2 as pointers
to null-terminated byte strings (C strings). If std::strcmp(expr1, expr2) == 0
,
increase the error count and output a message containing both expressions.
BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2)
Compares the content of two sequences. If they have different sizes, or if any pairwise element differs, increases the error count and outputs a message containing at most 8 differing elements.
BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate)
Compares the content of two sequences. If they have different sizes, or if any pairwise element do not fulfill the binary predicate, increases the error count and outputs a message containing at most 8 differing elements.
BOOST_TEST_THROWS(expr, excep)
If BOOST_NO_EXCEPTIONS
is not defined and if expr
does not throw an exception of
type excep
, increases
the error count and outputs a message containing the expression.
If BOOST_NO_EXCEPTIONS
is defined, this macro expands to nothing and expr
is not evaluated.
#include <boost/core/lightweight_test.hpp> int sqr( int x ) { return x * x; } int main() { BOOST_TEST( sqr(2) == 4 ); BOOST_TEST_EQ( sqr(-3), 9 ); return boost::report_errors(); }
The header <boost/core/lightweight_test_trait.hpp>
defines a couple of extra macros for
testing compile-time traits that return a boolean value.
#define BOOST_TEST_TRAIT_TRUE((Trait)) /*unspecified*/ #define BOOST_TEST_TRAIT_FALSE((Trait)) /*unspecified*/
BOOST_TEST_TRAIT_TRUE((Trait))
If Trait::value !=
true
increases the error count
and outputs a message containing Trait
.
Note the double set of parentheses; these enable Trait
to contain a comma, which is common for templates.
BOOST_TEST_TRAIT_FALSE((Trait))
If Trait::value !=
false
increases the error count
and outputs a message containing Trait
.
Note the double set of parentheses.
#include <boost/core/lightweight_test_trait.hpp> #include <boost/core/is_same.hpp> template<class T, class U> struct X { typedef T type; }; using boost::core::is_same; int main() { BOOST_TEST_TRAIT_TRUE(( is_same<X<int, long>::type, int> )); return boost::report_errors(); }
The header <boost/core/no_exceptions_support.hpp>
defines macros for use in code that
needs to be portable to environments that do not have support for C++ exceptions.
#define BOOST_TRY /*unspecified*/ #define BOOST_CATCH(x) /*unspecified*/ #define BOOST_CATCH_END /*unspecified*/ #define BOOST_RETHROW /*unspecified*/
void foo() { BOOST_TRY { ... } BOOST_CATCH(const std::bad_alloc&) { ... BOOST_RETHROW } BOOST_CATCH(const std::exception& e) { ... } BOOST_CATCH_END }
With exception support enabled it will expand into:
void foo() { { try { ... } catch (const std::bad_alloc&) { ... throw; } catch (const std::exception& e) { ... } } }
With exception support disabled it will expand into:
void foo() { { if(true) { ... } else if (false) { ... } else if (false) { ... } } }
The header <boost/noncopyable.hpp>
defines the class boost::noncopyable
.
It is intended to be used as a private base. boost::noncopyable
has private (under C++03) or deleted (under C++11) copy constructor and
a copy assignment operator and can't be copied or assigned; a class that
derives from it inherits these properties.
boost::noncopyable
was originally contributed
by Dave Abrahams.
namespace boost { class noncopyable; }
#include <boost/core/noncopyable.hpp> class X: private boost::noncopyable { };
Class noncopyable has protected constructor and destructor members to emphasize that it is to be used only as a base class. Dave Abrahams notes concern about the effect on compiler optimization of adding (even trivial inline) destructor declarations. He says:
“Probably this concern is misplaced, because noncopyable
will be used mostly for classes which own resources and thus have non-trivial
destruction semantics.”
With C++2011, using an optimized and trivial constructor and similar
destructor can be enforced by declaring both and marking them default
. This is done in the current implementation.
The header <boost/core/null_deleter.hpp>
defines the boost::null_deleter
function object, which can be used as a deleter with smart pointers such
as unique_ptr
or shared_ptr
. The deleter doesn't do anything
with the pointer provided upon deallocation, which makes it useful when
the pointed object is deallocated elsewhere.
std::shared_ptr< std::ostream > make_stream() { return std::shared_ptr< std::ostream >(&std::cout, boost::null_deleter()); }
The Ref library is a small library that is useful for passing references
to function templates (algorithms) that would usually take copies of their
arguments. It defines the class template boost::reference_wrapper<T>
, two functions boost::ref
and boost::cref
that return instances of boost::reference_wrapper<T>
,
a function boost::unwrap_ref
that unwraps a boost::reference_wrapper<T>
or returns a reference to any other type of object, and the two traits
classes boost::is_reference_wrapper<T>
and boost::unwrap_reference<T>
.
The purpose of boost::reference_wrapper<T>
is to contain a reference to an object of type T
.
It is primarily used to "feed" references to function templates
(algorithms) that take their parameter by value.
To support this usage, boost::reference_wrapper<T>
provides an implicit conversion to
T&
.
This usually allows the function templates to work on references unmodified.
boost::reference_wrapper<T>
is both CopyConstructible and Assignable (ordinary references are not Assignable).
The expression boost::ref(x)
returns a boost::reference_wrapper<X>(x)
where
X
is the type of x
. Similarly, boost::cref(x)
returns a boost::reference_wrapper<X const>(x)
.
The expression boost::unwrap_ref(x)
returns
a boost::unwrap_reference<X>::type&
where X
is the type of
x
.
The expression boost::is_reference_wrapper<T>::value
is true
if T
is a reference_wrapper
, and false
otherwise.
The type-expression boost::unwrap_reference<T>::type
is T::type
if T
is a reference_wrapper
,
T
otherwise.
namespace boost { template<typename T> class reference_wrapper; template<typename T> struct is_reference_wrapper; template<typename T> struct unwrap_reference; template<typename T> reference_wrapper< T > const ref(T &); template<typename T> reference_wrapper< T const > const cref(T const &); template<typename T> void ref(T const &&); template<typename T> void cref(T const &&); template<typename T> unwrap_reference< T >::type & unwrap_ref(T &); }
ref
and cref
were originally part of the Tuple library by Jaakko Järvi. They were
"promoted to boost::
status" by Peter Dimov because they
are generally useful. Douglas Gregor and Dave Abrahams contributed is_reference_wrapper
and unwrap_reference
. Frank Mori Hess and
Ronald Garcia contributed boost::unwrap_ref
.
The boost/core/scoped_enum.hpp
header contains a number of macros
that can be used to generate C++11 scoped enums (7.2 [dcl.enum]) if the
feature is supported by the compiler, otherwise emulate it with C++03 constructs.
The BOOST_NO_CXX11_SCOPED_ENUMS
macro from Boost.Config is used to detect the feature support in the compiler.
Some of the enumerations defined in the standard library are scoped enums.
enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied, no_state };
The user can portably declare such enumeration as follows:
BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc) { broken_promise, future_already_retrieved, promise_already_satisfied, no_state } BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
These macros allows to use future_errc
in almost all the cases as an scoped enum.
future_errc ev = future_errc::no_state;
It is possible to specify the underlying type of the enumeration:
BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(future_errc, unsigned int) { broken_promise, future_already_retrieved, promise_already_satisfied, no_state } BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
The enumeration supports explicit conversion from the underlying type.
The enumeration can be forward declared:
BOOST_SCOPED_ENUM_FORWARD_DECLARE(future_errc);
There are however some limitations. First, the emulated scoped enum is
not a C++ enum, so is_enum< future_errc
>
will be false_type
.
Second, the emulated scoped enum can not be used in switch nor in template arguments. For these cases the user needs to use some helpers. Instead of
switch (ev) { case future_errc::broken_promise: // ...
use
switch (boost::native_value(ev)) { case future_errc::broken_promise: // ...
and instead of
template <> struct is_error_code_enum< future_errc > : public true_type { };
use
template <> struct is_error_code_enum< BOOST_SCOPED_ENUM_NATIVE(future_errc) > : public true_type { };
Lastly, explicit conversion to the underlying type should be performed
with boost::underlying_cast
instead of static_cast
:
unsigned int val = boost::underlying_cast< unsigned int >(ev);
Here is usage example:
BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(algae, char) { green, red, cyan } BOOST_SCOPED_ENUM_DECLARE_END(algae) ... algae sample( algae::red ); void foo( algae color ); ... sample = algae::green; foo( algae::cyan );
In early versions of the header there were two ways to declare scoped enums, with different pros and cons to each. The other way used a different set of macros:
BOOST_SCOPED_ENUM_START(algae) { green, red, cyan }; BOOST_SCOPED_ENUM_END ... BOOST_SCOPED_ENUM(algae) sample( algae::red ); void foo( BOOST_SCOPED_ENUM(algae) color ); ... sample = algae::green; foo( algae::cyan );
Here BOOST_SCOPED_ENUM_START
corresponds to BOOST_SCOPED_ENUM_DECLARE_BEGIN
,
BOOST_SCOPED_ENUM_END
to
BOOST_SCOPED_ENUM_DECLARE_END
and BOOST_SCOPED_ENUM
to
BOOST_SCOPED_ENUM_NATIVE
.
Note also the semicolon before BOOST_SCOPED_ENUM_END
.
In the current version these macros produce equivalent result to the ones described above and are considered deprecated.
The header boost/core/underlying_type.hpp
defines the metafunction boost::underlying_type
which can be used to
obtain the underlying type of the scoped enum. This metafunction has support
for emulated scoped enums declared with macros in boost/core/scoped_enum.hpp
.
When native scoped enums are supported by the compiler, this metafunction
is equivalent to std::underlying_type
.
Unfortunately, there are configurations which implement scoped enums but
not std::underlying_type
. In this case boost::underlying_type
has to be specialized
by user. The macro BOOST_NO_UNDERLYING_TYPE
is defined to indicate such cases.
This scoped enum emulation was developed by Beman Dawes, Vicente J. Botet Escriba and Anthony Williams.
Helpful comments and suggestions were also made by Kjell Elster, Phil Endecott, Joel Falcou, Mathias Gaunard, Felipe Magno de Almeida, Matt Calabrese, Daniel James and Andrey Semashev.
template<class T> void swap(T& left, T& right);
The template function boost::swap
allows the values of two variables to be swapped, using argument dependent
lookup to select a specialized swap function if available. If no specialized
swap function is available, std::swap
is used.
The generic std::swap
function requires that the elements
to be swapped are assignable and copy constructible. It is usually implemented
using one copy construction and two assignments - this is often both unnecessarily
restrictive and unnecessarily slow. In addition, where the generic swap
implementation provides only the basic guarantee, specialized swap functions
are often able to provide the no-throw exception guarantee (and it is considered
best practice to do so where possible [1].
The alternative to using argument dependent lookup in this situation is
to provide a template specialization of std::swap
for every type that requires a specialized swap. Although this is legal
C++, no Boost libraries use this method, whereas many Boost libraries provide
specialized swap functions in their own namespaces.
boost::swap
also supports swapping built-in
arrays. Note that std::swap
originally did not do so, but a
request to add an overload of std::swap
for built-in arrays has been accepted by the C++ Standards Committee[2].
boost::swap
provides the same exception guarantee
as the underlying swap function used, with one exception; for an array
of type T[n]
, where
n >
1
and the underlying swap function
for T
provides the strong
exception guarantee, boost::swap
provides only the basic exception guarantee.
Either:
Or:
swap(T&,T&)
is available via argument dependent
lookup
Or:
std::swap
exists for T
Or:
Several older compilers do not support argument dependent lookup. On these
compilers boost::swap
will call std::swap
,
ignoring any specialized swap functions that could be found as a result
of argument dependent lookup.
boost::swap
less specialized than std::swap
, thereby allowing the function
to have the name 'swap' without introducing ambiguity
The header <boost/core/typeinfo.hpp>
defines a class boost::core::typeinfo
,
which is an alias for std::type_info
when RTTI is enabled, and is a reasonable substitute when RTTI is not supported.
The macro BOOST_CORE_TYPEID
,
when applied to a type T
,
is the equivalent of typeid(T)
and produces a reference to a const typeinfo
object.
The function boost::core::demangled_name
takes a boost::core::typeinfo const
& ti
and either returns ti.name()
,
when that string doesn't need to be demangled, or boost::core::demangle(ti.name())
,
when it does. The return type of boost::core::demangled_name
is char const*
in the first case and std::string
in the second.
namespace boost { namespace core { class typeinfo; /* char const* or std::string */ demangled_name( typeinfo const & ti ); } } #define BOOST_CORE_TYPEID(T) /*unspecified*/
#include <boost/core/typeinfo.hpp> #include <iostream> template<class T1, class T2> struct X { }; int main() { typedef X<void const*, void(*)(float)> T; boost::core::typeinfo const & ti = BOOST_CORE_TYPEID(T); std::cout << boost::core::demangled_name( ti ) << std::endl; }