|
||||
File indexing completed on 2025-01-18 09:30:25
0001 0002 #ifndef BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION_HPP_ 0003 #define BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION_HPP_ 0004 0005 // Copyright (C) 2008-2018 Lorenzo Caminiti 0006 // Distributed under the Boost Software License, Version 1.0 (see accompanying 0007 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). 0008 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html 0009 0010 /** @file 0011 Program preconditions for constructors. 0012 */ 0013 0014 // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes. 0015 #include <boost/contract/core/config.hpp> 0016 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 0017 #include <boost/contract/core/exception.hpp> 0018 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION 0019 #include <boost/contract/detail/checking.hpp> 0020 #endif 0021 #endif 0022 0023 namespace boost { namespace contract { 0024 0025 /** 0026 Program preconditions for constructors. 0027 0028 This class must be the very first base of the class declaring the 0029 constructor for which preconditions are programmed (that way constructor 0030 arguments can be checked by preconditions even before they are used to 0031 initialize other base classes): 0032 0033 @code 0034 class u 0035 #define BASES private boost::contract::constructor_precondition<u>, \ 0036 public b 0037 : BASES 0038 { 0039 friend class boost::contract::access; 0040 0041 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; 0042 #undef BASES 0043 0044 public: 0045 explicit u(unsigned x) : 0046 boost::contract::constructor_precondition<u>([&] { 0047 BOOST_CONTRACT_ASSERT(x != 0); 0048 ... 0049 }), 0050 b(1.0 / float(x)) 0051 { 0052 ... 0053 } 0054 0055 ... 0056 }; 0057 @endcode 0058 0059 User-defined classes should inherit privately from this class (to not alter the 0060 public interface of user-defined classes). 0061 In addition, this class should never be declared as a virtual base (because 0062 virtual bases are initialized only once across the entire inheritance hierarchy 0063 preventing preconditions of other base classes from being checked). 0064 0065 This class cannot be used this way in a @c union because unions cannot have base 0066 classes in C++. 0067 Instead, this class is used in a @c union to declare a local object within the 0068 constructor definition just before @RefFunc{boost::contract::constructor} is 0069 used (see @RefSect{extras.unions, Unions}). 0070 0071 @see @RefSect{tutorial.constructors, Constructors} 0072 0073 @tparam Class The class type of the constructor for which preconditions are 0074 being programmed. 0075 */ 0076 template<class Class> 0077 class constructor_precondition { // Copyable (has no data). 0078 public: 0079 /** 0080 Construct this object without specifying constructor preconditions. 0081 0082 This is implicitly called for those constructors of the contracted class 0083 that do not specify preconditions. 0084 0085 @note The implementation of this library is optimized so that calling this 0086 default constructor should amount to negligible compile-time and 0087 run-time overheads (likely to be optimized away completely by most 0088 compilers). 0089 */ 0090 constructor_precondition() {} 0091 0092 /** 0093 Construct this object specifying constructor preconditions. 0094 0095 @param f Nullary functor called by this library to check constructor 0096 preconditions @c f(). 0097 Assertions within this functor call are usually programmed 0098 using @RefMacro{BOOST_CONTRACT_ASSERT}, but any exception thrown 0099 by a call to this functor indicates a contract failure (and will 0100 result in this library calling 0101 @RefFunc{boost::contract::precondition_failure}). 0102 This functor should capture variables by (constant) value, or 0103 better by (constant) reference to avoid extra copies. 0104 */ 0105 template<typename F> 0106 explicit constructor_precondition(F const& f) { 0107 #ifndef BOOST_CONTRACT_NO_PRECONDITIONS 0108 try { 0109 #ifndef BOOST_CONTRACT_ALL_DISABLE_NO_ASSERTION 0110 if(boost::contract::detail::checking::already()) return; 0111 #ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION 0112 boost::contract::detail::checking k; 0113 #endif 0114 #endif 0115 f(); 0116 } catch(...) { precondition_failure(from_constructor); } 0117 #endif 0118 } 0119 0120 // Default copy operations (so user's derived classes can be copied, etc.). 0121 }; 0122 0123 } } // namespace 0124 0125 #endif // #include guard 0126
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |