// Copyright (C) 2008-2018 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 //[named_override_pure_virtual_assert_false template class generic_unary_pack { public: virtual void _1(T const& value, boost::contract::virtual_* v = 0) = 0; virtual T _1(boost::contract::virtual_* v = 0) const = 0; }; template void generic_unary_pack::_1(T const& value, boost::contract::virtual_* v) { boost::contract::check c = boost::contract::public_function(v, this) .precondition([&] { BOOST_CONTRACT_ASSERT(false); // Defer preconditions to overrides. }) ; assert(false); } /* ... */ //] template T generic_unary_pack::_1(boost::contract::virtual_* v) const { boost::optional result; // Do not assume T has default constructor. boost::contract::check c = boost::contract::public_function(v, result, this) .postcondition([&] (boost::optional const& result) { BOOST_CONTRACT_ASSERT(*result == _1()); }) ; assert(false); return *result; } //[named_override template class positive_unary_pack #define BASES public generic_unary_pack : BASES { public: typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; #undef BASES // BOOST_CONTRACT_OVERRIDE(_1) would generate reserved name `override__1`. BOOST_CONTRACT_NAMED_OVERRIDE(override1, _1) // Generate `override1`. virtual void _1(T const& value, boost::contract::virtual_* v = 0) /* override */ { // Use `override1` generated by BOOST_CONTRACT_NAMED_OVERRIDE above. boost::contract::check c = boost::contract::public_function( v, static_cast(&positive_unary_pack::_1), this, value ) .precondition([&] { BOOST_CONTRACT_ASSERT(value > 0); }) ; value1_ = value; } /* ... */ //] virtual T _1(boost::contract::virtual_* v = 0) const /* override */ { T result; // Class default constructor already used T's default ctor. boost::contract::check c = boost::contract::public_function( v, result, static_cast(&positive_unary_pack::_1), this ) .postcondition([&] (T const& result) { BOOST_CONTRACT_ASSERT(result > 0); }) ; return result = value1_; } private: T value1_; }; int main() { positive_unary_pack u; u._1(123); assert(u._1() == 123); return 0; }