summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/contract/example/features/ifdef_macro.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/contract/example/features/ifdef_macro.cpp')
-rw-r--r--src/boost/libs/contract/example/features/ifdef_macro.cpp150
1 files changed, 150 insertions, 0 deletions
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;
+}
+