summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/contract/example/features
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/contract/example/features
parentInitial commit. (diff)
downloadceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz
ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/contract/example/features')
-rw-r--r--src/boost/libs/contract/example/features/access.cpp95
-rw-r--r--src/boost/libs/contract/example/features/assertion_level.cpp135
-rw-r--r--src/boost/libs/contract/example/features/base_types.cpp188
-rw-r--r--src/boost/libs/contract/example/features/base_types_no_macro.cpp188
-rw-r--r--src/boost/libs/contract/example/features/call_if_cxx14.cpp92
-rw-r--r--src/boost/libs/contract/example/features/check.cpp41
-rw-r--r--src/boost/libs/contract/example/features/check_macro.cpp39
-rw-r--r--src/boost/libs/contract/example/features/code_block.cpp43
-rw-r--r--src/boost/libs/contract/example/features/condition_if.cpp58
-rw-r--r--src/boost/libs/contract/example/features/friend.cpp69
-rw-r--r--src/boost/libs/contract/example/features/friend_invariant.cpp59
-rw-r--r--src/boost/libs/contract/example/features/if_constexpr.cpp113
-rw-r--r--src/boost/libs/contract/example/features/ifdef.cpp213
-rw-r--r--src/boost/libs/contract/example/features/ifdef_macro.cpp150
-rw-r--r--src/boost/libs/contract/example/features/introduction.cpp34
-rw-r--r--src/boost/libs/contract/example/features/introduction_comments.cpp24
-rw-r--r--src/boost/libs/contract/example/features/introduction_public.cpp89
-rw-r--r--src/boost/libs/contract/example/features/lambda.cpp43
-rw-r--r--src/boost/libs/contract/example/features/loop.cpp40
-rw-r--r--src/boost/libs/contract/example/features/move.cpp201
-rw-r--r--src/boost/libs/contract/example/features/named_override.cpp104
-rw-r--r--src/boost/libs/contract/example/features/no_lambdas.cpp92
-rw-r--r--src/boost/libs/contract/example/features/no_lambdas.hpp77
-rw-r--r--src/boost/libs/contract/example/features/no_lambdas_local_func.cpp119
-rw-r--r--src/boost/libs/contract/example/features/non_member.cpp40
-rw-r--r--src/boost/libs/contract/example/features/old.cpp41
-rw-r--r--src/boost/libs/contract/example/features/old_if_copyable.cpp133
-rw-r--r--src/boost/libs/contract/example/features/old_no_macro.cpp46
-rw-r--r--src/boost/libs/contract/example/features/optional_result.cpp41
-rw-r--r--src/boost/libs/contract/example/features/optional_result_virtual.cpp88
-rw-r--r--src/boost/libs/contract/example/features/overload.cpp202
-rw-r--r--src/boost/libs/contract/example/features/private_protected.cpp77
-rw-r--r--src/boost/libs/contract/example/features/private_protected_virtual.cpp145
-rw-r--r--src/boost/libs/contract/example/features/private_protected_virtual_multi.cpp209
-rw-r--r--src/boost/libs/contract/example/features/public.cpp189
-rw-r--r--src/boost/libs/contract/example/features/pure_virtual_public.cpp89
-rw-r--r--src/boost/libs/contract/example/features/separate_body.cpp36
-rw-r--r--src/boost/libs/contract/example/features/separate_body.hpp88
-rw-r--r--src/boost/libs/contract/example/features/static_public.cpp69
-rw-r--r--src/boost/libs/contract/example/features/throw_on_failure.cpp145
-rw-r--r--src/boost/libs/contract/example/features/union.cpp134
-rw-r--r--src/boost/libs/contract/example/features/volatile.cpp102
42 files changed, 4180 insertions, 0 deletions
diff --git a/src/boost/libs/contract/example/features/access.cpp b/src/boost/libs/contract/example/features/access.cpp
new file mode 100644
index 00000000..07586172
--- /dev/null
+++ b/src/boost/libs/contract/example/features/access.cpp
@@ -0,0 +1,95 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <cassert>
+
+template<typename T>
+class pushable {
+ friend class boost::contract::access;
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(capacity() <= max_size());
+ }
+
+public:
+ virtual void push_back(T const& value, boost::contract::virtual_* v = 0)
+ = 0;
+
+protected:
+ virtual unsigned capacity() const = 0;
+ virtual unsigned max_size() const = 0;
+};
+
+template<typename T>
+void pushable<T>::push_back(T const& value, boost::contract::virtual_* v) {
+ boost::contract::old_ptr<unsigned> old_capacity =
+ BOOST_CONTRACT_OLDOF(v, capacity());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() < max_size());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() >= *old_capacity);
+ })
+ ;
+ assert(false);
+}
+
+//[access
+template<typename T>
+class vector
+ #define BASES public pushable<T>
+ : BASES
+{ // Private section of the class.
+ friend class boost::contract::access; // Friend `access` class so...
+
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // ...private bases.
+ #undef BASES
+
+ void invariant() const { // ...private invariants.
+ BOOST_CONTRACT_ASSERT(size() <= capacity());
+ }
+
+ BOOST_CONTRACT_OVERRIDE(push_back) // ...private overrides.
+
+public: // Public section of the class.
+ void push_back(T const& value, boost::contract::virtual_* v = 0)
+ /* override */ {
+ boost::contract::old_ptr<unsigned> old_size =
+ BOOST_CONTRACT_OLDOF(v, size());
+ boost::contract::check c = boost::contract::public_function<
+ override_push_back>(v, &vector::push_back, this, value)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(size() < max_size());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ })
+ ;
+
+ vect_.push_back(value);
+ }
+
+ /* ... */
+//]
+
+ unsigned size() const { return vect_.size(); }
+ unsigned max_size() const { return vect_.max_size(); }
+ unsigned capacity() const { return vect_.capacity(); }
+
+private: // Another private section.
+ std::vector<T> vect_;
+};
+
+int main() {
+ vector<int> vect;
+ vect.push_back(123);
+ assert(vect.size() == 1);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/assertion_level.cpp b/src/boost/libs/contract/example/features/assertion_level.cpp
new file mode 100644
index 00000000..c347b19c
--- /dev/null
+++ b/src/boost/libs/contract/example/features/assertion_level.cpp
@@ -0,0 +1,135 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+
+//[assertion_level_no_impl
+// If valid iterator range (cannot implement in C++ but OK to use in AXIOM).
+template<typename Iter>
+bool valid(Iter first, Iter last); // Only declared, not actually defined.
+//]
+
+//[assertion_level_class_begin
+template<typename T>
+class vector {
+//]
+
+public:
+ typedef typename std::vector<T>::iterator iterator;
+
+ // Could program class invariants and contracts for the following.
+ iterator begin() { return vect_.begin(); }
+ iterator end() { return vect_.end(); }
+ unsigned capacity() const { return vect_.capacity(); }
+ bool operator==(vector const& other) { return vect_ == other.vect_; }
+
+//[assertion_level_axiom
+public:
+ iterator insert(iterator where, T const& value) {
+ iterator result;
+ boost::contract::old_ptr<unsigned> old_capacity =
+ BOOST_CONTRACT_OLDOF(capacity());
+ boost::contract::check c = boost::contract::public_function(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() >= *old_capacity);
+ if(capacity() > *old_capacity) {
+ BOOST_CONTRACT_ASSERT_AXIOM(!valid(begin(), end()));
+ } else {
+ BOOST_CONTRACT_ASSERT_AXIOM(!valid(where, end()));
+ }
+ })
+ ;
+
+ return result = vect_.insert(where, value);
+ }
+//]
+
+//[assertion_level_audit_old
+public:
+ void swap(vector& other) {
+ boost::contract::old_ptr<vector> old_me, old_other;
+ #ifdef BOOST_CONTRACT_AUDITS
+ old_me = BOOST_CONTRACT_OLDOF(*this);
+ old_other = BOOST_CONTRACT_OLDOF(other);
+ #endif // Else, skip old value copies...
+ boost::contract::check c = boost::contract::public_function(this)
+ .postcondition([&] {
+ // ...and also skip related assertions.
+ BOOST_CONTRACT_ASSERT_AUDIT(*this == *old_other);
+ BOOST_CONTRACT_ASSERT_AUDIT(other == *old_me);
+ })
+ ;
+
+ vect_.swap(other.vect_);
+ }
+//]
+
+//[assertion_level_class_end
+ /* ... */
+
+private:
+ std::vector<T> vect_;
+};
+//]
+
+//[assertion_level_audit
+template<typename RandomIter, typename T>
+RandomIter random_binary_search(RandomIter first, RandomIter last,
+ T const& value) {
+ RandomIter result;
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(first <= last); // Default, not expensive.
+ // Expensive O(n) assertion (use AXIOM if prohibitive instead).
+ BOOST_CONTRACT_ASSERT_AUDIT(std::is_sorted(first, last));
+ })
+ .postcondition([&] {
+ if(result != last) BOOST_CONTRACT_ASSERT(*result == value);
+ })
+ ;
+
+ /* ... */
+//]
+
+ RandomIter begin = first, end = last;
+ while(begin < end) {
+ RandomIter middle = begin + ((end - begin) >> 1);
+ BOOST_CONTRACT_CHECK(*begin <= *middle || value < *middle ||
+ *middle < value);
+
+ if(value < *middle) end = middle;
+ else if(value > *middle) begin = middle + 1;
+ else return result = middle;
+ }
+ return result = last;
+}
+
+int main() {
+ vector<char> v;
+ v.insert(v.begin() + 0, 'a');
+ v.insert(v.begin() + 1, 'b');
+ v.insert(v.begin() + 2, 'c');
+
+ vector<char>::iterator i = random_binary_search(v.begin(), v.end(), 'b');
+ assert(i != v.end());
+ assert(*i == 'b');
+
+ vector<char> w;
+ w.insert(w.begin() + 0, 'x');
+ w.insert(w.begin() + 1, 'y');
+
+ w.swap(v);
+ assert(*(w.begin() + 0) == 'a');
+ assert(*(w.begin() + 1) == 'b');
+ assert(*(w.begin() + 2) == 'c');
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/base_types.cpp b/src/boost/libs/contract/example/features/base_types.cpp
new file mode 100644
index 00000000..56efcbfe
--- /dev/null
+++ b/src/boost/libs/contract/example/features/base_types.cpp
@@ -0,0 +1,188 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+template<typename T>
+class pushable {
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(capacity() <= max_size());
+ }
+
+ virtual void push_back(T x, boost::contract::virtual_* v = 0) = 0;
+
+protected:
+ virtual unsigned capacity() const = 0;
+ virtual unsigned max_size() const = 0;
+};
+
+template<typename T>
+void pushable<T>::push_back(T x, boost::contract::virtual_* v) {
+ boost::contract::old_ptr<unsigned> old_capacity =
+ BOOST_CONTRACT_OLDOF(v, capacity());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() < max_size());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() >= *old_capacity);
+ })
+ ;
+ assert(false); // Shall never execute this body.
+}
+
+struct has_size { virtual unsigned size() const = 0; };
+struct has_empty { virtual bool empty() const = 0; };
+
+class unique_chars
+ : private boost::contract::constructor_precondition<unique_chars>
+{
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(size() >= 0);
+ }
+
+ unique_chars(char from, char to) :
+ boost::contract::constructor_precondition<unique_chars>([&] {
+ BOOST_CONTRACT_ASSERT(from <= to);
+ })
+ {
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(int(size()) == (to - from + 1));
+ })
+ ;
+
+ for(char x = from; x <= to; ++x) vect_.push_back(x);
+ }
+
+ virtual ~unique_chars() {
+ boost::contract::check c = boost::contract::destructor(this);
+ }
+
+ unsigned size() const {
+ boost::contract::check c = boost::contract::public_function(this);
+ return vect_.size();
+ }
+
+ bool find(char x) const {
+ bool result;
+ boost::contract::check c = boost::contract::public_function(this)
+ .postcondition([&] {
+ if(size() == 0) BOOST_CONTRACT_ASSERT(!result);
+ })
+ ;
+
+ return result = std::find(vect_.begin(), vect_.end(), x) != vect_.end();
+ }
+
+ virtual void push_back(char x, boost::contract::virtual_* v = 0) {
+ boost::contract::old_ptr<bool> old_find =
+ BOOST_CONTRACT_OLDOF(v, find(x));
+ boost::contract::old_ptr<unsigned> old_size =
+ BOOST_CONTRACT_OLDOF(v, size());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(!find(x));
+ })
+ .postcondition([&] {
+ if(!*old_find) {
+ BOOST_CONTRACT_ASSERT(find(x));
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ }
+ })
+ ;
+
+ vect_.push_back(x);
+ }
+
+protected:
+ unique_chars() {}
+
+ std::vector<char> const& vect() const { return vect_; }
+
+private:
+ std::vector<char> vect_;
+};
+
+//[base_types
+class chars
+ #define BASES /* local macro (for convenience) */ \
+ private boost::contract::constructor_precondition<chars>, \
+ public unique_chars, \
+ public virtual pushable<char>, \
+ virtual protected has_size, \
+ private has_empty
+ : BASES // Bases of this class.
+{
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // Bases typedef.
+ #undef BASES // Undefine local macro.
+
+ /* ... */
+//]
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(empty() == (size() == 0));
+ }
+
+ chars(char from, char to) : unique_chars(from, to) {
+ boost::contract::check c = boost::contract::constructor(this);
+ }
+
+ chars(char const* const c_str) :
+ boost::contract::constructor_precondition<chars>([&] {
+ BOOST_CONTRACT_ASSERT(c_str[0] != '\0');
+ })
+ {
+ boost::contract::check c = boost::contract::constructor(this);
+
+ for(unsigned i = 0; c_str[i] != '\0'; ++i) push_back(c_str[i]);
+ }
+
+ void push_back(char x, boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::old_ptr<bool> old_find =
+ BOOST_CONTRACT_OLDOF(v, find(x));
+ boost::contract::old_ptr<unsigned> old_size =
+ BOOST_CONTRACT_OLDOF(v, size());
+ boost::contract::check c = boost::contract::public_function<
+ override_push_back>(v, &chars::push_back, this, x)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(find(x));
+ })
+ .postcondition([&] {
+ if(*old_find) BOOST_CONTRACT_ASSERT(size() == *old_size);
+ })
+ ;
+
+ if(!find(x)) unique_chars::push_back(x);
+ }
+ BOOST_CONTRACT_OVERRIDE(push_back);
+
+ bool empty() const {
+ boost::contract::check c = boost::contract::public_function(this);
+ return size() == 0;
+ }
+
+ unsigned size() const { return unique_chars::size(); }
+
+protected:
+ unsigned max_size() const { return vect().max_size(); }
+ unsigned capacity() const { return vect().capacity(); }
+};
+
+int main() {
+ chars s("abc");
+ assert(s.find('a'));
+ assert(s.find('b'));
+ assert(!s.find('x'));
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/base_types_no_macro.cpp b/src/boost/libs/contract/example/features/base_types_no_macro.cpp
new file mode 100644
index 00000000..f9add687
--- /dev/null
+++ b/src/boost/libs/contract/example/features/base_types_no_macro.cpp
@@ -0,0 +1,188 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+template<typename T>
+class pushable {
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(capacity() <= max_size());
+ }
+
+ virtual void push_back(T x, boost::contract::virtual_* v = 0) = 0;
+
+protected:
+ virtual unsigned capacity() const = 0;
+ virtual unsigned max_size() const = 0;
+};
+
+template<typename T>
+void pushable<T>::push_back(T x, boost::contract::virtual_* v) {
+ boost::contract::old_ptr<unsigned> old_capacity =
+ BOOST_CONTRACT_OLDOF(v, capacity());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() < max_size());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() >= *old_capacity);
+ })
+ ;
+ assert(false); // Shall never execute this body.
+}
+
+struct has_size { virtual unsigned size() const = 0; };
+struct has_empty { virtual bool empty() const = 0; };
+
+class unique_chars
+ : private boost::contract::constructor_precondition<unique_chars>
+{
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(size() >= 0);
+ }
+
+ unique_chars(char from, char to) :
+ boost::contract::constructor_precondition<unique_chars>([&] {
+ BOOST_CONTRACT_ASSERT(from <= to);
+ })
+ {
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(int(size()) == (to - from + 1));
+ })
+ ;
+
+ for(char x = from; x <= to; ++x) vect_.push_back(x);
+ }
+
+ virtual ~unique_chars() {
+ boost::contract::check c = boost::contract::destructor(this);
+ }
+
+ unsigned size() const {
+ boost::contract::check c = boost::contract::public_function(this);
+ return vect_.size();
+ }
+
+ bool find(char x) const {
+ bool result;
+ boost::contract::check c = boost::contract::public_function(this)
+ .postcondition([&] {
+ if(size() == 0) BOOST_CONTRACT_ASSERT(!result);
+ })
+ ;
+
+ return result = std::find(vect_.begin(), vect_.end(), x) != vect_.end();
+ }
+
+ virtual void push_back(char x, boost::contract::virtual_* v = 0) {
+ boost::contract::old_ptr<bool> old_find =
+ BOOST_CONTRACT_OLDOF(v, find(x));
+ boost::contract::old_ptr<unsigned> old_size =
+ BOOST_CONTRACT_OLDOF(v, size());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(!find(x));
+ })
+ .postcondition([&] {
+ if(!*old_find) {
+ BOOST_CONTRACT_ASSERT(find(x));
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ }
+ })
+ ;
+
+ vect_.push_back(x);
+ }
+
+protected:
+ unique_chars() {}
+
+ std::vector<char> const& vect() const { return vect_; }
+
+private:
+ std::vector<char> vect_;
+};
+
+//[base_types_no_macro
+#include <boost/mpl/vector.hpp>
+
+class chars :
+ private boost::contract::constructor_precondition<chars>,
+ public unique_chars,
+ public virtual pushable<char>,
+ virtual protected has_size,
+ private has_empty
+{
+public:
+ // Program `base_types` without macros (list only public bases).
+ typedef boost::mpl::vector<unique_chars, pushable<char> > base_types;
+
+ /* ... */
+//]
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(empty() == (size() == 0));
+ }
+
+ chars(char from, char to) : unique_chars(from, to) {
+ boost::contract::check c = boost::contract::constructor(this);
+ }
+
+ chars(char const* const c_str) :
+ boost::contract::constructor_precondition<chars>([&] {
+ BOOST_CONTRACT_ASSERT(c_str[0] != '\0');
+ })
+ {
+ boost::contract::check c = boost::contract::constructor(this);
+
+ for(unsigned i = 0; c_str[i] != '\0'; ++i) push_back(c_str[i]);
+ }
+
+ void push_back(char x, boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::old_ptr<bool> old_find =
+ BOOST_CONTRACT_OLDOF(v, find(x));
+ boost::contract::old_ptr<unsigned> old_size =
+ BOOST_CONTRACT_OLDOF(v, size());
+ boost::contract::check c = boost::contract::public_function<
+ override_push_back>(v, &chars::push_back, this, x)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(find(x));
+ })
+ .postcondition([&] {
+ if(*old_find) BOOST_CONTRACT_ASSERT(size() == *old_size);
+ })
+ ;
+
+ if(!find(x)) unique_chars::push_back(x);
+ }
+ BOOST_CONTRACT_OVERRIDE(push_back);
+
+ bool empty() const {
+ boost::contract::check c = boost::contract::public_function(this);
+ return size() == 0;
+ }
+
+ unsigned size() const { return unique_chars::size(); }
+
+protected:
+ unsigned max_size() const { return vect().max_size(); }
+ unsigned capacity() const { return vect().capacity(); }
+};
+
+int main() {
+ chars s("abc");
+ assert(s.find('a'));
+ assert(s.find('b'));
+ assert(!s.find('x'));
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/call_if_cxx14.cpp b/src/boost/libs/contract/example/features/call_if_cxx14.cpp
new file mode 100644
index 00000000..bdf4f424
--- /dev/null
+++ b/src/boost/libs/contract/example/features/call_if_cxx14.cpp
@@ -0,0 +1,92 @@
+
+// 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 <boost/contract/call_if.hpp>
+#include <type_traits>
+#include <iterator>
+#include <functional> // std::bind for generic lambdas.
+#include <vector>
+#include <list>
+#include <sstream>
+
+template<typename Iter>
+struct is_random_access_iterator : std::is_same<
+ typename std::iterator_traits<Iter>::iterator_category,
+ std::random_access_iterator_tag
+> {};
+
+template<typename Iter>
+struct is_bidirectional_iterator : std::is_same<
+ typename std::iterator_traits<Iter>::iterator_category,
+ std::bidirectional_iterator_tag
+> {};
+
+template<typename Iter>
+struct is_input_iterator : std::is_same<
+ typename std::iterator_traits<Iter>::iterator_category,
+ std::input_iterator_tag
+> {};
+
+//[call_if_cxx14
+template<typename Iter, typename Dist>
+void myadvance(Iter& i, Dist n) {
+ Iter* p = &i; // So captures change actual pointed iterator value.
+ boost::contract::call_if<is_random_access_iterator<Iter> >(
+ std::bind([] (auto p, auto n) { // C++14 generic lambda.
+ *p += n;
+ }, p, n)
+ ).template else_if<is_bidirectional_iterator<Iter> >(
+ std::bind([] (auto p, auto n) {
+ if(n >= 0) while(n--) ++*p;
+ else while(n++) --*p;
+ }, p, n)
+ ).template else_if<is_input_iterator<Iter> >(
+ std::bind([] (auto p, auto n) {
+ while(n--) ++*p;
+ }, p, n)
+ ).else_(
+ std::bind([] (auto false_) {
+ static_assert(false_, "requires at least input iterator");
+ }, std::false_type()) // Use constexpr value.
+ );
+}
+//]
+
+struct x {}; // Test not an iterator (static_assert failure in else_ above).
+
+namespace std {
+ template<>
+ struct iterator_traits<x> {
+ typedef void iterator_category;
+ };
+}
+
+int main() {
+ std::vector<char> v;
+ v.push_back('a');
+ v.push_back('b');
+ v.push_back('c');
+ v.push_back('d');
+ std::vector<char>::iterator r = v.begin(); // Random iterator.
+ myadvance(r, 1);
+ assert(*r == 'b');
+
+ std::list<char> l(v.begin(), v.end());
+ std::list<char>::iterator b = l.begin(); // Bidirectional iterator.
+ myadvance(b, 2);
+ assert(*b == 'c');
+
+ std::istringstream s("a b c d");
+ std::istream_iterator<char> i(s);
+ myadvance(i, 3);
+ assert(*i == 'd');
+
+ // x j;
+ // myadvance(j, 0); // Error (correctly because x not even input iter).
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/check.cpp b/src/boost/libs/contract/example/features/check.cpp
new file mode 100644
index 00000000..36aa9da3
--- /dev/null
+++ b/src/boost/libs/contract/example/features/check.cpp
@@ -0,0 +1,41 @@
+
+// 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 <boost/contract.hpp>
+
+int gcd(int const a, int const b) {
+ int result;
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(a > 0);
+ BOOST_CONTRACT_ASSERT(b > 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(result <= a);
+ BOOST_CONTRACT_ASSERT(result <= b);
+ })
+ ;
+
+ int x = a, y = b;
+ while(x != y) {
+ if(x > y) x = x - y;
+ else y = y - x;
+ }
+ return result = x;
+}
+
+//[check
+int main() {
+ // Implementation checks (via nullary functor).
+ boost::contract::check c = [] {
+ BOOST_CONTRACT_ASSERT(gcd(12, 28) == 4);
+ BOOST_CONTRACT_ASSERT(gcd(4, 14) == 2);
+ };
+
+ return 0;
+}
+//]
+
diff --git a/src/boost/libs/contract/example/features/check_macro.cpp b/src/boost/libs/contract/example/features/check_macro.cpp
new file mode 100644
index 00000000..80d9c66c
--- /dev/null
+++ b/src/boost/libs/contract/example/features/check_macro.cpp
@@ -0,0 +1,39 @@
+
+// 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 <boost/contract.hpp>
+
+int gcd(int const a, int const b) {
+ int result;
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(a > 0);
+ BOOST_CONTRACT_ASSERT(b > 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(result <= a);
+ BOOST_CONTRACT_ASSERT(result <= b);
+ })
+ ;
+
+ int x = a, y = b;
+ while(x != y) {
+ if(x > y) x = x - y;
+ else y = y - x;
+ }
+ return result = x;
+}
+
+//[check_macro
+int main() {
+ // Implementation checks (via macro, disable run-/compile-time overhead).
+ BOOST_CONTRACT_CHECK(gcd(12, 28) == 4);
+ BOOST_CONTRACT_CHECK(gcd(4, 14) == 2);
+
+ return 0;
+}
+//]
+
diff --git a/src/boost/libs/contract/example/features/code_block.cpp b/src/boost/libs/contract/example/features/code_block.cpp
new file mode 100644
index 00000000..2ec434aa
--- /dev/null
+++ b/src/boost/libs/contract/example/features/code_block.cpp
@@ -0,0 +1,43 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <algorithm>
+#include <limits>
+
+int main() {
+ std::vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ v.push_back(3);
+ int total = 10;
+
+ //[code_block
+ /* ... */
+
+ // Contract for a code block.
+ { // Code block entry (check preconditions).
+ boost::contract::old_ptr<int> old_total = BOOST_CONTRACT_OLDOF(total);
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(v.size() == 3);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(total == *old_total + v[0] + v[1] + v[2]);
+ })
+ ;
+
+ total += v[0] + v[1] + v[2]; // Code block body.
+ } // Code block exit (check postconditions and exceptions guarantees).
+
+ /* ... */
+ //]
+
+ assert(total == 16);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/condition_if.cpp b/src/boost/libs/contract/example/features/condition_if.cpp
new file mode 100644
index 00000000..c8ecb964
--- /dev/null
+++ b/src/boost/libs/contract/example/features/condition_if.cpp
@@ -0,0 +1,58 @@
+
+// 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 <boost/contract.hpp>
+#include <boost/type_traits/has_equal_to.hpp>
+#include <boost/bind.hpp>
+#include <vector>
+#include <functional>
+#include <cassert>
+
+//[condition_if
+template<typename T>
+class vector {
+public:
+ void push_back(T const& value) {
+ boost::contract::check c = boost::contract::public_function(this)
+ .postcondition([&] {
+ // Instead of `ASSERT(back() == value)` for T without `==`.
+ BOOST_CONTRACT_ASSERT(
+ boost::contract::condition_if<boost::has_equal_to<T> >(
+ boost::bind(std::equal_to<T>(),
+ boost::cref(back()),
+ boost::cref(value)
+ )
+ )
+ );
+ })
+ ;
+
+ vect_.push_back(value);
+ }
+
+ /* ... */
+//]
+
+ T const& back() const { return vect_.back(); }
+
+private:
+ std::vector<T> vect_;
+};
+
+int main() {
+ vector<int> v;
+ v.push_back(1); // Type `int` has `==` so check postcondition.
+ assert(v.back() == 1);
+
+ struct i { int value; } j;
+ j.value = 10;
+ vector<i> w;
+ w.push_back(j); // Type `i` has no `==` so skip postcondition.
+ assert(j.value == 10);
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/friend.cpp b/src/boost/libs/contract/example/features/friend.cpp
new file mode 100644
index 00000000..215cfa6d
--- /dev/null
+++ b/src/boost/libs/contract/example/features/friend.cpp
@@ -0,0 +1,69 @@
+
+// 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 <boost/contract.hpp>
+#include <string>
+#include <cassert>
+
+//[friend_byte
+class buffer;
+
+class byte {
+ friend bool operator==(buffer const& left, byte const& right);
+
+private:
+ char value_;
+
+ /* ... */
+//]
+
+public:
+ // Could program invariants and contracts for following too.
+ explicit byte(char value) : value_(value) {}
+ bool empty() const { return value_ == '\0'; }
+};
+
+//[friend_buffer
+class buffer {
+ // Friend functions are not member functions...
+ friend bool operator==(buffer const& left, byte const& right) {
+ // ...so check contracts via `function` (which won't check invariants).
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(!left.empty());
+ BOOST_CONTRACT_ASSERT(!right.empty());
+ })
+ ;
+
+ for(char const* x = left.values_.c_str(); *x != '\0'; ++x) {
+ if(*x != right.value_) return false;
+ }
+ return true;
+ }
+
+private:
+ std::string values_;
+
+ /* ... */
+//]
+
+public:
+ // Could program invariants and contracts for following too.
+ explicit buffer(std::string const& values) : values_(values) {}
+ bool empty() const { return values_ == ""; }
+};
+
+int main() {
+ buffer p("aaa");
+ byte a('a');
+ assert(p == a);
+
+ buffer q("aba");
+ assert(!(q == a)); // No operator!=.
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/friend_invariant.cpp b/src/boost/libs/contract/example/features/friend_invariant.cpp
new file mode 100644
index 00000000..b9f69bbe
--- /dev/null
+++ b/src/boost/libs/contract/example/features/friend_invariant.cpp
@@ -0,0 +1,59 @@
+
+// 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 <boost/contract.hpp>
+#include <cassert>
+
+//[friend_invariant
+template<typename T>
+class positive {
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(value() > 0);
+ }
+
+ // Can be considered an extension of enclosing class' public interface...
+ friend void swap(positive& object, T& value) {
+ boost::contract::old_ptr<T> old_object_value =
+ BOOST_CONTRACT_OLDOF(object.value());
+ boost::contract::old_ptr<T> old_value = BOOST_CONTRACT_OLDOF(value);
+ // ...so it can be made to check invariants via `public_function`.
+ boost::contract::check c = boost::contract::public_function(&object)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(value > 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(object.value() == *old_value);
+ BOOST_CONTRACT_ASSERT(value == *old_object_value);
+ })
+ ;
+
+ T saved = object.value_;
+ object.value_ = value;
+ value = saved;
+ }
+
+private:
+ T value_;
+
+ /* ... */
+//]
+
+public:
+ // Could program contracts for following too.
+ explicit positive(T const& value) : value_(value) {}
+ T value() const { return value_; }
+};
+
+int main() {
+ positive<int> i(123);
+ int x = 456;
+ swap(i, x);
+ assert(i.value() == 456);
+ assert(x == 123);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/if_constexpr.cpp b/src/boost/libs/contract/example/features/if_constexpr.cpp
new file mode 100644
index 00000000..f4561f14
--- /dev/null
+++ b/src/boost/libs/contract/example/features/if_constexpr.cpp
@@ -0,0 +1,113 @@
+
+// Copyright (C) 2008-2019 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 <boost/contract.hpp>
+#include <boost/type_traits/has_equal_to.hpp>
+#include <utility>
+#include <cassert>
+
+//[if_constexpr
+template<typename T>
+void swap(T& x, T& y) {
+ constexpr bool b = boost::contract::is_old_value_copyable<T>::value &&
+ boost::has_equal_to<T>::value;
+ boost::contract::old_ptr<T> old_x, old_y;
+ if constexpr(b) { // Contract requires copyable T...
+ old_x = BOOST_CONTRACT_OLDOF(x);
+ old_y = BOOST_CONTRACT_OLDOF(y);
+ }
+ boost::contract::check c = boost::contract::function()
+ .postcondition([&] {
+ if constexpr(b) { // ... and T with `==`...
+ BOOST_CONTRACT_ASSERT(x == *old_y);
+ BOOST_CONTRACT_ASSERT(y == *old_x);
+ }
+ })
+ ;
+
+ T t = std::move(x); // ...but body only requires movable T.
+ x = std::move(y);
+ y = std::move(t);
+}
+//]
+
+struct i { // Non-copyable but has operator==.
+ explicit i(int n) : n_(n) {}
+
+ i(i const&) = delete; // Non-copyable.
+ i& operator=(i const&) = delete;
+
+ i(i const&& o) : n_(o.n_) {}
+ i& operator=(i const&& o) { n_ = o.n_; return *this; }
+
+ friend bool operator==(i const& l, i const& r) { // Operator==.
+ return l.n_ == r.n_;
+ }
+
+private:
+ int n_;
+};
+
+struct j { // Copyable but no operator==.
+ explicit j(int n) : n_(n) {}
+
+ j(j const& o) : n_(o.n_) {} // Copyable.
+ j& operator=(j const& o) { n_ = o.n_; return *this; }
+
+ j(j const&& o) : n_(o.n_) {}
+ j& operator=(j const&& o) { n_ = o.n_; return *this; }
+
+ // No operator==.
+
+private:
+ int n_;
+};
+
+struct k { // Non-copyable and no operator==.
+ explicit k(int n) : n_(n) {}
+
+ k(k const&) = delete; // Non-copyable.
+ k& operator=(k const&) = delete;
+
+ k(k const&& o) : n_(o.n_) {}
+ k& operator=(k const&& o) { n_ = o.n_; return *this; }
+
+ // No operator==.
+
+private:
+ int n_;
+};
+
+int main() {
+ { // Copyable and operator== (so checks postconditions).
+ int x = 123, y = 456;
+ swap(x, y);
+ assert(x == 456);
+ assert(y == 123);
+ }
+
+ { // Non-copyable (so does not check postconditions).
+ i x{123}, y{456};
+ swap(x, y);
+ assert(x == i{456});
+ assert(y == i{123});
+ }
+
+ { // No operator== (so does not check postconditions).
+ j x{123}, y{456};
+ swap(x, y);
+ // Cannot assert x and y because no operator==.
+ }
+
+ { // Non-copyable and no operator== (so does not check postconditions).
+ k x{123}, y{456};
+ swap(x, y);
+ // Cannot assert x and y because no operator==.
+ }
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/ifdef.cpp b/src/boost/libs/contract/example/features/ifdef.cpp
new file mode 100644
index 00000000..74e74ee9
--- /dev/null
+++ b/src/boost/libs/contract/example/features/ifdef.cpp
@@ -0,0 +1,213 @@
+
+// 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 <vector>
+#include <limits>
+#include <cassert>
+
+//[ifdef_function
+// Use #ifdef to completely disable contract code compilation.
+#include <boost/contract/core/config.hpp>
+#ifndef BOOST_CONTRACT_NO_ALL
+ #include <boost/contract.hpp>
+#endif
+
+int inc(int& x) {
+ int result;
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x);
+ #endif
+ #ifndef BOOST_CONTRACT_NO_FUNCTIONS
+ boost::contract::check c = boost::contract::function()
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max());
+ })
+ #endif
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(x == *old_x + 1);
+ BOOST_CONTRACT_ASSERT(result == *old_x);
+ })
+ #endif
+ ;
+ #endif
+
+ return result = x++;
+}
+//]
+
+template<typename T>
+class pushable {
+ #ifndef BOOST_CONTRACT_NO_ALL
+ friend class boost::contract::access;
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_INVARIANTS
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(capacity() <= max_size());
+ }
+ #endif
+
+public:
+ virtual void push_back(
+ T const& x
+ #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+ , boost::contract::virtual_* v = 0
+ #endif
+ ) = 0;
+
+protected:
+ virtual unsigned capacity() const = 0;
+ virtual unsigned max_size() const = 0;
+};
+
+template<typename T>
+void pushable<T>::push_back(
+ T const& x
+ #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+ , boost::contract::virtual_* v
+ #endif
+) {
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ boost::contract::old_ptr<unsigned> old_capacity =
+ BOOST_CONTRACT_OLDOF(v, capacity());
+ #endif
+ #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+ boost::contract::check c = boost::contract::public_function(v, this)
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() < max_size());
+ })
+ #endif
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() >= *old_capacity);
+ })
+ #endif
+ ;
+ #endif
+ assert(false); // Shall never execute this body.
+}
+
+//[ifdef_class
+class integers
+ #define BASES public pushable<int>
+ :
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ private boost::contract::constructor_precondition<integers>, BASES
+ #else
+ BASES
+ #endif
+{
+ #ifndef BOOST_CONTRACT_NO_ALL
+ friend class boost::contract::access;
+ #endif
+
+ #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #endif
+ #undef BASES
+
+ #ifndef BOOST_CONTRACT_NO_INVARIANTS
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(size() <= capacity());
+ }
+ #endif
+
+public:
+ integers(int from, int to) :
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ boost::contract::constructor_precondition<integers>([&] {
+ BOOST_CONTRACT_ASSERT(from <= to);
+ }),
+ #endif
+ vect_(to - from + 1)
+ {
+ #ifndef BOOST_CONTRACT_NO_CONSTRUCTORS
+ boost::contract::check c = boost::contract::constructor(this)
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(int(size()) == (to - from + 1));
+ })
+ #endif
+ ;
+ #endif
+
+ for(int x = from; x <= to; ++x) vect_.at(x - from) = x;
+ }
+
+ virtual ~integers() {
+ #ifndef BOOST_CONTRACT_NO_DESTRUCTORS
+ // Check invariants.
+ boost::contract::check c = boost::contract::destructor(this);
+ #endif
+ }
+
+ virtual void push_back(
+ int const& x
+ #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+ , boost::contract::virtual_* v = 0
+ #endif
+ ) /* override */ {
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ boost::contract::old_ptr<unsigned> old_size;
+ #endif
+ #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+ boost::contract::check c = boost::contract::public_function<
+ override_push_back>(v, &integers::push_back, this, x)
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(size() < max_size());
+ })
+ #endif
+ #ifndef BOOST_CONTRACT_NO_OLDS
+ .old([&] {
+ old_size = BOOST_CONTRACT_OLDOF(v, size());
+ })
+ #endif
+ #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ })
+ #endif
+ #ifndef BOOST_CONTRACT_NO_EXCEPTS
+ .except([&] {
+ BOOST_CONTRACT_ASSERT(size() == *old_size);
+ })
+ #endif
+ ;
+ #endif
+
+ vect_.push_back(x);
+ }
+
+private:
+ #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS
+ BOOST_CONTRACT_OVERRIDE(push_back)
+ #endif
+
+ /* ... */
+//]
+
+public: // Could program contracts for these too...
+ unsigned size() const { return vect_.size(); }
+ unsigned max_size() const { return vect_.max_size(); }
+ unsigned capacity() const { return vect_.capacity(); }
+
+private:
+ std::vector<int> vect_;
+};
+
+int main() {
+ integers i(1, 10);
+ int x = 123;
+ i.push_back(inc(x));
+ assert(x == 124);
+ assert(i.size() == 11);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/ifdef_macro.cpp b/src/boost/libs/contract/example/features/ifdef_macro.cpp
new file mode 100644
index 00000000..cc979bfd
--- /dev/null
+++ b/src/boost/libs/contract/example/features/ifdef_macro.cpp
@@ -0,0 +1,150 @@
+
+// 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 <vector>
+#include <limits>
+#include <cassert>
+
+//[ifdef_macro_function
+// Use macro interface to completely disable contract code compilation.
+#include <boost/contract_macro.hpp>
+
+int inc(int& x) {
+ int result;
+ BOOST_CONTRACT_OLD_PTR(int)(old_x, x);
+ BOOST_CONTRACT_FUNCTION()
+ BOOST_CONTRACT_PRECONDITION([&] {
+ BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max());
+ })
+ BOOST_CONTRACT_POSTCONDITION([&] {
+ BOOST_CONTRACT_ASSERT(x == *old_x + 1);
+ BOOST_CONTRACT_ASSERT(result == *old_x);
+ })
+ ;
+
+ return result = x++;
+}
+//]
+
+template<typename T>
+class pushable {
+ friend class boost::contract::access; // Left in code (almost no overhead).
+
+ BOOST_CONTRACT_INVARIANT({
+ BOOST_CONTRACT_ASSERT(capacity() <= max_size());
+ })
+
+public:
+ virtual void push_back(
+ T const& x,
+ boost::contract::virtual_* v = 0 // Left in code (almost no overhead).
+ ) = 0;
+
+protected:
+ virtual unsigned capacity() const = 0;
+ virtual unsigned max_size() const = 0;
+};
+
+template<typename T>
+void pushable<T>::push_back(T const& x, boost::contract::virtual_* v) {
+ BOOST_CONTRACT_OLD_PTR(unsigned)(v, old_capacity, capacity());
+ BOOST_CONTRACT_PUBLIC_FUNCTION(v, this)
+ BOOST_CONTRACT_PRECONDITION([&] {
+ BOOST_CONTRACT_ASSERT(capacity() < max_size());
+ })
+ BOOST_CONTRACT_POSTCONDITION([&] {
+ BOOST_CONTRACT_ASSERT(capacity() >= *old_capacity);
+ })
+ ;
+ assert(false); // Shall never execute this body.
+}
+
+//[ifdef_macro_class
+class integers
+ #define BASES public pushable<int>
+ :
+ // Left in code (almost no overhead).
+ private boost::contract::constructor_precondition<integers>,
+ BASES
+{
+ // Followings left in code (almost no overhead).
+ friend class boost::contract::access;
+
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+
+ BOOST_CONTRACT_INVARIANT({
+ BOOST_CONTRACT_ASSERT(size() <= capacity());
+ })
+
+public:
+ integers(int from, int to) :
+ BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(integers)([&] {
+ BOOST_CONTRACT_ASSERT(from <= to);
+ }),
+ vect_(to - from + 1)
+ {
+ BOOST_CONTRACT_CONSTRUCTOR(this)
+ BOOST_CONTRACT_POSTCONDITION([&] {
+ BOOST_CONTRACT_ASSERT(int(size()) == (to - from + 1));
+ })
+ ;
+
+ for(int x = from; x <= to; ++x) vect_.at(x - from) = x;
+ }
+
+ virtual ~integers() {
+ BOOST_CONTRACT_DESTRUCTOR(this); // Check invariants.
+ }
+
+ virtual void push_back(
+ int const& x,
+ boost::contract::virtual_* v = 0 // Left in code (almost no overhead).
+ ) /* override */ {
+ BOOST_CONTRACT_OLD_PTR(unsigned)(old_size);
+ BOOST_CONTRACT_PUBLIC_FUNCTION_OVERRIDE(override_push_back)(
+ v, &integers::push_back, this, x)
+ BOOST_CONTRACT_PRECONDITION([&] {
+ BOOST_CONTRACT_ASSERT(size() < max_size());
+ })
+ BOOST_CONTRACT_OLD([&] {
+ old_size = BOOST_CONTRACT_OLDOF(v, size());
+ })
+ BOOST_CONTRACT_POSTCONDITION([&] {
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ })
+ BOOST_CONTRACT_EXCEPT([&] {
+ BOOST_CONTRACT_ASSERT(size() == *old_size);
+ })
+ ;
+
+ vect_.push_back(x);
+ }
+
+private:
+ BOOST_CONTRACT_OVERRIDE(push_back) // Left in code (almost no overhead).
+
+ /* ... */
+//]
+
+public: // Could program contracts for these too...
+ unsigned size() const { return vect_.size(); }
+ unsigned max_size() const { return vect_.max_size(); }
+ unsigned capacity() const { return vect_.capacity(); }
+
+private:
+ std::vector<int> vect_;
+};
+
+int main() {
+ integers i(1, 10);
+ int x = 123;
+ i.push_back(inc(x));
+ assert(x == 124);
+ assert(i.size() == 11);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/introduction.cpp b/src/boost/libs/contract/example/features/introduction.cpp
new file mode 100644
index 00000000..25baf10f
--- /dev/null
+++ b/src/boost/libs/contract/example/features/introduction.cpp
@@ -0,0 +1,34 @@
+
+// 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 <limits>
+#include <cassert>
+
+//[introduction
+#include <boost/contract.hpp>
+
+void inc(int& x) {
+ boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x); // Old value.
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max()); // Line 17.
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(x == *old_x + 1); // Line 20.
+ })
+ ;
+
+ ++x; // Function body.
+}
+//]
+
+int main() {
+ int x = 10;
+ inc(x);
+ assert(x == 11);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/introduction_comments.cpp b/src/boost/libs/contract/example/features/introduction_comments.cpp
new file mode 100644
index 00000000..3eba12f8
--- /dev/null
+++ b/src/boost/libs/contract/example/features/introduction_comments.cpp
@@ -0,0 +1,24 @@
+
+// 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 <cassert>
+
+//[introduction_comments
+void inc(int& x)
+ // Precondition: x < std::numeric_limit<int>::max()
+ // Postcondition: x == oldof(x) + 1
+{
+ ++x; // Function body.
+}
+//]
+
+int main() {
+ int x = 10;
+ inc(x);
+ assert(x == 11);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/introduction_public.cpp b/src/boost/libs/contract/example/features/introduction_public.cpp
new file mode 100644
index 00000000..2206bcab
--- /dev/null
+++ b/src/boost/libs/contract/example/features/introduction_public.cpp
@@ -0,0 +1,89 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <cassert>
+
+template<typename T>
+class pushable { // Somewhat arbitrary base (used just to show subcontracting).
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(capacity() <= max_size());
+ }
+
+ virtual void push_back(T const& value,
+ boost::contract::virtual_* v = 0) = 0; // Pure virtual function.
+
+protected:
+ virtual unsigned capacity() const = 0;
+ virtual unsigned max_size() const = 0;
+};
+
+template<typename T> // Contract for pure virtual function.
+void pushable<T>::push_back(T const& value, boost::contract::virtual_* v) {
+ boost::contract::old_ptr<unsigned> old_capacity =
+ BOOST_CONTRACT_OLDOF(v, capacity());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() < max_size());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() >= *old_capacity);
+ })
+ ;
+ assert(false); // Shall never execute this body.
+}
+
+//[introduction_public
+template<typename T>
+class vector
+ #define BASES public pushable<T>
+ : BASES
+{
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // For subcontracting.
+ #undef BASES
+
+ void invariant() const { // Checked in AND with base class invariants.
+ BOOST_CONTRACT_ASSERT(size() <= capacity());
+ }
+
+ virtual void push_back(T const& value,
+ boost::contract::virtual_* v = 0) /* override */ { // For virtuals.
+ boost::contract::old_ptr<unsigned> old_size =
+ BOOST_CONTRACT_OLDOF(v, size()); // Old values for virtuals.
+ boost::contract::check c = boost::contract::public_function< // For overrides.
+ override_push_back>(v, &vector::push_back, this, value)
+ .precondition([&] { // Checked in OR with base preconditions.
+ BOOST_CONTRACT_ASSERT(size() < max_size());
+ })
+ .postcondition([&] { // Checked in AND with base postconditions.
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ })
+ ;
+
+ vect_.push_back(value);
+ }
+ BOOST_CONTRACT_OVERRIDE(push_back) // Define `override_push_back` above.
+
+ // Could program contracts for those as well.
+ unsigned size() const { return vect_.size(); }
+ unsigned max_size() const { return vect_.max_size(); }
+ unsigned capacity() const { return vect_.capacity(); }
+
+private:
+ std::vector<T> vect_;
+};
+//]
+
+int main() {
+ vector<int> vect;
+ vect.push_back(123);
+ assert(vect.size() == 1);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/lambda.cpp b/src/boost/libs/contract/example/features/lambda.cpp
new file mode 100644
index 00000000..6eb99980
--- /dev/null
+++ b/src/boost/libs/contract/example/features/lambda.cpp
@@ -0,0 +1,43 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <algorithm>
+#include <limits>
+
+int main() {
+ std::vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ v.push_back(3);
+
+ //[lambda
+ int total = 0;
+ std::for_each(v.cbegin(), v.cend(),
+ // Contract for a lambda function.
+ [&total] (int const x) {
+ boost::contract::old_ptr<int> old_total =
+ BOOST_CONTRACT_OLDOF(total);
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(
+ total < std::numeric_limits<int>::max() - x);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(total == *old_total + x);
+ })
+ ;
+
+ total += x; // Lambda function body.
+ }
+ );
+ //]
+
+ assert(total == 6);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/loop.cpp b/src/boost/libs/contract/example/features/loop.cpp
new file mode 100644
index 00000000..1d8acdd7
--- /dev/null
+++ b/src/boost/libs/contract/example/features/loop.cpp
@@ -0,0 +1,40 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <algorithm>
+#include <limits>
+
+int main() {
+ std::vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ v.push_back(3);
+
+ //[loop
+ int total = 0;
+ // Contract for a for-loop (same for while- and all other loops).
+ for(std::vector<int>::const_iterator i = v.begin(); i != v.end(); ++i) {
+ boost::contract::old_ptr<int> old_total = BOOST_CONTRACT_OLDOF(total);
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(
+ total < std::numeric_limits<int>::max() - *i);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(total == *old_total + *i);
+ })
+ ;
+
+ total += *i; // For-loop body.
+ }
+ //]
+
+ assert(total == 6);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/move.cpp b/src/boost/libs/contract/example/features/move.cpp
new file mode 100644
index 00000000..de54d16a
--- /dev/null
+++ b/src/boost/libs/contract/example/features/move.cpp
@@ -0,0 +1,201 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <utility>
+#include <cassert>
+
+//[move
+class circular_buffer :
+ private boost::contract::constructor_precondition<circular_buffer> {
+public:
+ void invariant() const {
+ if(!moved()) { // Do not check (some) invariants for moved-from objects.
+ BOOST_CONTRACT_ASSERT(index() < size());
+ }
+ // More invariants here that hold also for moved-from objects (e.g.,
+ // all assertions necessary to successfully destroy moved-from objects).
+ }
+
+ // Move constructor.
+ circular_buffer(circular_buffer&& other) :
+ boost::contract::constructor_precondition<circular_buffer>([&] {
+ BOOST_CONTRACT_ASSERT(!other.moved());
+ })
+ {
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(!moved());
+ BOOST_CONTRACT_ASSERT(other.moved());
+ })
+ ;
+
+ move(std::forward<circular_buffer>(other));
+ }
+
+ // Move assignment.
+ circular_buffer& operator=(circular_buffer&& other) {
+ // Moved-from can be (move) assigned (so no pre `!moved()` here).
+ boost::contract::check c = boost::contract::public_function(this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(!other.moved());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(!moved());
+ BOOST_CONTRACT_ASSERT(other.moved());
+ })
+ ;
+
+ return move(std::forward<circular_buffer>(other));
+ }
+
+ ~circular_buffer() {
+ // Moved-from can always be destroyed (in fact no preconditions).
+ boost::contract::check c = boost::contract::destructor(this);
+ }
+
+ bool moved() const {
+ boost::contract::check c = boost::contract::public_function(this);
+ return moved_;
+ }
+
+private:
+ bool moved_;
+
+ /* ... */
+//]
+
+public:
+ explicit circular_buffer(std::vector<char> const& data,
+ unsigned start = 0) :
+ boost::contract::constructor_precondition<circular_buffer>([&] {
+ BOOST_CONTRACT_ASSERT(start < data.size());
+ }),
+ moved_(false),
+ data_(data),
+ index_(start)
+ {
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(!moved());
+ })
+ ;
+ }
+
+ // Copy constructor.
+ circular_buffer(circular_buffer const& other) :
+ boost::contract::constructor_precondition<circular_buffer>([&] {
+ BOOST_CONTRACT_ASSERT(!other.moved());
+ })
+ {
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(!moved());
+ })
+ ;
+
+ copy(other);
+ }
+
+ // Copy assignment.
+ circular_buffer& operator=(circular_buffer const& other) {
+ // Moved-from can be (copy) assigned (so no pre `!moved()` here).
+ boost::contract::check c = boost::contract::public_function(this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(!other.moved());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(!moved());
+ })
+ ;
+
+ return copy(other);
+ }
+
+ char read() {
+ boost::contract::check c = boost::contract::public_function(this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(!moved());
+ })
+ ;
+
+ unsigned i = index_++;
+ if(index_ == data_.size()) index_ = 0; // Circular.
+ return data_.at(i);
+ }
+
+private:
+ circular_buffer& copy(circular_buffer const& other) {
+ data_ = other.data_;
+ index_ = other.index_;
+ moved_ = false;
+ return *this;
+ }
+
+ circular_buffer& move(circular_buffer&& other) {
+ data_ = std::move(other.data_);
+ index_ = std::move(other.index_);
+ moved_ = false;
+ other.moved_ = true; // Mark moved-from object.
+ return *this;
+ }
+
+ std::vector<char> data_;
+ unsigned index_;
+
+public:
+ unsigned index() const {
+ boost::contract::check c = boost::contract::public_function(this);
+ return index_;
+ }
+
+ unsigned size() const {
+ boost::contract::check c = boost::contract::public_function(this);
+ return data_.size();
+ }
+};
+
+int main() {
+ struct err {};
+ boost::contract::set_precondition_failure(
+ [] (boost::contract::from) { throw err(); });
+
+ {
+ circular_buffer x({'a', 'b', 'c', 'd'}, 2);
+ assert(x.read() == 'c');
+
+ circular_buffer y1 = x; // Copy constructor.
+ assert(y1.read() == 'd');
+ assert(x.read() == 'd');
+
+ circular_buffer y2({'h'});
+ y2 = x; // Copy assignment.
+ assert(y2.read() == 'a');
+ assert(x.read() == 'a');
+
+ circular_buffer z1 = std::move(x); // Move constructor.
+ assert(z1.read() == 'b');
+ // Calling `x.read()` would fail `!moved()` precondition.
+
+ x = y1; // Moved-from `x` can be copy assigned.
+ assert(x.read() == 'a');
+ assert(y1.read() == 'a');
+
+ circular_buffer z2({'k'});
+ z2 = std::move(x); // Move assignment.
+ assert(z2.read() == 'b');
+ // Calling `x.read()` would fail `!moved()` precondition.
+
+ x = std::move(y2); // Moved-from `x` can be move assigned.
+ assert(x.read() == 'b');
+ // Calling `y2.read()` would fail `!moved()` precondition.
+
+ } // Moved-from `y2` can be destroyed.
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/named_override.cpp b/src/boost/libs/contract/example/features/named_override.cpp
new file mode 100644
index 00000000..9afc5f60
--- /dev/null
+++ b/src/boost/libs/contract/example/features/named_override.cpp
@@ -0,0 +1,104 @@
+
+// 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 <boost/contract.hpp>
+#include <boost/optional.hpp>
+#include <cassert>
+
+//[named_override_pure_virtual_assert_false
+template<typename T>
+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<typename T>
+void generic_unary_pack<T>::_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<typename T>
+T generic_unary_pack<T>::_1(boost::contract::virtual_* v) const {
+ boost::optional<T> result; // Do not assume T has default constructor.
+ boost::contract::check c = boost::contract::public_function(v, result, this)
+ .postcondition([&] (boost::optional<T const&> const& result) {
+ BOOST_CONTRACT_ASSERT(*result == _1());
+ })
+ ;
+
+ assert(false);
+ return *result;
+}
+
+//[named_override
+template<typename T>
+class positive_unary_pack
+ #define BASES public generic_unary_pack<T>
+ : 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<override1>(
+ v,
+ static_cast<void (positive_unary_pack::*)(T const&,
+ boost::contract::virtual_*)>(&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<override1>(
+ v,
+ result,
+ static_cast<T (positive_unary_pack::*)(boost::contract::virtual_*)
+ const>(&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<int> u;
+ u._1(123);
+ assert(u._1() == 123);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/no_lambdas.cpp b/src/boost/libs/contract/example/features/no_lambdas.cpp
new file mode 100644
index 00000000..783adce5
--- /dev/null
+++ b/src/boost/libs/contract/example/features/no_lambdas.cpp
@@ -0,0 +1,92 @@
+
+// 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 "no_lambdas.hpp"
+#include <boost/bind.hpp>
+#include <cassert>
+
+//[no_lambdas_cpp
+iarray::iarray(unsigned max, unsigned count) :
+ boost::contract::constructor_precondition<iarray>(boost::bind(
+ &iarray::constructor_precondition, max, count)),
+ values_(new int[max]), // Member initializations can be here.
+ capacity_(max)
+{
+ boost::contract::old_ptr<int> old_instances;
+ boost::contract::check c = boost::contract::constructor(this)
+ .old(boost::bind(&iarray::constructor_old, boost::ref(old_instances)))
+ .postcondition(boost::bind(
+ &iarray::constructor_postcondition,
+ this,
+ boost::cref(max),
+ boost::cref(count),
+ boost::cref(old_instances)
+ ))
+ ;
+
+ for(unsigned i = 0; i < count; ++i) values_[i] = int();
+ size_ = count;
+ ++instances_;
+}
+
+iarray::~iarray() {
+ boost::contract::old_ptr<int> old_instances;
+ boost::contract::check c = boost::contract::destructor(this)
+ .old(boost::bind(&iarray::destructor_old, this,
+ boost::ref(old_instances)))
+ .postcondition(boost::bind(&iarray::destructor_postcondition,
+ boost::cref(old_instances)))
+ ;
+
+ delete[] values_;
+ --instances_;
+}
+
+void iarray::push_back(int value, boost::contract::virtual_* v) {
+ boost::contract::old_ptr<unsigned> old_size;
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition(boost::bind(&iarray::push_back_precondition, this))
+ .old(boost::bind(&iarray::push_back_old, this, boost::cref(v),
+ boost::ref(old_size)))
+ .postcondition(boost::bind(&iarray::push_back_postcondition, this,
+ boost::cref(old_size)))
+ ;
+
+ values_[size_++] = value;
+}
+
+unsigned iarray::capacity() const {
+ // Check invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return capacity_;
+}
+
+unsigned iarray::size() const {
+ // Check invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return size_;
+}
+
+int iarray::instances() {
+ // Check static invariants.
+ boost::contract::check c = boost::contract::public_function<iarray>();
+ return instances_;
+}
+
+int iarray::instances_ = 0;
+//]
+
+int main() {
+ iarray a(3, 2);
+ assert(a.capacity() == 3);
+ assert(a.size() == 2);
+
+ a.push_back(-123);
+ assert(a.size() == 3);
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/no_lambdas.hpp b/src/boost/libs/contract/example/features/no_lambdas.hpp
new file mode 100644
index 00000000..5f0dbe72
--- /dev/null
+++ b/src/boost/libs/contract/example/features/no_lambdas.hpp
@@ -0,0 +1,77 @@
+
+#ifndef NO_LAMBDAS_HPP_
+#define NO_LAMBDAS_HPP_
+
+// 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 <boost/contract.hpp>
+
+//[no_lambdas_hpp
+class iarray :
+ private boost::contract::constructor_precondition<iarray> {
+public:
+ static void static_invariant() {
+ BOOST_CONTRACT_ASSERT(instances() >= 0);
+ }
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(size() <= capacity());
+ }
+
+ explicit iarray(unsigned max, unsigned count = 0);
+ static void constructor_precondition(unsigned const max,
+ unsigned const count) {
+ BOOST_CONTRACT_ASSERT(count <= max);
+ }
+ static void constructor_old(boost::contract::old_ptr<int>&
+ old_instances) {
+ old_instances = BOOST_CONTRACT_OLDOF(instances());
+ }
+ void constructor_postcondition(unsigned const max, unsigned const count,
+ boost::contract::old_ptr<int> const old_instances) const {
+ BOOST_CONTRACT_ASSERT(capacity() == max);
+ BOOST_CONTRACT_ASSERT(size() == count);
+ BOOST_CONTRACT_ASSERT(instances() == *old_instances + 1);
+ }
+
+ virtual ~iarray();
+ void destructor_old(boost::contract::old_ptr<int>& old_instances)
+ const {
+ old_instances = BOOST_CONTRACT_OLDOF(instances());
+ }
+ static void destructor_postcondition(boost::contract::old_ptr<int> const
+ old_instances) {
+ BOOST_CONTRACT_ASSERT(instances() == *old_instances - 1);
+ }
+
+ virtual void push_back(int value, boost::contract::virtual_* v = 0);
+ void push_back_precondition() const {
+ BOOST_CONTRACT_ASSERT(size() < capacity());
+ }
+ void push_back_old(boost::contract::virtual_* v,
+ boost::contract::old_ptr<unsigned>& old_size) const {
+ old_size = BOOST_CONTRACT_OLDOF(v, size());
+ }
+ void push_back_postcondition(
+ boost::contract::old_ptr<unsigned> const old_size) const {
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ }
+
+ unsigned capacity() const;
+ unsigned size() const;
+
+ static int instances();
+
+private:
+ int* values_;
+ unsigned capacity_;
+ unsigned size_;
+ static int instances_;
+};
+//]
+
+#endif // #include guard
+
diff --git a/src/boost/libs/contract/example/features/no_lambdas_local_func.cpp b/src/boost/libs/contract/example/features/no_lambdas_local_func.cpp
new file mode 100644
index 00000000..801e1639
--- /dev/null
+++ b/src/boost/libs/contract/example/features/no_lambdas_local_func.cpp
@@ -0,0 +1,119 @@
+
+// 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 <boost/contract.hpp>
+#include <boost/local_function.hpp>
+#include <boost/bind.hpp>
+#include <cassert>
+
+class iarray :
+ private boost::contract::constructor_precondition<iarray> {
+public:
+ static void static_invariant() {
+ BOOST_CONTRACT_ASSERT(instances() >= 0);
+ }
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(size() <= capacity());
+ }
+
+ static void constructor_pre(unsigned const max, unsigned const count) {
+ BOOST_CONTRACT_ASSERT(count <= max);
+ }
+ explicit iarray(unsigned max, unsigned count = 0) :
+ boost::contract::constructor_precondition<iarray>(boost::bind(
+ &iarray::constructor_pre, max, count)),
+ values_(new int[max]),
+ capacity_(max)
+ {
+ boost::contract::old_ptr<int> old_instances;
+ void BOOST_LOCAL_FUNCTION(bind& old_instances) {
+ old_instances = BOOST_CONTRACT_OLDOF(iarray::instances());
+ } BOOST_LOCAL_FUNCTION_NAME(old)
+ void BOOST_LOCAL_FUNCTION(const bind this_, const bind& count,
+ const bind& old_instances) {
+ BOOST_CONTRACT_ASSERT(this_->size() == count);
+ BOOST_CONTRACT_ASSERT(this_->instances() == *old_instances + 1);
+ } BOOST_LOCAL_FUNCTION_NAME(post)
+ boost::contract::check c = boost::contract::constructor(this)
+ .old(old).postcondition(post);
+
+ for(unsigned i = 0; i < count; ++i) values_[i] = int();
+ size_ = count;
+ ++instances_;
+ }
+
+ virtual ~iarray() {
+ boost::contract::old_ptr<int> old_instances;
+ void BOOST_LOCAL_FUNCTION(const bind this_, bind& old_instances) {
+ old_instances = BOOST_CONTRACT_OLDOF(this_->instances());
+ } BOOST_LOCAL_FUNCTION_NAME(old)
+ void BOOST_LOCAL_FUNCTION(const bind& old_instances) {
+ BOOST_CONTRACT_ASSERT(iarray::instances() == *old_instances - 1);
+ } BOOST_LOCAL_FUNCTION_NAME(post)
+ boost::contract::check c = boost::contract::destructor(this)
+ .old(old).postcondition(post);
+
+ delete[] values_;
+ --instances_;
+ }
+
+ virtual void push_back(int value, boost::contract::virtual_* v = 0) {
+ boost::contract::old_ptr<unsigned> old_size;
+ void BOOST_LOCAL_FUNCTION(const bind this_) {
+ BOOST_CONTRACT_ASSERT(this_->size() < this_->capacity());
+ } BOOST_LOCAL_FUNCTION_NAME(pre)
+ void BOOST_LOCAL_FUNCTION(const bind v, const bind this_,
+ bind& old_size) {
+ old_size = BOOST_CONTRACT_OLDOF(v, this_->size());
+ } BOOST_LOCAL_FUNCTION_NAME(old)
+ void BOOST_LOCAL_FUNCTION(const bind this_, const bind& old_size) {
+ BOOST_CONTRACT_ASSERT(this_->size() == *old_size + 1);
+ } BOOST_LOCAL_FUNCTION_NAME(post)
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition(pre).old(old).postcondition(post);
+
+ values_[size_++] = value;
+ }
+
+ unsigned capacity() const {
+ // Check invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return capacity_;
+ }
+
+ unsigned size() const {
+ // Check invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return size_;
+ }
+
+ static int instances() {
+ // Check static invariants.
+ boost::contract::check c = boost::contract::public_function<iarray>();
+ return instances_;
+ }
+
+private:
+ int* values_;
+ unsigned capacity_;
+ unsigned size_;
+ static int instances_;
+};
+
+int iarray::instances_ = 0;
+
+int main() {
+ iarray a(3, 2);
+ assert(a.capacity() == 3);
+ assert(a.size() == 2);
+
+ a.push_back('x');
+ assert(a.size() == 3);
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/non_member.cpp b/src/boost/libs/contract/example/features/non_member.cpp
new file mode 100644
index 00000000..12224154
--- /dev/null
+++ b/src/boost/libs/contract/example/features/non_member.cpp
@@ -0,0 +1,40 @@
+
+// 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 <limits>
+#include <cassert>
+
+//[non_member
+#include <boost/contract.hpp>
+
+// Contract for a non-member function.
+int inc(int& x) {
+ int result;
+ boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x);
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(x < std::numeric_limits<int>::max());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(x == *old_x + 1);
+ BOOST_CONTRACT_ASSERT(result == *old_x);
+ })
+ .except([&] {
+ BOOST_CONTRACT_ASSERT(x == *old_x);
+ })
+ ;
+
+ return result = x++; // Function body.
+}
+//]
+
+int main() {
+ int x = std::numeric_limits<int>::max() - 1;
+ assert(inc(x) == std::numeric_limits<int>::max() - 1);
+ assert(x == std::numeric_limits<int>::max());
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/old.cpp b/src/boost/libs/contract/example/features/old.cpp
new file mode 100644
index 00000000..bdf8b8c6
--- /dev/null
+++ b/src/boost/libs/contract/example/features/old.cpp
@@ -0,0 +1,41 @@
+
+// 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 <boost/contract.hpp>
+#include <string>
+#include <cassert>
+
+//[old
+char replace(std::string& s, unsigned index, char x) {
+ char result;
+ boost::contract::old_ptr<char> old_char; // Null, old value copied later...
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(index < s.size());
+ })
+ .old([&] { // ...after preconditions (and invariants) checked.
+ old_char = BOOST_CONTRACT_OLDOF(s[index]);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(s[index] == x);
+ BOOST_CONTRACT_ASSERT(result == *old_char);
+ })
+ ;
+
+ result = s[index];
+ s[index] = x;
+ return result;
+}
+//]
+
+int main() {
+ std::string s = "abc";
+ char r = replace(s, 1, '_');
+ assert(s == "a_c");
+ assert(r == 'b');
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/old_if_copyable.cpp b/src/boost/libs/contract/example/features/old_if_copyable.cpp
new file mode 100644
index 00000000..8cf1acc7
--- /dev/null
+++ b/src/boost/libs/contract/example/features/old_if_copyable.cpp
@@ -0,0 +1,133 @@
+
+// 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 <boost/contract.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/noncopyable.hpp>
+#include <cassert>
+
+//[old_if_copyable_offset
+template<typename T> // T might or might not be copyable.
+void offset(T& x, int count) {
+ // No compiler error if T has no copy constructor...
+ boost::contract::old_ptr_if_copyable<T> old_x = BOOST_CONTRACT_OLDOF(x);
+ boost::contract::check c = boost::contract::function()
+ .postcondition([&] {
+ // ...but old value null if T has no copy constructor.
+ if(old_x) BOOST_CONTRACT_ASSERT(x == *old_x + count);
+ })
+ ;
+
+ x += count;
+}
+//]
+
+//[old_if_copyable_w_decl
+// Copyable type but...
+class w {
+public:
+ w(w const&) { /* Some very expensive copy operation here... */ }
+
+ /* ... */
+//]
+ w() : num_(0) {}
+ int operator+(int i) const { return num_ + i; }
+ w& operator+=(int i) { num_ += i; return *this; }
+ bool operator==(int i) const { return long(num_) == i; }
+private:
+ unsigned long num_;
+};
+
+//[old_if_copyable_w_spec
+// ...never copy old values for type `w` (because its copy is too expensive).
+namespace boost { namespace contract {
+ template<>
+ struct is_old_value_copyable<w> : boost::false_type {};
+} }
+//]
+
+//[old_if_copyable_p_decl
+// Non-copyable type but...
+class p : private boost::noncopyable {
+ int* num_;
+
+ friend struct boost::contract::old_value_copy<p>;
+
+ /* ... */
+//]
+public:
+ p() : num_(new int(0)) {}
+ ~p() { delete num_; }
+ int operator+(int i) const { return *num_ + i; }
+ p& operator+=(int i) { *num_ += i; return *this; }
+ bool operator==(int i) const { return *num_ == i; }
+};
+
+//[old_if_copyable_p_spec
+// ...still copy old values for type `p` (using a deep copy).
+namespace boost { namespace contract {
+ template<>
+ struct old_value_copy<p> {
+ explicit old_value_copy(p const& old) {
+ *old_.num_ = *old.num_; // Deep copy pointed value.
+ }
+
+ p const& old() const { return old_; }
+
+ private:
+ p old_;
+ };
+
+ template<>
+ struct is_old_value_copyable<p> : boost::true_type {};
+} }
+//]
+
+//[old_if_copyable_n_decl
+class n { // Do not want to use boost::noncopyable but...
+ int num_;
+
+private:
+ n(n const&); // ...unimplemented private copy constructor (so non-copyable).
+
+ /* ... */
+//]
+
+public:
+ n() : num_(0) {}
+ int operator+(int i) const { return num_ + i; }
+ n& operator+=(int i) { num_ += i; return *this; }
+ bool operator==(int i) const { return num_ == i; }
+};
+
+//[old_if_copyable_n_spec
+// Specialize `boost::is_copy_constructible` (no need for this on C++11).
+namespace boost { namespace contract {
+ template<>
+ struct is_old_value_copyable<n> : boost::false_type {};
+} }
+//]
+
+int main() {
+ int i = 0; // Copy constructor, copy and check old values.
+ offset(i, 3);
+ assert(i == 3);
+
+ w j; // Expensive copy constructor, so never copy or check old values.
+ offset(j, 3);
+ assert(j == 3);
+
+ p k; // No copy constructor, but still copy and check old values.
+ offset(k, 3);
+ assert(k == 3);
+
+ n h; // No copy constructor, no compiler error but no old value checks.
+ offset(h, 3);
+ assert(h == 3);
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/old_no_macro.cpp b/src/boost/libs/contract/example/features/old_no_macro.cpp
new file mode 100644
index 00000000..29c06a68
--- /dev/null
+++ b/src/boost/libs/contract/example/features/old_no_macro.cpp
@@ -0,0 +1,46 @@
+
+// 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 <boost/contract.hpp>
+#include <cassert>
+#include <vector>
+
+//[old_no_macro
+template<typename T>
+class vector {
+public:
+ virtual void push_back(T const& value, boost::contract::virtual_* v = 0) {
+ // Program old value instead of using `OLD(size())` macro.
+ boost::contract::old_ptr<unsigned> old_size =
+ boost::contract::make_old(v, boost::contract::copy_old(v) ?
+ size() : boost::contract::null_old())
+ ;
+
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ })
+ ;
+
+ vect_.push_back(value);
+ }
+
+ /* ... */
+//]
+
+ unsigned size() const { return vect_.size(); }
+
+private:
+ std::vector<T> vect_;
+};
+
+int main() {
+ vector<int> vect;
+ vect.push_back(123);
+ assert(vect.size() == 1);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/optional_result.cpp b/src/boost/libs/contract/example/features/optional_result.cpp
new file mode 100644
index 00000000..330c780d
--- /dev/null
+++ b/src/boost/libs/contract/example/features/optional_result.cpp
@@ -0,0 +1,41 @@
+
+// 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 <boost/contract.hpp>
+#include <boost/optional.hpp>
+#include <vector>
+#include <cassert>
+
+//[optional_result
+template<unsigned Index, typename T>
+T& get(std::vector<T>& vect) {
+ boost::optional<T&> result; // Result not initialized here...
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(Index < vect.size());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(*result == vect[Index]);
+ })
+ ;
+
+ // Function body (executed after preconditions checked).
+ return *(result = vect[Index]); // ...result initialized here instead.
+}
+//]
+
+int main() {
+ std::vector<int> v;
+ v.push_back(123);
+ v.push_back(456);
+ v.push_back(789);
+ int& x = get<1>(v);
+ assert(x == 456);
+ x = -456;
+ assert(v[1] == -456);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/optional_result_virtual.cpp b/src/boost/libs/contract/example/features/optional_result_virtual.cpp
new file mode 100644
index 00000000..724a1849
--- /dev/null
+++ b/src/boost/libs/contract/example/features/optional_result_virtual.cpp
@@ -0,0 +1,88 @@
+
+// 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 <boost/contract.hpp>
+#include <boost/optional.hpp>
+#include <vector>
+#include <cassert>
+
+template<typename T>
+class accessible {
+public:
+ virtual T& at(unsigned index, boost::contract::virtual_* v = 0) = 0;
+
+ // Could program class invariants and contracts for following too.
+ virtual T const& operator[](unsigned index) const = 0;
+ virtual unsigned size() const = 0;
+};
+
+//[optional_result_virtual
+template<typename T>
+T& accessible<T>::at(unsigned index, boost::contract::virtual_* v) {
+ boost::optional<T&> result;
+ // Pass `result` right after `v`...
+ boost::contract::check c = boost::contract::public_function(v, result, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(index < size());
+ })
+ // ...plus postconditions take `result` as a parameter (not capture).
+ .postcondition([&] (boost::optional<T const&> const& result) {
+ BOOST_CONTRACT_ASSERT(*result == operator[](index));
+ })
+ ;
+
+ assert(false);
+ return *result;
+}
+//]
+
+template<typename T>
+class vector
+ #define BASES public accessible<T>
+ : BASES
+{
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+
+ T& at(unsigned index, boost::contract::virtual_* v = 0) /* override */ {
+ boost::optional<T&> result;
+ // Pass `result` right after `v`...
+ boost::contract::check c = boost::contract::public_function<
+ override_at>(v, result, &vector::at, this, index)
+ // ...plus postconditions take `result` as parameter (not capture).
+ .postcondition([&] (boost::optional<T const&> const& result) {
+ if(index == 0) BOOST_CONTRACT_ASSERT(*result == front());
+ })
+ ;
+
+ return *(result = vect_[index]);
+ }
+
+ // Could program class invariants and contracts for following too.
+ T const& operator[](unsigned index) const { return vect_[index]; }
+ unsigned size() const { return vect_.size(); }
+ T const& front() const { return vect_.front(); }
+ void push_back(T const& value) { vect_.push_back(value); }
+
+ BOOST_CONTRACT_OVERRIDE(at)
+
+private:
+ std::vector<T> vect_;
+};
+
+int main() {
+ vector<int> v;
+ v.push_back(123);
+ v.push_back(456);
+ v.push_back(789);
+ int& x = v.at(1);
+ assert(x == 456);
+ x = -456;
+ assert(v.at(1) == -456);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/overload.cpp b/src/boost/libs/contract/example/features/overload.cpp
new file mode 100644
index 00000000..2feab347
--- /dev/null
+++ b/src/boost/libs/contract/example/features/overload.cpp
@@ -0,0 +1,202 @@
+
+// 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 <boost/contract.hpp>
+#include <boost/optional.hpp>
+#include <string>
+#include <sstream>
+#include <cassert>
+
+class lines {
+public:
+ virtual std::string str(boost::contract::virtual_* v = 0) const = 0;
+ virtual std::string& str(boost::contract::virtual_* v = 0) = 0;
+
+ virtual void put(std::string const& x,
+ boost::contract::virtual_* v = 0) = 0;
+
+ virtual void put(char x, boost::contract::virtual_* v = 0) = 0;
+
+ virtual void put(int x, bool tab = false,
+ boost::contract::virtual_* v = 0) = 0;
+};
+
+std::string lines::str(boost::contract::virtual_* v) const {
+ std::string result;
+ boost::contract::check c = boost::contract::public_function(v, result, this)
+ .postcondition([&] (std::string const& result) {
+ if(result != "") BOOST_CONTRACT_ASSERT(*result.rbegin() == '\n');
+ })
+ ;
+ assert(false);
+ return result;
+}
+
+std::string& lines::str(boost::contract::virtual_* v) {
+ boost::optional<std::string&> result;
+ boost::contract::check c = boost::contract::public_function(v, result, this)
+ .postcondition([&] (boost::optional<std::string const&> const& result) {
+ if(*result != "") BOOST_CONTRACT_ASSERT(*result->rbegin() == '\n');
+ })
+ ;
+ assert(false);
+ return *result;
+}
+
+void lines::put(std::string const& x, boost::contract::virtual_* v) {
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(*x.rbegin() != '\n');
+ })
+ ;
+ assert(false);
+}
+
+void lines::put(char x, boost::contract::virtual_* v) {
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(x != '\n');
+ })
+ ;
+ assert(false);
+}
+
+void lines::put(int x, bool tab,
+ boost::contract::virtual_* v) {
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(x >= 0);
+ })
+ ;
+ assert(false);
+}
+
+//[overload
+class string_lines
+ #define BASES public lines
+ : BASES
+{
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+
+ BOOST_CONTRACT_OVERRIDES(str) // Invoked only once for all `str` overloads.
+
+ std::string str(boost::contract::virtual_* v = 0) const /* override */ {
+ std::string result;
+ boost::contract::check c = boost::contract::public_function<
+ override_str>(
+ v, result,
+ // `static_cast` resolves overloaded function pointer ambiguities.
+ static_cast<std::string (string_lines::*)(
+ boost::contract::virtual_*) const>(&string_lines::str),
+ this
+ );
+
+ return result = str_;
+ }
+
+ // Overload on (absence of) `const` qualifier.
+ std::string& str(boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::check c = boost::contract::public_function<
+ override_str>(
+ v, str_,
+ // `static_cast` resolves overloaded function pointer ambiguities.
+ static_cast<std::string& (string_lines::*)(
+ boost::contract::virtual_*)>(&string_lines::str),
+ this
+ );
+
+ return str_;
+ }
+
+ BOOST_CONTRACT_OVERRIDES(put) // Invoked only once for all `put` overloads.
+
+ void put(std::string const& x,
+ boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::old_ptr<std::string> old_str =
+ BOOST_CONTRACT_OLDOF(v, str());
+ boost::contract::check c = boost::contract::public_function<
+ override_put>(
+ v,
+ // `static_cast` resolves overloaded function pointer ambiguities.
+ static_cast<void (string_lines::*)(std::string const&,
+ boost::contract::virtual_*)>(&string_lines::put),
+ this, x
+ )
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(str() == *old_str + x + '\n');
+ })
+ ;
+
+ str_ = str_ + x + '\n';
+ }
+
+ // Overload on argument type.
+ void put(char x, boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::old_ptr<std::string> old_str =
+ BOOST_CONTRACT_OLDOF(v, str());
+ boost::contract::check c = boost::contract::public_function<
+ override_put>(
+ v,
+ // `static_cast` resolves overloaded function pointer ambiguities.
+ static_cast<void (string_lines::*)(char,
+ boost::contract::virtual_*)>(&string_lines::put),
+ this, x
+ )
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(str() == *old_str + x + '\n');
+ })
+ ;
+
+ str_ = str_ + x + '\n';
+ }
+
+ // Overload on argument type and arity (also with default parameter).
+ void put(int x, bool tab = false,
+ boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::old_ptr<std::string> old_str =
+ BOOST_CONTRACT_OLDOF(v, str());
+ boost::contract::check c = boost::contract::public_function<
+ override_put>(
+ v,
+ // `static_cast` resolves overloaded function pointer ambiguities.
+ static_cast<void (string_lines::*)(int, bool,
+ boost::contract::virtual_*)>(&string_lines::put),
+ this, x, tab
+ )
+ .postcondition([&] {
+ std::ostringstream s;
+ s << x;
+ BOOST_CONTRACT_ASSERT(
+ str() == *old_str + (tab ? "\t" : "") + s.str() + '\n');
+ })
+ ;
+
+ std::ostringstream s;
+ s << str_ << (tab ? "\t" : "") << x << '\n';
+ str_ = s.str();
+ }
+
+private:
+ std::string str_;
+};
+//]
+
+int main() {
+ string_lines s;
+ s.put("abc");
+ assert(s.str() == "abc\n");
+ s.put('x');
+ assert(s.str() == "abc\nx\n");
+ s.put(10);
+ assert(s.str() == "abc\nx\n10\n");
+ s.put(20, true);
+ lines const& l = s;
+ assert(l.str() == "abc\nx\n10\n\t20\n");
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/private_protected.cpp b/src/boost/libs/contract/example/features/private_protected.cpp
new file mode 100644
index 00000000..7651a925
--- /dev/null
+++ b/src/boost/libs/contract/example/features/private_protected.cpp
@@ -0,0 +1,77 @@
+
+// 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 <boost/contract.hpp>
+#include <limits>
+#include <cassert>
+
+//[private_protected
+class counter {
+protected: // Protected functions use `function()` (like non-members).
+ void set(int n) {
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(n <= 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == n);
+ })
+ ;
+
+ n_ = n;
+ }
+
+private: // Private functions use `function()` (like non-members).
+ void dec() {
+ boost::contract::old_ptr<int> old_get = BOOST_CONTRACT_OLDOF(get());
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(
+ get() + 1 >= std::numeric_limits<int>::min());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == *old_get - 1);
+ })
+ ;
+
+ set(get() - 1);
+ }
+
+ int n_;
+
+ /* ... */
+//]
+
+public:
+ int get() const {
+ int result;
+ boost::contract::check c = boost::contract::public_function(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(result <= 0);
+ BOOST_CONTRACT_ASSERT(result == n_);
+ })
+ ;
+
+ return result = n_;
+ }
+
+ counter() : n_(0) {} // Should contract constructor and destructor too.
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(get() <= 0);
+ }
+
+ friend int main();
+};
+
+int main() {
+ counter cnt;
+ assert(cnt.get() == 0);
+ cnt.dec();
+ assert(cnt.get() == -1);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/private_protected_virtual.cpp b/src/boost/libs/contract/example/features/private_protected_virtual.cpp
new file mode 100644
index 00000000..534da508
--- /dev/null
+++ b/src/boost/libs/contract/example/features/private_protected_virtual.cpp
@@ -0,0 +1,145 @@
+
+// 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 <boost/contract.hpp>
+#include <limits>
+#include <cassert>
+
+//[private_protected_virtual_counter
+class counter {
+ // Virtual private and protected functions still declare extra
+ // `virtual_* = 0` parameter (otherwise they cannot be overridden), but...
+protected:
+ virtual void set(int n, boost::contract::virtual_* = 0) {
+ boost::contract::check c = boost::contract::function() // ...no `v`.
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(n <= 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == n);
+ })
+ ;
+
+ n_ = n;
+ }
+
+private:
+ virtual void dec(boost::contract::virtual_* = 0) {
+ boost::contract::old_ptr<int> old_get = BOOST_CONTRACT_OLDOF(get()); // ...no `v`.
+ boost::contract::check c = boost::contract::function() // ...no `v`.
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(
+ get() + 1 >= std::numeric_limits<int>::min());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == *old_get - 1);
+ })
+ ;
+
+ set(get() - 1);
+ }
+
+ int n_;
+
+ /* ... */
+//]
+
+public:
+ virtual int get(boost::contract::virtual_* v = 0) const {
+ int result;
+ boost::contract::check c = boost::contract::public_function(
+ v, result, this)
+ .postcondition([&] (int const result) {
+ BOOST_CONTRACT_ASSERT(result <= 0);
+ BOOST_CONTRACT_ASSERT(result == n_);
+ })
+ ;
+
+ return result = n_;
+ }
+
+ counter() : n_(0) {} // Should contract constructor and destructor too.
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(get() <= 0);
+ }
+
+ friend int main();
+};
+
+//[private_protected_virtual_counter10
+class counter10
+ #define BASES public counter
+ : BASES
+{
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+
+ // Overriding from non-public members so no subcontracting, no override_...
+
+ virtual void set(int n, boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(n % 10 == 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == n);
+ })
+ ;
+
+ counter::set(n);
+ }
+
+ virtual void dec(boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::old_ptr<int> old_get = BOOST_CONTRACT_OLDOF(v, get());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(
+ get() + 10 >= std::numeric_limits<int>::min());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == *old_get - 10);
+ })
+ ;
+
+ set(get() - 10);
+ }
+
+ /* ... */
+//]
+
+ virtual int get(boost::contract::virtual_* v = 0) const {
+ int result;
+ boost::contract::check c = boost::contract::public_function<
+ override_get>(v, result, &counter10::get, this);
+
+ return result = counter::get();
+ }
+ BOOST_CONTRACT_OVERRIDE(get)
+
+ // Should contract default constructor and destructor too.
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(get() % 10 == 0);
+ }
+};
+
+int main() {
+ counter cnt;
+ assert(cnt.get() == 0);
+ cnt.dec();
+ assert(cnt.get() == -1);
+
+ counter10 cnt10;
+ counter& b = cnt10; // Polymorphic calls.
+ assert(b.get() == 0);
+ b.dec();
+ assert(b.get() == -10);
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/private_protected_virtual_multi.cpp b/src/boost/libs/contract/example/features/private_protected_virtual_multi.cpp
new file mode 100644
index 00000000..2ab875fb
--- /dev/null
+++ b/src/boost/libs/contract/example/features/private_protected_virtual_multi.cpp
@@ -0,0 +1,209 @@
+
+// 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 <boost/config.hpp>
+#ifdef BOOST_MSVC
+
+// WARNING: MSVC (at least up to VS 2015) gives a compile-time error if SFINAE
+// cannot introspect a member because of its private or protected access level.
+// That is incorrect, SFINAE should fail in these cases without generating
+// compile-time errors like GCC and CLang do. Therefore, currently it is not
+// possible to override a member that is public in one base but private or
+// protected in other base using this library on MSVC (that can be done instead
+// using this library on GCC or CLang).
+int main() { return 0; } // Trivial program for MSVC.
+
+#else
+
+#include <boost/contract.hpp>
+#include <limits>
+#include <cassert>
+
+class counter {
+ // Virtual private and protected functions still declare extra
+ // `virtual_* = 0` parameter (otherwise they cannot be overridden).
+protected:
+ virtual void set(int n, boost::contract::virtual_* = 0) {
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(n <= 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == n);
+ })
+ ;
+
+ n_ = n;
+ }
+
+private:
+ virtual void dec(boost::contract::virtual_* = 0) {
+ boost::contract::old_ptr<int> old_get = BOOST_CONTRACT_OLDOF(get());
+ boost::contract::check c = boost::contract::function()
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(
+ get() + 1 >= std::numeric_limits<int>::min());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == *old_get - 1);
+ })
+ ;
+
+ set(get() - 1);
+ }
+
+ int n_;
+
+public:
+ virtual int get(boost::contract::virtual_* v = 0) const {
+ int result;
+ boost::contract::check c = boost::contract::public_function(
+ v, result, this)
+ .postcondition([&] (int const result) {
+ BOOST_CONTRACT_ASSERT(result <= 0);
+ BOOST_CONTRACT_ASSERT(result == n_);
+ })
+ ;
+
+ return result = n_;
+ }
+
+ counter() : n_(0) {} // Should contract constructor and destructor too.
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(get() <= 0);
+ }
+
+ friend int main();
+};
+
+//[private_protected_virtual_multi_countable
+class countable {
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(get() <= 0);
+ }
+
+ virtual void dec(boost::contract::virtual_* v = 0) = 0;
+ virtual void set(int n, boost::contract::virtual_* v = 0) = 0;
+ virtual int get(boost::contract::virtual_* v = 0) const = 0;
+};
+
+/* ... */
+//]
+
+void countable::dec(boost::contract::virtual_* v) {
+ boost::contract::old_ptr<int> old_get = BOOST_CONTRACT_OLDOF(v, get());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(get() > std::numeric_limits<int>::min());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() < *old_get);
+ })
+ ;
+ assert(false); // Never executed by this library.
+}
+
+void countable::set(int n, boost::contract::virtual_* v) {
+ boost::contract::check c = boost::contract::public_function(
+ v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(n <= 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == n);
+ })
+ ;
+ assert(false); // Never executed by this library.
+}
+
+int countable::get(boost::contract::virtual_* v) const {
+ int result;
+ boost::contract::check c = boost::contract::public_function(
+ v, result, this);
+ assert(false); // Never executed by this library.
+}
+
+//[private_protected_virtual_multi_counter10
+class counter10
+ #define BASES public countable, public counter // Multiple inheritance.
+ : BASES
+{
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+
+ // Overriding from public members from `countable` so use `override_...`.
+
+ virtual void set(int n, boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::check c = boost::contract::public_function<
+ override_set>(v, &counter10::set, this, n)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(n % 10 == 0);
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == n);
+ })
+ ;
+
+ counter::set(n);
+ }
+
+ virtual void dec(boost::contract::virtual_* v = 0) /* override */ {
+ boost::contract::old_ptr<int> old_get = BOOST_CONTRACT_OLDOF(v, get());
+ boost::contract::check c = boost::contract::public_function<
+ override_dec>(v, &counter10::dec, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(
+ get() + 10 >= std::numeric_limits<int>::min());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(get() == *old_get - 10);
+ })
+ ;
+
+ set(get() - 10);
+ }
+
+ BOOST_CONTRACT_OVERRIDES(set, dec)
+
+ /* ... */
+//]
+
+ virtual int get(boost::contract::virtual_* v = 0) const {
+ int result;
+ boost::contract::check c = boost::contract::public_function<
+ override_get>(v, result, &counter10::get, this);
+
+ return result = counter::get();
+ }
+ BOOST_CONTRACT_OVERRIDE(get)
+
+ // Should contract default constructor and destructor too.
+
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(get() % 10 == 0);
+ }
+};
+
+int main() {
+ counter cnt;
+ assert(cnt.get() == 0);
+ cnt.dec();
+ assert(cnt.get() == -1);
+
+ counter10 cnt10;
+ countable& b = cnt10; // Polymorphic calls.
+ assert(b.get() == 0);
+ b.dec();
+ assert(b.get() == -10);
+
+ return 0;
+}
+
+#endif // MSVC
+
diff --git a/src/boost/libs/contract/example/features/public.cpp b/src/boost/libs/contract/example/features/public.cpp
new file mode 100644
index 00000000..a6d94aa7
--- /dev/null
+++ b/src/boost/libs/contract/example/features/public.cpp
@@ -0,0 +1,189 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+//[public_class_begin
+class unique_identifiers :
+ private boost::contract::constructor_precondition<unique_identifiers>
+{
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(size() >= 0);
+ }
+//]
+
+//[public_constructor
+public:
+ // Contract for a constructor.
+ unique_identifiers(int from, int to) :
+ boost::contract::constructor_precondition<unique_identifiers>([&] {
+ BOOST_CONTRACT_ASSERT(from >= 0);
+ BOOST_CONTRACT_ASSERT(to >= from);
+ })
+ {
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(size() == (to - from + 1));
+ })
+ ;
+
+ // Constructor body.
+ for(int id = from; id <= to; ++id) vect_.push_back(id);
+ }
+//]
+
+//[public_destructor
+public:
+ // Contract for a destructor.
+ virtual ~unique_identifiers() {
+ // Following contract checks class invariants.
+ boost::contract::check c = boost::contract::destructor(this);
+
+ // Destructor body here... (do nothing in this example).
+ }
+//]
+
+ int size() const {
+ // Following contract checks invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return vect_.size();
+ }
+
+//[public_function
+public:
+ // Contract for a public function (but no static, virtual, or override).
+ bool find(int id) const {
+ bool result;
+ boost::contract::check c = boost::contract::public_function(this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(id >= 0);
+ })
+ .postcondition([&] {
+ if(size() == 0) BOOST_CONTRACT_ASSERT(!result);
+ })
+ ;
+
+ // Function body.
+ return result = std::find(vect_.begin(), vect_.end(), id) !=
+ vect_.end();
+ }
+//]
+
+//[public_virtual_function
+public:
+ // Contract for a public virtual function (but no override).
+ virtual int push_back(int id, boost::contract::virtual_* v = 0) { // Extra `v`.
+ int result;
+ boost::contract::old_ptr<bool> old_find =
+ BOOST_CONTRACT_OLDOF(v, find(id)); // Pass `v`.
+ boost::contract::old_ptr<int> old_size =
+ BOOST_CONTRACT_OLDOF(v, size()); // Pass `v`.
+ boost::contract::check c = boost::contract::public_function(
+ v, result, this) // Pass `v` and `result`.
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(id >= 0);
+ BOOST_CONTRACT_ASSERT(!find(id)); // ID cannot be already present.
+ })
+ .postcondition([&] (int const result) {
+ if(!*old_find) {
+ BOOST_CONTRACT_ASSERT(find(id));
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ }
+ BOOST_CONTRACT_ASSERT(result == id);
+ })
+ ;
+
+ // Function body.
+ vect_.push_back(id);
+ return result = id;
+ }
+//]
+
+private:
+ std::vector<int> vect_;
+//[public_class_end
+ /* ... */
+};
+//]
+
+//[public_derived_class_begin
+class identifiers
+ #define BASES public unique_identifiers
+ : BASES
+{
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // Bases typedef.
+ #undef BASES
+
+ void invariant() const { // Check in AND with bases.
+ BOOST_CONTRACT_ASSERT(empty() == (size() == 0));
+ }
+//]
+
+//[public_function_override
+public:
+ // Contract for a public function override.
+ int push_back(int id, boost::contract::virtual_* v = 0) /* override */ {
+ int result;
+ boost::contract::old_ptr<bool> old_find =
+ BOOST_CONTRACT_OLDOF(v, find(id));
+ boost::contract::old_ptr<int> old_size =
+ BOOST_CONTRACT_OLDOF(v, size());
+ boost::contract::check c = boost::contract::public_function<
+ override_push_back // Pass override type plus below function pointer...
+ >(v, result, &identifiers::push_back, this, id) // ...and arguments.
+ .precondition([&] { // Check in OR with bases.
+ BOOST_CONTRACT_ASSERT(id >= 0);
+ BOOST_CONTRACT_ASSERT(find(id)); // ID can be already present.
+ })
+ .postcondition([&] (int const result) { // Check in AND with bases.
+ if(*old_find) BOOST_CONTRACT_ASSERT(size() == *old_size);
+ })
+ ;
+
+ // Function body.
+ if(!find(id)) unique_identifiers::push_back(id); // Else, do nothing.
+ return result = id;
+ }
+ BOOST_CONTRACT_OVERRIDE(push_back) // Define `override_push_back`.
+//]
+
+ bool empty() const {
+ // Following contract checks invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return size() == 0;
+ }
+
+ identifiers(int from, int to) : unique_identifiers(from, to) {
+ // Following contract checks invariants.
+ boost::contract::check c = boost::contract::constructor(this);
+ }
+
+//[public_derived_class_end
+ /* ... */
+};
+//]
+
+int main() {
+ unique_identifiers uids(1, 4);
+ assert(uids.find(2));
+ assert(!uids.find(5));
+ uids.push_back(5);
+ assert(uids.find(5));
+
+ identifiers ids(10, 40);
+ assert(!ids.find(50));
+ ids.push_back(50);
+ ids.push_back(50);
+ assert(ids.find(50));
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/pure_virtual_public.cpp b/src/boost/libs/contract/example/features/pure_virtual_public.cpp
new file mode 100644
index 00000000..917a6c71
--- /dev/null
+++ b/src/boost/libs/contract/example/features/pure_virtual_public.cpp
@@ -0,0 +1,89 @@
+
+// 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 <boost/contract.hpp>
+#include <vector>
+#include <cassert>
+
+//[pure_virtual_public_base_begin
+template<typename Iterator>
+class range {
+public:
+ // Pure virtual function declaration (contract in definition below).
+ 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_base_end
+ /* ... */
+};
+//]
+
+//[pure_virtual_public_base_impl
+// Pure virtual function default implementation (out-of-line in C++).
+template<typename Iterator>
+Iterator range<Iterator>::begin(boost::contract::virtual_* v) {
+ Iterator result; // As usual, virtual pass `result` right after `v`...
+ boost::contract::check c = boost::contract::public_function(v, result, this)
+ .postcondition([&] (Iterator const& result) {
+ if(empty()) BOOST_CONTRACT_ASSERT(result == end());
+ })
+ ;
+
+ // Pure function body (never executed by this library).
+ assert(false);
+ return result;
+}
+//]
+
+template<typename T>
+class vector
+ #define BASES public range<typename std::vector<T>::iterator>
+ : BASES
+{
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+ typedef typename std::vector<T>::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();
+ }
+ BOOST_CONTRACT_OVERRIDE(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); }
+
+private:
+ std::vector<T> vect_;
+};
+
+int main() {
+ vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ v.push_back(3);
+ range<std::vector<int>::iterator>& r = v;
+ assert(*(r.begin()) == 1);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/separate_body.cpp b/src/boost/libs/contract/example/features/separate_body.cpp
new file mode 100644
index 00000000..10e05b2e
--- /dev/null
+++ b/src/boost/libs/contract/example/features/separate_body.cpp
@@ -0,0 +1,36 @@
+
+// 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 "separate_body.hpp"
+#include <cassert>
+
+//[separate_body_cpp
+void iarray::constructor_body(unsigned max, unsigned count) {
+ for(unsigned i = 0; i < count; ++i) values_[i] = int();
+ size_ = count;
+}
+
+void iarray::destructor_body() { delete[] values_; }
+
+void iarray::push_back_body(int value) { values_[size_++] = value; }
+
+/* ... */
+//]
+
+unsigned iarray::capacity_body() const { return capacity_; }
+unsigned iarray::size_body() const { return size_; }
+
+int main() {
+ iarray a(3, 2);
+ assert(a.capacity() == 3);
+ assert(a.size() == 2);
+
+ a.push_back(-123);
+ assert(a.size() == 3);
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/separate_body.hpp b/src/boost/libs/contract/example/features/separate_body.hpp
new file mode 100644
index 00000000..6b83afd5
--- /dev/null
+++ b/src/boost/libs/contract/example/features/separate_body.hpp
@@ -0,0 +1,88 @@
+
+#ifndef SEPARATE_BODY_HPP_
+#define SEPARATE_BODY_HPP_
+
+// 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 <boost/contract.hpp>
+
+//[separate_body_hpp
+class iarray :
+ private boost::contract::constructor_precondition<iarray> {
+public:
+ void invariant() const {
+ BOOST_CONTRACT_ASSERT(size() <= capacity());
+ }
+
+ explicit iarray(unsigned max, unsigned count = 0) :
+ boost::contract::constructor_precondition<iarray>([&] {
+ BOOST_CONTRACT_ASSERT(count <= max);
+ }),
+ // Still, member initializations must be here.
+ values_(new int[max]),
+ capacity_(max)
+ {
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(capacity() == max);
+ BOOST_CONTRACT_ASSERT(size() == count);
+ })
+ ;
+ constructor_body(max, count); // Separate constructor body impl.
+ }
+
+ virtual ~iarray() {
+ boost::contract::check c = boost::contract::destructor(this); // Inv.
+ destructor_body(); // Separate destructor body implementation.
+ }
+
+ virtual void push_back(int value, boost::contract::virtual_* v = 0) {
+ boost::contract::old_ptr<unsigned> old_size =
+ BOOST_CONTRACT_OLDOF(v, size());
+ boost::contract::check c = boost::contract::public_function(v, this)
+ .precondition([&] {
+ BOOST_CONTRACT_ASSERT(size() < capacity());
+ })
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(size() == *old_size + 1);
+ })
+ ;
+ push_back_body(value); // Separate member function body implementation.
+ }
+
+private:
+ // Contracts in class declaration (above), but body implementations are not.
+ void constructor_body(unsigned max, unsigned count);
+ void destructor_body();
+ void push_back_body(int value);
+
+ /* ... */
+//]
+
+public:
+ unsigned capacity() const {
+ // Check invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return capacity_body();
+ }
+
+ unsigned size() const {
+ // Check invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return size_body();
+ }
+
+private:
+ unsigned size_body() const;
+ unsigned capacity_body() const;
+
+ int* values_;
+ unsigned capacity_;
+ unsigned size_;
+};
+
+#endif // #include guard
+
diff --git a/src/boost/libs/contract/example/features/static_public.cpp b/src/boost/libs/contract/example/features/static_public.cpp
new file mode 100644
index 00000000..146de0fa
--- /dev/null
+++ b/src/boost/libs/contract/example/features/static_public.cpp
@@ -0,0 +1,69 @@
+
+// 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 <boost/contract.hpp>
+#include <cassert>
+
+//[static_public
+template<class C>
+class make {
+public:
+ static void static_invariant() { // Static class invariants.
+ BOOST_CONTRACT_ASSERT(instances() >= 0);
+ }
+
+ // Contract for a static public function.
+ static int instances() {
+ // Explicit template parameter `make` (check static invariants).
+ boost::contract::check c = boost::contract::public_function<make>();
+
+ return instances_; // Function body.
+ }
+
+ /* ... */
+//]
+
+ make() : object() {
+ boost::contract::old_ptr<int> old_instances =
+ BOOST_CONTRACT_OLDOF(instances());
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(instances() == *old_instances + 1);
+ })
+ ;
+
+ ++instances_;
+ }
+
+ ~make() {
+ boost::contract::old_ptr<int> old_instances =
+ BOOST_CONTRACT_OLDOF(instances());
+ boost::contract::check c = boost::contract::destructor(this)
+ .postcondition([&] { // (An example of destructor postconditions.)
+ BOOST_CONTRACT_ASSERT(instances() == *old_instances - 1);
+ })
+ ;
+
+ --instances_;
+ }
+
+ C object;
+
+private:
+ static int instances_;
+};
+
+template<class C>
+int make<C>::instances_ = 0;
+
+int main() {
+ struct x {};
+ make<x> x1, x2, x3;
+ assert(make<x>::instances() == 3);
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/throw_on_failure.cpp b/src/boost/libs/contract/example/features/throw_on_failure.cpp
new file mode 100644
index 00000000..4cff315f
--- /dev/null
+++ b/src/boost/libs/contract/example/features/throw_on_failure.cpp
@@ -0,0 +1,145 @@
+
+// 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 <boost/contract.hpp>
+#include <iostream>
+#include <cstring>
+#include <cassert>
+
+//[throw_on_failure_class_begin
+struct too_large_error {};
+
+template<unsigned MaxSize>
+class cstring
+ #define BASES private boost::contract::constructor_precondition<cstring< \
+ MaxSize> >
+ : BASES
+{
+//]
+public:
+ typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
+ #undef BASES
+
+//[throw_on_failure_ctor
+public:
+ /* implicit */ cstring(char const* chars) :
+ boost::contract::constructor_precondition<cstring>([&] {
+ BOOST_CONTRACT_ASSERT(chars); // Throw `assertion_failure`.
+ // Or, throw user-defined exception.
+ if(std::strlen(chars) > MaxSize) throw too_large_error();
+ })
+ {
+//]
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(size() == std::strlen(chars));
+ })
+ ;
+
+ size_ = std::strlen(chars);
+ for(unsigned i = 0; i < size_; ++i) chars_[i] = chars[i];
+ chars_[size_] = '\0';
+ }
+
+//[throw_on_failure_dtor
+public:
+ void invariant() const {
+ if(size() > MaxSize) throw too_large_error(); // Throw user-defined ex.
+ BOOST_CONTRACT_ASSERT(chars_); // Or, throw `assertion_failure`.
+ BOOST_CONTRACT_ASSERT(chars_[size()] == '\0');
+ }
+
+ ~cstring() noexcept { // Exception specifiers apply to contract code.
+ // Check invariants.
+ boost::contract::check c = boost::contract::destructor(this);
+ }
+//]
+
+ unsigned size() const {
+ // Check invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ return size_;
+ }
+
+private:
+ char chars_[MaxSize + 1];
+ unsigned size_;
+//[throw_on_failure_class_end
+ /* ... */
+};
+//]
+
+void bad_throwing_handler() { // For docs only (not actually used here).
+ //[throw_on_failure_bad_handler
+ /* ... */
+
+ // Warning... might cause destructors to throw (unless declared noexcept).
+ boost::contract::set_invariant_failure(
+ [] (boost::contract::from) {
+ throw; // Throw no matter if from destructor, etc.
+ }
+ );
+
+ /* ... */
+ //]
+}
+
+//[throw_on_failure_handlers
+int main() {
+ boost::contract::set_precondition_failure(
+ boost::contract::set_postcondition_failure(
+ boost::contract::set_invariant_failure(
+ boost::contract::set_old_failure(
+ [] (boost::contract::from where) {
+ if(where == boost::contract::from_destructor) {
+ // Shall not throw from C++ destructors.
+ std::clog << "ignored destructor contract failure" << std::endl;
+ } else throw; // Re-throw (assertion_failure, user-defined, etc.).
+ }
+ ))));
+ boost::contract::set_except_failure(
+ [] (boost::contract::from) {
+ // Already an active exception so shall not throw another...
+ std::clog << "ignored exception guarantee failure" << std::endl;
+ }
+ );
+ boost::contract::set_check_failure(
+ [] {
+ // But now CHECK shall not be used in destructor implementations.
+ throw; // Re-throw (assertion_failure, user-defined, etc.).
+ }
+ );
+
+ /* ... */
+//]
+
+ {
+ cstring<3> s("abc");
+ assert(s.size() == 3);
+ }
+
+ #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
+ // These failures properly handled only when preconditions checked.
+
+ try {
+ char* c = 0;
+ cstring<3> s(c);
+ assert(false);
+ } catch(boost::contract::assertion_failure const& error) {
+ // OK (expected).
+ std::clog << "ignored: " << error.what() << std::endl;
+ } catch(...) { assert(false); }
+
+ try {
+ cstring<3> s("abcd");
+ assert(false);
+ } catch(too_large_error const&) {} // OK (expected).
+ catch(...) { assert(false); }
+ #endif
+
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/union.cpp b/src/boost/libs/contract/example/features/union.cpp
new file mode 100644
index 00000000..0681c774
--- /dev/null
+++ b/src/boost/libs/contract/example/features/union.cpp
@@ -0,0 +1,134 @@
+
+// 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 <boost/contract.hpp>
+#include <boost/config.hpp>
+#include <cassert>
+
+#ifdef BOOST_GCC // G++ does not support static union members yet.
+ int instances_ = 0;
+#endif
+
+//[union
+union positive {
+public:
+ static void static_invariant() { // Static class invariants (as usual).
+ BOOST_CONTRACT_ASSERT(instances() >= 0);
+ }
+
+ void invariant() const { // Class invariants (as usual).
+ BOOST_CONTRACT_ASSERT(i_ > 0);
+ BOOST_CONTRACT_ASSERT(d_ > 0);
+ }
+
+ // Contracts for constructor, as usual but...
+ explicit positive(int x) : d_(0) {
+ // ...unions cannot have bases so constructor preconditions here.
+ boost::contract::constructor_precondition<positive> pre([&] {
+ BOOST_CONTRACT_ASSERT(x > 0);
+ });
+ boost::contract::old_ptr<int> old_instances =
+ BOOST_CONTRACT_OLDOF(instances());
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ { int y; get(y); BOOST_CONTRACT_ASSERT(y == x); }
+ BOOST_CONTRACT_ASSERT(instances() == *old_instances + 1);
+ })
+ ;
+
+ i_ = x;
+ ++instances_;
+ }
+
+ // Contracts for destructor (as usual).
+ ~positive() {
+ boost::contract::old_ptr<int> old_instances =
+ BOOST_CONTRACT_OLDOF(instances());
+ boost::contract::check c = boost::contract::destructor(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(instances() == *old_instances - 1);
+ })
+ ;
+
+ --instances_;
+ }
+
+ // Contracts for public function (as usual, but no virtual or override).
+ void get(int& x) const {
+ boost::contract::check c = boost::contract::public_function(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(x > 0);
+ })
+ ;
+
+ x = i_;
+ }
+
+ // Contracts for static public function (as usual).
+ static int instances() {
+ boost::contract::check c = boost::contract::public_function<positive>();
+ return instances_;
+ }
+
+private:
+ int i_;
+ double d_;
+
+ /* ... */
+//]
+
+public:
+ explicit positive(double x) : d_(0) {
+ // Unions cannot have bases so constructor preconditions here.
+ boost::contract::constructor_precondition<positive> pre([&] {
+ BOOST_CONTRACT_ASSERT(x > 0);
+ });
+ boost::contract::old_ptr<int> old_instances =
+ BOOST_CONTRACT_OLDOF(instances());
+ boost::contract::check c = boost::contract::constructor(this)
+ .postcondition([&] {
+ { double y; get(y); BOOST_CONTRACT_ASSERT(y == x); }
+ BOOST_CONTRACT_ASSERT(instances() == *old_instances + 1);
+ })
+ ;
+
+ d_ = x;
+ ++instances_;
+ }
+
+ void get(double& x) const {
+ boost::contract::check c = boost::contract::public_function(this)
+ .postcondition([&] {
+ BOOST_CONTRACT_ASSERT(x > 0);
+ })
+ ;
+
+ x = d_;
+ }
+
+ #ifndef BOOST_GCC // G++ does not support static union members yet.
+ static int instances_;
+ #endif
+};
+
+#ifndef BOOST_GCC // G++ does not support static union members yet.
+ int positive::instances_ = 0;
+#endif
+
+int main() {
+ {
+ positive p(123);
+ assert(p.instances() == 1);
+ { int y = -456; p.get(y); assert(y == 123); }
+
+ positive q(1.23);
+ assert(q.instances() == 2);
+ { double y = -4.56; q.get(y); assert(y == 1.23); }
+ }
+ assert(positive::instances() == 0);
+ return 0;
+}
+
diff --git a/src/boost/libs/contract/example/features/volatile.cpp b/src/boost/libs/contract/example/features/volatile.cpp
new file mode 100644
index 00000000..eb9b2e71
--- /dev/null
+++ b/src/boost/libs/contract/example/features/volatile.cpp
@@ -0,0 +1,102 @@
+
+// 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 <boost/contract.hpp>
+#include <cassert>
+
+//[volatile
+class u {
+public:
+ static void static_invariant(); // Static invariants.
+ void invariant() const volatile; // Volatile invariants.
+ void invariant() const; // Const invariants.
+
+ u() { // Check static, volatile, and const invariants.
+ boost::contract::check c= boost::contract::constructor(this);
+ }
+
+ ~u() { // Check static, volatile, and const invariants.
+ boost::contract::check c = boost::contract::destructor(this);
+ }
+
+ void nc() { // Check static and const invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ }
+
+ void c() const { // Check static and const invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ }
+
+ void v() volatile { // Check static and volatile invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ }
+
+ void cv() const volatile { // Check static and volatile invariants.
+ boost::contract::check c = boost::contract::public_function(this);
+ }
+
+ static void s() { // Check static invariants only.
+ boost::contract::check c = boost::contract::public_function<u>();
+ }
+};
+//]
+
+bool static_inv_checked, cv_inv_checked, const_inv_checked;
+void u::static_invariant() { static_inv_checked = true; }
+void u::invariant() const volatile { cv_inv_checked = true; }
+void u::invariant() const { const_inv_checked = true; }
+
+int main() {
+ #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
+ {
+ static_inv_checked = cv_inv_checked = const_inv_checked = false;
+ u x;
+ assert(static_inv_checked);
+ assert(cv_inv_checked);
+ assert(const_inv_checked);
+
+ static_inv_checked = cv_inv_checked = const_inv_checked = false;
+ x.nc();
+ assert(static_inv_checked);
+ assert(!cv_inv_checked);
+ assert(const_inv_checked);
+
+ static_inv_checked = cv_inv_checked = const_inv_checked = false;
+ x.c();
+ assert(static_inv_checked);
+ assert(!cv_inv_checked);
+ assert(const_inv_checked);
+
+ static_inv_checked = cv_inv_checked = const_inv_checked = false;
+ x.v();
+ assert(static_inv_checked);
+ assert(cv_inv_checked);
+ assert(!const_inv_checked);
+
+ static_inv_checked = cv_inv_checked = const_inv_checked = false;
+ x.cv();
+ assert(static_inv_checked);
+ assert(cv_inv_checked);
+ assert(!const_inv_checked);
+
+ static_inv_checked = cv_inv_checked = const_inv_checked = false;
+ x.s();
+ assert(static_inv_checked);
+ assert(!cv_inv_checked);
+ assert(!const_inv_checked);
+
+ static_inv_checked = cv_inv_checked = const_inv_checked = false;
+ } // Call destructor.
+ #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
+ assert(static_inv_checked);
+ assert(cv_inv_checked);
+ assert(const_inv_checked);
+ #endif
+ #endif
+
+ return 0;
+}
+