source: NonGTP/Boost/boost/state_saver.hpp @ 857

Revision 857, 2.7 KB checked in by igarcia, 19 years ago (diff)
Line 
1#ifndef BOOST_STATE_SAVER_HPP
2#define BOOST_STATE_SAVER_HPP
3
4// MS compatible compilers support #pragma once
5#if defined(_MSC_VER) && (_MSC_VER >= 1020)
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 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/detail/no_exceptions_support.hpp>
34
35#include <boost/mpl/eval_if.hpp>
36#include <boost/mpl/identity.hpp>
37
38namespace boost {
39
40template<class T>
41// T requirements:
42//  - POD or object semantic (cannot be reference, function, ...)
43//  - copy constructor
44//  - operator = (no-throw one preferred)
45class state_saver : private boost::noncopyable
46{
47private:
48    const T previous_value;
49    T & previous_ref;
50
51    struct restore {
52        static void invoke(T & previous_ref, const T & previous_value){
53            previous_ref = previous_value; // won't throw
54        }
55    };
56
57    struct restore_with_exception {
58        static void invoke(T & previous_ref, const T & previous_value){
59            BOOST_TRY{
60                previous_ref = previous_value;
61            }
62            BOOST_CATCH(::std::exception &) {
63                // we must ignore it - we are in destructor
64            }
65            BOOST_CATCH_END
66        }
67    };
68
69public:
70    state_saver(
71        T & object
72    ) :
73        previous_value(object),
74        previous_ref(object)
75    {}
76   
77    ~state_saver() {
78        #ifndef BOOST_NO_EXCEPTIONS
79            typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
80                has_nothrow_copy<T>,
81                mpl::identity<restore>,
82                mpl::identity<restore_with_exception>
83            >::type typex;
84            typex::invoke(previous_ref, previous_value);
85        #else
86            previous_ref = previous_value;
87        #endif
88    }
89
90}; // state_saver<>
91
92} // boost
93
94#endif //BOOST_STATE_SAVER_HPP
Note: See TracBrowser for help on using the repository browser.