diff --git a/doc/advanced.qbk b/doc/advanced.qbk index ea8ab0e..8e26d36 100644 --- a/doc/advanced.qbk +++ b/doc/advanced.qbk @@ -243,7 +243,7 @@ For example (see [@../../example/features/code_block.cpp =code_block.cpp=]): [import ../example/features/code_block.cpp] [code_block] -Finally, at the moment this library does not support contracts for functions declared `constexpr` and literal classes. +Finally, at the moment this library does not support contracts for functions and classes declared `constexpr`. [footnote *Rationale:* In general, it might be useful to specify contracts for `constexpr` functions and literal classes. diff --git a/doc/extras.qbk b/doc/extras.qbk index 0a0c0f7..0cd3d0b 100644 --- a/doc/extras.qbk +++ b/doc/extras.qbk @@ -333,18 +333,18 @@ The assertion levels predefined by this library are similar to the default, audi * [macroref BOOST_CONTRACT_ASSERT] is used to assert conditions that are not computationally expensive, at least compared to the cost of executing the function body. These assertions are always checked at run-time and cannot be disabled. * [macroref BOOST_CONTRACT_ASSERT_AUDIT] is used to assert conditions that are computationally expensive compared to the cost of executing the function body. -These assertions are checked at run-time by default but programmers can disable them by defining [macroref BOOST_CONTRACT_NO_AUDITS] (the asserted conditions will always be compiled and validated syntactically even when they are not actually evaluated and checked at run-time). +These assertions are not checked at run-time unless programmers explicitly define [macroref BOOST_CONTRACT_AUDITS] (undefined by default), but the conditions are always compiled and validated syntactically (even when they are not actually evaluated and checked at run-time). * [macroref BOOST_CONTRACT_ASSERT_AXIOM] is used to assert conditions that are computationally prohibitive, at least compared to the cost of executing the function body. -These assertions are never evaluated or checked at run-time (but the asserted conditions are always compiled and validated syntactically so these assertions can serve as formal comments in the code). +These assertions are never evaluated or checked at run-time, but the asserted conditions are always compiled and validated syntactically so these assertions can serve as formal comments in the code. -In addition, [macroref BOOST_CONTRACT_CHECK_AUDIT] and [macroref BOOST_CONTRACT_CHECK_AXIOM] are similar to [macroref BOOST_CONTRACT_ASSERT_AUDIT] and [macroref BOOST_CONTRACT_ASSERT_AXIOM] but they are used to program audit and axiom implementation checks instead of assertions (see __Implementation_Checks__). +In addition, [macroref BOOST_CONTRACT_CHECK_AUDIT] and [macroref BOOST_CONTRACT_CHECK_AXIOM] are similar to [macroref BOOST_CONTRACT_ASSERT_AUDIT] and [macroref BOOST_CONTRACT_ASSERT_AXIOM] but they are used to program audit and axiom levels for implementation checks instead of assertions (see __Implementation_Checks__). For example, [macroref BOOST_CONTRACT_ASSERT_AUDIT] can be used to program computationally expensive assertions (see [@../../example/features/assertion_level.cpp =assertion_level.cpp=]): [import ../example/features/assertion_level.cpp] [assertion_level_audit] -Also [macroref BOOST_CONTRACT_NO_AUDITS] can be used to disable expensive old value copies and related assertions that use them (see [@../../example/features/assertion_level.cpp =assertion_level.cpp=]): +Also [macroref BOOST_CONTRACT_AUDITS] can be used to disable expensive old value copies and related assertions that use them (see [@../../example/features/assertion_level.cpp =assertion_level.cpp=]): [assertion_level_class_begin] [assertion_level_audit_old] @@ -558,12 +558,12 @@ However, using [macroref BOOST_CONTRACT_ASSERT] is convenient because it always The [macroref BOOST_CONTRACT_ASSERT_AUDIT] and [macroref BOOST_CONTRACT_ASSERT_AXIOM] macros are not a variadic macros and programmers should be able to use them on all C++ compilers. Their implements are equivalent to the following: - #ifdef BOOST_CONTRACT_NO_AUDIT_ASSERTIONS - #define BOOST_CONTRACT_ASSERT_AUDIT(condition) \ - BOOST_CONTRACT_ASSERT(true || (condition)) - #else + #ifdef BOOST_CONTRACT_AUDITS #define BOOST_CONTRACT_ASSERT_AUDIT(condition) \ BOOST_CONTRACT_ASSERT(condition) + #else + #define BOOST_CONTRACT_ASSERT_AUDIT(condition) \ + BOOST_CONTRACT_ASSERT(true || (condition)) #endif #define BOOST_CONTRACT_ASSERT_AXIOM(condition) \ diff --git a/doc/tutorial.qbk b/doc/tutorial.qbk index 38a3560..65abeba 100644 --- a/doc/tutorial.qbk +++ b/doc/tutorial.qbk @@ -633,6 +633,10 @@ Remember: For the rest, considerations made in __Public_Functions__ apply to virtual public functions as well. +[note +A virtual public function should always call [funcref boost::contract::public_function] (even if it has no preconditions, no postconditions, no exception guarantees, and its class has no invariants), otherwise this library will not be able to correctly use it for subcontracting. +] + [endsect] [section Public Function Overrides (Subcontracting)] @@ -748,6 +752,10 @@ This ensures that public function override contracts and subcontracts are correc For the rest, considerations made in __Virtual_Public_Functions__ apply to public function overrides as well. +[note +A public function override should always call [funcref boost::contract::public_function] (even if it has no preconditions, no postconditions, no exception guarantees, and its class has no invariants), otherwise this library will not be able to correctly use it for subcontracting. +] + [endsect] [section Base Classes (Subcontracting)] diff --git a/example/features/assertion_level.cpp b/example/features/assertion_level.cpp index 9f23833..ea4af54 100644 --- a/example/features/assertion_level.cpp +++ b/example/features/assertion_level.cpp @@ -55,10 +55,10 @@ public: public: void swap(vector& other) { boost::contract::old_ptr old_me, old_other; - #ifndef BOOST_CONTRACT_NO_AUDITS // Skip old copies if NO_AUDIT... + #ifdef BOOST_CONTRACT_AUDITS old_me = BOOST_CONTRACT_OLDOF(*this); old_other = BOOST_CONTRACT_OLDOF(other); - #endif + #endif // Else, skip old value copies... boost::contract::check c = boost::contract::public_function(this) .postcondition([&] { // ...and also skip related assertions. diff --git a/example/mitchell02/counter/counter.hpp b/example/mitchell02/counter/counter.hpp index 4ac671d..70bf140 100644 --- a/example/mitchell02/counter/counter.hpp +++ b/example/mitchell02/counter/counter.hpp @@ -33,6 +33,7 @@ public: // Destroy counter. virtual ~counter() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::destructor(this); } @@ -40,6 +41,7 @@ public: // Current counter value. int value() const { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::public_function(this); return value_; } diff --git a/example/mitchell02/counter/decrement_button.hpp b/example/mitchell02/counter/decrement_button.hpp index 1ca16a4..eced10b 100644 --- a/example/mitchell02/counter/decrement_button.hpp +++ b/example/mitchell02/counter/decrement_button.hpp @@ -39,6 +39,7 @@ public: // Destroy button. virtual ~decrement_button() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::destructor(this); } diff --git a/example/mitchell02/counter/push_button.hpp b/example/mitchell02/counter/push_button.hpp index ba66286..e7e2250 100644 --- a/example/mitchell02/counter/push_button.hpp +++ b/example/mitchell02/counter/push_button.hpp @@ -28,6 +28,7 @@ public: // Destroy button. virtual ~push_button() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::destructor(this); } @@ -35,6 +36,7 @@ public: // If button is enabled. bool enabled() const { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::public_function(this); return enabled_; } diff --git a/example/mitchell02/counter_main.cpp b/example/mitchell02/counter_main.cpp index 1200752..0927169 100644 --- a/example/mitchell02/counter_main.cpp +++ b/example/mitchell02/counter_main.cpp @@ -26,6 +26,7 @@ public: // Create view associated with given counter. explicit view_of_counter(counter& a_counter) : counter_(a_counter) { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::constructor(this); counter_.attach(this); @@ -34,6 +35,7 @@ public: // Destroy view. virtual ~view_of_counter() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::destructor(this); } diff --git a/example/mitchell02/observer/observer.hpp b/example/mitchell02/observer/observer.hpp index 591291e..b7d3653 100644 --- a/example/mitchell02/observer/observer.hpp +++ b/example/mitchell02/observer/observer.hpp @@ -20,10 +20,12 @@ public: /* Creation */ observer() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::constructor(this); } virtual ~observer() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::destructor(this); } diff --git a/example/mitchell02/observer/subject.hpp b/example/mitchell02/observer/subject.hpp index 86a66a2..6cb3662 100644 --- a/example/mitchell02/observer/subject.hpp +++ b/example/mitchell02/observer/subject.hpp @@ -56,7 +56,7 @@ public: // Attach given object as an observer. void attach(observer* ob) { boost::contract::old_ptr > old_observers; - #ifndef BOOST_CONTRACT_NO_AUDITS + #ifdef BOOST_CONTRACT_AUDITS old_observers = BOOST_CONTRACT_OLDOF(observers()); #endif boost::contract::check c = boost::contract::public_function(this) diff --git a/example/mitchell02/observer_main.cpp b/example/mitchell02/observer_main.cpp index 5ecffab..93a7931 100644 --- a/example/mitchell02/observer_main.cpp +++ b/example/mitchell02/observer_main.cpp @@ -25,14 +25,17 @@ public: typedef int state; // Some state being observed. concrete_subject() : state_() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::constructor(this); } virtual ~concrete_subject() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::destructor(this); } void set_state(state const& new_state) { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::public_function(this); state_ = new_state; @@ -41,6 +44,7 @@ public: } state get_state() const { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::public_function(this); return state_; } @@ -63,10 +67,12 @@ public: // Create concrete observer. explicit concrete_observer(concrete_subject const& subj) : subject_(subj), observed_state_() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::constructor(this); } virtual ~concrete_observer() { + // Could have omitted contracts here (nothing to check). boost::contract::check c = boost::contract::destructor(this); } diff --git a/example/mitchell02/simple_queue.cpp b/example/mitchell02/simple_queue.cpp index cbb1fce..70124ec 100644 --- a/example/mitchell02/simple_queue.cpp +++ b/example/mitchell02/simple_queue.cpp @@ -131,7 +131,7 @@ public: void remove() { // Expensive all_equal postcond. and old_items copy might be skipped. boost::contract::old_ptr > old_items; - #ifndef BOOST_CONTRACT_NO_AUDIT_ASSERTIONS + #ifdef BOOST_CONTRACT_AUDIITS = BOOST_CONTRACT_OLDOF(items()) #endif // Else, leave old pointer null... ; @@ -142,7 +142,7 @@ public: }) .postcondition([&] { BOOST_CONTRACT_ASSERT(count() == *old_count - 1); // Count dec. - // ...following skipped #if NO_AUDIT. + // ...following skipped #ifndef AUDITS. if(old_items) all_equal(items(), *old_items, /* shifted = */ 1); }) ; @@ -154,7 +154,7 @@ public: void put(T const& item) { // Expensive all_equal postcond. and old_items copy might be skipped. boost::contract::old_ptr > old_items; - #ifndef BOOST_CONTRACT_NO_AUDIT_ASSERTIONS + #ifdef BOOST_CONTRACT_AUDITS = BOOST_CONTRACT_OLDOF(items()) #endif // Else, leave old pointer null... ; @@ -167,7 +167,7 @@ public: BOOST_CONTRACT_ASSERT(count() == *old_count + 1); // Count inc. // Second to last item. BOOST_CONTRACT_ASSERT(items().at(count() - 1) == item); - // ...following skipped #if NO_AUDIT. + // ...following skipped #ifndef AUDITS. if(old_items) all_equal(items(), *old_items); }) ; diff --git a/example/n1962/vector.cpp b/example/n1962/vector.cpp index 29c0f98..b206d70 100644 --- a/example/n1962/vector.cpp +++ b/example/n1962/vector.cpp @@ -181,6 +181,7 @@ public: } virtual ~vector() { + // Check invariants. boost::contract::check c = boost::contract::destructor(this); } @@ -231,11 +232,13 @@ public: } iterator end() { + // Check invariants. boost::contract::check c = boost::contract::public_function(this); return vect_.end(); } const_iterator end() const { + // Check invariants. boost::contract::check c = boost::contract::public_function(this); return vect_.end(); } @@ -263,11 +266,13 @@ public: } reverse_iterator rend() { + // Check invariants. boost::contract::check c = boost::contract::public_function(this); return vect_.rend(); } const_reverse_iterator rend() const { + // Check invariants. boost::contract::check c = boost::contract::public_function(this); return vect_.rend(); } @@ -326,18 +331,19 @@ public: } Allocator get_allocator() const { + // Check invariants. boost::contract::check c = boost::contract::public_function(this); return vect_.get_allocator(); } reference at(size_type index) { - // No precondition because throws out_of_range for invalid index. + // Check invariants, no pre (throw out_of_range for invalid index). boost::contract::check c = boost::contract::public_function(this); return vect_.at(index); } const_reference at(size_type index) const { - // No precondition because throws out_of_range for invalid index. + // Check invariants, no pre (throw out_of_range for invalid index). boost::contract::check c = boost::contract::public_function(this); return vect_.at(index); } @@ -586,7 +592,7 @@ public: .postcondition([&] { BOOST_CONTRACT_ASSERT(size() == *old_size - 1); if(empty()) BOOST_CONTRACT_ASSERT(result == end()); - BOOST_CONTRACT_AXIOM(!valid(where, end())); + BOOST_CONTRACT_ASSERT_AXIOM(!valid(where, end())); }) ; @@ -623,9 +629,8 @@ public: } void swap(vector& other) { - boost::contract::old_ptr old_me; - boost::contract::old_ptr old_other; - #ifndef BOOST_CONTRACT_NO_AUDITS + boost::contract::old_ptr old_me, old_other; + #ifdef BOOST_CONTRACT_AUDITS old_me = BOOST_CONTRACT_OLDOF(*this); old_other = BOOST_CONTRACT_OLDOF(other); #endif @@ -655,6 +660,11 @@ public: } friend bool operator==(vector const& left, vector const& right) { + // Check class invariants for left and right objects. + boost::contract::check left_inv = + boost::contract::public_function(&left); + boost::contract::check right_inv = + boost::contract::public_function(&right); return left.vect_ == right.vect_; } diff --git a/example/n1962/vector_n1962.hpp b/example/n1962/vector_n1962.hpp index 50cbdb7..3c9ca25 100644 --- a/example/n1962/vector_n1962.hpp +++ b/example/n1962/vector_n1962.hpp @@ -184,6 +184,7 @@ public: + void reserve(size_type count) precondition { count < max_size(); @@ -234,12 +235,14 @@ public: return vect_.end(); } - + + const_iterator end() const { return vect_.end(); } + reverse_iterator rbegin() postcondition(result) { if(empty()) result == rend(); @@ -267,11 +270,13 @@ public: } + const_reverse_iterator rend() const { return vect_.rend(); } + void resize(size_type count, T const& value = T()) postcondition { size() == count; @@ -330,14 +335,15 @@ public: } + reference at(size_type index) { - // No precondition because throws out_of_range for invalid index. + // No precondition (throw out_of_range for invalid index). return vect_.at(index); } const_reference at(size_type index) const { - // No precondition because throws out_of_range for invalid index. + // No precondition (throw out_of_range for invalid index). return vect_.at(index); } @@ -655,9 +661,14 @@ public: friend bool operator==(vector const& left, vector const& right) { + // Cannot check class invariants for left and right objects. return left.vect_ == right.vect_; } + + + + private: std::vector vect_; }; diff --git a/include/boost/contract.hpp b/include/boost/contract.hpp index 660c545..902ebcc 100644 --- a/include/boost/contract.hpp +++ b/include/boost/contract.hpp @@ -9,9 +9,12 @@ /** @file Include all header files required by this library at once (for convenience). -All headers file boost/contract/\*.hpp are independent from one another -and can be included one-by-one to reduce the amount of the code of this library -being compiled in user code (but that should not make a significant difference). + +All header files boost/contract/\*.hpp are independent from one another +and can be included one-by-one to reduce the amount of code to compile from this +library in user code (but this was measured to not make an appreciable +difference in compile-time so boost/contract.hpp can be included directly +in most cases). Instead the headers boost/contract/core/\*.hpp are not independent from other library headers and they are automatically included by the boost/contract/\*.hpp headers (so the boost/contract/core/\*.hpp @@ -22,6 +25,7 @@ All files under the boost/contract/detail/ directory, names within the @c boost_contract_detail... and @c BOOST_CONTRACT_DETAIL... (in any namesapce, including user's code) are reserved for internal use of this library and should never be used directly by programmers. + @see @RefSect{getting_started, Getting Started} */ diff --git a/include/boost/contract/assert.hpp b/include/boost/contract/assert.hpp index b3ca15e..4f6c7af 100644 --- a/include/boost/contract/assert.hpp +++ b/include/boost/contract/assert.hpp @@ -16,8 +16,8 @@ Assert contract conditions. #ifndef BOOST_CONTRACT_NO_ALL #include - #define BOOST_CONTRACT_ASSERT(condition) \ - BOOST_CONTRACT_DETAIL_ASSERT(condition) /* no `;` here */ + #define BOOST_CONTRACT_ASSERT(cond) \ + BOOST_CONTRACT_DETAIL_ASSERT(cond) /* no `;` here */ #else /** Preferred way to assert contract conditions. @@ -29,43 +29,103 @@ Assert contract conditions. exception when an asserted condition is checked to be @c false (this library will then call the appropriate contract failure handler @RefFunc{boost::contract::precondition_failure}, etc.). - However, it is preferred to use this macro instead because it expands to + However, it is preferred to use this macro because it expands to code that throws @RefClass{boost::contract::assertion_failure} with the correct assertion file name (using __FILE__), line number (using __LINE__), and asserted condition code so to produce informative error messages. - - @see @RefSect{tutorial, Tutorial}, - @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, - @RefSect{extra_topics.no_macros__no_c__11_, No Macros} - @param condition The contract condition being checked. - (This is not a variadic macro parameter so any comma it - might contain must be protected by round parenthesis, - but @c BOOST_CONTRACT_ASSERT((condition)) will always - work.) + @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT} and + @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels + predefined by this library. + + @see @RefSect{tutorial.preconditions, Preconditions}, + @RefSect{tutorial.postconditions, Postconditions}, + @RefSect{tutorial.exception_guarantees, Exceptions Guarantees}, + @RefSect{tutorial.class_invariants, Class Invariants} + + @param cond Boolean contract condition to check. + (This is not a variadic macro parameter so any comma it might + contain must be protected by round parenthesis, + @c BOOST_CONTRACT_ASSERT((cond)) will always work.) */ // This must be an expression (a trivial one so the compiler can optimize it // away). It cannot an empty code block `{}`, etc. otherwise code like // `if(...) ASSERT(...); else ASSERT(...);` won't work when NO_ALL. - #define BOOST_CONTRACT_ASSERT(condition) \ + #define BOOST_CONTRACT_ASSERT(cond) \ BOOST_CONTRACT_DETAIL_NOOP #endif -#ifndef BOOST_CONTRACT_NO_AUDITS - // Compiles and evaluates condition (default). - #define BOOST_CONTRACT_ASSERT_AUDIT(condition) \ - BOOST_CONTRACT_ASSERT(condition) +#ifdef BOOST_CONTRACT_AUDITS + /** + Preferred way to assert contract conditions that are computationally + expensive, at least compared to the cost of executing the function body. + + The asserted condition will always be compiled and validated syntactically, + but it will not be evaluated at run-time unless + @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default). + + This macro is defined by code equivalent to: + + @code + #ifdef BOOST_CONTRACT_AUDITS + #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ + BOOST_CONTRACT_ASSERT(cond) + #else + #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ + BOOST_CONTRACT_ASSERT(true || cond) + #endif + @endcode + + @RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT} and + @RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels + predefined by this library. + If there is a need, programmers are free to implement their own assertion + levels defining macros similar to the one above. + + @see @RefSect{extras.assertion_levels, Assertions Levels} + + @param cond Boolean contract condition to check. + (This is not a variadic macro parameter so any comma it might + contain must be protected by round parenthesis, + @c BOOST_CONTRACT_ASSERT_AUDIT((cond)) will always work.) + */ + #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ + BOOST_CONTRACT_ASSERT(cond) #else - /** TODO */ - // Compiles but does not evaluate condition. - #define BOOST_CONTRACT_ASSERT_AUDIT(condition) \ - BOOST_CONTRACT_DETAIL_NOEVAL(condition) + #define BOOST_CONTRACT_ASSERT_AUDIT(cond) \ + BOOST_CONTRACT_DETAIL_NOEVAL(cond) #endif -/** TODO */ -#define BOOST_CONTRACT_ASSERT_AXIOM(condition) \ - BOOST_CONTRACT_DETAIL_NOEVAL(condition) +/** +Preferred way to assert contract conditions that are computationally +prohibitive, at least compared to the cost of executing the function body. + +The asserted condition will always be compiled and validated syntactically, but +it will never be evaluated at run-time. + +This macro is defined by code equivalent to: + +@code + #define BOOST_CONTRACT_ASSERT_AXIOM(cond) \ + BOOST_CONTRACT_ASSERT(true || cond) +@endcode + +@RefMacro{BOOST_CONTRACT_ASSERT}, @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT} and +@RefMacro{BOOST_CONTRACT_ASSERT_AXIOM} are the three assertion levels predefined +by this library. +If there is a need, programmers are free to implement their own assertion levels +defining macros similar to the one above. + +@see @RefSect{extras.assertion_levels, Assertion Levels} + +@param cond Boolean contract condition to check. + (This is not a variadic macro parameter so any comma it might + contain must be protected by round parenthesis, + @c BOOST_CONTRACT_ASSERT_AXIOM((cond)) will always work.) +*/ +#define BOOST_CONTRACT_ASSERT_AXIOM(cond) \ + BOOST_CONTRACT_DETAIL_NOEVAL(cond) #endif // #include guard diff --git a/include/boost/contract/base_types.hpp b/include/boost/contract/base_types.hpp index 26968e3..ba34719 100644 --- a/include/boost/contract/base_types.hpp +++ b/include/boost/contract/base_types.hpp @@ -159,9 +159,7 @@ one or more overriding public function must declare a @c typedef named This @c typedef must be @c public unless @RefClass{boost::contract::access} is used. -@see @RefSect{tutorial.base_classes, Base Classes}, - @RefSect{advanced_topics.access_specifiers, Access Specifiers}, - @RefSect{extra_topics.no_macros__no_c__11_, No Macros} +@see @RefSect{tutorial.base_classes__subcontracting_, Base Classes} @param ... Comma separated list of base classes. Each base must explicitly specify its access specifier @c public, @@ -171,7 +169,7 @@ used. (because of similar limits in Boost.MPL internally used by this library). This is a variadic macro parameter, on compilers that do not support - variadic macros, the base classes @c typedef can be programmed + variadic macros, the @c typedef for base classes can be programmed manually without using this macro. */ #define BOOST_CONTRACT_BASE_TYPES(...) void /* dummy type for typedef */ diff --git a/include/boost/contract/call_if.hpp b/include/boost/contract/call_if.hpp index 71299b2..d512448 100644 --- a/include/boost/contract/call_if.hpp +++ b/include/boost/contract/call_if.hpp @@ -8,11 +8,10 @@ // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html /** @file -Statically disable compilation and execution of functor template calls. +Statically disable compilation and execution of functor calls. -@note This facility also allows to emulate C++17 if constexpr - statements but only when used together with functor templates (or C++14 - generic lambdas). +@note This facility allows to emulate C++17 if constexpr statements + when used together with functor templates (or C++14 generic lambdas). */ #include @@ -54,8 +53,8 @@ Usually this class template is instantiated only via the return value of @see @RefSect{extra_topics.assertion_requirements__templates_, Assertion Requirements} -@tparam Pred Static boolean predicate selecting which functor template call - to compile and execute. +@tparam Pred Static boolean predicate that selects which functor template + call to compile and execute. @tparam Then Type of the functor template to call if the static predicate is @c true. @tparam ThenResult Return type of then-branch functor template call (this is @@ -451,7 +450,7 @@ Select compilation and execution of functor template calls using a static boolean predicate. Create a call-if object with the specified then-branch functor template. -Optional functor template for else-if-branches and the else-branch can be +Optional functor templates for else-if-branches and the else-branch can be specified as needed. For example: @@ -462,8 +461,8 @@ boost::contract::call_if( then_functor_template2 ) ... // Optionally, other `else_if`. -.else_( // Optional for `void` functors. - else_functor_template +.else_( // Optional for `void` functors, + else_functor_template // but required for non `void`. ) @endcode @@ -495,9 +494,9 @@ call_if_statement call_if_c(Then f) { Select compilation and execution of functor template calls using a nullary boolean meta-function. -Create a call-if object with the specified then-branch functor template (this is -equivalent to boost::contract::call_if_c(f)). -Optional functor template for else-if-branches and the else-branch can be +Create a call-if object with the specified then-branch functor template. +This is equivalent to boost::contract::call_if_c(f). +Optional functor templates for else-if-branches and the else-branch can be specified as needed. For example: @@ -508,8 +507,8 @@ boost::contract::call_if( then_functor_template2 ) ... // Optionally, other `else_if`. -.else_( // Optional for `void` functors. - else_functor_template +.else_( // Optional for `void` functors, + else_functor_template // but required for non `void`. ) @endcode @@ -545,6 +544,9 @@ static boolean predicate. Compile and execute the nullary boolean functor template call @c f() if and only if the specified static boolean predicate @p Pred is @c true, otherwise trivially return @p else_ (@c true by default) at run-time. +A call to boost::contract::condition_if_c(f, b) is logically +equivalent to boost::contract::call_if_c(f, [b] { return b; }) (but +its implementation is optimized with respsect to the @c call_if_c equivalent). @see @RefSect{extra_topics.assertion_requirements__templates_, Assertion Requirements} diff --git a/include/boost/contract/check.hpp b/include/boost/contract/check.hpp index ef30c1a..d3d4dbb 100644 --- a/include/boost/contract/check.hpp +++ b/include/boost/contract/check.hpp @@ -8,7 +8,7 @@ // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html /** @file -RAII object to check contracts. +RAII object that checks contracts. */ #include @@ -49,21 +49,27 @@ namespace boost { namespace contract { /** RAII object that checks the contracts. -In general, this object checks entry invariants, preconditions, and assigns old -values when it is constructed. -Then it checks exit invariants and postconditions or exception guarantees when -it is destructed. -That said, this object also enforces the following (see also +In general, when this object is constructed it checks class invariants at entry, +preconditions, and makes old value copies at body. +When it is destructed, it checks class invariants at exist, postconditions, and +exception guarantees. +This object enforces the following (see also @RefSect{contract_programming_overview, Contract Programming Overview}): @li Postconditions are checked only if the body does not throw an exception. -@li Exceptions guarantee are checked only if the body throws an exception. -@li Constructors never check entry invariants. -@li Destructors check exit invariants only if their bodies throw an exception. -@li Static invariants are always checked at entry and exit, etc. +@li Exceptions guarantees are checked only if the body throws an exception. +@li Constructor entry never checks class invariants. +@li Destructor exit checks class invariants only if the body throws an +exception. +@li Static invariants are always checked at entry and exit (and regardless of +the body throwing exceptions or not). -Plus, one of the constructors of this object can be used to program -implementation checks. +This object is usually constructed initializing it to the return value of one +of the contract functions @RefFunc{boost::contract::function}, +@RefFunc{boost::contract::constructor}, @RefFunc{boost::contract::destructor}, +or @RefFunc{boost::contract::public_function}. +In addition, this object can be constructed from a nullary functor that is used +to program implementation checks. @see @RefSect{tutorial, Tutorial}, @RefSect{advanced_topics.implementation_checks, Implementation Checks} @@ -75,15 +81,17 @@ public: Construct this object for implementation checks. This can be used to program checks within implementation code (body, etc.). + This constructor is not declared @c explicit so initializations can use + operator @c = syntax. - @b Throws: This can throw (i.e., declared @c noexcept(false)) in case - programmers specify failure handlers that throw exceptions - instead of terminating the program (see + @b Throws: This can throw (it is declared @c noexcept(false)) in case + programmers specify contract failure handlers that throw + exceptions instead of terminating the program (see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). - @param f Nullary functor that asserts implementation checks @c f() will + @param f Nullary functor that asserts implementation checks. @c f() will be called as soon as this object is constructed at the point it - is declared within the body code. + is declared within the implementation code. */ template // Cannot check `if(f) ...` as f can be a lambda. /* implicit */ check(F const& f) { BOOST_CONTRACT_DETAIL_CHECK({ f(); }) } @@ -105,15 +113,16 @@ public: {} /** - Construct this object from the specified contract. + Construct this object to check the specified contract. - Check entry invariants (if they apply to the specified contract). + This checks class invariants at entry (if they apply to the specified + contract). This constructor is not declared @c explicit so initializations can use operator @c = syntax. - @b Throws: This can throw (i.e., declared @c noexcept(false)) in case - programmers specify failure handlers that throw exceptions - instead of terminating the program (see + @b Throws: This can throw (it is declared @c noexcept(false)) in case + programmers specify contract failure handlers that throw + exceptions instead of terminating the program (see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). @param contract Contract to be checked. @@ -134,16 +143,16 @@ public: #endif /** - Construct this object from the specified contract. + Construct this object to check the specified contract. - Check entry invariants (if they apply to the specified contract) and check - preconditions. + This checks class invariants at entry (if they apply to the specified + contract) and preconditions. This constructor is not declared @c explicit so initializations can use operator @c = syntax. - @b Throws: This can throw (i.e., declared @c noexcept(false)) in case - programmers specify failure handlers that throw exceptions - instead of terminating the program (see + @b Throws: This can throw (it is declared @c noexcept(false)) in case + programmers specify contract failure handlers that throw + exceptions instead of terminating the program (see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). @param contract Contract to be checked. @@ -164,16 +173,16 @@ public: #endif /** - Construct this object from the specified contract. + Construct this object to check the specified contract. - Check entry invariants (if they apply to the specified contract) and check - preconditions, and assign old values. + This checks class invariants at entry (if they apply to the specified + contract) and preconditions, then it makes old value copies at body. This constructor is not declared @c explicit so initializations can use operator @c = syntax. - @b Throws: This can throw (i.e., declared @c noexcept(false)) in case - programmers specify failure handlers that throw exceptions - instead of terminating the program (see + @b Throws: This can throw (it is declared @c noexcept(false)) in case + programmers specify contract failure handlers that throw + exceptions instead of terminating the program (see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). @param contract Contract to be checked. @@ -194,17 +203,17 @@ public: #endif /** - Construct this object from the specified contract. + Construct this object to check the specified contract. - Check entry invariants (if they apply to the specified contract) and check - preconditions, and assign old values (plus the destructor of this object - will also check postconditions in this case). + This checks class invariants at entry (if they apply to the specified + contract) and preconditions, then it makes old value copies at body. + (plus the destructor of this object will check postconditions in this case). This constructor is not declared @c explicit so initializations can use operator @c = syntax. - @b Throws: This can throw (i.e., declared @c noexcept(false)) in case - programmers specify failure handlers that throw exceptions - instead of terminating the program (see + @b Throws: This can throw (it is declared @c noexcept(false)) in case + programmers specify contract failure handlers that throw + exceptions instead of terminating the program (see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). @param contract Contract to be checked. @@ -222,17 +231,18 @@ public: #endif /** - Construct this object from the specified contract. + Construct this object to check the specified contract. - Check entry invariants (if they apply to the specified contract) and check - preconditions, and assign old values (plus the destructor of this object - will also check postconditions and exception guarantees in this case). + This checks class invariants at entry (if they apply to the specified + contract) and preconditions, then it makes old value copies at body. + (plus the destructor of this object will check postconditions and + exception guarantees in this case). This constructor is not declared @c explicit so initializations can use operator @c = syntax. - @b Throws: This can throw (i.e., declared @c noexcept(false)) in case - programmers specify failure handlers that throw exceptions - instead of terminating the program (see + @b Throws: This can throw (it is declared @c noexcept(false)) in case + programmers specify contract failure handlers that throw + exceptions instead of terminating the program (see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). @param contract Contract to be checked. @@ -251,15 +261,16 @@ public: /** Destruct this object. - Check exit invariants (if they apply to the contract specified at - construction) and postconditions (if they apply to the contract specified at - construction and the enclosing function body did not throw) or exception - guarantees (if they apply to the contract specified at construction and the - enclosing function body threw). - @b Throws: This can throw (i.e., declared @c noexcept(false)) in case - programmers specify failure handlers that throw exceptions - instead of terminating the program (see + This checks class invariants at exit and either postconditions when the + enclosing function body did not throw an exception, or exception guarantees + when the function body threw an exception (that is if class invariants, + postconditions, and exception guarantees respectively apply to the object + specified when constructing this object). + + @b Throws: This can throw (it is declared @c noexcept(false)) in case + programmers specify contract failure handlers that throw + exceptions instead of terminating the program (see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). */ ~check() BOOST_NOEXCEPT_IF(false) {} // Allow auto_ptr dtor to throw. diff --git a/include/boost/contract/constructor.hpp b/include/boost/contract/constructor.hpp index ac43a68..9f0389d 100644 --- a/include/boost/contract/constructor.hpp +++ b/include/boost/contract/constructor.hpp @@ -32,8 +32,7 @@ at body, and check class invariants for constructors (see for constructors instead). For optimization, this can be omitted for constructors that do not have -postconditions and exception guarantees when the enclosing class has no -invariants. +postconditions and exception guarantees, within classes that have no invariants. @see @RefSect{tutorial.constructors, Constructors} @@ -42,10 +41,10 @@ invariants. (Constructors check all class invariants, including static and volatile invariants, see also @RefSect{tutorial.class_invariants, Class Invariants} and - @RefSect{advanced_topics.volatile_public_functions, + @RefSect{advanced.volatile_public_functions, Volatile Public Functions}). -@tparam Class The class type of the enclosing constructor declaring the +@tparam Class The type of the class containing the constructor declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) diff --git a/include/boost/contract/core/access.hpp b/include/boost/contract/core/access.hpp index cdd198c..e30f258 100644 --- a/include/boost/contract/core/access.hpp +++ b/include/boost/contract/core/access.hpp @@ -16,7 +16,7 @@ Allow to declare invariants, base types, etc all as private members. #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) #include - #include + #include #endif #ifndef BOOST_CONTRACT_NO_INVARIANTS #include @@ -45,8 +45,9 @@ namespace boost { namespace contract { /** Friend this class to declare invariants and base types as private members. -Declare this class as friend of the contracted class in order to declare -the invariants functions and the base types @c typedef as non-public members. +Declare this class a friend of the user-defined class specifying the contracts +in order to declare the invariant functions and the base types @c typedef as +non-public members. In real code, programmers will likely chose to declare this class as friend so to fully control public interfaces of their user-defined classes. @@ -60,11 +61,11 @@ member and it is not copyable). On other compilers (e.g., GCC and CLang), the private access will instead fail SFINAE and no compiler error will be reported while invariants and subcontracting will be silently skipped at run-time. - Therefore, programmers must make sure to either declare invariant - functions and base types @c typedef as public members or to declare - this class as friend. + Therefore, programmers must make sure to either declare this class + as friend (preferred) or to always declare invariant functions and + base types @c typedef as public members. -@see @RefSect{advanced_topics.access_specifiers, Access Specifiers} +@see @RefSect{advanced.access_specifiers, Access Specifiers} */ class access { // Non-copyable (see below). /** @cond */ @@ -79,7 +80,7 @@ private: // No public APIs (so users cannot use it directly by mistake). #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \ defined(BOOST_CONTRACT_STATIC_LINK) - BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_TYPE(has_base_types, + BOOST_CONTRACT_DETAIL_MIRROR_HAS_TYPE(has_base_types, BOOST_CONTRACT_BASES_TYPEDEF) template @@ -89,10 +90,10 @@ private: // No public APIs (so users cannot use it directly by mistake). #endif #ifndef BOOST_CONTRACT_NO_INVARIANTS - BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_MEMBER_FUNCTION( + BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( has_static_invariant_f, BOOST_CONTRACT_STATIC_INVARIANT_FUNC) - BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_STATIC_MEMBER_FUNCTION( + BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION( has_static_invariant_s, BOOST_CONTRACT_STATIC_INVARIANT_FUNC) template @@ -113,10 +114,10 @@ private: // No public APIs (so users cannot use it directly by mistake). } }; - BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_MEMBER_FUNCTION( + BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( has_invariant_f, BOOST_CONTRACT_INVARIANT_FUNC) - BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_STATIC_MEMBER_FUNCTION( + BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION( has_invariant_s, BOOST_CONTRACT_INVARIANT_FUNC) template diff --git a/include/boost/contract/core/check_macro.hpp b/include/boost/contract/core/check_macro.hpp index f52fa1b..21344e8 100644 --- a/include/boost/contract/core/check_macro.hpp +++ b/include/boost/contract/core/check_macro.hpp @@ -19,8 +19,8 @@ Macro for implementation checks. #include #include - #define BOOST_CONTRACT_CHECK(condition) \ - BOOST_CONTRACT_DETAIL_CHECK(BOOST_CONTRACT_DETAIL_ASSERT(condition)) + #define BOOST_CONTRACT_CHECK(cond) \ + BOOST_CONTRACT_DETAIL_CHECK(BOOST_CONTRACT_DETAIL_ASSERT(cond)) #else /** Preferred way to assert implementation check conditions. @@ -29,31 +29,95 @@ Macro for implementation checks. checks in a nullary functor passed to @RefClass{boost::contract::check} constructor because this macro will completely remove implementation checks from the code when @RefMacro{BOOST_CONTRACT_NO_CHECKS} is defined. + + @RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and + @RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels + predefined by this library. - @see @RefSect{advanced_topics.implementation_checks, Implementation Checks} + @see @RefSect{advanced.implementation_checks, Implementation Checks} - @param condition The condition to be asserted within implementation code - (function body, etc.). - (This is not a variadic macro parameter so any comma it - might contain must be protected by round parenthesis, - but @c BOOST_CONTRACT_CHECK((condition)) will always - work.) + @param cond Boolean condition to check within implementation code (function + body, etc.). + (This is not a variadic macro parameter so any comma it might + contain must be protected by round parenthesis, + @c BOOST_CONTRACT_CHECK((cond)) will always work.) */ - #define BOOST_CONTRACT_CHECK(condition) /* nothing */ + #define BOOST_CONTRACT_CHECK(cond) /* nothing */ #endif -#ifndef BOOST_CONTRACT_NO_AUDITS - #define BOOST_CONTRACT_CHECK_AUDIT(condition) \ - BOOST_CONTRACT_CHECK(condition) +#ifdef BOOST_CONTRACT_AUDITS + /** + Preferred way to assert implementation check conditions that are + computationally expensive, at least compared to the cost of executing the + function body. + + The specified condition will always be compiled and validated + syntactically, but it will not be evaluated at run-time unless + @RefMacro{BOOST_CONTRACT_AUDITS} is defined (undefined by default). + + This macro is defined by code equivalent to: + + @code + #ifdef BOOST_CONTRACT_AUDITS + #define BOOST_CONTRACT_CHECK_AUDIT(cond) \ + BOOST_CONTRACT_CHECK(cond) + #else + #define BOOST_CONTRACT_CHECK_AUDIT(cond) \ + BOOST_CONTRACT_CHECK(true || cond) + #endif + @endcode + + @RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and + @RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels + predefined by this library. + If there is a need, programmers are free to implement their own assertion + levels defining macros similar to the one above. + + @see @RefSect{extras.assertion_levels, Assertion Levels} + + @param cond Boolean condition to check within implementation code (function + body, etc.). + (This is not a variadic macro parameter so any comma it might + contain must be protected by round parenthesis, + @c BOOST_CONTRACT_CHECK((cond)) will always work.) + */ + #define BOOST_CONTRACT_CHECK_AUDIT(cond) \ + BOOST_CONTRACT_CHECK(cond) #else - /** TODO */ - #define BOOST_CONTRACT_CHECK_AUDIT(condition) \ - BOOST_CONTRACT_DETAIL_NOEVAL(condition) + #define BOOST_CONTRACT_CHECK_AUDIT(cond) \ + BOOST_CONTRACT_DETAIL_NOEVAL(cond) #endif -/** TODO */ -#define BOOST_CONTRACT_CHECK_AXIOM(condition) \ - BOOST_CONTRACT_DETAIL_NOEVAL(condition) +/** +Preferred way to assert implementation check conditions that are computationally +prohibitive, at least compared to the cost of executing the function body. + +The specified condition will always be compiled and validated +syntactically, but it will never be evaluated at run-time. + +This macro is defined by code equivalent to: + +@code +#define BOOST_CONTRACT_CHECK_AXIOM(cond) \ + BOOST_CONTRACT_CHECK(true || cond) +@endcode + +@RefMacro{BOOST_CONTRACT_CHECK}, @RefMacro{BOOST_CONTRACT_CHECK_AUDIT}, and +@RefMacro{BOOST_CONTRACT_CHECK_AXIOM} are the three assertion levels predefined +by this library. +If there is a need, programmers are free to implement their own assertion levels +defining macros similar to the one above. + +@see @RefSect{extras.assertion_levels, Assertion Levels} + +@param cond Boolean condition to check within implementation code (function + body, etc.). + (This is not a variadic macro parameter so any comma it might + contain must be protected by round parenthesis, + @c BOOST_CONTRACT_CHECK((cond)) will always work.) +*/ +#define BOOST_CONTRACT_CHECK_AXIOM(cond) \ + BOOST_CONTRACT_DETAIL_NOEVAL(cond) #endif // #include guard diff --git a/include/boost/contract/core/config.hpp b/include/boost/contract/core/config.hpp index 78d3f69..5830661 100644 --- a/include/boost/contract/core/config.hpp +++ b/include/boost/contract/core/config.hpp @@ -24,9 +24,12 @@ Configure this library compile-time and run-time behaviours. If this macro is defined, this library is compiled so it can be linked statically to user code (and not as a shared library as by default). - @warning In general this library must be compiled as a shared library - (i.e., not defining this macro) otherwise the contracts might - not always be checked correctly at run-time. + @warning This library is not guaranteed to always work correctly at + run-time when this macro is defined. + However, this macro can be defined and this library can be + safely used as a static library for user code that checks + contracts in a single program unit (e.g., a single program with + only statically linked libraries that check contracts). @see @RefSect{getting_started.install_and_compile, Install and Compile} */ @@ -41,17 +44,20 @@ Configure this library compile-time and run-time behaviours. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** - Define this macro when compiling user code to avoid compiling this library - (undefined by default). + Define this macro to use this library as a header-only library (undefined by + default). If this macro is defined, this library does not have to be compiled separately from user code. - This library headers are simply included in the user program and this - library implementation code is compiled as part of the user program. + This library headers are simply included and compiled as part of the user + program. - @warning In general this library must be compiled as a shared library - (i.e., not defining this macro) otherwise the contracts might - not always be checked correctly at run-time. + @warning This library is not guaranteed to always work correctly at + run-time when this macro is defined. + However, this macro can be defined and this library can be + safely used as a header-only library for user code that checks + contracts in a single program unit (e.g., a single program with + only statically linked libraries that check contracts). @see @RefSect{getting_started.install_and_compile, Install and Compile} */ @@ -70,15 +76,17 @@ Configure this library compile-time and run-time behaviours. (undefined by default). Defining this macro will make the library implementation code not thread - safe so this macro should not be defined unless the library is being used - strictly under single-threaded applications. + safe so this macro should not be defined unless the library is being used by + single-threaded applications only. + However, when this macro is left undefined this library needs to internally - use some sort of "global" locks (to ensure contract checking is globally + use some sort of "global" lock (to ensure contract checking is globally disabled when other contracts are being checked and also to safely access - failure handler functors) and that could introduce an undesired amount of - synchronization in some multi-threaded applications. + failure handler functors). + That could introduce an undesired amount of synchronization in some + multi-threaded applications. - @see @RefSect{contract_programming_overview, Contract Programming Overview} + @see @RefSect{contract_programming_overview.assertions, Assertions} */ #define BOOST_CONTRACT_DISABLE_THREADS #endif @@ -90,16 +98,15 @@ Configure this library compile-time and run-time behaviours. On compilers that support variadic macros, this macro has no effect. On compilers that do not support variadic macros, this macro can be defined - to support a maximum number of arguments different than @c 10 for - public function overrides (that use - @RefFunc{boost::contract::public_function}). + to the maximum number of arguments that public function overrides can + have and pass to @RefFunc{boost::contract::public_function}. @note Regardless of the value of this macro and of compiler support for variadic macros, there is an intrinsic limit of about 18 arguments for public function overrides (because of similar limits in Boost.MPL and Boost.FunctionTypes internally used by this library). - @see @RefSect{extra_topics.no_macros__no_c__11_, No Macros} + @see @RefSect{extras.no_macros__no_c__11_, No Macros} */ #define BOOST_CONTRACT_MAX_ARGS 10 #endif @@ -110,8 +117,8 @@ Configure this library compile-time and run-time behaviours. This macro expands to the name of the @c typedef that lists the base classes for subcontracting via @RefMacro{BOOST_CONTRACT_BASE_TYPES}. - This macro can be defined if that @c typedef must have a name different from - @c base_types. + This macro can be defined if the @c typedef must have a name different from + @c base_types (because of name clashes in user code, etc.). @see @RefSect{tutorial.base_classes__subcontracting_, Base Classes} */ @@ -120,16 +127,17 @@ Configure this library compile-time and run-time behaviours. #ifndef BOOST_CONTRACT_INVARIANT_FUNC /** - Define the name of the invariant member functions (@c invariant by defult). + Define the name of the class invariant member function (@c invariant by + default). This macro expands to the name of the @c const and const volatile - member functions that check mutable and volatile class invariants + member functions that check class invariants and volatile class invariants respectively. This macro can be defined if these invariant functions must have a name - different from @c invariant. + different from @c invariant (because of name clashes in user code, etc.). @see @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ #define BOOST_CONTRACT_INVARIANT_FUNC invariant @@ -143,10 +151,11 @@ Configure this library compile-time and run-time behaviours. This macro expands to the name of the @c static member function that checks static class invariants. This macro can be defined if this static invariant function must have a name - different from @c static_invariant. + different from @c static_invariant (because of name clashes in suer code, + etc.). @note C++ does not allow to overload member functions based on the - @c static qualifier, so this macro must always be defined to be + @c static classifier, so this macro must always be defined to be different than the function name defined for @RefMacro{BOOST_CONTRACT_INVARIANT_FUNC}. @@ -160,8 +169,8 @@ Configure this library compile-time and run-time behaviours. Disable some compile-time errors generated by this library (undefined by default). - Defining this macro disables a number of static checks and compile-time - errors, for example: + Defining this macro disables a number of static checks and related + compile-time errors, for example: @li The static invariant member @c BOOST_CONTRACT_STATIC_INVARIANT_FUNC function must be declared @c static. @@ -171,6 +180,9 @@ Configure this library compile-time and run-time behaviours. @li Derived classes that program contracts for one or more public function overrides via @RefFunc{boost::contract::public_function} must also define the @RefMacro{BOOST_CONTRACT_BASE_TYPES} @c typedef. + + In general, it is not recommended to define this macro because these + compile-time checks can guard against missuses of this library. @see @RefSect{tutorial.class_invariants, Class Invariants}, @RefSect{tutorial.base_classes__subcontracting_, Base Classes} @@ -181,7 +193,8 @@ Configure this library compile-time and run-time behaviours. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN /** Code block to execute if contracts are not assigned to a - @RefClass{boost::contract::check} variable (undefined by default). + @RefClass{boost::contract::check} variable (undefined by default and + executes @c assert(false)). In general, there is a logic error in the program when contracts are not assigned to a local variable of type @RefClass{boost::contract::check}. @@ -194,7 +207,7 @@ Configure this library compile-time and run-time behaviours. This macro can be defined to be any block of code (including @c {} to generate no error), for example (on GCC): @code - -DBOOST_CONTRACT_ON_MISSING_CHECK_DECL='{ throw std::logic_error(); }' + -DBOOST_CONTRACT_ON_MISSING_CHECK_DECL='{ throw std::logic_error("missing contract check declaration"); }' @endcode @see @RefSect{tutorial.non_member_functions, Non-Member Functions} @@ -209,15 +222,17 @@ Configure this library compile-time and run-time behaviours. Not disabling other assertions while checking preconditions can lead to infinite recursion in user code so by default this macro is not defined. + However, the @RefSect{bibliography, [1962]} proposal does not disable any assertion while checking preconditions because arguments can reach the function body unchecked if assertions are disabled while checking - preconditions (when these same functions bodies are called to check the - preconditions in question). + preconditions (e.g., when these same functions bodies are called to check + the preconditions in question). This macro can be defined to obtain the behaviour specified in @RefSect{bibliography, [1962]} (at the risk of infinite recursion). - @see @RefSect{contract_programming_overview, Contract Programming Overview} + @see @RefSect{contract_programming_overview.feature_summary, + Feature Summary} */ #define BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION #endif @@ -234,14 +249,28 @@ Configure this library compile-time and run-time behaviours. @RefMacro{BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION} was also defined.) - @see @RefSect{contract_programming_overview, Contract Programming Overview} + @see @RefSect{contract_programming_overview.feature_summary, + Feature Summary} */ #define BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN - /** TODO */ - #define BOOST_CONTRACT_NO_AUDITS + /** + Define this macro to evaluate and check audit assertions at run-time + (undefined by default). + + Audit assertions and implementation checks programmed via + @RefMacro{BOOST_CONTRACT_ASSERT_AUDIT} and + @RefMacro{BOOST_CONTRACT_CHECK_AUDIT} are always compiled and validated + syntactically. + However, they are not evaluated and checked at run-time unless + this macro is defined (because these conditions can be computationally + expensive, at least compared to the cost of executing the function body). + + @see @RefSect{extras.assertion_levels, Assertion Levels} + */ + #define BOOST_CONTRACT_AUDITS #endif #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN @@ -254,12 +283,12 @@ Configure this library compile-time and run-time behaviours. implementation checks. Use @RefMacro{BOOST_CONTRACT_CHECK} to completely disable compilation of implementation checks when @RefMacro{BOOST_CONTRACT_NO_CHECKS} is defined. - - @see @RefSect{advanced_topics.implementation_checks, + + @see @RefSect{advanced.implementation_checks, Implementation Checks}, - @RefSect{extra_topics.disable_contract_checking, + @RefSect{extras.disable_contract_checking, Disable Contract Checking}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_CHECKS @@ -280,9 +309,9 @@ Configure this library compile-time and run-time behaviours. from production code). @see @RefSect{tutorial.preconditions, Preconditions}, - @RefSect{extra_topics.disable_contract_checking, + @RefSect{extras.disable_contract_checking, Disable Contract Checking}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_PRECONDITIONS @@ -303,9 +332,9 @@ Configure this library compile-time and run-time behaviours. from production code). @see @RefSect{tutorial.postconditions, Postconditions}, - @RefSect{extra_topics.disable_contract_checking, + @RefSect{extras.disable_contract_checking, Disable Contract Checking}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_POSTCONDITIONS @@ -326,9 +355,9 @@ Configure this library compile-time and run-time behaviours. compilation from production code). @see @RefSect{tutorial.exception_guarantees, Exception Guarantees}, - @RefSect{extra_topics.disable_contract_checking, + @RefSect{extras.disable_contract_checking, Disable Contract Checking}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_EXCEPTS @@ -345,7 +374,7 @@ Configure this library compile-time and run-time behaviours. If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with - checking entry class invariants. + checking class invariants at entry. Users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of entry class invariants or use the macros defined in @c boost/contract_macro.hpp (recommended only for @@ -356,9 +385,9 @@ Configure this library compile-time and run-time behaviours. @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined. @see @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.disable_contract_checking, + @RefSect{extras.disable_contract_checking, Disable Contract Checking}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_ENTRY_INVARIANTS @@ -375,7 +404,7 @@ Configure this library compile-time and run-time behaviours. If this macro is defined, this library internal code is also optimized to reduce compile-time (not just run-time) overhead associated with - checking exit class invariants. + checking class invariants at exit. Users can manually program @c \#ifndef statements in their code using this macro to completely disable compilation of exit class invariants or use the macros defined in @c boost/contract_macro.hpp (recommended only for @@ -386,9 +415,9 @@ Configure this library compile-time and run-time behaviours. @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} is defined. @see @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.disable_contract_checking, + @RefSect{extras.disable_contract_checking, Disable Contract Checking}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_EXIT_INVARIANTS @@ -415,9 +444,9 @@ Configure this library compile-time and run-time behaviours. @RefMacro{BOOST_CONTRACT_NO_EXIT_INVARIANTS}. @see @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.disable_contract_checking, + @RefSect{extras.disable_contract_checking, Disable Contract Checking}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_INVARIANTS @@ -445,8 +474,8 @@ Configure this library compile-time and run-time behaviours. compilation from production code). @see @RefSect{tutorial.old_values, Old Values}, - @RefSect{advanced_topics.old_values_at_body, Old Values at Body}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{advanced.old_values_at_body, Old Values at Body}, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_OLDS @@ -459,8 +488,8 @@ Configure this library compile-time and run-time behaviours. defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** - Automatically defined by this library when contracts are not to be checked - for constructors. + Automatically defined by this library when contracts are not checked for + constructors. This library will define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @@ -479,7 +508,7 @@ Configure this library compile-time and run-time behaviours. disabled by @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS} instead. @see @RefSect{tutorial.constructors, Constructors}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_CONSTRUCTORS @@ -491,8 +520,8 @@ Configure this library compile-time and run-time behaviours. defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** - Automatically defined by this library when contracts are not to be checked - for destructors. + Automatically defined by this library when contracts are not checked for + destructors. This library will define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @@ -507,7 +536,7 @@ Configure this library compile-time and run-time behaviours. compilation from production code). @see @RefSect{tutorial.destructors, Destructors}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_DESTRUCTORS @@ -520,8 +549,8 @@ Configure this library compile-time and run-time behaviours. defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** - Automatically defined by this library when contracts are not to be checked - for public functions. + Automatically defined by this library when contracts are not checked for + public functions. This library will define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @@ -537,7 +566,7 @@ Configure this library compile-time and run-time behaviours. compilation from production code). @see @RefSect{tutorial.public_functions, Public Functions}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS @@ -549,8 +578,8 @@ Configure this library compile-time and run-time behaviours. defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** - Automatically defined by this library when contracts are not to be checked - for (non-public) functions. + Automatically defined by this library when contracts are not checked for + non-member, private and protected functions. This library will define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS}, @@ -559,20 +588,21 @@ Configure this library compile-time and run-time behaviours. macro and this library will generate a compile-time error if users try to define it directly). Users can manually program @c \#ifndef statements in their code using this - macro to completely disable compilation of contracts for (non-public) - functions or use the macros defined in @c boost/contract_macro.hpp - (recommended only for applications where it is truly necessary to completely - remove contract code compilation from production code). + macro to completely disable compilation of contracts for non-member, + private and protected functions, or use the macros defined in + @c boost/contract_macro.hpp (recommended only for applications where it is + truly necessary to completely remove contract code compilation from + production code). - This macro is also used when contracts are not to be checked for private and + This macro is also used when contracts are not checked for private and protected functions, lambda functions, code blocks, loops, etc. @see @RefSect{tutorial.non_member_functions, Non-Member Functions}, - @RefSect{advanced_topics.private_and_protected_functions, + @RefSect{advanced.private_and_protected_functions, Private and Protected Functions}, - @RefSect{advanced_topics.lambdas__code_blocks__loops__etc_, + @RefSect{advanced.lambdas__code_blocks__loops__etc_, Lambdas\, Code Blocks\, Loops\, Etc.}, - @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_FUNCTIONS @@ -585,14 +615,15 @@ Configure this library compile-time and run-time behaviours. defined(BOOST_CONTRACT_NO_POSTCONDITIONS) && \ defined(BOOST_CONTRACT_NO_EXCEPTS) /** - Automatically defined by this library when contracts are not to be checked - for specification conditions (but excluding implementation checks). + Automatically defined by this library when contracts are not checked for + preconditions, postconditions, exceptions guarantees, and class invariants + (excluding implementation checks). This library will define this macro when users define all - @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @RefMacro{BOOST_CONTRACT_NO_PRECONDITIONS}, - @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, and - @RefMacro{BOOST_CONTRACT_NO_EXCEPTS} (this macro is not a configuration + @RefMacro{BOOST_CONTRACT_NO_POSTCONDITIONS}, + @RefMacro{BOOST_CONTRACT_NO_EXCEPTS}, and + @RefMacro{BOOST_CONTRACT_NO_INVARIANTS} (this macro is not a configuration macro and this library will generate a compile-time error if users try to define it directly). Users can manually program @c \#ifndef statements in their code using this @@ -601,7 +632,7 @@ Configure this library compile-time and run-time behaviours. for applications where it is truly necessary to completely remove contract code compilation from production code). - @see @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @see @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_CONDITIONS @@ -615,8 +646,7 @@ Configure this library compile-time and run-time behaviours. defined(BOOST_CONTRACT_NO_EXCEPTS) && \ defined(BOOST_CONTRACT_NO_CHECKS) /** - Automatically defined by this library when contracts are not to be checked - for any operation. + Automatically defined by this library when contracts are not checked at all. This library will define this macro when users define all @RefMacro{BOOST_CONTRACT_NO_INVARIANTS}, @@ -637,11 +667,13 @@ Configure this library compile-time and run-time behaviours. #endif @endcode - Or, include @c boost/contract_macro.hpp instead (recommended only for - applications where it is truly necessary to completely remove contract - code compilation from production code). + Or, use the @c boost/contract_macro.hpp header and related macros instead + (because the @c boost/contract/_macro.hpp header is already optimized to not + include other headers from this library when contracts are not checked, but + recommended only for applications where it is truly necessary to completely + remove contract code compilation from production code). - @see @RefSect{extra_topics.disable_contract_compilation__macro_interface_, + @see @RefSect{extras.disable_contract_compilation__macro_interface_, Disable Contract Compilation} */ #define BOOST_CONTRACT_NO_ALL @@ -657,7 +689,7 @@ Configure this library compile-time and run-time behaviours. ) /** Automatically defined when this library is being compiled as a shared - library (automatically defined by default). + library (defined by default). This library will define this macro unless users define @RefMacro{BOOST_CONTRACT_STATIC_LINK} or @@ -668,7 +700,10 @@ Configure this library compile-time and run-time behaviours. @warning In general this library will correctly check contracts at run-time only when compiled as a shared library (i.e., this - macro will be automatically defined by default). + macro will be automatically defined by default), unless user + code checks contracts in a single program unit (e.g., a single + program with only statically linked libraries that check + contracts). @see @RefSect{getting_started.install_and_compile, Install and Compile} */ diff --git a/include/boost/contract/core/constructor_precondition.hpp b/include/boost/contract/core/constructor_precondition.hpp index adde6e6..aec5e0c 100644 --- a/include/boost/contract/core/constructor_precondition.hpp +++ b/include/boost/contract/core/constructor_precondition.hpp @@ -26,11 +26,14 @@ namespace boost { namespace contract { Program preconditions for constructors. This class must be the very first base of the class declaring the -constructor for which preconditions are being programmed (that way constructor -arguments are checked by preconditions even before they are used to initialize -any other base class). -Also user-defined classes should inherit privately (and never virtually) from -this class (to not alter the public interface of user-defined classes). +constructor for which preconditions are programmed (that way constructor +arguments can be checked by preconditions even before they are used to +initialize other base classes). +User-defined classes should inherit privately from this class (to not alter the +public interface of user-defined classes). +In addition, this class should never be declared as a virtual base (because +virtual bases are initialized only once across the entire inheritance hierarchy +preventing preconditions of other base classes from being checked). Unions cannot have base classes in C++ so this class can be used to declare a local object within the constructor definition just before @@ -53,7 +56,7 @@ public: @note Calling this default constructor should amount to negligible compile-time and run-time overheads (likely to be optimized away - completely in most cases). + completely by most compilers). */ constructor_precondition() {} diff --git a/include/boost/contract/core/exception.hpp b/include/boost/contract/core/exception.hpp index 66e753c..0c1d833 100644 --- a/include/boost/contract/core/exception.hpp +++ b/include/boost/contract/core/exception.hpp @@ -35,7 +35,7 @@ namespace std { namespace boost { namespace contract { /** -Public base class for all exceptions of this library. +Public base class for all exceptions directly thrown by this library. This class does not inherit from @c std::exception because exceptions deriving from this class will (inheriting from @c std::exception, @c std::bad_cast, @@ -68,6 +68,7 @@ This exception is internally thrown by this library when programmers specify return values for public function overrides in derived classes that are not consistent with the return types of the virtual public functions being overridden in the base classes. +This allows this library to give more descriptive error messages in such cases. @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} @@ -76,7 +77,7 @@ class BOOST_CONTRACT_DETAIL_DECLSPEC bad_virtual_result_cast : // Copy (as str). public std::bad_cast, public boost::contract::exception { public: /** - Construct this object with the name of the from- and to- types. + Construct this object with the name of the from- and to- result types. @param from_type_name Name of the from-type (source of the cast). @param to_type_name Name of the to-type (destination of the cast). */ @@ -109,26 +110,27 @@ Exception typically used to report a contract assertion failure. This exception is thrown by code expanded by @RefMacro{BOOST_CONTRACT_ASSERT} (but it can also be thrown by user code programmed manually without that macro). This exception is typically used to report contract assertion failures because -it contains detailed information about the assertion file name, line number, -condition source code, etc. (so it provides detailed error messages), but any -other exception can be used to report a contract assertion failure (including -user-defined exceptions). +it contains detailed information about the file name, line number, and source +code of the asserted condition (so it can be used by this library to provide +detailed error messages). +However, any other exception can be used to report a contract assertion failure +(including user-defined exceptions). This library will call the appropriate contract failure handler function (@RefFunc{boost::contract::precondition_failure}, etc.) when this or any other exception is thrown while checking contracts (by default, these failure handler -functions print an error message to @c std::cerr and then terminate the program, -but they can be customized to take any other action). +functions print an error message to @c std::cerr and terminate the program, but +they can be customized to take any other action). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, - @RefSect{extra_topics.no_macros__c__11_, No Macros} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, + @RefSect{extras.no_macros__c__11_, No Macros} */ class BOOST_CONTRACT_DETAIL_DECLSPEC assertion_failure : // Copy (as str, etc.). public std::exception, public boost::contract::exception { public: /** - Construct this object with the asserted condition file name, line number, - and source code text (all optional). + Construct this object with file name, line number, and source code text of + an assertion condition (all optional). This constructor can also be used to specify no information (default constructor), or to specify only file name and line number but not source @@ -138,14 +140,15 @@ public: __FILE__). @param line Number of the line containing the assertion (usually set using __LINE__). - @param code Text listing the source code of the asserted condition. + @param code Text listing the source code of the assertion condition. */ - explicit assertion_failure(char const* file = "", - unsigned long const line = 0, char const* code = ""); + explicit assertion_failure(char const* file = "", unsigned long line = 0, + char const* code = ""); /** - Construct this object with the asserted condition source code text only. - @param code Text listing the source code of the asserted condition. + Construct this object only with the source code text of the assertion + condition. + @param code Text listing the source code of the assertion condition. */ explicit assertion_failure(char const* code); @@ -162,29 +165,29 @@ public: @return A string formatted similarly to the following: assertion "`code()`" failed: file "`file()`", line \`line()\`. File, line, and code will be omitted from this string if they were - not specified at construction. + not specified when constructing this object. */ virtual char const* what() const /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */; /** - Name of the file listing the assertion. - @return File as specified at construction (or @c "" if no file was + Name of the file containing the assertion. + @return File name as specified at construction (or @c "" if no file was specified). */ char const* file() const; /** - Number of the line listing the assertion. + Number of the line containing the assertion. @return Line number as specified at construction (or @c 0 if no line number was specified). */ unsigned long line() const; /** - Text listing the source code of the asserted condition. - @return Asserted condition source code as specified at construction (or - @c "" if no code text was specified). + Text listing the source code of the assertion condition. + @return Assertion condition source code as specified at construction (or + @c "" if no source code text was specified). */ char const* code() const; @@ -212,7 +215,7 @@ failed to make sure exceptions are never thrown from destructors, not even when contract failure handlers are programmed by users to throw exceptions instead of terminating the program. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure} */ enum from { /** Assertion failed when checking contracts for constructors. */ @@ -228,23 +231,23 @@ enum from { }; /** -Assertion failure handler function type (with @c from parameter). +Type of assertion failure handler functions (with @c from parameter). Assertion failure handler functions specified by this type must be functors returning @c void and taking a single parameter of type @RefEnum{boost::contract::from}. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure} */ typedef boost::function from_failure_handler; /** -Assertion failure handler function type (without @c from parameter). +Type of assertion failure handler functions (without @c from parameter). Assertion failure handler functions specified by this type must be nullary functors returning @c void. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure} */ typedef boost::function failure_handler; @@ -441,11 +444,11 @@ Set a new failure handler and returns it. @param f New failure handler functor to set. -@return Same failure handler functor @p f passed as parameter (for concatenating - function calls). +@return Same failure handler functor @p f passed as parameter (e.g., for + concatenating function calls). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, - @RefSect{advanced_topics.implementation_checks, Implementation Checks} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, + @RefSect{advanced.implementation_checks, Implementation Checks} */ inline failure_handler const& set_check_failure(failure_handler const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { @@ -465,8 +468,8 @@ This is often called only internally by this library. @return A copy of the failure handler currently set. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, - @RefSect{advanced_topics.implementation_checks, Implementation Checks} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, + @RefSect{advanced.implementation_checks, Implementation Checks} */ inline failure_handler get_check_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { @@ -485,8 +488,8 @@ This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on contract assertion failures (not the default). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, - @RefSect{advanced_topics.implementation_checks, Implementation Checks} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, + @RefSect{advanced.implementation_checks, Implementation Checks} */ inline void check_failure() /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS @@ -505,10 +508,10 @@ Set a new failure handler and returns it. @param f New failure handler functor to set. -@return Same failure handler functor @p f passed as parameter (for concatenating - function calls). +@return Same failure handler functor @p f passed as parameter (e.g., for + concatenating function calls). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.preconditions, Preconditions} */ inline from_failure_handler const& set_precondition_failure(from_failure_handler @@ -529,7 +532,7 @@ This is often called only internally by this library. @return A copy of the failure handler currently set. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.preconditions, Preconditions} */ inline from_failure_handler get_precondition_failure() @@ -549,10 +552,11 @@ This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that throws exceptions on contract assertion failures (not the default). -@param where Operation that failed the contract assertion (note that - destructors never have preconditions). +@param where Operation that failed the contract assertion (when called by + this library, this parameter will never be @c from_destructor + because destructors never have preconditions). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.preconditions, Preconditions} */ inline void precondition_failure(from where) /* can throw */ { @@ -572,10 +576,10 @@ Set a new failure handler and returns it. @param f New failure handler functor to set. -@return Same failure handler functor @p f passed as parameter (for concatenating - function calls). +@return Same failure handler functor @p f passed as parameter (e.g., fr + concatenating function calls). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.postconditions, Postconditions} */ inline from_failure_handler const& set_postcondition_failure( @@ -597,7 +601,7 @@ This is often called only internally by this library. @return A copy of the failure handler currently set. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.postconditions, Postconditions} */ inline from_failure_handler get_postcondition_failure() @@ -622,7 +626,7 @@ This is often called only internally by this library. from destructors, not even when they are programmed by users to throw exceptions instead of terminating the program). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.postconditions, Postconditions} */ inline void postcondition_failure(from where) /* can throw */ { @@ -642,10 +646,10 @@ Set a new failure handler and returns it. @param f New failure handler functor to set. -@return Same failure handler functor @p f passed as parameter (for concatenating - function calls). +@return Same failure handler functor @p f passed as parameter (e.g., for + concatenating function calls). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} */ inline from_failure_handler const& set_except_failure(from_failure_handler @@ -666,7 +670,7 @@ This is often called only internally by this library. @return A copy of the failure handler currently set. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} */ inline from_failure_handler get_except_failure() @@ -684,16 +688,18 @@ Call failure handler for exception guarantees. This is often called only internally by this library. @b Throws: This can throw in case programmers specify a failure handler that - throws exceptions on contract assertion failures (not the default). + throws exceptions on contract assertion failures (not the default), + however: -@warning However, note that when this failure handler is called there is - already an active exception (the one that caused the exception - guarantees to be checked in the first place) so throwing yet another - exception will force C++ to terminate the program. +@warning When this failure handler is called there is already an active + exception (the one that caused the exception guarantees to be + checked in the first place). + Therefore, programming this failure handler to throw yet another + exception will force C++ to always terminate the program. @param where Operation that failed the contract assertion. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} */ inline void except_failure(from where) /* can throw */ { @@ -713,11 +719,11 @@ Set a new failure handler and returns it. @param f New failure handler functor to set. -@return Same failure handler functor @p f passed as parameter (for concatenating - function calls). +@return Same failure handler functor @p f passed as parameter (e.g., for + concatenating function calls). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, - @RefSect{advanced_topics.old_values_at_body, Old Values at Body} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, + @RefSect{advanced.old_values_at_body, Old Values at Body} */ inline from_failure_handler const& set_old_failure(from_failure_handler const& f) /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { @@ -737,8 +743,8 @@ This is often called only internally by this library. @return A copy of the failure handler currently set. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, - @RefSect{advanced_topics.old_values_at_body, Old Values at Body} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, + @RefSect{advanced.old_values_at_body, Old Values at Body} */ inline from_failure_handler get_old_failure() /** @cond */ BOOST_NOEXCEPT_OR_NOTHROW /** @endcond */ { @@ -762,8 +768,8 @@ This is often called only internally by this library. from destructors, not even when they are programmed by users to throw exceptions instead of terminating the program). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, - @RefSect{advanced_topics.old_values_at_body, Old Values at Body} +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, + @RefSect{advanced.old_values_at_body, Old Values at Body} */ inline void old_failure(from where) /* can throw */ { #ifndef BOOST_CONTRACT_DISABLE_THREADS @@ -782,12 +788,12 @@ Set a new failure handler and returns it. @param f New failure handler functor to set. -@return Same failure handler functor @p f passed as parameter (for concatenating - function calls). +@return Same failure handler functor @p f passed as parameter (e.g., for + concatenating function calls). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler const& set_entry_invariant_failure( @@ -809,9 +815,9 @@ This is often called only internally by this library. @return A copy of the failure handler currently set. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler get_entry_invariant_failure() @@ -836,9 +842,9 @@ This is often called only internally by this library. from destructors, not even when they are programmed by users to throw exceptions instead of terminating the program). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline void entry_invariant_failure(from where) /* can throw */ { @@ -858,12 +864,12 @@ Set a new failure handler and returns it. @param f New failure handler functor to set. -@return Same failure handler functor @p f passed as parameter (for concatenating - function calls). +@return Same failure handler functor @p f passed as parameter (e.g., for + concatenating function calls). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler const& set_exit_invariant_failure( @@ -885,9 +891,9 @@ This is often called only internally by this library. @return A copy of the failure handler currently set. -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler get_exit_invariant_failure() @@ -912,9 +918,9 @@ This is often called only internally by this library. from destructors, not even when they are programmed by users to throw exceptions instead of terminating the program). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline void exit_invariant_failure(from where) /* can throw */ { @@ -929,7 +935,7 @@ inline void exit_invariant_failure(from where) /* can throw */ { /** Set failure handler for class invariants (at both entry and exit). -This is equivalent to calling both +This is provided for convenience and it is equivalent to call both @RefFunc{boost::contract::set_entry_invariant_failure} and @RefFunc{boost::contract::set_exit_invariant_failure} with the same functor parameter @p f. @@ -938,12 +944,12 @@ parameter @p f. @param f New failure handler functor to set for both entry and exit invariants. -@return Same failure handler functor @p f passed as parameter (for concatenating - function calls). +@return Same failure handler functor @p f passed as parameter (e.g., for + concatenating function calls). -@see @RefSect{advanced_topics.throw_on_failure, Throw on Failure}, +@see @RefSect{advanced.throw_on_failure__and__noexcept__, Throw on Failure}, @RefSect{tutorial.class_invariants, Class Invariants}, - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions} */ inline from_failure_handler const& set_invariant_failure(from_failure_handler diff --git a/include/boost/contract/core/specify.hpp b/include/boost/contract/core/specify.hpp index 50371a4..b3a32ce 100644 --- a/include/boost/contract/core/specify.hpp +++ b/include/boost/contract/core/specify.hpp @@ -147,7 +147,7 @@ public: @b Throws: This can throw (i.e., @c noexcept(false)) in case programmers specify failure handlers that throw exceptions instead of terminating the program (see - @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). + @RefSect{advanced.throw_on_failure, Throw on Failure}). */ ~specify_nothing() BOOST_NOEXCEPT_IF(false) {} @@ -191,7 +191,7 @@ public: @b Throws: This can throw (i.e., @c noexcept(false)) in case programmers specify failure handlers that throw exceptions instead of terminating the program (see - @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). + @RefSect{advanced.throw_on_failure, Throw on Failure}). */ ~specify_except() BOOST_NOEXCEPT_IF(false) {} @@ -205,7 +205,6 @@ public: call to this functor indicates a contract assertion failure (and will result in this library calling @RefFunc{boost::contract::except_failure}). - @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). This functor should capture variables by (constant) references (to access the values they will have at function exit). @@ -238,9 +237,9 @@ private: }; /** -Allow to specify postconditions and exception guarantees. +Allow to specify postconditions or exception guarantees. -Allow to specify functors this library will call to check postconditions and +Allow to specify functors this library will call to check postconditions or exception guarantees. @see @RefSect{tutorial.postconditions, Postconditions}, @@ -260,7 +259,7 @@ public: @b Throws: This can throw (i.e., @c noexcept(false)) in case programmers specify failure handlers that throw exceptions instead of terminating the program (see - @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). + @RefSect{advanced.throw_on_failure, Throw on Failure}). */ ~specify_postcondition_except() BOOST_NOEXCEPT_IF(false) {} @@ -329,12 +328,12 @@ private: }; /** -Allow to specify old copies at body, postconditions, and exception guarantees. +Allow to specify old copies at body, postconditions, or exception guarantees. Allow to specify functors this library will call to copy old value at body, -check postconditions, and check exception guarantees. +check postconditions, or check exception guarantees. -@see @RefSect{advanced_topics.old_values_at_body, Old Values at Body}, +@see @RefSect{advanced.old_copies_at_body, Old Copies at Body}, @RefSect{tutorial.postconditions, Postconditions}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} @@ -352,7 +351,7 @@ public: @b Throws: This can throw (i.e., @c noexcept(false)) in case programmers specify failure handlers that throw exceptions instead of terminating the program (see - @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). + @RefSect{advanced.throw_on_failure, Throw on Failure}). */ ~specify_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {} @@ -361,7 +360,7 @@ public: It should often be sufficient to initialize old value pointers as soon as they are declared, without using this function (see - @RefSect{advanced_topics.old_values_at_body, Old Values at Body}). + @RefSect{advanced.old_copies_at_body, Old Copies at Body}). @param f Nullary functor called by this library @c f() to assign old value copies just before the body is executed but after entry @@ -463,7 +462,7 @@ Allow to specify functors this library will call to check preconditions, copy old values at body, check postconditions, and check exception guarantees. @see @RefSect{tutorial.preconditions, Preconditions}, - @RefSect{advanced_topics.old_values_at_body, Old Values at Body}, + @RefSect{advanced.old_copies_at_body, Old Copies at Body}, @RefSect{tutorial.postconditions, Postconditions}, @RefSect{tutorial.exception_guarantees, Exception Guarantees} @@ -486,7 +485,7 @@ public: @b Throws: This can throw (i.e., @c noexcept(false)) in case programmers specify failure handlers that throw exceptions instead of terminating the program (see - @RefSect{advanced_topics.throw_on_failure, Throw on Failure}). + @RefSect{advanced.throw_on_failure, Throw on Failure}). */ ~specify_precondition_old_postcondition_except() BOOST_NOEXCEPT_IF(false) {} @@ -517,7 +516,7 @@ public: It should often be sufficient to initialize old value pointers as soon as they are declared, without using this function (see - @RefSect{advanced_topics.old_values_at_body, Old Values at Body}). + @RefSect{advanced.old_copies_at_body, Old Copies at Body}). @param f Nullary functor called by this library @c f() to assign old value copies just before the body is executed but after entry diff --git a/include/boost/contract/core/virtual.hpp b/include/boost/contract/core/virtual.hpp index 632e996..5ccd606 100644 --- a/include/boost/contract/core/virtual.hpp +++ b/include/boost/contract/core/virtual.hpp @@ -8,7 +8,7 @@ // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html /** @file -Handle virtual public functions for contracts (for subcontracting). +Handle virtual public functions with contracts (for subcontracting). */ // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes. @@ -45,20 +45,21 @@ This parameter must be a pointer to this class and it must have default value (This extra parameter is often named @c v in this documentation, but any name can be used.) -This extra parameter does not alter the calling interface of the enclosing -function declaring the contract because it is always the very last parameter and -it has a default value (so it can always be omitted when users call the -function). +In practice this extra parameter does not alter the calling interface of the +enclosing function declaring the contract because it is always the very last +parameter and it has a default value (so it can always be omitted when users +call the function). This extra parameter must be passed to @RefFunc{boost::contract::public_function}, @RefMacro{BOOST_CONTRACT_OLDOF}, and -all other operations of this library that require a pointer to +all other operations of this library that accept a pointer to @RefClass{boost::contract::virtual_}. A part from that, this class is not intended to be directly used by programmers (and that is why this class does not have any public member and it is not copyable). @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions}, - @RefSect{tutorial.public_function_overrides, Public Function Overrides} + @RefSect{tutorial.public_function_overrides__subcontracting_, + Public Function Overrides} */ class virtual_ { // Non-copyable (see below) to avoid copy queue, stack, etc. /** @cond */ diff --git a/include/boost/contract/destructor.hpp b/include/boost/contract/destructor.hpp index 00f04ae..7d7a866 100644 --- a/include/boost/contract/destructor.hpp +++ b/include/boost/contract/destructor.hpp @@ -31,8 +31,7 @@ preconditions, see @RefSect{contract_programming_overview, Contract Programming Overview}). For optimization, this can be omitted for destructors that do not have -postconditions and exception guarantees when the enclosing class has no -invariants. +postconditions and exception guarantees, within classes that have no invariants. @see @RefSect{tutorial.destructors, Destructors} @@ -41,10 +40,10 @@ invariants. (Destructors check all class invariants, including static and volatile invariants, see also @RefSect{tutorial.class_invariants, Class Invariants} and - @RefSect{advanced_topics.volatile_public_functions, + @RefSect{advanced.volatile_public_functions, Volatile Public Functions}). -@tparam Class The class type of the enclosing destructor declaring the +@tparam Class The type of the class containing the destructor declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) diff --git a/include/boost/contract/detail/operation/public_static_function.hpp b/include/boost/contract/detail/operation/static_public_function.hpp similarity index 92% rename from include/boost/contract/detail/operation/public_static_function.hpp rename to include/boost/contract/detail/operation/static_public_function.hpp index 83b2460..d706024 100644 --- a/include/boost/contract/detail/operation/public_static_function.hpp +++ b/include/boost/contract/detail/operation/static_public_function.hpp @@ -1,6 +1,6 @@ -#ifndef BOOST_CONTRACT_DETAIL_PUBLIC_STATIC_FUNCTION_HPP_ -#define BOOST_CONTRACT_DETAIL_PUBLIC_STATIC_FUNCTION_HPP_ +#ifndef BOOST_CONTRACT_DETAIL_STATIC_PUBLIC_FUNCTION_HPP_ +#define BOOST_CONTRACT_DETAIL_STATIC_PUBLIC_FUNCTION_HPP_ // Copyright (C) 2008-2016 Lorenzo Caminiti // Distributed under the Boost Software License, Version 1.0 (see accompanying @@ -29,9 +29,9 @@ namespace boost { namespace contract { namespace detail { // No subcontracting because static so no obj and no substitution principle. template // Non-copyable base. -class public_static_function : public cond_inv { +class static_public_function : public cond_inv { public: - explicit public_static_function() : cond_inv( + explicit static_public_function() : cond_inv( boost::contract::from_function, /* obj = */ 0) {} private: @@ -74,7 +74,7 @@ public: #if !defined(BOOST_CONTRACT_NO_EXIT_INVARIANTS) || \ !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ !defined(BOOST_CONTRACT_NO_EXCEPTS) - ~public_static_function() BOOST_NOEXCEPT_IF(false) { + ~static_public_function() BOOST_NOEXCEPT_IF(false) { this->assert_initialized(); #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION if(checking::already()) return; diff --git a/include/boost/contract/detail/type_traits/introspection.hpp b/include/boost/contract/detail/type_traits/mirror.hpp similarity index 70% rename from include/boost/contract/detail/type_traits/introspection.hpp rename to include/boost/contract/detail/type_traits/mirror.hpp index 002fe58..fe00c30 100644 --- a/include/boost/contract/detail/type_traits/introspection.hpp +++ b/include/boost/contract/detail/type_traits/mirror.hpp @@ -1,6 +1,6 @@ -#ifndef BOOST_CONTRACT_DETAIL_INTROSPECTION_HPP_ -#define BOOST_CONTRACT_DETAIL_INTROSPECTION_HPP_ +#ifndef BOOST_CONTRACT_DETAIL_MIRROR_HPP_ +#define BOOST_CONTRACT_DETAIL_MIRROR_HPP_ // Copyright (C) 2008-2016 Lorenzo Caminiti // Distributed under the Boost Software License, Version 1.0 (see accompanying @@ -18,21 +18,21 @@ #include // NOTE: Unfortunately, it is not possible to use Boost.TTI because it not -// always works on MSVC (e.g., when the introspecting meta-function is invoked +// always works on MSVC (e.g., when the mirror meta-function is invoked // multiple times, MSVC 2010 gives an internal compiler error). This is a -// simpler introspecting implementation that seems to work better on MSVC. +// simpler mirror implementation that seems to work better on MSVC. /* PRIVATE */ -#define BOOST_CONTRACT_DETAIL_INTROSPECTION_END_(tparam) \ +#define BOOST_CONTRACT_DETAIL_MIRROR_END_(tparam) \ template \ - static boost::contract::detail::introspection::no& check(...); \ + static boost::contract::detail::mirror::no& check(...); \ public: \ static bool const value = sizeof(check(0)) == \ - sizeof(boost::contract::detail::introspection::yes); \ + sizeof(boost::contract::detail::mirror::yes); \ typedef boost::mpl::bool_ type; -#define BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_MEMBER_FUNCTION_(is_static, \ +#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_(is_static, \ trait, func_name) \ template< \ typename BOOST_CONTRACT_DETAIL_NAME1(T), \ @@ -42,8 +42,8 @@ > \ class trait { \ template \ - static boost::contract::detail::introspection::yes& check( \ - boost::contract::detail::introspection::check_function< \ + static boost::contract::detail::mirror::yes& check( \ + boost::contract::detail::mirror::check_function< \ typename \ BOOST_PP_IIF(is_static, \ boost::function_types::function_pointer \ @@ -70,36 +70,35 @@ &BOOST_CONTRACT_DETAIL_NAME1(C)::func_name \ >* \ ); \ - BOOST_CONTRACT_DETAIL_INTROSPECTION_END_( \ + BOOST_CONTRACT_DETAIL_MIRROR_END_( \ BOOST_CONTRACT_DETAIL_NAME1(T)) \ }; /* PUBLIC */ -#define BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_TYPE(trait, type_name)\ +#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_TYPE(trait, type_name)\ template \ class trait { \ template \ - static boost::contract::detail::introspection::yes& check( \ + static boost::contract::detail::mirror::yes& check( \ typename BOOST_CONTRACT_DETAIL_NAME1(C)::type_name*); \ - BOOST_CONTRACT_DETAIL_INTROSPECTION_END_( \ + BOOST_CONTRACT_DETAIL_MIRROR_END_( \ BOOST_CONTRACT_DETAIL_NAME1(T)) \ }; -#define BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_MEMBER_FUNCTION( \ +#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( \ trait, func_name) \ - BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_MEMBER_FUNCTION_( \ + BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_( \ /* is_static = */ 0, trait, func_name) -#define BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_STATIC_MEMBER_FUNCTION(trait, \ +#define BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION(trait, \ func_name) \ - BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_MEMBER_FUNCTION_( \ + BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION_( \ /* is_static = */ 1, trait, func_name) /* CODE */ -namespace boost { namespace contract { namespace detail { - namespace introspection { +namespace boost { namespace contract { namespace detail { namespace mirror { typedef class {} yes; typedef yes no[2]; diff --git a/include/boost/contract/function.hpp b/include/boost/contract/function.hpp index f7da36d..a8fe6e3 100644 --- a/include/boost/contract/function.hpp +++ b/include/boost/contract/function.hpp @@ -29,16 +29,16 @@ old copies at body for non-member, private and protected functions (these functions never check class invariants, see @RefSect{contract_programming_overview, Contract Programming Overview}). It can be used also to program contracts in implementation code for lambda -functions, loops, arbitrary blocks of code, etc. +functions, loops, and arbitrary blocks of code. For optimization, this can be omitted for code that does not have preconditions, postconditions, and exception guarantees. @see @RefSect{tutorial.non_member_functions, Non-Member Functions}, - @RefSect{advanced_topics.private_and_protected_functions, + @RefSect{advanced.private_and_protected_functions, Private and Protected Functions}, - @RefSect{advanced_topics.lambdas__loops__code_blocks__etc_, - Lambdas\, Loops\, Code Blocks\, Etc.} + @RefSect{advanced.lambdas__loops__code_blocks__and__constexpr__, + Lambdas\, Loops\, Code Blocks} @return The result of this function must be explicitly assigned to a variable of type @RefClass{boost::contract::check} declared locally just before the diff --git a/include/boost/contract/old.hpp b/include/boost/contract/old.hpp index 3acd910..822892c 100644 --- a/include/boost/contract/old.hpp +++ b/include/boost/contract/old.hpp @@ -98,17 +98,17 @@ Where: from the enclosing virtual public function or public function overrides declaring the contract. (This is not a variadic macro parameter so any comma it might contain - must be protected by round parenthesis, but + must be protected by round parenthesis, BOOST_CONTRACT_OLDOF((v), expr) will always work.) -@arg expr is the expression to be evaluated and copied in - the old value pointer. +@arg expr is the expression to be evaluated and copied to the + old value pointer. (This is not a variadic macro parameter so any comma it might contain - must be protected by round parenthesis, but + must be protected by round parenthesis, BOOST_CONTRACT_OLDOF(v, (expr)) will always work.) On compilers that do not support variadic macros, programmers can manually copy old value expressions without using this macro (see -@RefSect{extra_topics.no_macros__no_c__11_, No Macros}). +@RefSect{extras.no_macros__and_no_variadic_macros_, No Macros}). @see @RefSect{tutorial.old_values, Old Values} */ @@ -132,8 +132,8 @@ Trait to check if an old value type can be copied or not. By default, this unary boolean meta-function is equivalent to @c boost::is_copy_constructible but programmers can chose to specialize it -for specific user-defined types (in general some kind of specialization is -needed on compilers that do not support C++11, see also +for user-defined types (in general some kind of specialization is needed on +compilers that do not support C++11, see also boost::is_copy_constructible). @@ -144,9 +144,9 @@ Copyable old value types are always copied using Non-copyable old value types generate a compile-time error when @c boost::contract::old_ptr is dereferenced, but instead leave @c boost::contract::old_ptr_if_copyable always null (without generating -a compile-time error). +compile-time errors). -@see @RefSect{extra_topics.old_value_requirements__templates_, +@see @RefSect{extras.old_value_requirements__templates_, Old Value Requirements} */ template @@ -187,23 +187,30 @@ This library will instantiate and use this trait only on old value types @c T that are copyable (i.e., for which boost::contract::is_old_value_copyable::value is @c true). -@see @RefSect{extra_topics.old_value_requirements__templates_, +@see @RefSect{extras.old_value_requirements__templates_, Old Value Requirements} */ template // Used only if is_old_value_copyable. struct old_value_copy { /** - Construct this object by making a copy of the specified old value. + Construct this object by making one single copy of the specified old value. - This is the operation within this library that makes the one single copy of - old values. + This is the only operation within this library that actually copies old + values. @param old The old value to copy. */ explicit old_value_copy(T const& old) : old_(old) {} // This makes the one single copy of T. - /** Return a (constant) reference to the old value that was copied. */ + /** + Return a (constant) reference to the old value that was copied. + + Contract assertions should not change the state of the program so the old + value copy is returned as @c const (see also + @RefSect{contract_programming_overview.constant_correctness, + Constant Correctness}). + */ T const& old() const { return old_; } private: @@ -244,7 +251,7 @@ public: compile-time error if the pointed type @c T is not copyable (i.e., if @c boost::contract::is_old_value_copyable::value is @c false). - @return The old value. + @return The pointed old value. Contract assertions should not change the state of the program so this member function is @c const and it returns the old value as a reference to a constant object (see also @@ -290,7 +297,7 @@ public: !!typed_copy_) #else /** - Check if this old value pointer is null or not (safe-bool operator). + Check if this old value pointer is null or not. (This is implemented using safe-bool emulation on compilers that do not support C++11 explicit type conversion operators.) @@ -321,7 +328,7 @@ copyable). This is set to point to an actual old value copy using either @RefMacro{BOOST_CONTRACT_OLDOF} or @RefFunc{boost::contract::make_old}. -@see @RefSect{extra_topics.old_value_requirements__templates_, +@see @RefSect{extras.old_value_requirements__templates_, Old Value Requirements} @tparam T Type of the pointed old value. @@ -340,14 +347,15 @@ public: old_ptr_if_copyable() {} /** - Construct this old value pointer from from an old value pointer of - copyable-only type. + Construct this old value pointer from an old value pointer that requires + the old value type to be copyable. This constructor is implicitly called by this library when assigning an object of this type using @RefMacro{BOOST_CONTRACT_OLDOF} (this constructor - will often not be called directly by user code). + is usually not explicitly called by user code). - @param other Old value pointer of copyable-only type. + @param other Old value pointer that requires the old value type to be + copyable. */ /* implicit */ old_ptr_if_copyable(old_ptr const& other) : typed_copy_(other.typed_copy_) {} @@ -359,7 +367,7 @@ public: compile-time error is generated if the pointed type @c T is not copyable (i.e., if @c boost::contract::is_old_value_copyable::value is @c false). - @return The old value. + @return The pointed old value. Contract assertions should not change the state of the program so this member function is @c const and it returns the old value as a reference to a constant object (see also @@ -374,9 +382,9 @@ public: /** Structure-dereference this old value pointer. - This will not generate a compile-time error if the pointed type @c T is not - copyable (i.e., if @c boost::contract::is_old_value_copyable::value is - @c false). + This will return null but will not generate a compile-time error if the + pointed type @c T is not copyable (i.e., if + @c boost::contract::is_old_value_copyable::value is @c false). @return A pointer to the old value (null if this old value pointer is null). Contract assertions should not change the state of the program so @@ -390,7 +398,7 @@ public: return 0; } - #ifndef DBOOST_CONTRACT_DETAIL_OXYGEN + #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN BOOST_CONTRACT_DETAIL_OPERATOR_SAFE_BOOL(old_ptr_if_copyable, !!typed_copy_) #else @@ -419,7 +427,7 @@ private: }; /** -Convert user-specified expressions in old values. +Convert user-specified expressions to old values. This class is often only implicitly used by this library and it does not explicitly appear in user code. @@ -429,7 +437,7 @@ On older compilers that cannot correctly deduce the specialize that trait to make sure that only old value types that are copyable are actually copied. -@see @RefSect{extra_topics.old_value_requirements__templates_, +@see @RefSect{extras.old_value_requirements__templates_, Old Value Requirements} */ class old_value { // Copyable (as *). @@ -441,9 +449,9 @@ public: is copy constructible. The specified old value is copied (one time only) using - @c boost::contract::old_value_copy and the related old value pointer will - not be null (no copy is made instead if postconditions are not being - checked, see @RefMacro{BOOST_CONTRACT_NO_OLDS}). + @c boost::contract::old_value_copy, in which case related old value pointer + will not be null (no copy is made if postconditions and exception guarantees + are not being checked, see @RefMacro{BOOST_CONTRACT_NO_OLDS}). @param old Old value to be copied. @@ -465,8 +473,9 @@ public: is not copyable. The specified old value cannot be copied in this case so it is not copied - and the related old value pointer will always be null (in this case, a call - to this function amounts to a no-op and it will likely be optimized away). + and the related old value pointer will always be null (thus a call to this + constructor has no effect and it will likely be optimized away by most + compilers). @param old Old value (that will not be copied in this case). @@ -502,8 +511,8 @@ constructors, etc.). class old_pointer { // Copyable (as *). public: /** - Convert this object to an old value pointer (the old value type might or not - be copyable). + Convert this object to an actual old value pointer (the old value type might + or not be copyable). For example, this is implicitly called when assigning or initializing old value pointers. @@ -512,7 +521,7 @@ public: The old value pointer will always be null if this type is not copyable (see @c boost::contract::is_old_value_copyable), but this library - will not generate a compile-time error). + will not generate a compile-time error. */ template /* implicit */ operator old_ptr_if_copyable() { @@ -520,8 +529,8 @@ public: } /** - Convert this object to an old value pointer (the old value type must be - copyable). + Convert this object to an actual old value pointer (the old value type must + be copyable). For example, this is implicitly called when assigning or initializing old value pointers. @@ -617,10 +626,10 @@ private: Return a null old value. The related old value pointer will also be null. -This operation is often only used by the code expanded by -@c BOOST_CONTRACT_OLDOF. +This function is often only used by the code expanded by +@RefMacro{BOOST_CONTRACT_OLDOF}. -@see @RefSect{extra_topics.no_macros__no_c__11_, No Macros} +@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @return Null old value. */ @@ -632,10 +641,10 @@ functions overrides). The related old value pointer will not be null if the specified old value was actually copied. -This operation is often only used by the code expanded by -@c BOOST_CONTRACT_OLDOF. +This function is often only used by the code expanded by +@RefMacro{BOOST_CONTRACT_OLDOF} which is equivalent to: -@see @RefSect{extra_topics.no_macros__no_c__11_, No Macros} +@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param old Old value (usually implicitly constructed from the user old value expression to be copied). @@ -654,10 +663,10 @@ overrides). The related old value pointer will not be null if the specified old value was actually copied. -This operation is often only used by the code expanded by -@c BOOST_CONTRACT_OLDOF. +This function is often only used by the code expanded by +@RefMacro{BOOST_CONTRACT_OLDOF}. -@see @RefSect{extra_topics.no_macros__no_c__11_, No Macros} +@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param v The trailing parameter of type @RefClass{boost::contract::virtual_}* and default value @c 0 @@ -681,10 +690,10 @@ public function overrides). For example, this function always returns false when both postconditions and exception guarantees are not being checked (see also @RefMacro{BOOST_CONTRACT_NO_OLDS}). -This operation is often only used by the code expanded by +This function is often only used by the code expanded by @c BOOST_CONTRACT_OLDOF. -@see @RefSect{extra_topics.no_macros__no_c__11_, No Macros} +@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @return True if old values need to be copied, false otherwise. */ @@ -707,10 +716,12 @@ function overrides). For example, this function always returns false when both postconditions and exception guarantees are not being checked (see also @RefMacro{BOOST_CONTRACT_NO_OLDS}). -This operation is often only used by the code expanded by +In addition, this function returns false when overridden functions are being +called subsequent times by this library to support subcontracting. +This function is often only used by the code expanded by @c BOOST_CONTRACT_OLDOF. -@see @RefSect{extra_topics.no_macros__no_c__11_, No Macros} +@see @RefSect{extras.no_macros__and_no_variadic_macros_, No Macros} @param v The trailing parameter of type @RefClass{boost::contract::virtual_}* and default value @c 0 diff --git a/include/boost/contract/override.hpp b/include/boost/contract/override.hpp index 79ed655..3dd8508 100644 --- a/include/boost/contract/override.hpp +++ b/include/boost/contract/override.hpp @@ -18,7 +18,7 @@ Handle public function overrides (for subcontracting). #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS #include - #include + #include #include #include #include @@ -78,7 +78,7 @@ Handle public function overrides (for subcontracting). #define BOOST_CONTRACT_NAMED_OVERRIDE(override_name, function_name) \ struct override_name { \ - BOOST_CONTRACT_DETAIL_INTROSPECTION_HAS_MEMBER_FUNCTION( \ + BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( \ BOOST_CONTRACT_DETAIL_NAME1(has_member_function), \ function_name \ ) \ @@ -88,24 +88,23 @@ Handle public function overrides (for subcontracting). /** Declare an override type with an arbitrary name. - Declare the override type to be passed as an explicit template parameter to + Declare the override type to pass as an explicit template parameter to @RefFunc{boost::contract::public_function} for public function overrides. - @see @RefSect{advanced_topics.named_overrides, Named Overrides} + @see @RefSect{advanced.named_overrides, Named Overrides} - @param override_name Name of the override type being declared. - (This is not a variadic macro parameter but it will - never contain any comma because it is an + @param override_name Name of the override type this macro will declare. + (This is not a variadic macro parameter but it + should never contain any comma because it is an identifier.) @param function_name Function name of the public function override. This macro is called just once even if the function - name is overloaded and the same override type is - used for all overloaded functions with the same - name (see + name is overloaded (the same override type is used + for all overloaded functions with the same name, see @RefSect{advanced_topics.function_overloads, Function Overloads}). - (This is not a variadic macro parameter but it will - never contain any comma because it is an + (This is not a variadic macro parameter but it + should never contain any comma because it is an identifier.) */ #define BOOST_CONTRACT_NAMED_OVERRIDE(override_name, function_name) \ @@ -117,7 +116,7 @@ Handle public function overrides (for subcontracting). /** Declare an override type named override_function_name. -Declare the override type to be passed as an explicit template parameter to +Declare the override type to pass as an explicit template parameter to @RefFunc{boost::contract::public_function} for public function overrides. @see @RefSect{tutorial.public_function_overrides__subcontracting_, @@ -125,12 +124,11 @@ Declare the override type to be passed as an explicit template parameter to @param function_name Function name of the public function override. This macro is called just once even if the function - name is overloaded and the same override type is - used for all overloaded functions with the same - name (see + name is overloaded (the same override type is used for + all overloaded functions with the same name, see @RefSect{advanced_topics.function_overloads, Function Overloads}). - (This is not a variadic macro parameter but it will + (This is not a variadic macro parameter but it should never contain any comma because it is an identifier.) */ #define BOOST_CONTRACT_OVERRIDE(function_name) \ @@ -154,18 +152,28 @@ Declare the override type to be passed as an explicit template parameter to Declare multiple override types at once naming them override_... (for convenience). - This variadic macro is provided for convenience only. + This variadic macro is provided for convenience only, + BOOST_CONTRACT_OVERRIDES(f1, f2, ..., fn) expands to code equivalent + to: + + @code + BOOST_CONTRACT_OVERRIDE(f1) + BOOST_CONTRACT_OVERRIDE(f2) + ... + BOOST_CONTRACT_OVERRIDE(fn) + @endcode + On compilers that do not support variadic macros, the override types can be equivalently programmed one-by-one calling - @RefMacro{BOOST_CONTRACT_OVERRIDE} for each function name. + @RefMacro{BOOST_CONTRACT_OVERRIDE} for each function name as shown above. @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} @param ... A comma separated list of one or more function names of public function overrides. - (Each function name will never contain any commas because it is - an identifier.) + (Each function name should never contain any commas because it + is an identifier.) */ #define BOOST_CONTRACT_OVERRIDES(...) \ BOOST_PP_SEQ_FOR_EACH(BOOST_CONTRACT_OVERRIDES_SEQ_, ~, \ diff --git a/include/boost/contract/public_function.hpp b/include/boost/contract/public_function.hpp index bd33670..1df91b7 100644 --- a/include/boost/contract/public_function.hpp +++ b/include/boost/contract/public_function.hpp @@ -8,7 +8,7 @@ // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html /** @file -Program contracts for public member functions. +Program contracts for public functions (including subcontracting). Overloads handle public functions that are static, virtual void, virtual non-void, overriding void, and overriding non-void. */ @@ -28,7 +28,7 @@ Overloads handle public functions that are static, virtual void, virtual non-voi #include #include #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ - #include + #include #include #include #include @@ -73,13 +73,13 @@ value copies at body, and check static class invariants for static public functions. For optimization, this can be omitted for static public functions that do not -have preconditions, postconditions, and exception guarantees when the enclosing -class has no static invariants. +have preconditions, postconditions and exception guarantees, within classes that +have no static invariants. @see @RefSect{tutorial.static_public_functions, Static Public Functions} -@tparam Class The class type of the enclosing static public function declaring - the contract. +@tparam Class The type of the class containing the static public function + declaring the contract. This template parameter must be explicitly specified for static public functions (because they have no object @c this so there is no function argument from which this type template parameter @@ -87,14 +87,14 @@ class has no static invariants. @return The result of this function must be explicitly assigned to a variable of type @RefClass{boost::contract::check} declared locally just before the - static function body code (otherwise this library will generate a + code of the static function body (otherwise this library will generate a run-time error, see @RefMacro{BOOST_CONTRACT_ON_MISSING_CHECK_DECL}). */ template specify_precondition_old_postcondition_except<> public_function() { #if BOOST_CONTRACT_PUBLIC_FUNCTIONS_IMPL_ return specify_precondition_old_postcondition_except<>( - new boost::contract::detail::public_static_function()); + new boost::contract::detail::static_public_function()); #else return specify_precondition_old_postcondition_except<>(); #endif @@ -109,8 +109,8 @@ value copies at body, and check class invariants for public functions that are not static, not virtual, and do not override. For optimization, this can be omitted for public functions that do not have -preconditions, postconditions, and exception guarantees when the enclosing class -has no (non-static) invariants. +preconditions, postconditions and exception guarantees, within classes that have +no invariants. @see @RefSect{tutorial.public_functions, Public Functions} @@ -120,11 +120,11 @@ has no (non-static) invariants. const volatile depending on the cv-qualifier of the enclosing function (volatile virtual public functions will check volatile class invariants, see - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions}). -@tparam Class The class type of the enclosing public function declaring the - contract. +@tparam Class The type of the class containing the public function declaring + the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) @@ -234,9 +234,9 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { old value copies at body, and check class invariants for public functions that are virtual, do not override, and return @c void. - For optimization, this can be omitted for virtual public functions that do - not have preconditions, postconditions, and exception guarantees when the - enclosing class has no (non-static) invariants. + A virtual public function should always call + @RefFunc{boost::contract::public_function} otherwise this library will not + be able to correctly use it for subcontracting. @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions} @@ -249,10 +249,10 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { const volatile depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions}). - @tparam Class The class type of the enclosing virtual public function + @tparam Class The type of the class containing the virtual public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by @@ -276,9 +276,9 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { old value copies at body, and check class invariants for public functions that are virtual, do not override, and do not return @c void. - For optimization, this can be omitted for virtual public functions that do - not have preconditions, postconditions, and exception guarantees when the - enclosing class has no (non-static) invariants. + A virtual public function should always call + @RefFunc{boost::contract::public_function} otherwise this library will not + be able to correctly use it for subcontracting. @see @RefSect{tutorial.virtual_public_functions, Virtual Public Functions} @@ -297,7 +297,7 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { const volatile depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @tparam VirtualResult This type must be the same as, or compatible with, @@ -309,12 +309,12 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { Alternatively, boost::optional<return-type> can also be used (see - @RefSect{advanced_topics.optional_return_value, + @RefSect{advanced.optional_return_value, Optional Return Value}). (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) - @tparam Class The class type of the enclosing virtual public function + @tparam Class The type of the class containing the virtual public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by @@ -421,9 +421,9 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { old value copies at body, and check class invariants for public function overrides (virtual or not) that return @c void. - For optimization, this can be omitted for public function overrides that do - not have preconditions, postconditions, and exception guarantees when the - enclosing class has no (non-static) invariants. + A public function override should always call + @RefFunc{boost::contract::public_function} otherwise this library will not + be able to correctly use it for subcontracting. @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} @@ -439,28 +439,26 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { const volatile depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @param args All arguments passed to the enclosing public function override - declaring the contract (by reference and in order they appear in - the enclosing function declaration), but excluding the trailing - argument @c v. + declaring the contract (by reference and in the order they + appear in the enclosing function declaration), but excluding the + trailing argument @c v. @tparam Override The type override_function-name declared - using the @RefMacro{BOOST_CONTRACT_OVERRIDE} (or - equivalent) macro from the enclosing function name. + using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or related + macros. This template parameter must be explicitly specified - (because there is no function argument from which this - type template parameter can be automatically deduced by - C++). - @tparam F The function pointer type for the enclosing public function + (because there is no function argument from which it can + be automatically deduced by C++). + @tparam F The function pointer type of the enclosing public function override declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers, but see - @RefSect{advanced_topics.function_overloads, - Function Overloads}.) - @tparam Class The class type of the enclosing virtual public function + @RefSect{advanced.function_overloads, Function Overloads}.) + @tparam Class The type of the class containing the virtual public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by @@ -494,9 +492,9 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { old value copies at body, and check class invariants for public function overrides (virtual or not) that do not return @c void. - For optimization, this can be omitted for public function overrides that do - not have preconditions, postconditions, and exception guarantees when the - enclosing class has no (non-static) invariants. + A public function override should always call + @RefFunc{boost::contract::public_function} otherwise this library will not + be able to correctly use it for subcontracting. @see @RefSect{tutorial.public_function_overrides__subcontracting_, Public Function Overrides} @@ -518,20 +516,19 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { const volatile depending on the cv-qualifier of the enclosing function (volatile public functions will check volatile class invariants, see - @RefSect{extra_topics.volatile_public_functions, + @RefSect{extras.volatile_public_functions, Volatile Public Functions}). @param args All arguments passed to the enclosing public function override - declaring the contract (by reference and in order they appear in - the enclosing function declaration), but excluding the trailing - argument @c v. + declaring the contract (by reference and in the order they + appear in the enclosing function declaration), but excluding the + trailing argument @c v. @tparam Override The type override_function-name declared - using the @RefMacro{BOOST_CONTRACT_OVERRIDE} (or - equivalent) macro from the enclosing function name. + using the @RefMacro{BOOST_CONTRACT_OVERRIDE} or related + macros. This template parameter must be explicitly specified - (because there is no function argument from which this - type template parameter can be automatically deduced by - C++). + (because there is no function argument from which it can + be automatically deduced by C++). @tparam VirtualResult This type must be the same as, or compatible with, the return type of the enclosing public function override declaring the contract (this library might @@ -541,19 +538,19 @@ specify_precondition_old_postcondition_except<> public_function(Class* obj) { Alternatively, boost::optional<return-type> can also be used (see - @RefSect{advanced_topics.optional_return_value, + @RefSect{advanced.optional_return_value, Optional Return Value}). (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers.) - @tparam F The function pointer type for the enclosing public function + @tparam F The function pointer type of the enclosing public function override declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by programmers, but see - @RefSect{advanced_topics.function_overloads, + @RefSect{advanced.function_overloads, Function Overloads}.) - @tparam Class The class type of the enclosing virtual public function + @tparam Class The type of the class containing the virtual public function declaring the contract. (Usually this template parameter is automatically deduced by C++ and it does not need to be explicitly specified by diff --git a/include/boost/contract_macro.hpp b/include/boost/contract_macro.hpp index 9c37fd7..fa1ab2c 100644 --- a/include/boost/contract_macro.hpp +++ b/include/boost/contract_macro.hpp @@ -8,11 +8,9 @@ // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html /** @file -Completely disable run-time and compile-time overheads of contract code. - -This header also includes all headers file boost/contract/\*.hpp are -necessary to use this macro (including the ones that define ASSERT, virtual_, -access, OVERRIDE, BASE_TYPES, CHECK, constructor_precondition, etc.) +Completely disable compile-time and run-time overhead introduced by contracts. +This header also includes all headers file boost/contract/\*.hpp that are +necessary to use its macros. Almost all the macros defined in this header file are variadic macros. On compilers that do not support variadic macros, programmers can manually code @@ -93,7 +91,7 @@ Disable Contract Compilation}). Where: @arg f is the functor called by this library to check - postconditions @c f(...). + postconditions f(...). Assertions within this functor are usually programmed using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown by a call to this functor indicates a contract assertion failure (and will diff --git a/test/check/audit.cpp b/test/check/audit.cpp index 61760b8..81fdb83 100644 --- a/test/check/audit.cpp +++ b/test/check/audit.cpp @@ -4,5 +4,6 @@ // 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 +#define BOOST_CONTRACT_AUDITS #include "audit.hpp" diff --git a/test/check/audit.hpp b/test/check/audit.hpp index c9bf2fa..d6fb3e4 100644 --- a/test/check/audit.hpp +++ b/test/check/audit.hpp @@ -22,7 +22,7 @@ int main() { #endif } catch(err const&) { threw = true; } - #ifndef BOOST_CONTRACT_NO_AUDITS + #ifdef BOOST_CONTRACT_AUDITS BOOST_TEST(threw); #else BOOST_TEST(!threw); diff --git a/test/check/audit_disabled.cpp b/test/check/audit_disabled.cpp index 6548bd4..61760b8 100644 --- a/test/check/audit_disabled.cpp +++ b/test/check/audit_disabled.cpp @@ -4,6 +4,5 @@ // 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 -#define BOOST_CONTRACT_NO_AUDITS #include "audit.hpp" diff --git a/test/check/audit_disabled_error.cpp b/test/check/audit_disabled_error.cpp index 8d22c74..15ced1c 100644 --- a/test/check/audit_disabled_error.cpp +++ b/test/check/audit_disabled_error.cpp @@ -5,6 +5,5 @@ // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html #define BOOST_CONTRACT_TEST_ERROR -#define BOOST_CONTRACT_NO_AUDITS #include "audit.hpp" diff --git a/test/disable/audit.cpp b/test/disable/audit.cpp index 61760b8..81fdb83 100644 --- a/test/disable/audit.cpp +++ b/test/disable/audit.cpp @@ -4,5 +4,6 @@ // 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 +#define BOOST_CONTRACT_AUDITS #include "audit.hpp" diff --git a/test/disable/audit.hpp b/test/disable/audit.hpp index 3c3d97e..c4639c6 100644 --- a/test/disable/audit.hpp +++ b/test/disable/audit.hpp @@ -19,7 +19,7 @@ int main() { #endif } catch(boost::contract::assertion_failure const&) { threw = true; } - #ifndef BOOST_CONTRACT_NO_AUDITS + #ifdef BOOST_CONTRACT_AUDITS BOOST_TEST(threw); #else BOOST_TEST(!threw); diff --git a/test/disable/audit_disabled.cpp b/test/disable/audit_disabled.cpp index 6548bd4..61760b8 100644 --- a/test/disable/audit_disabled.cpp +++ b/test/disable/audit_disabled.cpp @@ -4,6 +4,5 @@ // 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 -#define BOOST_CONTRACT_NO_AUDITS #include "audit.hpp" diff --git a/test/disable/audit_disabled_error.cpp b/test/disable/audit_disabled_error.cpp index 8d22c74..15ced1c 100644 --- a/test/disable/audit_disabled_error.cpp +++ b/test/disable/audit_disabled_error.cpp @@ -5,6 +5,5 @@ // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html #define BOOST_CONTRACT_TEST_ERROR -#define BOOST_CONTRACT_NO_AUDITS #include "audit.hpp"