|  | Home | Libraries | People | FAQ | More | 
This section can be consulted selectively for specific topics of interest.
        Old values require to copy the expression passed to BOOST_CONTRACT_OLDOF
        thus the type of that expression needs to be copyable. More precisely, dereferencing
        an old value pointer of type boost::contract::old_ptr<T>
        requires boost::contract::is_old_value_copyable<T>::value to be true,
        otherwise this library will generate a compile-time error.
      
        In some cases it might be acceptable, or even desirable, to cause a compile-time
        error when a program uses old value types that are not copyable (because
        it is not possible to fully check the correctness of the program as stated
        by the contract assertions that use these old values). In these cases, programmers
        can declare old values using boost::contract::old_ptr
        as seen so far.
      
        However, in some other cases it might be desirable to simply skip assertions
        that use old values when the respective old value types are not copyable,
        without causing compile-time errors. Programmers can do this using boost::contract::old_ptr_if_copyable
        instead of boost::contract::old_ptr
        and checking if the old value pointer is not null before dereferencing it
        in postconditions. For example, consider the following function template
        that could in general be instantiated for types T
        that are not copy constructible (that is for which boost::contract::is_old_value_copyable<T>::value is false,
        see old_if_copyable.cpp):
        [68]
      
template<typename T> // T might or might not be copyable. void offset(T& x, int count) { // No compiler error if T has no copy constructor... boost::contract::old_ptr_if_copyable<T> old_x = BOOST_CONTRACT_OLDOF(x); boost::contract::check c = boost::contract::function() .postcondition([&] { // ...but old value null if T has no copy constructor. if(old_x) BOOST_CONTRACT_ASSERT(x == *old_x + count); }) ; x += count; }
        The old value pointer old_x
        is programmed using boost::contract::old_ptr_if_copyable.
        When T is copyable, boost::contract::old_ptr_if_copyable<T>
        behaves like boost::contract::old_ptr<T>.
        When T is not copyable instead,
        boost::contract::old_ptr_if_copyable<T>
        will simply not copy x at
        run-time and leave old_x
        initialized to a null pointer. Therefore, boost::contract::old_ptr_if_copyable
        objects like old_x must be
        checked to be not null as in if(old_x) ... before
        they are dereferenced in postconditions and exception guarantees (to avoid
        run-time errors of dereferencing null pointers).
      
        If the above example used boost::contract::old_ptr
        instead then this library would have generated a compile-time error when
        offset is instantiated with
        types T that are not copy
        constructible (but only if old_x
        is actually dereferenced somewhere, for example in the contract assertions
        using *old_x
        ... or old_x->...). [69]
      
        When C++11 auto declarations
        are used with BOOST_CONTRACT_OLDOF,
        this library always defaults to using the boost::contract::old_ptr
        type (because its type requirements are more stringent than boost::contract::old_ptr_if_copyable).
        For example, the following statements are equivalent:
      
auto old_x = BOOST_CONTRACT_OLDOF(x); // C++11 auto declarations always use `old_ptr` (never `old_ptr_if_copyable`). boost::contract::old_ptr<decltype(x)> old_x = BOOST_CONTRACT_OLDOF(x);
        If programmers want to relax the copyable type requirement, they must do
        so explicitly by using the boost::contract::old_ptr_if_copyable
        type instead of using auto declarations.
      
        This library uses boost::contract::is_old_value_copyable
        to determine if an old value type is copyable or not, and then boost::contract::old_value_copy
        to actually copy the old value.
      
        By default, boost::contract::is_old_value_copyable<T>
        is equivalent to boost::is_copy_constructible<T> and
        boost::contract::old_value_copy<T>
        is implemented using T's
        copy constructor. However, these type traits can be specialized by programmers
        for example to avoid making old value copies of types even when they have
        a copy constructor (maybe because these copy constructors are too expensive),
        or to make old value copies for types that do not have a copy constructor,
        or for any other specific need programmers might have for the types in question.
      
        For example, the following specialization of boost::contract::is_old_value_copyable
        intentionally avoids making old value copies for all expressions of type
        w even if that type has a
        copy constructor (see old_if_copyable.cpp):
      
// Copyable type but... class w { public: w(w const&) { /* Some very expensive copy operation here... */ } /* ... */
// ...never copy old values for type `w` (because its copy is too expensive). namespace boost { namespace contract { template<> struct is_old_value_copyable<w> : boost::false_type {}; } }
        On the flip side, the following specializations of boost::contract::is_old_value_copyable
        and boost::contract::old_value_copy
        make old value copies of expressions of type p
        even if that type does not actually have a copy constructor (see old_if_copyable.cpp):
      
// Non-copyable type but... class p : private boost::noncopyable { int* num_; friend struct boost::contract::old_value_copy<p>; /* ... */
// ...still copy old values for type `p` (using a deep copy). namespace boost { namespace contract { template<> struct old_value_copy<p> { explicit old_value_copy(p const& old) { *old_.num_ = *old.num_; // Deep copy pointed value. } p const& old() const { return old_; } private: p old_; }; template<> struct is_old_value_copyable<p> : boost::true_type {}; } }
        In general, boost::is_copy_constructible and therefore boost::contract::is_old_value_copyable
        require C++11 decltype and SFINAE
        to automatically detect if a given type is copyable or not. On non-C++11
        compilers, it is possible to inherit the old value type from boost::noncopyable, or use BOOST_MOVABLE_BUT_NOT_COPYABLE,
        or specialize boost::is_copy_constructible (see boost::is_copy_constructible documentation
        for more information), or just specialize boost::contract::is_old_value_copyable.
        For example, for a non-copyable type n
        the following code will work also on non-C++11 compilers (see old_if_copyable.cpp):
      
class n { // Do not want to use boost::noncopyable but... int num_; private: n(n const&); // ...unimplemented private copy constructor (so non-copyable). /* ... */
// Specialize `boost::is_copy_constructible` (no need for this on C++11). namespace boost { namespace contract { template<> struct is_old_value_copyable<n> : boost::false_type {}; } }
In general, assertions can introduce a new set of requirements on the types used by the program. Some of these type requirements might be necessary only to check the assertions and they would not be required by the program otherwise.
In some cases it might be acceptable, or even desirable, to cause a compile-time error when a program uses types that do not provide all the operations needed to check contract assertions (because it is not possible to fully check the correctness of the program as specified by its contracts). In these cases, programmers can specify contract assertions as we have seen so far, compilation will fail if user types do not provide all operations necessary to check the contracts.
        However, in some other cases it might be desirable to not augment the type
        requirements of a program just because of contract assertions and to simply
        skip assertions when user types do not provide all the operations necessary
        to check them, without causing compile-time errors. Programmers can do this
        using if constexpr
        on C++17 compilers, and boost::contract::condition_if
        (or boost::contract::condition_if_c)
        on non-C++17 compilers.
      
