blob: 196b84785d2a0dba30e1e84f9c1e371367500202 [file] [log] [blame]
#ifndef BOOST_SERIALIZATION_STATE_SAVER_HPP
#define BOOST_SERIALIZATION_STATE_SAVER_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// state_saver.hpp:
// (C) Copyright 2003-4 Pavel Vozenilek and Robert Ramey - http://www.rrsd.com.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/serialization for updates, documentation, and revision history.
// Inspired by Daryle Walker's iostate_saver concept. This saves the original
// value of a variable when a state_saver is constructed and restores
// upon destruction. Useful for being sure that state is restored to
// variables upon exit from scope.
#include <boost/config.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#include <exception>
#endif
#include <boost/call_traits.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/has_nothrow_copy.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
namespace boost {
namespace serialization {
template<class T>
// T requirements:
// - POD or object semantic (cannot be reference, function, ...)
// - copy constructor
// - operator = (no-throw one preferred)
class state_saver : private boost::noncopyable
{
private:
const T previous_value;
T & previous_ref;
struct restore {
static void invoke(T & previous_ref, const T & previous_value){
previous_ref = previous_value; // won't throw
}
};
struct restore_with_exception {
static void invoke(T & previous_ref, const T & previous_value){
BOOST_TRY{
previous_ref = previous_value;
}
BOOST_CATCH(::std::exception &) {
// we must ignore it - we are in destructor
}
BOOST_CATCH_END
}
};
public:
state_saver(
T & object
) :
previous_value(object),
previous_ref(object)
{}
~state_saver() {
#ifndef BOOST_NO_EXCEPTIONS
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
has_nothrow_copy< T >,
mpl::identity<restore>,
mpl::identity<restore_with_exception>
>::type typex;
typex::invoke(previous_ref, previous_value);
#else
previous_ref = previous_value;
#endif
}
}; // state_saver<>
} // serialization
} // boost
#endif //BOOST_SERIALIZATION_STATE_SAVER_HPP