1 2 // Copyright (C) 2008-2018 Lorenzo Caminiti 3 // Distributed under the Boost Software License, Version 1.0 (see accompanying 4 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). 5 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html 6 7 #include <boost/contract.hpp> 8 #include <cassert> 9 10 //[friend_invariant 11 template<typename T> 12 class positive { 13 public: invariant() const14 void invariant() const { 15 BOOST_CONTRACT_ASSERT(value() > 0); 16 } 17 18 // Can be considered an extension of enclosing class' public interface... swap(positive & object,T & value)19 friend void swap(positive& object, T& value) { 20 boost::contract::old_ptr<T> old_object_value = 21 BOOST_CONTRACT_OLDOF(object.value()); 22 boost::contract::old_ptr<T> old_value = BOOST_CONTRACT_OLDOF(value); 23 // ...so it can be made to check invariants via `public_function`. 24 boost::contract::check c = boost::contract::public_function(&object) 25 .precondition([&] { 26 BOOST_CONTRACT_ASSERT(value > 0); 27 }) 28 .postcondition([&] { 29 BOOST_CONTRACT_ASSERT(object.value() == *old_value); 30 BOOST_CONTRACT_ASSERT(value == *old_object_value); 31 }) 32 ; 33 34 T saved = object.value_; 35 object.value_ = value; 36 value = saved; 37 } 38 39 private: 40 T value_; 41 42 /* ... */ 43 //] 44 45 public: 46 // Could program contracts for following too. positive(T const & value)47 explicit positive(T const& value) : value_(value) {} value() const48 T value() const { return value_; } 49 }; 50 main()51int main() { 52 positive<int> i(123); 53 int x = 456; 54 swap(i, x); 55 assert(i.value() == 456); 56 assert(x == 123); 57 return 0; 58 } 59 60