        For example, let's consider the following vector<T>
        class template equivalent to std::vector<T>.
        C++ std::vector<T> does
        not require that its value type parameter T
        has an equality operator ==
        (it only requires T to be
        copy constructible, see std::vector
        documentation). However, the contracts for the vector<T>::push_back(value)
        public function include a postcondition back() == value
        that introduces the new requirement that T
        must also have an equality operator ==.
        Programmers can specify this postcondition as usual with BOOST_CONTRACT_ASSERT(back()
        == value) an let the program fail to compile when
        users instantiate vector<T>
        with a type T that does not
        provide an equality operator ==.
        Otherwise, programmers can guard this postcondition using C++17 if constexpr
        to evaluate the asserted condition only for types T
        that have an equality operator ==
        and skip it otherwise. [70] For example:
      
template<typename T> class vector { public: void push_back(T const& value) { boost::contract::check c = boot::contract::public_function(this) .postcondition([&] { // Guard with `if constexpr` for T without `==`. if constexpr(boost::has_equal_to<T>::value) BOOST_CONTRACT_ASSERT(back() == value); }) ; vect_.push_back(value); } /* ... */
        More in general, if constexpr
        can be used to guard a mix of both old value copies and contract assertions
        that introduce specific extra type requirements. For example, the following
        swap function can be called
        on any type T that is movable
        but its old value copies and postcondition assertions are evaluated only
        for types T that are also
        copyable and have an equality operator ==
        (see if_constexpr.cpp):
      
template<typename T> void swap(T& x, T& y) { constexpr bool b = boost::contract::is_old_value_copyable<T>::value && boost::has_equal_to<T>::value; boost::contract::old_ptr<T> old_x, old_y; if constexpr(b) { // Contract requires copyable T... old_x = BOOST_CONTRACT_OLDOF(x); old_y = BOOST_CONTRACT_OLDOF(y); } boost::contract::check c = boost::contract::function() .postcondition([&] { if constexpr(b) { // ... and T with `==`... BOOST_CONTRACT_ASSERT(x == *old_y); BOOST_CONTRACT_ASSERT(y == *old_x); } }) ; T t = std::move(x); // ...but body only requires movable T. x = std::move(y); y = std::move(t); }
if constexpr
        (no C++17)
      
        On non-C++17 compilers where if constexpr is not available, it is possible
        to use boost::contract::condition_if
        to skip assertions based on type requirements (even if this code is less
        readable and more verbose than using if
        constexpr). For example (see condition_if.cpp):
      
template<typename T> class vector { public: void push_back(T const& value) { boost::contract::check c = boost::contract::public_function(this) .postcondition([&] { // Instead of `ASSERT(back() == value)` for T without `==`. BOOST_CONTRACT_ASSERT( boost::contract::condition_if<boost::has_equal_to<T> >( boost::bind(std::equal_to<T>(), boost::cref(back()), boost::cref(value) ) ) ); }) ; vect_.push_back(value); } /* ... */
        More in general, boost::contract::condition_if
        is used as follow:
      
boost::contract::condition_if<Pred>( cond )
        Where Pred is a nullary boolean
        meta-function and cond is
        a nullary boolean functor. If Pred::value
        is statically evaluated to be true
        at compile-time then cond() is called at run-time and its boolean result
        is returned by the enclosing boost::contract::condition_if
        call. Otherwise, if Pred::value
        is statically evaluated to be false
        at compile-time then boost::contract::condition_if
        trivially returns true. Therefore,
        if cond is a functor template
        instantiation (not just a functor) then its call that contains the assertion
        operations with the extra type requirements (e.g., the equality operator
        ==) will not be actually instantiated
        and compiled unless the compiler determines at compile-time that Pred::value is true
        (when used this way, functor templates like std::equal_to
        and C++14 generic lambdas can be used to program cond,
        but C++11 lambdas cannot).
      
        The boost::contract::condition_if
        function template is a special case of the more general boost::contract::call_if,
        specifically boost::contract::condition_if<Pred>(cond) is logically equivalent to boost::contract::call_if<Pred>(cond).else_([] { return
        true; }). [71] The boost::contract::call_if
        function template also accepts a number of optional else-if
        statements and one optional else statement:
      
boost::contract::call_if<Pred1>( t1 ).template else_if<Pred2>( // Optional. t2 ) ... // Optionally, other `else_if` statements. .else_( // Optional for `void` functors, otherwise required. e )
        Where Pred1, Pred2, ... are nullary boolean meta-functions
        and t1, t2,
        ..., e are nullary functors.
        The return types of the functor calls t1(), t2(), ..., e() must either be all the same (including
        possibly all void) or be of
        types implicitly convertible into one another. At run-time boost::contract::call_if will
        call the functor t1(),
        or t2(),
        ..., or e()
        depending on which meta-function Pred1::value,
        Pred2::value, ... is statically evaluated to be
        true or false
        at compile-time, and it will return the value returned by the functor being
        called. If t1, t2, ..., e
        are functor template instantiations (not just functors) then their code will
        only be compiled if the compiler determines they need to be actually called
        at run-time (so only if the related Pred1::value,
        Pred2::value, ... are respectively evaluated to
        be true or false
        at compile-time). All the else_if<...>(...) statements are optional.
        The else_(...)
        statement is optional if the functor calls return void,
        otherwise it is required.
      
        In general, boost::contract::call_if
        can be used to program contract assertions that compile and check different
        functor templates depending on related predicates being statically evaluated
        to be true or false at compile-time (but in most cases
        boost::contract::condition_if
        should be sufficient and less verbose to use). The boost::contract::condition_if_c,
        boost::contract::call_if_c,
        and .else_if_c
        function templates work similarly to their counterparts without the ..._c postfix
        seen so far, but they take their predicate template parameters as static
        boolean values instead of nullary boolean meta-functions.
      
        On compilers that support C++17 if
        constexpr there should be no need
        to use boost::contract::condition_if
        or boost::contract::call_if
        because if constexpr
        can be used instead (making the code more readable and easier to program).
        [72]
      
        This library allows to specify a different set of class invariants to check
        for volatile public functions. These volatile class invariants
        are programmed in a public const volatile function, named invariant,
        taking no argument, and returning void
        (see BOOST_CONTRACT_INVARIANT_FUNC
        to name the invariant function differently from invariant
        and Access Specifiers
        to not have to declare it public).
        Classes that do no have invariants for their volatile public functions, simply
        do not declare the void invariant() const volatile function.
      
        In general, const volatile
        invariants work the same as const
        invariants (see Class
        Invariants) with the only difference that volatile
        and const volatile
        functions check const volatile
        invariants while non-const (i.e.,
        neither const nor volatile) and const
        functions check const invariants.
        A given class can specify any combination of static,
        const volatile,
        and const invariant functions
        (see Class Invariants):
        [73]
      
static
            invariants at entry and exit (even if an exception is thrown), plus
            const volatile
            and const invariants in
            that order at exit but only if no exception is thrown.
          static
            invariants at entry and exit (even if an exception is thrown), plus
            const volatile
            and const invariants in
            that order at entry (and at exit but only if an exception is thrown,
            even is destructors should in general never throw in C++).
          const and const public functions check static and const
            invariants at entry and at exit (even if an exception is thrown).
          volatile and const volatile
            public functions check static
            and const volatile
            invariants at entry and at exit (even if an exception is thrown).
          
        These rules ensure that volatile class invariants are correctly checked (see
        Constructor
        Calls, Destructor
        Calls, and Public
        Function Calls). For example (see volatile.cpp):
      
class u { public: static void static_invariant(); // Static invariants. void invariant() const volatile; // Volatile invariants. void invariant() const; // Const invariants. u() { // Check static, volatile, and const invariants. boost::contract::check c= boost::contract::constructor(this); } ~u() { // Check static, volatile, and const invariants. boost::contract::check c = boost::contract::destructor(this); } void nc() { // Check static and const invariants. boost::contract::check c = boost::contract::public_function(this); } void c() const { // Check static and const invariants. boost::contract::check c = boost::contract::public_function(this); } void v() volatile { // Check static and volatile invariants. boost::contract::check c = boost::contract::public_function(this); } void cv() const volatile { // Check static and volatile invariants. boost::contract::check c = boost::contract::public_function(this); } static void s() { // Check static invariants only. boost::contract::check c = boost::contract::public_function<u>(); } };
        This library does not automatically check const
        volatile invariants for non-volatile functions. However, if the contract
        specifications require it, programmers can explicitly call the const volatile
        invariant function from the const
        invariant function (preferably in that order to be consistent with the order
        const volatile
        and const invariants are checked
        for constructors and destructors). That way all public functions, volatile or not, will check const volatile
        invariants (while only const
        and non-const public functions
        will check only const invariants,
        correctly so because the volatile
        qualifier shall not be stripped away): [74]
      
class u { public: void invariant() const volatile { ... } // Volatile invariants. void invariant() const { auto const volatile* cv = this; cv->invariant(); // Call `const volatile` invariant function above. ... // Other non-volatile invariants. } ... };
        (As usual, private and protected functions do not check any invariant, not
        even when they are volatile
        or const volatile,
        see Private
        and Protected Functions).
      
As with all public operations of a class, also public move operations should maintain class invariants (see [Stroustrup13], p. 520). Specifically, at a minimum C++ requires the following:
        Therefore, both the move constructor and the move assignment operator need
        to maintain the class invariants of the moved-from object so their contracts
        can be programmed using boost::contract::constructor
        and boost::contract::public_function
        as usual. For example (see move.cpp):
      
class circular_buffer : private boost::contract::constructor_precondition<circular_buffer> { public: void invariant() const { if(!moved()) { // Do not check (some) invariants for moved-from objects. BOOST_CONTRACT_ASSERT(index() < size()); } // More invariants here that hold also for moved-from objects (e.g., // all assertions necessary to successfully destroy moved-from objects). } // Move constructor. circular_buffer(circular_buffer&& other) : boost::contract::constructor_precondition<circular_buffer>([&] { BOOST_CONTRACT_ASSERT(!other.moved()); }) { boost::contract::check c = boost::contract::constructor(this) .postcondition([&] { BOOST_CONTRACT_ASSERT(!moved()); BOOST_CONTRACT_ASSERT(other.moved()); }) ; move(std::forward<circular_buffer>(other)); } // Move assignment. circular_buffer& operator=(circular_buffer&& other) { // Moved-from can be (move) assigned (so no pre `!moved()` here). boost::contract::check c = boost::contract::public_function(this) .precondition([&] { BOOST_CONTRACT_ASSERT(!other.moved()); }) .postcondition([&] { BOOST_CONTRACT_ASSERT(!moved()); BOOST_CONTRACT_ASSERT(other.moved()); }) ; return move(std::forward<circular_buffer>(other)); } ~circular_buffer() { // Moved-from can always be destroyed (in fact no preconditions). boost::contract::check c = boost::contract::destructor(this); } bool moved() const { boost::contract::check c = boost::contract::public_function(this); return moved_; } private: bool moved_; /* ... */
        This example assumes that it is possible to call the public function moved()
        on the moved-from object. [75]
      
| ![[Note]](../../../../../doc/src/images/note.png) | Note | 
|---|---|
| 
          The default move constructor and move assignment operator generated by
          C++ will not automatically check contracts. Therefore, unless the move
          operations are not public or they have no preconditions, no postconditions,
          and their class has no invariants, programmers should manually define them
          using  | 
As always, programmers can decide to not program contracts for a given type. Specifically, they might decide to not program contracts for a class that needs to be moved in order to avoid the run-time overhead of checking contract assertions and to maximize performance (see Benefits and Costs).
        A C++ union cannot have virtual
        functions, base classes, and cannot be used as a base class thus subcontracting
        (boost::contract::virtual_,
        BOOST_CONTRACT_OVERRIDE,
        etc.) do not apply to unions. Also a union
        cannot inherit from boost::contract::constructor_precondition
        (because it cannot have base classes), instead boost::contract::constructor_precondition
        is used to declare a local object that checks constructor preconditions (at
        the very beginning of the constructor before old value copies and other contracts,
        see declaration of pre in
        the example below). A part from that, this library is used as usual to program
        contracts for unions. For example (see union.cpp):
      
union positive { public: static void static_invariant() { // Static class invariants (as usual). BOOST_CONTRACT_ASSERT(instances() >= 0); } void invariant() const { // Class invariants (as usual). BOOST_CONTRACT_ASSERT(i_ > 0); BOOST_CONTRACT_ASSERT(d_ > 0); } // Contracts for constructor, as usual but... explicit positive(int x) : d_(0) { // ...unions cannot have bases so constructor preconditions here. boost::contract::constructor_precondition<positive> pre([&] { BOOST_CONTRACT_ASSERT(x > 0); }); boost::contract::old_ptr<int> old_instances = BOOST_CONTRACT_OLDOF(instances()); boost::contract::check c = boost::contract::constructor(this) .postcondition([&] { { int y; get(y); BOOST_CONTRACT_ASSERT(y == x); } BOOST_CONTRACT_ASSERT(instances() == *old_instances + 1); }) ; i_ = x; ++instances_; } // Contracts for destructor (as usual). ~positive() { boost::contract::old_ptr<int> old_instances = BOOST_CONTRACT_OLDOF(instances()); boost::contract::check c = boost::contract::destructor(this) .postcondition([&] { BOOST_CONTRACT_ASSERT(instances() == *old_instances - 1); }) ; --instances_; } // Contracts for public function (as usual, but no virtual or override). void get(int& x) const { boost::contract::check c = boost::contract::public_function(this) .postcondition([&] { BOOST_CONTRACT_ASSERT(x > 0); }) ; x = i_; } // Contracts for static public function (as usual). static int instances() { boost::contract::check c = boost::contract::public_function<positive>(); return instances_; } private: int i_; double d_; /* ... */
This library provides three predefined assertion levels that can be used to selectively disable assertions depending on their computational complexity: [76]
BOOST_CONTRACT_ASSERT
            is used to assert conditions that are not computationally expensive,
            at least compared to the cost of executing the function body. These assertions
            are the ones we have seen so far, they are always checked at run-time
            and they cannot be disabled.
          BOOST_CONTRACT_ASSERT_AUDIT
            is used to assert conditions that are computationally expensive compared
            to the cost of executing the function body. These assertions are not
            checked at run-time unless programmers explicitly define BOOST_CONTRACT_AUDITS
            (undefined by default), but the asserted conditions are always compiled
            and therefore validated syntactically (even when they are not actually
            evaluated and checked at run-time).
          BOOST_CONTRACT_ASSERT_AXIOM
            is used to assert conditions that are computationally prohibitive, at
            least compared to the cost of executing the function body. These assertions
            are never evaluated or checked at run-time, but the asserted conditions
            are always compiled and therefore validated syntactically (so these assertions
            can serve as formal comments to the code).
          
        In addition, BOOST_CONTRACT_CHECK_AUDIT
        and BOOST_CONTRACT_CHECK_AXIOM
        are similar to BOOST_CONTRACT_ASSERT_AUDIT
        and BOOST_CONTRACT_ASSERT_AXIOM
        but they are used to program audit and axiom levels for implementation checks
        instead of assertions (see Implementation
        Checks).
      
        For example, BOOST_CONTRACT_ASSERT_AUDIT
        can be used to program computationally expensive assertions (see assertion_level.cpp):
      
template<typename RandomIter, typename T> RandomIter random_binary_search(RandomIter first, RandomIter last, T const& value) { RandomIter result; boost::contract::check c = boost::contract::function() .precondition([&] { BOOST_CONTRACT_ASSERT(first <= last); // Default, not expensive. // Expensive O(n) assertion (use AXIOM if prohibitive instead). BOOST_CONTRACT_ASSERT_AUDIT(std::is_sorted(first, last)); }) .postcondition([&] { if(result != last) BOOST_CONTRACT_ASSERT(*result == value); }) ; /* ... */
        Similarly, BOOST_CONTRACT_AUDITS
        can be used to disable expensive old value copies and related assertions
        that use them (see assertion_level.cpp):
      
template<typename T> class vector {
public: void swap(vector& other) { boost::contract::old_ptr<vector> old_me, old_other; #ifdef BOOST_CONTRACT_AUDITS old_me = BOOST_CONTRACT_OLDOF(*this); old_other = BOOST_CONTRACT_OLDOF(other); #endif // Else, skip old value copies... boost::contract::check c = boost::contract::public_function(this) .postcondition([&] { // ...and also skip related assertions. BOOST_CONTRACT_ASSERT_AUDIT(*this == *old_other); BOOST_CONTRACT_ASSERT_AUDIT(other == *old_me); }) ; vect_.swap(other.vect_); }
/* ... */ private: std::vector<T> vect_; };
        The condition passed to BOOST_CONTRACT_ASSERT_AXIOM
        is compiled but not actually evaluated at run-time so this macro can be used
        to program computationally prohibitive assertions but also assertions that
        cannot actually be programmed in C++ using functions that are declared but
        left undefined. For example, (see assertion_level.cpp):
      
// If valid iterator range (cannot implement in C++ but OK to use in AXIOM). template<typename Iter> bool valid(Iter first, Iter last); // Only declared, not actually defined.
template<typename T> class vector {
public: iterator insert(iterator where, T const& value) { iterator result; boost::contract::old_ptr<unsigned> old_capacity = BOOST_CONTRACT_OLDOF(capacity()); boost::contract::check c = boost::contract::public_function(this) .postcondition([&] { BOOST_CONTRACT_ASSERT(capacity() >= *old_capacity); if(capacity() > *old_capacity) { BOOST_CONTRACT_ASSERT_AXIOM(!valid(begin(), end())); } else { BOOST_CONTRACT_ASSERT_AXIOM(!valid(where, end())); } }) ; return result = vect_.insert(where, value); }
/* ... */ private: std::vector<T> vect_; };
        In addition to these assertion levels that are predefined by this library,
        programmers are free to define their own. For example, the following macro
        could be used to program and selectively disable assertions that have exponential
        computational complexity O(e^n):
      
#ifdef EXPONENTIALLY_COMPLEX_ASSERTIONS
    // Following will compile and also evaluate `cond`.
    #define ASSERT_EXP(cond) BOOST_CONTRACT_ASSERT(cond)
#else
    // Following will compile but never actually evaluate `cond`.
    #define ASSERT_EXP(cond) BOOST_CONTRACT_ASSERT(true || (cond))
#endif
...
ASSERT_EXP(some-exponentially-complex-boolean-condition);
        Checking contracts adds run-time overhead and can slow down program execution
        (see Benefits
        and Costs). Therefore, programmers can define any combination of the
        following macros (-D
        option in Clang and GCC, /D
        option in MSVC, etc.) to instruct this library to not check specific groups
        of contract conditions at run-time:
      
BOOST_CONTRACT_NO_PRECONDITIONS
            to not check preconditions.
          BOOST_CONTRACT_NO_POSTCONDITIONS
            to not check postconditions.
          BOOST_CONTRACT_NO_EXCEPTS
            to not check exception guarantees.
          BOOST_CONTRACT_NO_ENTRY_INVARIANTS
            to not check class invariants at call entry.
          BOOST_CONTRACT_NO_EXIT_INVARIANTS
            to not check class invariants at call exit.
          BOOST_CONTRACT_NO_INVARIANTS
            to not check class invariants at both call entry and exit. (This is provided
            for convenience, it is equivalent to defining both BOOST_CONTRACT_NO_ENTRY_INVARIANTS
            and BOOST_CONTRACT_NO_EXIT_INVARIANTS.)
          BOOST_CONTRACT_NO_CHECKS
            to not evaluate implementation checks.
          | ![[Note]](../../../../../doc/src/images/note.png) | Note | 
|---|---|
| 
          Old values can be used by both postconditions and exception guarantees
          so it is necessary to define both  | 
By default, none of these macros are defined so this library checks all contracts. When these macros are defined by the user, the implementation code of this library is internally optimized to minimize as much as possible any run-time and compile-time overhead associated with checking and compiling contracts (see Disable Contract Compilation for techniques to completely remove any run-time and compile-time overheads associated with contract code).
        For example, programmers could decide to check all contracts during early
        development builds, but later check only preconditions and maybe entry invariants
        for release builds by defining BOOST_CONTRACT_NO_POSTCONDITIONS,
        BOOST_CONTRACT_NO_EXCEPTS,
        BOOST_CONTRACT_NO_EXIT_INVARIANTS,
        and BOOST_CONTRACT_NO_CHECKS.
      
        This library provides macros that can be used to completely disable compile-time
        and run-time overhead introduced by contracts but at the cost of manually
        programming #ifndef BOOST_CONTRACT_NO_... statements around contract code:
      
BOOST_CONTRACT_NO_CONSTRUCTORS
            when contract checking is disabled for constructors.
          BOOST_CONTRACT_NO_DESTRUCTORS
            when contract checking is disabled for destructors.
          BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
            when contract checking is disabled for public functions.
          BOOST_CONTRACT_NO_FUNCTIONS
            when contract checking is disabled for (non-public and non-member) functions.
          BOOST_CONTRACT_NO_OLDS
            when old value copies are disabled.
          BOOST_CONTRACT_NO_ALL
            when all contracts above and also implementation checks (see BOOST_CONTRACT_NO_CHECKS)
            are disabled.
          
        These macros are not configuration macros and they should not be defined
        directly by programmers (otherwise this library will generate compile-time
        errors). Instead, these macros are automatically defined by this library
        when programmers define BOOST_CONTRACT_NO_PRECONDITIONS,
        BOOST_CONTRACT_NO_POSTCONDITIONS,
        BOOST_CONTRACT_NO_EXCEPTS,
        BOOST_CONTRACT_NO_INVARIANTS
        (or BOOST_CONTRACT_NO_ENTRY_INVARIANTS
        and BOOST_CONTRACT_NO_EXIT_INVARIANTS),
        and BOOST_CONTRACT_NO_CHECKS
        (see Disable
        Contract Checking).
      
        Alternatively, this library provides a macro-based interface defined in
        boost/contract_macro.hpp
        that can also be used to completely disable compile-time and run-time overheads
        introduced by contracts but without the burden of manually writing the #ifndef BOOST_CONTRACT_NO_... statements. For example, the following
        code shows how to use both the boost/contract_macro.hpp
        macro interface and the #ifndef
        BOOST_CONTRACT_NO_...
        statements to completely disable compile-time and run-time overheads for
        non-member function contracts (see ifdef_macro.cpp
        and ifdef.cpp):
      
| Macro Interface | 
                   | 
|---|---|
| 
 // Use macro interface to completely disable contract code compilation. #include <boost/contract_macro.hpp> int inc(int& x) { int result; BOOST_CONTRACT_OLD_PTR(int)(old_x, x); BOOST_CONTRACT_FUNCTION() BOOST_CONTRACT_PRECONDITION([&] { BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max()); }) BOOST_CONTRACT_POSTCONDITION([&] { BOOST_CONTRACT_ASSERT(x == *old_x + 1); BOOST_CONTRACT_ASSERT(result == *old_x); }) ; return result = x++; } 
 | 
 // Use #ifdef to completely disable contract code compilation. #include <boost/contract/core/config.hpp> #ifndef BOOST_CONTRACT_NO_ALL #include <boost/contract.hpp> #endif int inc(int& x) { int result; #ifndef BOOST_CONTRACT_NO_OLDS boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x); #endif #ifndef BOOST_CONTRACT_NO_FUNCTIONS boost::contract::check c = boost::contract::function() #ifndef BOOST_CONTRACT_NO_PRECONDITIONS .precondition([&] { BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max()); }) #endif #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS .postcondition([&] { BOOST_CONTRACT_ASSERT(x == *old_x + 1); BOOST_CONTRACT_ASSERT(result == *old_x); }) #endif ; #endif return result = x++; } 
 | 
        The same can be done to disable contract code complication for private and
        protected functions. The BOOST_CONTRACT_OLD_PTR_IF_COPYABLE
        macro is provided to handle non-copyable old value types (similar to boost::contract::old_ptr_if_copyable).
      
        For constructors, destructors, and public functions the boost/contract_macro.hpp
        macro interface and the #ifndef
        BOOST_CONTRACT_NO_...
        statements can be used as follow (see ifdef_macro.cpp
        and ifdef.cpp):
      
| Macro Interface | 
                   | 
|---|---|
| 
 class integers #define BASES public pushable<int> : // Left in code (almost no overhead). private boost::contract::constructor_precondition<integers>, BASES { // Followings left in code (almost no overhead). friend class boost::contract::access; typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #undef BASES BOOST_CONTRACT_INVARIANT({ BOOST_CONTRACT_ASSERT(size() <= capacity()); }) public: integers(int from, int to) : BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(integers)([&] { BOOST_CONTRACT_ASSERT(from <= to); }), vect_(to - from + 1) { BOOST_CONTRACT_CONSTRUCTOR(this) BOOST_CONTRACT_POSTCONDITION([&] { BOOST_CONTRACT_ASSERT(int(size()) == (to - from + 1)); }) ; for(int x = from; x <= to; ++x) vect_.at(x - from) = x; } virtual ~integers() { BOOST_CONTRACT_DESTRUCTOR(this); // Check invariants. } virtual void push_back( int const& x, boost::contract::virtual_* v = 0 // Left in code (almost no overhead). ) /* override */ { BOOST_CONTRACT_OLD_PTR(unsigned)(old_size); BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_push_back)( v, &integers::push_back, this, x) BOOST_CONTRACT_PRECONDITION([&] { BOOST_CONTRACT_ASSERT(size() < max_size()); }) BOOST_CONTRACT_OLD([&] { old_size = BOOST_CONTRACT_OLDOF(v, size()); }) BOOST_CONTRACT_POSTCONDITION([&] { BOOST_CONTRACT_ASSERT(size() == *old_size + 1); }) BOOST_CONTRACT_EXCEPT([&] { BOOST_CONTRACT_ASSERT(size() == *old_size); }) ; vect_.push_back(x); } private: BOOST_CONTRACT_OVERRIDE(push_back) // Left in code (almost no overhead). /* ... */ 
 | 
 class integers #define BASES public pushable<int> : #ifndef BOOST_CONTRACT_NO_PRECONDITIONS private boost::contract::constructor_precondition<integers>, BASES #else BASES #endif { #ifndef BOOST_CONTRACT_NO_ALL friend class boost::contract::access; #endif #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #endif #undef BASES #ifndef BOOST_CONTRACT_NO_INVARIANTS void invariant() const { BOOST_CONTRACT_ASSERT(size() <= capacity()); } #endif public: integers(int from, int to) : #ifndef BOOST_CONTRACT_NO_PRECONDITIONS boost::contract::constructor_precondition<integers>([&] { BOOST_CONTRACT_ASSERT(from <= to); }), #endif vect_(to - from + 1) { #ifndef BOOST_CONTRACT_NO_CONSTRUCTORS boost::contract::check c = boost::contract::constructor(this) #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS .postcondition([&] { BOOST_CONTRACT_ASSERT(int(size()) == (to - from + 1)); }) #endif ; #endif for(int x = from; x <= to; ++x) vect_.at(x - from) = x; } virtual ~integers() { #ifndef BOOST_CONTRACT_NO_DESTRUCTORS // Check invariants. boost::contract::check c = boost::contract::destructor(this); #endif } virtual void push_back( int const& x #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS , boost::contract::virtual_* v = 0 #endif ) /* override */ { #ifndef BOOST_CONTRACT_NO_OLDS boost::contract::old_ptr<unsigned> old_size; #endif #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS boost::contract::check c = boost::contract::public_function< override_push_back>(v, &integers::push_back, this, x) #ifndef BOOST_CONTRACT_NO_PRECONDITIONS .precondition([&] { BOOST_CONTRACT_ASSERT(size() < max_size()); }) #endif #ifndef BOOST_CONTRACT_NO_OLDS .old([&] { old_size = BOOST_CONTRACT_OLDOF(v, size()); }) #endif #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS .postcondition([&] { BOOST_CONTRACT_ASSERT(size() == *old_size + 1); }) #endif #ifndef BOOST_CONTRACT_NO_EXCEPTS .except([&] { BOOST_CONTRACT_ASSERT(size() == *old_size); }) #endif ; #endif vect_.push_back(x); } private: #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS BOOST_CONTRACT_OVERRIDE(push_back) #endif /* ... */ 
 | 
        Static and volatile class invariants can be programmed using BOOST_CONTRACT_STATIC_INVARIANT
        and BOOST_CONTRACT_INVARIANT_VOLATILE
        respectively (these macros expand code equivalent to the static
        void BOOST_CONTRACT_STATIC_INVARIANT_FUNC() and void
        BOOST_CONTRACT_INVARIANT_FUNC()
        const volatile
        functions).
      
        The boost/contract_macro.hpp
        macro interface is usually preferred because more concise and easier to use
        than programming #ifndef BOOST_CONTRACT_NO_...
        statements by hand. However, C++ macros expand on a single line of code and
        that can make compiler errors less useful when using this macro interface
        plus all contract assertions within a given set of preconditions, postconditions,
        exception guarantees, and class invariants will list the same line number
        in error messages when assertions fail at run-time (but error messages still
        list the assertion code and that should still allow programmers to identify
        the specific assertion that failed). Finally, the macro interface leaves
        a bit of contract decorations in the code but that should add no measurable
        compile-time or run-time overhead (specifically, extra boost::contract::virtual_* parameters, calls to boost::contract::constructor_precondition
        default constructor which does nothing, BOOST_CONTRACT_BASE_TYPES
        typedefs, and boost::contract::access
        friendships are left in user code even when contracts are disabled unless
        #ifndef BOOST_CONTRACT_NO_... statements are used).
      
        Disabling contract as shown in Disable
        Contract Checking leaves the overhead of compiling contract code plus
        some small run-time overhead due to the initialization of old value pointers
        (even if those will be all null and no old value will be actually copied),
        the calls to the contract functions used to initialize boost::contract::check
        and boost::contract::constructor_precondition
        (even if those calls will be internally optimized by this library to essentially
        do nothing), etc. For truly performance critical code for which even such
        small run-time overhead might not be acceptable, the macro interface (or
        the #ifndef BOOST_CONTRACT_NO_... statements) can be used to completely
        disable compile-time and run-time overheads of contracts. However, for such
        performance critical code even the overhead of checking simple preconditions
        might be too much so it might be best to not program contracts at all.
      
        Usually, if the overhead of checking preconditions and other assertions is
        already considered acceptable for an application then the compile-time overhead
        of contracts should not represent an issue and it should be sufficient to
        disable contract checking at run-time as indicated in Disable
        Contract Checking (without a real need to use the boost/contract_macro.hpp
        macro interface or the #ifndef
        BOOST_CONTRACT_NO_...
        statements in most cases).
      
Contracts are part of the program specifications and not of its implementation (see Specifications vs. Implementation). However, this library uses function definitions to program contracts so contract code appears together with the function implementation code. This is not ideal (even if contracts programmed using this library will always appear at the very beginning of the function definition so programmers will easily be able to distinguish contract code from the rest of the function implementation code so this might not be real limitation in practise).
In some cases, it might be desirable to completely separate the contract code from the function implementation code. For example, this could be necessary for software that ships only header files and compiled object files to its users. If contracts are programmed in function definitions that are compiled in the object files, users will not be able to see the contract code to understand semantics and usage of the functions (again, this might not be a real problem in practice for example if contracts are already somehow extracted from the source code by some tool and presented as part of the documentation of the shipped software).
        In any case, when it is truly important to separate contracts from function
        implementation code, function implementations can be programmed in extra
        body functions (here named ..._body, but any other naming scheme could
        be used) that are compiled in object files. Function definitions that remain
        in header files instead will contain just contract code followed by calls
        to the extra body functions. This technique allows to keep the contract code
        in header files while separating the implementation code to source and object
        files. However, this adds the overhead of manually programming an extra function
        declaration for each body function (plus the limitation that constructor
        member initialization lists must be programmed in header files because that
        is where constructors need to be defined to list constructor contract code).
        [77]
      
        For example, the following header file only contains function declarations,
        contract code, and constructor member initializations, but it does not contain
        the code implementing the function bodies (see separate_body.hpp):
      
class iarray : private boost::contract::constructor_precondition<iarray> { public: void invariant() const { BOOST_CONTRACT_ASSERT(size() <= capacity()); } explicit iarray(unsigned max, unsigned count = 0) : boost::contract::constructor_precondition<iarray>([&] { BOOST_CONTRACT_ASSERT(count <= max); }), // Still, member initializations must be here. values_(new int[max]), capacity_(max) { boost::contract::check c = boost::contract::constructor(this) .postcondition([&] { BOOST_CONTRACT_ASSERT(capacity() == max); BOOST_CONTRACT_ASSERT(size() == count); }) ; constructor_body(max, count); // Separate constructor body impl. } virtual ~iarray() { boost::contract::check c = boost::contract::destructor(this); // Inv. destructor_body(); // Separate destructor body implementation. } virtual void push_back(int value, boost::contract::virtual_* v = 0) { boost::contract::old_ptr<unsigned> old_size = BOOST_CONTRACT_OLDOF(v, size()); boost::contract::check c = boost::contract::public_function(v, this) .precondition([&] { BOOST_CONTRACT_ASSERT(size() < capacity()); }) .postcondition([&] { BOOST_CONTRACT_ASSERT(size() == *old_size + 1); }) ; push_back_body(value); // Separate member function body implementation. } private: // Contracts in class declaration (above), but body implementations are not. void constructor_body(unsigned max, unsigned count); void destructor_body(); void push_back_body(int value); /* ... */
        Instead, the function bodies are implemented in a separate source file (see
        separate_body.cpp):
      
void iarray::constructor_body(unsigned max, unsigned count) { for(unsigned i = 0; i < count; ++i) values_[i] = int(); size_ = count; } void iarray::destructor_body() { delete[] values_; } void iarray::push_back_body(int value) { values_[size_++] = value; } /* ... */
The same technique can be used for non-member, private, and protected functions, etc.
| ![[Note]](../../../../../doc/src/images/note.png) | Note | 
|---|---|
| 
          When contracts are programmed only in  
          On the flip side, if contracts are programmed only in header files (e.g.,
          using extra  | 
This section shows how to use this library without C++11 lambda functions. This has some advantages:
..._precondition, ..._old, and ..._postcondition functions in the example
            below) can be programmed to fully enforce constant-correctness and other
            contract requirements at compile-time (see Constant-Correctness).
            [79]
          
        However, not using C++11 lambda functions comes at the significant cost of
        having to manually program the extra contract functions and related boiler-plate
        code. For example, the header file (see no_lambdas.hpp):
      
class iarray : private boost::contract::constructor_precondition<iarray> { public: static void static_invariant() { BOOST_CONTRACT_ASSERT(instances() >= 0); } void invariant() const { BOOST_CONTRACT_ASSERT(size() <= capacity()); } explicit iarray(unsigned max, unsigned count = 0); static void constructor_precondition(unsigned const max, unsigned const count) { BOOST_CONTRACT_ASSERT(count <= max); } static void constructor_old(boost::contract::old_ptr<int>& old_instances) { old_instances = BOOST_CONTRACT_OLDOF(instances()); } void constructor_postcondition(unsigned const max, unsigned const count, boost::contract::old_ptr<int> const old_instances) const { BOOST_CONTRACT_ASSERT(capacity() == max); BOOST_CONTRACT_ASSERT(size() == count); BOOST_CONTRACT_ASSERT(instances() == *old_instances + 1); } virtual ~iarray(); void destructor_old(boost::contract::old_ptr<int>& old_instances) const { old_instances = BOOST_CONTRACT_OLDOF(instances()); } static void destructor_postcondition(boost::contract::old_ptr<int> const old_instances) { BOOST_CONTRACT_ASSERT(instances() == *old_instances - 1); } virtual void push_back(int value, boost::contract::virtual_* v = 0); void push_back_precondition() const { BOOST_CONTRACT_ASSERT(size() < capacity()); } void push_back_old(boost::contract::virtual_* v, boost::contract::old_ptr<unsigned>& old_size) const { old_size = BOOST_CONTRACT_OLDOF(v, size()); } void push_back_postcondition( boost::contract::old_ptr<unsigned> const old_size) const { BOOST_CONTRACT_ASSERT(size() == *old_size + 1); } unsigned capacity() const; unsigned size() const; static int instances(); private: int* values_; unsigned capacity_; unsigned size_; static int instances_; };
        And, the source file (see no_lambdas.cpp):
      
iarray::iarray(unsigned max, unsigned count) : boost::contract::constructor_precondition<iarray>(boost::bind( &iarray::constructor_precondition, max, count)), values_(new int[max]), // Member initializations can be here. capacity_(max) { boost::contract::old_ptr<int> old_instances; boost::contract::check c = boost::contract::constructor(this) .old(boost::bind(&iarray::constructor_old, boost::ref(old_instances))) .postcondition(boost::bind( &iarray::constructor_postcondition, this, boost::cref(max), boost::cref(count), boost::cref(old_instances) )) ; for(unsigned i = 0; i < count; ++i) values_[i] = int(); size_ = count; ++instances_; } iarray::~iarray() { boost::contract::old_ptr<int> old_instances; boost::contract::check c = boost::contract::destructor(this) .old(boost::bind(&iarray::destructor_old, this, boost::ref(old_instances))) .postcondition(boost::bind(&iarray::destructor_postcondition, boost::cref(old_instances))) ; delete[] values_; --instances_; } void iarray::push_back(int value, boost::contract::virtual_* v) { boost::contract::old_ptr<unsigned> old_size; boost::contract::check c = boost::contract::public_function(v, this) .precondition(boost::bind(&iarray::push_back_precondition, this)) .old(boost::bind(&iarray::push_back_old, this, boost::cref(v), boost::ref(old_size))) .postcondition(boost::bind(&iarray::push_back_postcondition, this, boost::cref(old_size))) ; values_[size_++] = value; } unsigned iarray::capacity() const { // Check invariants. boost::contract::check c = boost::contract::public_function(this); return capacity_; } unsigned iarray::size() const { // Check invariants. boost::contract::check c = boost::contract::public_function(this); return size_; } int iarray::instances() { // Check static invariants. boost::contract::check c = boost::contract::public_function<iarray>(); return instances_; } int iarray::instances_ = 0;
If programmers also want to fully enforce all contract programming constant-correctness requirements at compile-time, they should follow these rules when programming the contract functions (see Constant-Correctness):
..._precondition functions in the example
            above) can take their arguments either by const
            value or by const&,
            and when they are member functions they should be either static or const
            functions.
          ..._postcondition functions in the example
            above) should take their arguments by const&, and when they are member functions
            they should be either static
            or const functions.
          const&, and when they are member functions
            they should be either static
            or const functions.
          ..._old functions in the example above)
            should take their arguments by const& a part from old value pointers that
            should be taken by &
            (so only old value pointers can be modified), and when they are member
            functions they should be either static
            or const functions.
          static (because
            there is no valid object this
            if the constructor body does not run successfully, see Constructor
            Calls).
          static
            (because there is no valid object this
            after the destructor body runs successfully, but exception guarantee
            functions do not have to be static
            since the object this is
            still valid because the destructor body did not run successfully, see
            Destructor
            Calls).
          
        Note that the extra contract functions also allow to keep the contract code
        in the header file while all function bodies are implemented in a separate
        source file (including the constructor member initialization list, that could
        not be done with the techniques shown in Separate
        Body Implementation). [80] Also note that the contract functions can always be declared
        private if programmers need
        to exactly control the public members of the class (this was not done in
        this example only for brevity).
      
The authors think this library is most useful when used together with C++11 lambda functions (because of the large amount of boiler-plate code required when C++11 lambdas are not used as also shown by the example above).
        It is possible to specify contracts without using most of the macros provided
        by this library and programming the related code manually instead (the only
        macros that cannot be programmed manually are BOOST_CONTRACT_OVERRIDE,
        BOOST_CONTRACT_OVERRIDES,
        and BOOST_CONTRACT_NAMED_OVERRIDE).
      
| ![[Note]](../../../../../doc/src/images/note.png) | Note | 
|---|---|
| Some of this library macros are variadic macros, others are not (see below). Variadic macros were officially added to the language in C++11 but most compilers have been supporting them as an extension for a long time, plus all compilers that support C++11 lambda functions should also support C++11 variadic macros (and this library might rarely be used without the convenience of C++11 lambda functions, see No Lambda Functions). [81] Therefore, the rest of this section can be considered mainly a curiosity because programmers should seldom, if ever, need to use this library without using its macros. | 
        As shown in Public
        Function Overrides and Named
        Overrides, this library provides the BOOST_CONTRACT_OVERRIDE
        and BOOST_CONTRACT_NAMED_OVERRIDE
        macros to program contracts for overriding public functions (see BOOST_CONTRACT_MAX_ARGS for compilers
        that do not support variadic templates). [82] These macro cannot be programmed manually but they are not variadic
        macros (so programmers should be able to use them on any C++ compiler with
        a sound support for SFINAE). [83] The BOOST_CONTRACT_OVERRIDES
        macro is a variadic macro instead but programmes can manually repeat the
        non-variadic macro BOOST_CONTRACT_OVERRIDE
        for each overriding public function name on compilers that do not support
        variadic macros.
      
        As shown in Preconditions,
        Postconditions,
        Exception Guarantees,
        Class Invariants,
        etc. this library provides the BOOST_CONTRACT_ASSERT
        macro to assert contract conditions. This is not a variadic macro and programmers
        should be able to use it on all C++ compilers. In any case, the invocation
        BOOST_CONTRACT_ASSERT(cond) simply expands to code equivalent to the
        following: [84]
      
if(!(cond)) { throw boost::contract::assertion_failure(__FILE__, __LINE__, BOOST_PP_STRINGIZE(cond)); }
        In fact, this library considers any exception thrown from within preconditions,
        postconditions, exception guarantees, and class invariants as a contract
        failure and reports it calling the related contract failure handler (boost::contract::precondition_failure,
        etc.). If there is a need for it, programmers can always program contract
        assertions that throw specific user-defined exceptions as follow (see Throw
        on Failures):
      
if(!cond) throwexception-object;
        However, using BOOST_CONTRACT_ASSERT
        is convenient because it always allows this library to show an informative
        message in case of assertion failure containing the assertion code, file
        name, line number, etc.
      
        As shown in Assertion
        Levels, this library pre-defines BOOST_CONTRACT_ASSERT_AUDIT
        and BOOST_CONTRACT_ASSERT_AXIOM
        assertion levels. These macros are not variadic macros and programmers should
        be able to use them on all C++ compilers. In any case, their implementations
        are equivalent to the following:
      
#ifdef BOOST_CONTRACT_AUDITS #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ BOOST_CONTRACT_ASSERT(cond) #else #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ BOOST_CONTRACT_ASSERT(true || (cond)) #endif #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \ BOOST_CONTRACT_ASSERT(true || (cond))
        As shown in Base
        Classes, this library provides the BOOST_CONTRACT_BASE_TYPES
        variadic macro to declare the base_types
        member type that will expand to the list of all public bases for a derived
        class. Programmers can also declare base_types
        without using BOOST_CONTRACT_BASE_TYPES
        at the cost of writing a bit more code and increase maintenance efforts.
        For example (see base_types_no_macro.cpp):
      
#include <boost/mpl/vector.hpp> class chars : private boost::contract::constructor_precondition<chars>, public unique_chars, public virtual pushable<char>, virtual protected has_size, private has_empty { public: // Program `base_types` without macros (list only public bases). typedef boost::mpl::vector<unique_chars, pushable<char> > base_types; /* ... */
        The base_types member type
        must be a boost::mpl::vector
        which must list all and only public
        base classes (because only public bases subcontract, see Function
        Calls), and in the same order these public base classes appear in
        the derived class inheritance list. If the BOOST_CONTRACT_BASE_TYPES
        macro is not used, it is the responsibility of the programmers to maintain
        the correct list of bases in the boost::mpl::vector each time the derived class inheritance
        list changes (this might significantly complicate maintenance).
      
        In general, it is recommended to use the BOOST_CONTRACT_BASE_TYPES
        macro whenever possible.
      
        As shown in Old Values,
        this library provides the BOOST_CONTRACT_OLDOF
        variadic macro to assign old value copies. Programmers can also assign old
        values without using BOOST_CONTRACT_OLDOF
        at the cost of writing a bit more code manually. For example (see old_no_macro.cpp):
      
template<typename T> class vector { public: virtual void push_back(T const& value, boost::contract::virtual_* v = 0) { // Program old value instead of using `OLD(size())` macro. boost::contract::old_ptr<unsigned> old_size = boost::contract::make_old(v, boost::contract::copy_old(v) ? size() : boost::contract::null_old()) ; boost::contract::check c = boost::contract::public_function(v, this) .postcondition([&] { BOOST_CONTRACT_ASSERT(size() == *old_size + 1); }) ; vect_.push_back(value); } /* ... */
        The ternary operator boost::contract::copy_old(v)
        ? size() : boost::contract::null_old() must be used here to avoid evaluating and
        copying the old value expression size() when boost::contract::copy_old
        returns false (because old values
        are not being copied when postcondition and exception guarantee checking
        is disabled at run-time, an overridden virtual function call is not checking
        postconditions or exception guarantees yet, etc.). The enclosing boost::contract::make_old
        copies the old value expression and creates an old value pointer. Otherwise,
        boost::contract::null_old
        indicates that a null old value pointer should be created.
      
        The boost::contract::make_old
        and boost::contract::copy_old
        functions are used exactly as shown above but without the extra v parameter when they are called from within
        non-virtual functions (see Public
        Function Overrides). The old value pointer returned by boost::contract::make_old
        can be assigned to either boost::contract::old_ptr
        or boost::contract::old_ptr_if_copyable
        (see Old
        Value Requirements).
      
        In general, it is recommended to use the BOOST_CONTRACT_OLDOF
        macro whenever possible.
      
        Almost all macros defined in boost/contract_macro.hpp
        are variadic macros. On compilers that do not support variadic macros, programmers
        can manually disable contract code compilation using #ifndef
        BOOST_CONTRACT_NO_...
        statements as shown in Disable
        Contract Compilation.
      
[68] 
          Rationale: [N1962]
          and other proposals to add contracts to C++ do not provide a mechanism
          to selectively disable copies only for old value types that are not copy
          constructible. However, this library provides such a mechanism to allow
          to program contracts for template code without necessarily adding extra
          copy constructible type requirements that would not be present if it were
          not for copying old values (so compiling the code with and without contracts
          will not necessarily alter the type requirements of the program). Something
          similar could be achieved combing C++17 if
          constexpr with [N1962]
          or [P0380] so that old value expressions
          within template code can be guarded by if
          constexpr statements checking if
          the old value types are copyable or not. For example, assuming old values
          are added to [P0380] (using some kind
          of oldof(...)
          syntax) and that C++17 if constexpr can be used within [P0380]
          contracts:
template<typename T> void offset(T& x, int count) [[ensures: if constexpr(std::is_copy_constructible<T>::value) x == oldof(x) + count]] ...
[69] 
          Technically, on C++17 it is possible to use boost::contract::old_ptr
          together with if constexpr
          instead of using boost::contract::old_ptr_if_copyable,
          for example:
template<typename T> void offset(T& x, int count) { boost::contract::old_ptr<T> old_x; if constexpr(boost::contract::is_old_value_copyable<T>::value) old_x = BOOST_CONTRACT_OLDOF(x); boost::contract::check c = boost::contract::function() .postcondition([&] { if constexpr(boost::contract::is_old_value_copyable<T>::value) BOOST_CONTRACT_ASSERT(x == *old_x + count); }) ; x += count; }
          However, the authors find this code less readable and more verbose than
          its equivalent that uses boost::contract::old_ptr_if_copyable.
          Guarding old value copies and related assertions with if
          constexpr is useful instead when
          the guard condition checks type requirements more complex than just boost::contract::is_old_value_copyable
          (as shown later in this documentation).
        
[70] 
          Rationale: [N1962]
          and other proposals to add contracts to C++ do not provide a mechanism
          to selectively disable assertions based on their type requirements. However,
          this library provides such a mechanism to allow to program contracts for
          template code without necessarily adding extra type requirements that would
          not be present if it was not for the contracts (so compiling the code with
          and without contracts will not alter the type requirements of the program).
          Something similar could be achieved combing C++17 if
          constexpr with [N1962]
          or [P0380] so that contract assertions
          within template code could be guarded by if
          constexpr statements checking the
          related type requirements ([N1962]
          already allows of if statements
          in contracts under the name of select assertions,
          [P0380] does not so probably if statements should be added to [P0380]
          as well). For example, assuming C++17 if
          constexpr can be used within [P0380] contracts:
template<typename T> class vector { public: void push_back(T const& value) [[ensures: if constexpr(boost::has_equal_to<T>::value) back() == value]] ... };
[71] 
          The internal implementation of boost::contract::condition_if
          is optimized and it does not actually use boost::contract::call_if.
        
            A part from its use within contracts, boost::contract::call_if
            can be used together with C++14 generic lambdas to emulate C++17 if constexpr
            (boost::hana::if_ and probably other approaches can
            also be used together with generic lambdas to emulate C++17 if constexpr
            on C++14 compilers). For example, the following implementation of myadvance will compile since C++14
            and it is more concise, easier to read and maintain than the usual implementation
            of std::advance that uses tag dispatching (see
            call_if_cxx14.cpp):
          
template<typename Iter, typename Dist> void myadvance(Iter& i, Dist n) { Iter* p = &i; // So captures change actual pointed iterator value. boost::contract::call_if<is_random_access_iterator<Iter> >( std::bind([] (auto p, auto n) { // C++14 generic lambda. *p += n; }, p, n) ).template else_if<is_bidirectional_iterator<Iter> >( std::bind([] (auto p, auto n) { if(n >= 0) while(n--) ++*p; else while(n++) --*p; }, p, n) ).template else_if<is_input_iterator<Iter> >( std::bind([] (auto p, auto n) { while(n--) ++*p; }, p, n) ).else_( std::bind([] (auto false_) { static_assert(false_, "requires at least input iterator"); }, std::false_type()) // Use constexpr value. ); }
            Of course, since C++17 the implementation that uses if
            constexpr is even more readable
            and concise:
template<typename Iter, typename Dist> void myadvance(Iter& i, Dist n) { if constexpr(is_random_access_iterator<Iter>::value) { i += n; } else if constexpr(is_bidirectional_iterator<Iter>::value) { if(n >= 0) while(n--) ++i; else while(n++) --i; } else if constexpr(is_input_iterator<Iter>::value) { while(n--) ++i; } else { static_assert(false, "requires at least input iterator"); } }
[73] 
          Rationale: Constructors and destructors
          check const volatile
          and const invariants in that
          order because the qualifier that can be applied to more calls is checked
          first (note that const volatile
          calls can be made on any object while const
          calls cannot be made on volatile
          objects, in that sense the const
          volatile qualifier can be applied
          to more calls than const alone
          can). This is consistent with static
          class invariants that are checked even before const
          volatile invariants (the static classifier can be applied to even
          more calls than const volatile,
          in fact an object is not even needed to make static calls).
        
[74] 
          Rationale: Note that while all public
          functions can be made to check const
          volatile invariants, it is never
          possible to make volatile public functions check const
          non-volatile invariants. That is because both const
          and volatile can always be
          added but never stripped in C++ (a part from forcefully via const_cast) but const
          is always automatically added by this library in order to enforce contract
          constant-correctness (see Constant-Correctness).
          That said, it would be too stringent for this library to also automatically
          add volatile and require all
          functions to check const volatile (not just const)
          invariants because only volatile
          members can be accessed from const
          volatile invariants so there could
          be many const (but not const volatile)
          members that are accessible from const
          invariants but not from const volatile invariants. To avoid this confusion,
          this library has chosen to draw a clear dichotomy between const and const
          volatile invariants so that only
          volatile public functions check const
          volatile invariants and only non-volatile
          public functions check const
          (but not const volatile)
          invariants. This is a clear distinction and it should serve most cases.
          If programmers need non-volatile public functions to also check const volatile
          invariants, they can explicitly do so by calling the const
          volatile invariant function from
          the const invariant function
          as shown in this documentation.
        
[75] 
          In this example, the moved() function is simple enough that programmers
          could decide to not even call boost::contract::public_function
          from it for optimization reasons. However, calling boost::contract::public_function
          from moved()
          has no negative impact, a part from run-time overhead, because this library
          automatically disables contract checking while checking other contracts
          (so this call will not cause infinite recursion).
        
[76] The assertion levels predefined by this library are similar to the default, audit, and axiom levels from [P0380].
[77] When used as default parameter values, lambda functions allow to program code statements within function declarations. However, these lambadas cannot be effectively used to program contracts in function declarations instead of definitions. That is because the C++11 standard does not allow lambdas in function declarations to capture any variable (for the good reason that it is not at all obvious how to correctly define the semantics of such captures). For example, the following code is not valid C++ and it does not compile:
// Specifications (in declaration). int inc(int& x, // Error: Lambdas in default parameters cannot capture `this`, `x`, or any other variable. std::function<void ()> pre = [&] { BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max()); }, std::function<void (int const&, boost::contract::old_ptr<int> const&)> post = [&] (int const& result, boost::contract::old_ptr<int> const& old_x) { BOOST_CONTRACT_ASSERT(x == *old_x + 1); BOOST_CONTRACT_ASSERT(result == *old_x); } ); // Implementation (in definition). int inc(int& x, std::function<void ()> pre, std::function<void (int const&, boost::contract::old_ptr<int> const&)> post ) { int result; boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x); boost::contract::check c = boost::contract::function() .precondition(pre) .postcondition(std::bind(post, std::cref(result), std::cref(old_x))) ; return result = x++; // Function body. }
In any case, even if the above code compiled, it would require significant boiler-plate code to bind return and old values.
[78] 
              Alternatively, on compilers that do not support C++11 lambda functions,
              Boost.LocalFunction
              could be used to program the contract functors still within the function
              definitions (for example, see no_lambda_local_func.cpp).
              In general, such a code is less verbose than the example shown in this
              section that uses contract functions programmed outside of the original
              function definitions (about 30% less lines of code) but the contract
              code is hard to read. Other libraries could also be used to program
              the contract functors without C++11 lambda functions (Boost.Lambda,
              Boost.Fusion, etc.) but again all these techniques will result in contract
              code either more verbose, or harder to read and maintain than the code
              that uses C++11 lambda functions.
            
[79] 
              If C++ allowed lambda functions to capture variables by constant reference
              (for example allowing a syntax like this [const&]
              { ...
              } and [const&
              variable-name] { ... },
              see https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/0UKQw9eo3N0)
              also lambdas could be used to program contract functors that fully
              enforce Constant-Correctness
              at compile-time. Note that C++11 lambdas allow to capture variables
              by value (using [=] {
              ... }
              and [variable-name] { ... })
              and these value captures are const
              (unless the lambda is explicitly declared mutable)
              but they are not suitable to program postconditions and exception guarantees
              using this library (because those require capturing by reference, see
              Postconditions
              and Exception
              Guarantees), plus they introduce a copy of the captured value
              that might be too expensive in general and therefore not suitable for
              preconditions either.
            
[80] 
          In this example, bind was
          used to generate nullary functors from the contract functions. As always
          with bind, cref and ref
          must be used to bind arguments by const& and &
          respectively, plus it might be necessary to explicitly static_cast
          the function pointer passed to bind
          for overloaded functions.
        
[81] Compilation times of this library were measured to be comparable between compilers that support variadic macros and compilers that do not.
[82] 
          Rationale: The BOOST_CONTRACT_MAX_ARGS
          macro is named after BOOST_FUNCTION_MAX_ARGS.
        
[83] 
          Rationale: These macros expand to SFINAE-based
          introspection template code that are too complex to be programmed manually
          by users (that remains the case even if C++14 generic lambdas were to be
          used here). On a related note, in theory using C++14 generic lambdas, the
          BOOST_CONTRACT_OVERRIDE
          macro could be re-implemented in a way that can be expanded at function
          scope, instead of class scope (but there is not really a need to do that).
        
[84] 
          Rationale: There is no need for the code
          expanded by BOOST_CONTRACT_ASSERT
          to also use C++11 __func__.
          That is because __func__
          will always expand to the name operator() of the functor used to program the contract
          assertions (e.g., the internal name the compiler assigns to lambda functions)
          and it will not expand to the name of the actual function enclosing the
          contract declaration.