state_saver.hpp 2.6 KB

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