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