Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:26

0001 
0002 #ifndef BOOST_CONTRACT_DETAIL_COND_BASE_HPP_
0003 #define BOOST_CONTRACT_DETAIL_COND_BASE_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 // NOTE: It seemed not possible to implement this library without inheritance
0011 // here because some sort of base type needs to be used to hold contract objects
0012 // in instances of boost::contract::check while polymorphically calling
0013 // init and destructor functions to check contracts at entry and exit. This
0014 // could be possible without inheritance only if boost::contract::check was made
0015 // a template type but that would complicate user code. In any case, early
0016 // experimentation with removing this base class and its virtual methods did not
0017 // seem to reduce compilation and/or run time.
0018 
0019 #include <boost/contract/core/exception.hpp>
0020 #include <boost/contract/core/config.hpp>
0021 #if     !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \
0022         !defined(BOOST_CONTRACT_NO_OLDS) || \
0023         !defined(BOOST_CONTRACT_NO_EXEPTS)
0024     #include <boost/function.hpp>
0025 #endif
0026 #include <boost/noncopyable.hpp>
0027 #ifndef BOOST_CONTRACT_ON_MISSING_CHECK_DECL
0028     #include <boost/assert.hpp>
0029 #endif
0030 #include <boost/config.hpp>
0031 
0032 namespace boost { namespace contract { namespace detail {
0033 
0034 class cond_base : // Base to hold all contract objects for RAII.
0035     private boost::noncopyable // Avoid copying possible user's ftor captures.
0036 {
0037 public:
0038     explicit cond_base(boost::contract::from from) :
0039           BOOST_CONTRACT_ERROR_missing_check_object_declaration(false)
0040         , init_asserted_(false)
0041         #ifndef BOOST_CONTRACT_NO_CONDITIONS
0042             , from_(from)
0043             , failed_(false)
0044         #endif
0045     {}
0046     
0047     // Can override for checking on exit, but should call assert_initialized().
0048     virtual ~cond_base() BOOST_NOEXCEPT_IF(false) {
0049         // Catch error (but later) even if overrides miss assert_initialized().
0050         if(!init_asserted_) assert_initialized();
0051     }
0052 
0053     void initialize() { // Must be called by owner ctor (i.e., check class).
0054         BOOST_CONTRACT_ERROR_missing_check_object_declaration = true;
0055         this->init(); // So all inits (pre, old, post) done after owner decl.
0056     }
0057     
0058     #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
0059         template<typename F>
0060         void set_pre(F const& f) { pre_ = f; }
0061     #endif
0062 
0063     #ifndef BOOST_CONTRACT_NO_OLDS
0064         template<typename F>
0065         void set_old(F const& f) { old_ = f; }
0066     #endif
0067 
0068     #ifndef BOOST_CONTRACT_NO_EXCEPTS
0069         template<typename F>
0070         void set_except(F const& f) { except_ = f; }
0071     #endif
0072 
0073 protected:
0074     void assert_initialized() { // Derived dtors must assert this at entry.
0075         init_asserted_ = true;
0076         #ifdef BOOST_CONTRACT_ON_MISSING_CHECK_DECL
0077             if(!BOOST_CONTRACT_ERROR_missing_check_object_declaration) {
0078                 BOOST_CONTRACT_ON_MISSING_CHECK_DECL;
0079             }
0080         #else
0081             // Cannot use a macro instead of this ERROR_... directly here
0082             // because assert will not expand it in the error message.
0083             BOOST_ASSERT(BOOST_CONTRACT_ERROR_missing_check_object_declaration);
0084         #endif
0085     }
0086     
0087     virtual void init() {} // Override for checking on entry.
0088     
0089     // Return true if actually checked calling user ftor.
0090     #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
0091         bool check_pre(bool throw_on_failure = false) {
0092             if(failed()) return true;
0093             try { if(pre_) pre_(); else return false; }
0094             catch(...) {
0095                 // Subcontracted pre must throw on failure (instead of
0096                 // calling failure handler) so to be checked in logic-or.
0097                 if(throw_on_failure) throw;
0098                 fail(&boost::contract::precondition_failure);
0099             }
0100             return true;
0101         }
0102     #endif
0103 
0104     #ifndef BOOST_CONTRACT_NO_OLDS
0105         void copy_old() {
0106             if(failed()) return;
0107             try { if(old_) old_(); }
0108             catch(...) { fail(&boost::contract::old_failure); }
0109         }
0110     #endif
0111 
0112     #ifndef BOOST_CONTRACT_NO_EXCEPTS
0113         void check_except() {
0114             if(failed()) return;
0115             try { if(except_) except_(); }
0116             catch(...) { fail(&boost::contract::except_failure); }
0117         }
0118     #endif
0119     
0120     #ifndef BOOST_CONTRACT_NO_CONDITIONS
0121         void fail(void (*h)(boost::contract::from)) {
0122             failed(true);
0123             if(h) h(from_);
0124         }
0125     
0126         // Virtual so overriding pub func can use virtual_::failed_ instead.
0127         virtual bool failed() const { return failed_; }
0128         virtual void failed(bool value) { failed_ = value; }
0129     #endif
0130 
0131 private:
0132     bool BOOST_CONTRACT_ERROR_missing_check_object_declaration;
0133     bool init_asserted_; // Avoid throwing twice from dtors (undef behavior).
0134     #ifndef BOOST_CONTRACT_NO_CONDITIONS
0135         boost::contract::from from_;
0136         bool failed_;
0137     #endif
0138     // Following use Boost.Function to handle also lambdas, binds, etc.
0139     #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
0140         boost::function<void ()> pre_;
0141     #endif
0142     #ifndef BOOST_CONTRACT_NO_OLDS
0143         boost::function<void ()> old_;
0144     #endif
0145     #ifndef BOOST_CONTRACT_NO_EXCEPTS
0146         boost::function<void ()> except_;
0147     #endif
0148 };
0149 
0150 } } } // namespace
0151 
0152 #endif // #include guard
0153