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