...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
BOOST_CONTRACT_OLD_PTR_IF_COPYABLE — Program old values that can be completely disabled at compile-time and do not require the old value type to be copyable.
// In header: <boost/contract_macro.hpp>
BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(...)
This is used to program old value copies for types that might or might not be copyable:
template<typename T> // Type `T` might or not be copyable. class u { public: void f(...) { BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_a)(old_var_a); BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_b)(old_var_b, old_expr_b); BOOST_CONTRACT_PUBLIC_FUNCTION(this) ... BOOST_CONTRACT_OLD([&] { old_var_a = BOOST_CONTRACT_OLDOF(old_expr_a); ... }) ... // In postconditions or exception guarantees: if(old_var_a) ... // Always null for non-copyable types. if(old_var_b) ... // Always null for non-copyable types. ... ; ... // Function body. } virtual void g(..., boost::contract::virtual_* v = 0) { BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_a)(old_var_a); BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type_b)(v, old_var_b, old_expr_b); BOOST_CONTRACT_PUBLIC_FUNCTION(v, this) ... BOOST_CONTRACT_OLD([&] { old_var_a = BOOST_CONTRACT_OLDOF(v, old_expr_a); ... }) ... // In postconditions or exception guarantees: if(old_var_a) ... // Always null for non-copyable types. if(old_var_b) ... // Always null for non-copyable types. ... ; ... // Function body. } ... };
This is an overloaded variadic macro and it can be used in the following different ways (note that no code is generated when BOOST_CONTRACT_NO_OLDS
is defined).
BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(old_var)
expands to code equivalent to the following (this leaves the old value pointer null):
#ifndef BOOST_CONTRACT_NO_OLDS // This declaration does not need to use `v`. boost::contract::old_ptr_if_copyable<old_type> old_var #endif
BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(old_var, old_expr)
expands to code equivalent to the following (this initializes the pointer to the old value copy, but not to be used for virtual public functions and public function overrides):
#ifndef BOOST_CONTRACT_NO_OLDS boost::contract::old_ptr_if_copyable<old_type> old_var = BOOST_CONTRACT_OLDOF(old_expr) #endif
BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(v, old_var, old_expr)
expands to code equivalent to the following (this initializes the pointer to the old value copy for virtual public functions and public function overrides):
#ifndef BOOST_CONTRACT_NO_OLDS boost::contract::old_ptr_if_copyable<old_type> old_var = BOOST_CONTRACT_OLDOF(v, old_expr) #endif
Where:
old_type
is the type of the pointed old value. If this type is not copyable (i.e., boost::contract::is_old_value_copyable<old_type>::value
is false
), this pointer will always be null, but this library will not generate a compile-time error when this pointer is dereferenced (see BOOST_CONTRACT_OLD_PTR
). (This is a variadic macro parameter so it can contain commas not protected by round parenthesis.)
v
is the extra parameter of type boost::contract::virtual_
*
and default value 0
from the enclosing virtual public function or public function override declaring the contract. (This is not a variadic macro parameter.)
old_var
is the name of the old value pointer variable. (This is not a variadic macro parameter but it should never contain commas because it is an identifier.)
old_expr
is the expression to be evaluated and copied in the old value pointer. (This is not a variadic macro parameter so any comma it might contain must be protected by round parenthesis, BOOST_CONTRACT_OLD_PTR_IF_COPYABLE(old_type)(v, old_var, (old_expr))
will always work.)
See Also:
Disable Contract Compilation, Old Value Requirements