Back to home page

EIC code displayed by LXR

 
 

    


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