1 // Copyright Daniel Wallin 2004. Use, modification and distribution is 2 // subject to the Boost Software License, Version 1.0. (See accompanying 3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 5 #ifndef TORRENT_INVARIANT_ACCESS_HPP_INCLUDED 6 #define TORRENT_INVARIANT_ACCESS_HPP_INCLUDED 7 8 #include "libtorrent/config.hpp" 9 #include "libtorrent/assert.hpp" 10 #include <cstdio> 11 12 #if TORRENT_USE_INVARIANT_CHECKS 13 14 namespace libtorrent { 15 16 class invariant_access 17 { 18 public: 19 template<class T> check_invariant(T const & self)20 static void check_invariant(T const& self) 21 { 22 self.check_invariant(); 23 } 24 }; 25 26 template<class T> check_invariant(T const & x)27 void check_invariant(T const& x) 28 { 29 #ifndef BOOST_NO_EXCEPTIONS 30 try 31 { 32 invariant_access::check_invariant(x); 33 } 34 catch (std::exception const& err) 35 { 36 std::fprintf(stderr, "invariant_check failed with exception: %s\n" 37 , err.what()); 38 } 39 catch (...) 40 { 41 std::fprintf(stderr, "invariant_check failed with exception\n"); 42 } 43 #else 44 invariant_access::check_invariant(x); 45 #endif 46 } 47 48 struct invariant_checker {}; 49 50 template<class T> 51 struct invariant_checker_impl : invariant_checker 52 { invariant_checker_impllibtorrent::invariant_checker_impl53 explicit invariant_checker_impl(T const& self_) 54 : self(self_) 55 { 56 check_invariant(self); 57 } 58 invariant_checker_impllibtorrent::invariant_checker_impl59 invariant_checker_impl(invariant_checker_impl const& rhs) 60 : self(rhs.self) {} 61 ~invariant_checker_impllibtorrent::invariant_checker_impl62 ~invariant_checker_impl() 63 { 64 check_invariant(self); 65 } 66 67 T const& self; 68 69 private: 70 invariant_checker_impl& operator=(invariant_checker_impl const&); 71 }; 72 73 template<class T> make_invariant_checker(T const & x)74 invariant_checker_impl<T> make_invariant_checker(T const& x) 75 { 76 return invariant_checker_impl<T>(x); 77 } 78 } 79 80 #define INVARIANT_CHECK \ 81 invariant_checker const& _invariant_check = make_invariant_checker(*this); \ 82 (void)_invariant_check 83 #else 84 #define INVARIANT_CHECK do {} TORRENT_WHILE_0 85 #endif 86 87 #endif // TORRENT_INVARIANT_ACCESS_HPP_INCLUDED 88 89