Files
contract/example/features/old_if_copyable.cpp
2017-02-26 09:23:01 -08:00

67 lines
1.8 KiB
C++

// Copyright (C) 2008-2016 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
#include <boost/contract.hpp>
#include <cassert>
//[old_if_copyable
template<typename T>
void accumulate(T& total, T const& x) {
// No compiler error if T has no copy constructor...
boost::contract::old_ptr_if_copyable<T> old_total =
BOOST_CONTRACT_OLD(total);
boost::contract::check c = boost::contract::function()
.postcondition([&] {
// ...but old value null if T has no copy constructor.
if(old_total) BOOST_CONTRACT_ASSERT(total == *old_total + x);
})
;
total += x;
}
//]
struct n {
int value;
n() : value(0) {}
n operator+(n const& r) const { n x; x.value = value + r.value; return x; }
n& operator+=(n const& r) { value = value + r.value; return *this; }
bool operator==(n const& r) const { return value == r.value; }
private:
n(n const&) {} // Hide copy constructor (non copy-constructible).
};
// Specialize `boost::is_copy_constructible<n>` trait (not needed on C++11):
#include <boost/config.hpp>
#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
//[old_if_copyable_specialization
#include <boost/type_traits/is_copy_constructible.hpp>
namespace boost {
template<>
struct is_copy_constructible<n> : false_type {};
}
//]
#endif
int main() {
n j, k; // Non copyable (no compiler error but no old-value checks).
j.value = 1;
k.value = 2;
accumulate(j, k);
assert(j.value == 3);
int i = 1; // Copyable (check old values).
accumulate(i, 2);
assert(i == 3);
return 0;
}