// 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 #include #include //[pure_virtual_public_base template class range { public: // Pure virtual function declaration (contract not here, below instead). virtual Iterator begin(boost::contract::virtual_* v = 0) = 0; /* ... */ //] // Could program class invariants and contracts for the following too. virtual Iterator end() = 0; virtual bool empty() const = 0; }; //[pure_virtual_public_impl // Pure virtual function default implementation (out-of-line in C++). template Iterator range::begin(boost::contract::virtual_* v) { Iterator result; // Pass `result` right after `v`... boost::contract::check c = boost::contract::public_function(v, result, this) // ...plus postconditions take `result` as parameter (not capture). .postcondition([&] (Iterator const& result) { if(empty()) BOOST_CONTRACT_ASSERT(result == end()); }) ; assert(false); // Pure function body never executed by this library. return result; } //] //[pure_virtual_public_derived template class vector #define BASES public range::iterator> : BASES { public: typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #undef BASES typedef typename std::vector::iterator iterator; iterator begin(boost::contract::virtual_* v = 0) /* override */ { iterator result; // Again, pass result right after `v`... boost::contract::check c = boost::contract::public_function< override_begin>(v, result, &vector::begin, this) // ...plus postconditions take `result` as parameter (not capture). .postcondition([&] (iterator const& result) { if(!empty()) BOOST_CONTRACT_ASSERT(*result == front()); }) ; return result = vect_.begin(); } /* ... */ //] // Could program class invariants and contracts for the following too. iterator end() { return vect_.end(); } bool empty() const { return vect_.empty(); } T const& front() const { return vect_.front(); } void push_back(T const& value) { vect_.push_back(value); } BOOST_CONTRACT_OVERRIDE(begin) private: std::vector vect_; }; int main() { vector v; v.push_back(1); v.push_back(2); v.push_back(3); range::iterator>& r = v; assert(*(r.begin()) == 1); return 0; }