setting.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
  2. #define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
  3. #if defined(_MSC_VER) || \
  4. (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
  5. (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
  6. #pragma once
  7. #endif
  8. #include <memory>
  9. #include <vector>
  10. #include "yaml-cpp/noncopyable.h"
  11. namespace YAML {
  12. class SettingChangeBase;
  13. template <typename T>
  14. class Setting {
  15. public:
  16. Setting() : m_value() {}
  17. const T get() const { return m_value; }
  18. std::unique_ptr<SettingChangeBase> set(const T& value);
  19. void restore(const Setting<T>& oldSetting) { m_value = oldSetting.get(); }
  20. private:
  21. T m_value;
  22. };
  23. class SettingChangeBase {
  24. public:
  25. virtual ~SettingChangeBase() {}
  26. virtual void pop() = 0;
  27. };
  28. template <typename T>
  29. class SettingChange : public SettingChangeBase {
  30. public:
  31. SettingChange(Setting<T>* pSetting) : m_pCurSetting(pSetting) {
  32. // copy old setting to save its state
  33. m_oldSetting = *pSetting;
  34. }
  35. virtual void pop() { m_pCurSetting->restore(m_oldSetting); }
  36. private:
  37. Setting<T>* m_pCurSetting;
  38. Setting<T> m_oldSetting;
  39. };
  40. template <typename T>
  41. inline std::unique_ptr<SettingChangeBase> Setting<T>::set(const T& value) {
  42. std::unique_ptr<SettingChangeBase> pChange(new SettingChange<T>(this));
  43. m_value = value;
  44. return pChange;
  45. }
  46. class SettingChanges : private noncopyable {
  47. public:
  48. SettingChanges() {}
  49. ~SettingChanges() { clear(); }
  50. void clear() {
  51. restore();
  52. m_settingChanges.clear();
  53. }
  54. void restore() {
  55. for (setting_changes::const_iterator it = m_settingChanges.begin();
  56. it != m_settingChanges.end(); ++it)
  57. (*it)->pop();
  58. }
  59. void push(std::unique_ptr<SettingChangeBase> pSettingChange) {
  60. m_settingChanges.push_back(std::move(pSettingChange));
  61. }
  62. // like std::unique_ptr - assignment is transfer of ownership
  63. SettingChanges& operator=(SettingChanges&& rhs) {
  64. if (this == &rhs)
  65. return *this;
  66. clear();
  67. std::swap(m_settingChanges, rhs.m_settingChanges);
  68. return *this;
  69. }
  70. private:
  71. typedef std::vector<std::unique_ptr<SettingChangeBase>> setting_changes;
  72. setting_changes m_settingChanges;
  73. };
  74. }
  75. #endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66