• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <boost/optional.hpp>
9 #include <cassert>
10 
11 //[named_override_pure_virtual_assert_false
12 template<typename T>
13 class generic_unary_pack {
14 public:
15     virtual void _1(T const& value, boost::contract::virtual_* v = 0) = 0;
16     virtual T _1(boost::contract::virtual_* v = 0) const = 0;
17 };
18 
19 template<typename T>
_1(T const & value,boost::contract::virtual_ * v)20 void generic_unary_pack<T>::_1(T const& value, boost::contract::virtual_* v) {
21     boost::contract::check c = boost::contract::public_function(v, this)
22         .precondition([&] {
23             BOOST_CONTRACT_ASSERT(false); // Defer preconditions to overrides.
24         })
25     ;
26     assert(false);
27 }
28 
29 /* ... */
30 //]
31 
32 template<typename T>
_1(boost::contract::virtual_ * v) const33 T generic_unary_pack<T>::_1(boost::contract::virtual_* v) const {
34     boost::optional<T> result; // Do not assume T has default constructor.
35     boost::contract::check c = boost::contract::public_function(v, result, this)
36         .postcondition([&] (boost::optional<T const&> const& result) {
37             BOOST_CONTRACT_ASSERT(*result == _1());
38         })
39     ;
40 
41     assert(false);
42     return *result;
43 }
44 
45 //[named_override
46 template<typename T>
47 class positive_unary_pack
48     #define BASES public generic_unary_pack<T>
49     : BASES
50 {
51 public:
52     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
53     #undef BASES
54 
55     // BOOST_CONTRACT_OVERRIDE(_1) would generate reserved name `override__1`.
BOOST_CONTRACT_NAMED_OVERRIDE(override1,_1)56     BOOST_CONTRACT_NAMED_OVERRIDE(override1, _1) // Generate `override1`.
57 
58     virtual void _1(T const& value, boost::contract::virtual_* v = 0)
59             /* override */ {
60         // Use `override1` generated by BOOST_CONTRACT_NAMED_OVERRIDE above.
61         boost::contract::check c = boost::contract::public_function<override1>(
62             v,
63             static_cast<void (positive_unary_pack::*)(T const&,
64                     boost::contract::virtual_*)>(&positive_unary_pack::_1),
65             this,
66             value
67         )
68             .precondition([&] {
69                 BOOST_CONTRACT_ASSERT(value > 0);
70             })
71         ;
72         value1_ = value;
73     }
74 
75     /* ... */
76 //]
77 
_1(boost::contract::virtual_ * v=0) const78     virtual T _1(boost::contract::virtual_* v = 0) const /* override */ {
79         T result; // Class default constructor already used T's default ctor.
80         boost::contract::check c = boost::contract::public_function<override1>(
81             v,
82             result,
83             static_cast<T (positive_unary_pack::*)(boost::contract::virtual_*)
84                     const>(&positive_unary_pack::_1),
85             this
86         )
87             .postcondition([&] (T const& result) {
88                 BOOST_CONTRACT_ASSERT(result > 0);
89             })
90         ;
91         return result = value1_;
92     }
93 
94 private:
95     T value1_;
96 };
97 
main()98 int main() {
99     positive_unary_pack<int> u;
100     u._1(123);
101     assert(u._1() == 123);
102     return 0;
103 }
104 
105