]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/contract/example/features/throw_on_failure.cpp
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
7 #include <boost/contract.hpp>
12 //[throw_on_failure_class_begin
13 struct too_large_error
{};
15 template<unsigned MaxSize
>
17 #define BASES private boost::contract::constructor_precondition<cstring< \
23 typedef BOOST_CONTRACT_BASE_TYPES(BASES
) base_types
;
26 //[throw_on_failure_ctor
28 /* implicit */ cstring(char const* chars
) :
29 boost::contract::constructor_precondition
<cstring
>([&] {
30 BOOST_CONTRACT_ASSERT(chars
); // Throw `assertion_failure`.
31 // Or, throw user-defined exception.
32 if(std::strlen(chars
) > MaxSize
) throw too_large_error();
36 boost::contract::check c
= boost::contract::constructor(this)
38 BOOST_CONTRACT_ASSERT(size() == std::strlen(chars
));
42 size_
= std::strlen(chars
);
43 for(unsigned i
= 0; i
< size_
; ++i
) chars_
[i
] = chars
[i
];
47 //[throw_on_failure_dtor
49 void invariant() const {
50 if(size() > MaxSize
) throw too_large_error(); // Throw user-defined ex.
51 BOOST_CONTRACT_ASSERT(chars_
); // Or, throw `assertion_failure`.
52 BOOST_CONTRACT_ASSERT(chars_
[size()] == '\0');
55 ~cstring() noexcept
{ // Exception specifiers apply to contract code.
57 boost::contract::check c
= boost::contract::destructor(this);
61 unsigned size() const {
63 boost::contract::check c
= boost::contract::public_function(this);
68 char chars_
[MaxSize
+ 1];
70 //[throw_on_failure_class_end
75 void bad_throwing_handler() { // For docs only (not actually used here).
76 //[throw_on_failure_bad_handler
79 // Warning... might cause destructors to throw (unless declared noexcept).
80 boost::contract::set_invariant_failure(
81 [] (boost::contract::from
) {
82 throw; // Throw no matter if from destructor, etc.
90 //[throw_on_failure_handlers
92 boost::contract::set_precondition_failure(
93 boost::contract::set_postcondition_failure(
94 boost::contract::set_invariant_failure(
95 boost::contract::set_old_failure(
96 [] (boost::contract::from where
) {
97 if(where
== boost::contract::from_destructor
) {
98 // Shall not throw from C++ destructors.
99 std::clog
<< "ignored destructor contract failure" << std::endl
;
100 } else throw; // Re-throw (assertion_failure, user-defined, etc.).
103 boost::contract::set_except_failure(
104 [] (boost::contract::from
) {
105 // Already an active exception so shall not throw another...
106 std::clog
<< "ignored exception guarantee failure" << std::endl
;
109 boost::contract::set_check_failure(
111 // But now CHECK shall not be used in destructor implementations.
112 throw; // Re-throw (assertion_failure, user-defined, etc.).
121 assert(s
.size() == 3);
124 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
125 // These failures properly handled only when preconditions checked.
131 } catch(boost::contract::assertion_failure
const& error
) {
133 std::clog
<< "ignored: " << error
.what() << std::endl
;
134 } catch(...) { assert(false); }
137 cstring
<3> s("abcd");
139 } catch(too_large_error
const&) {} // OK (expected).
140 catch(...) { assert(false); }