Skip to content

Commit

Permalink
reviewed doc up to extra section. also edited some examples as a resu…
Browse files Browse the repository at this point in the history
…lt. added if_constexpr example for assertion requirements (templates).
  • Loading branch information
lcaminiti committed Aug 19, 2019
1 parent 3ddfca1 commit 0c14650
Show file tree
Hide file tree
Showing 19 changed files with 492 additions and 324 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Distributed under the [Boost Software License, Version 1.0](http://www.boost.org
### Properties

* C++11 (C++03 possible but not recommended without lambda functions and variadic macros, see documentation for more information).
* Shared Library / DLL with `BOOST_CONTRACT_DYN_LINK` (static library with `BOOST_CONTRACT_STATIC_LINK` and header-only with `BOOST_CONTRACT_HEADER_ONLY` possible but not recommended, see documentation for more information).
* Shared Library / DLL with `BOOST_CONTRACT_DYN_LINK` (static library with `BOOST_CONTRACT_STATIC_LINK` and header-only with `BOOST_CONTRACT_HEADER_ONLY` also possible but not recommended, see documentation for more information).

### Build Status

Expand Down
148 changes: 79 additions & 69 deletions doc/advanced.qbk

Large diffs are not rendered by default.

163 changes: 91 additions & 72 deletions doc/contract_programming_overview.qbk

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/examples.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This section lists some examples taken from different sources discussing contrac

[note
Some of these examples might be from old code, containing obsolete coding practices, not optimized for execution speed, not complete, and they might be more relevant in the context of programming languages different from C++.
Nevertheless, programmers are encouraged to review these examples to see a few diverse usages of this library that might be relevant to their needs.
Nevertheless, programmers are encouraged to review these examples to see a few diverse uses of this library that might be relevant to their needs.
]

Sources of the listed examples:
Expand Down
161 changes: 87 additions & 74 deletions doc/extras.qbk

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/full_table_of_contents.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ __Advanced__
__Function_Overloads__
__Lambdas_Loops_Code_Blocks_and_constexpr__
__Implementation_Checks__
__Old_Value_Copies_at_Body__
__Old_Values_Copied_at_Body__
__Named_Overrides__
__Access_Specifiers__
__Throw_on_Failures_and_noexcept__
Expand Down
1 change: 1 addition & 0 deletions doc/getting_started.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ This library has been developed and tested using:
* Clang version 3.8.1 on Cygwin (with C++11 features enabled =-std=c++11=).

For information on other compilers and platforms see the library [@http://www.boost.org/development/tests/master/developer/contract.html regression tests].
The development and maintenance of this library is hosted on [@https://github.com/boostorg/contract GitHub].

[endsect]

Expand Down
2 changes: 1 addition & 1 deletion doc/main.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
[def __Lambdas_Loops_Code_Blocks__ [link boost_contract.advanced.lambdas__loops__code_blocks__and__constexpr__ Lambdas, Loops, Code Blocks]]
[def __Lambdas_Loops_Code_Blocks_and_constexpr__ [link boost_contract.advanced.lambdas__loops__code_blocks__and__constexpr__ Lambdas, Loops, Code Blocks (and `constexpr`)]]
[def __Implementation_Checks__ [link boost_contract.advanced.implementation_checks Implementation Checks]]
[def __Old_Value_Copies_at_Body__ [link boost_contract.advanced.old_value_copies_at_body Old Value Copies at Body]]
[def __Old_Values_Copied_at_Body__ [link boost_contract.advanced.old_values_copied_at_body Old Values Copied at Body]]
[def __Named_Overrides__ [link boost_contract.advanced.named_overrides Named Overrides]]
[def __Access_Specifiers__ [link boost_contract.advanced.access_specifiers Access Specifiers]]
[def __Throw_on_Failures__ [link boost_contract.advanced.throw_on_failures__and__noexcept__ Throw on Failures]]
Expand Down
188 changes: 96 additions & 92 deletions doc/tutorial.qbk

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions example/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ test-suite features :
[ boost_contract_build.subdir-run features : volatile ]

[ boost_contract_build.subdir-run-cxx11 features : old_if_copyable ]
[ boost_contract_build.subdir-run-cxx11 features : if_constexpr :
[ requires cxx17_if_constexpr ] ]
[ boost_contract_build.subdir-run-cxx11 features : condition_if ]
[ boost_contract_build.subdir-run-cxx11 features : call_if_cxx14 :
[ requires cxx14_generic_lambdas ] ]
Expand Down
6 changes: 3 additions & 3 deletions example/features/access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ 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.
Expand All @@ -57,7 +57,7 @@ class vector

BOOST_CONTRACT_OVERRIDE(push_back) // ...private overrides.

public:
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 =
Expand All @@ -82,7 +82,7 @@ class vector
unsigned max_size() const { return vect_.max_size(); }
unsigned capacity() const { return vect_.capacity(); }

private:
private: // Another private section.
std::vector<T> vect_;
};

Expand Down
2 changes: 1 addition & 1 deletion example/features/check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int gcd(int const a, int const b) {
//[check
int main() {
// Implementation checks (via nullary functor).
boost::contract::check c = [&] {
boost::contract::check c = [] {
BOOST_CONTRACT_ASSERT(gcd(12, 28) == 4);
BOOST_CONTRACT_ASSERT(gcd(4, 14) == 2);
};
Expand Down
113 changes: 113 additions & 0 deletions example/features/if_constexpr.cpp
Original file line number Diff line number Diff line change
@@ -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;
}

2 changes: 1 addition & 1 deletion example/features/lambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ int main() {
boost::contract::check c = boost::contract::function()
.precondition([&] {
BOOST_CONTRACT_ASSERT(
total + x <= std::numeric_limits<int>::max());
total < std::numeric_limits<int>::max() - x);
})
.postcondition([&] {
BOOST_CONTRACT_ASSERT(total == *old_total + x);
Expand Down
2 changes: 1 addition & 1 deletion example/features/loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ int main() {
boost::contract::check c = boost::contract::function()
.precondition([&] {
BOOST_CONTRACT_ASSERT(
total + *i <= std::numeric_limits<int>::max());
total < std::numeric_limits<int>::max() - *i);
})
.postcondition([&] {
BOOST_CONTRACT_ASSERT(total == *old_total + *i);
Expand Down
6 changes: 3 additions & 3 deletions example/features/old.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
//[old
char replace(std::string& s, unsigned index, char x) {
char result;
boost::contract::old_ptr<char> old_y; // Null, old value copied later...
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_y = BOOST_CONTRACT_OLDOF(s[index]);
old_char = BOOST_CONTRACT_OLDOF(s[index]);
})
.postcondition([&] {
BOOST_CONTRACT_ASSERT(s[index] == x);
BOOST_CONTRACT_ASSERT(result == *old_y);
BOOST_CONTRACT_ASSERT(result == *old_char);
})
;

Expand Down
2 changes: 1 addition & 1 deletion example/features/old_if_copyable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void offset(T& x, int count) {
// Copyable type but...
class w {
public:
w(w const&) { /* Some very expensive copy here operation here... */ }
w(w const&) { /* Some very expensive copy operation here... */ }

/* ... */
//]
Expand Down
10 changes: 8 additions & 2 deletions example/features/public.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class unique_identifiers :
// Contract for a constructor.
unique_identifiers(int from, int to) :
boost::contract::constructor_precondition<unique_identifiers>([&] {
BOOST_CONTRACT_ASSERT(from <= to);
BOOST_CONTRACT_ASSERT(from >= 0);
BOOST_CONTRACT_ASSERT(to >= from);
})
{
boost::contract::check c = boost::contract::constructor(this)
Expand Down Expand Up @@ -61,6 +62,9 @@ class unique_identifiers :
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);
})
Expand All @@ -84,6 +88,7 @@ class unique_identifiers :
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) {
Expand Down Expand Up @@ -132,9 +137,10 @@ class identifiers
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 plus below function pointer...
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.
Expand Down
2 changes: 1 addition & 1 deletion example/features/throw_on_failure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ int main() {
}
))));
boost::contract::set_except_failure(
[] (boost::contract::from where) {
[] (boost::contract::from) {
// Already an active exception so shall not throw another...
std::clog << "ignored exception guarantee failure" << std::endl;
}
Expand Down

0 comments on commit 0c14650

Please sign in to comment.