Chris@16
|
1 #ifndef BOOST_SERIALIZATION_STATE_SAVER_HPP
|
Chris@16
|
2 #define BOOST_SERIALIZATION_STATE_SAVER_HPP
|
Chris@16
|
3
|
Chris@16
|
4 // MS compatible compilers support #pragma once
|
Chris@101
|
5 #if defined(_MSC_VER)
|
Chris@16
|
6 # pragma once
|
Chris@16
|
7 #endif
|
Chris@16
|
8
|
Chris@16
|
9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
Chris@16
|
10 // state_saver.hpp:
|
Chris@16
|
11
|
Chris@16
|
12 // (C) Copyright 2003-4 Pavel Vozenilek and Robert Ramey - http://www.rrsd.com.
|
Chris@16
|
13 // Use, modification and distribution is subject to the Boost Software
|
Chris@16
|
14 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
15 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
16
|
Chris@16
|
17 // See http://www.boost.org/libs/serialization for updates, documentation, and revision history.
|
Chris@16
|
18
|
Chris@16
|
19 // Inspired by Daryle Walker's iostate_saver concept. This saves the original
|
Chris@16
|
20 // value of a variable when a state_saver is constructed and restores
|
Chris@16
|
21 // upon destruction. Useful for being sure that state is restored to
|
Chris@16
|
22 // variables upon exit from scope.
|
Chris@16
|
23
|
Chris@16
|
24
|
Chris@16
|
25 #include <boost/config.hpp>
|
Chris@16
|
26 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
27 #include <exception>
|
Chris@16
|
28 #endif
|
Chris@16
|
29
|
Chris@16
|
30 #include <boost/call_traits.hpp>
|
Chris@16
|
31 #include <boost/noncopyable.hpp>
|
Chris@16
|
32 #include <boost/type_traits/has_nothrow_copy.hpp>
|
Chris@101
|
33 #include <boost/core/no_exceptions_support.hpp>
|
Chris@16
|
34
|
Chris@16
|
35 #include <boost/mpl/eval_if.hpp>
|
Chris@16
|
36 #include <boost/mpl/identity.hpp>
|
Chris@16
|
37
|
Chris@16
|
38 namespace boost {
|
Chris@16
|
39 namespace serialization {
|
Chris@16
|
40
|
Chris@16
|
41 template<class T>
|
Chris@16
|
42 // T requirements:
|
Chris@16
|
43 // - POD or object semantic (cannot be reference, function, ...)
|
Chris@16
|
44 // - copy constructor
|
Chris@16
|
45 // - operator = (no-throw one preferred)
|
Chris@16
|
46 class state_saver : private boost::noncopyable
|
Chris@16
|
47 {
|
Chris@16
|
48 private:
|
Chris@16
|
49 const T previous_value;
|
Chris@16
|
50 T & previous_ref;
|
Chris@16
|
51
|
Chris@16
|
52 struct restore {
|
Chris@16
|
53 static void invoke(T & previous_ref, const T & previous_value){
|
Chris@16
|
54 previous_ref = previous_value; // won't throw
|
Chris@16
|
55 }
|
Chris@16
|
56 };
|
Chris@16
|
57
|
Chris@16
|
58 struct restore_with_exception {
|
Chris@16
|
59 static void invoke(T & previous_ref, const T & previous_value){
|
Chris@16
|
60 BOOST_TRY{
|
Chris@16
|
61 previous_ref = previous_value;
|
Chris@16
|
62 }
|
Chris@16
|
63 BOOST_CATCH(::std::exception &) {
|
Chris@16
|
64 // we must ignore it - we are in destructor
|
Chris@16
|
65 }
|
Chris@16
|
66 BOOST_CATCH_END
|
Chris@16
|
67 }
|
Chris@16
|
68 };
|
Chris@16
|
69
|
Chris@16
|
70 public:
|
Chris@16
|
71 state_saver(
|
Chris@16
|
72 T & object
|
Chris@16
|
73 ) :
|
Chris@16
|
74 previous_value(object),
|
Chris@16
|
75 previous_ref(object)
|
Chris@16
|
76 {}
|
Chris@16
|
77
|
Chris@16
|
78 ~state_saver() {
|
Chris@16
|
79 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@101
|
80 typedef typename mpl::eval_if<
|
Chris@16
|
81 has_nothrow_copy< T >,
|
Chris@16
|
82 mpl::identity<restore>,
|
Chris@16
|
83 mpl::identity<restore_with_exception>
|
Chris@16
|
84 >::type typex;
|
Chris@16
|
85 typex::invoke(previous_ref, previous_value);
|
Chris@16
|
86 #else
|
Chris@16
|
87 previous_ref = previous_value;
|
Chris@16
|
88 #endif
|
Chris@16
|
89 }
|
Chris@16
|
90
|
Chris@16
|
91 }; // state_saver<>
|
Chris@16
|
92
|
Chris@16
|
93 } // serialization
|
Chris@16
|
94 } // boost
|
Chris@16
|
95
|
Chris@16
|
96 #endif //BOOST_SERIALIZATION_STATE_SAVER_HPP
|