You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.6 KiB

2 months ago
  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 "yaml-cpp/noexcept.h"
  9. #include <memory>
  10. #include <utility>
  11. #include <vector>
  12. namespace YAML {
  13. class SettingChangeBase {
  14. public:
  15. virtual ~SettingChangeBase() = default;
  16. virtual void pop() = 0;
  17. };
  18. template <typename T>
  19. class Setting {
  20. public:
  21. Setting() : m_value() {}
  22. Setting(const T& value) : m_value() { set(value); }
  23. const T get() const { return m_value; }
  24. std::unique_ptr<SettingChangeBase> set(const T& value);
  25. void restore(const Setting<T>& oldSetting) { m_value = oldSetting.get(); }
  26. private:
  27. T m_value;
  28. };
  29. template <typename T>
  30. class SettingChange : public SettingChangeBase {
  31. public:
  32. SettingChange(Setting<T>* pSetting)
  33. : m_pCurSetting(pSetting),
  34. m_oldSetting(*pSetting) // copy old setting to save its state
  35. {}
  36. SettingChange(const SettingChange&) = delete;
  37. SettingChange(SettingChange&&) = delete;
  38. SettingChange& operator=(const SettingChange&) = delete;
  39. SettingChange& operator=(SettingChange&&) = delete;
  40. void pop() override { m_pCurSetting->restore(m_oldSetting); }
  41. private:
  42. Setting<T>* m_pCurSetting;
  43. Setting<T> m_oldSetting;
  44. };
  45. template <typename T>
  46. inline std::unique_ptr<SettingChangeBase> Setting<T>::set(const T& value) {
  47. std::unique_ptr<SettingChangeBase> pChange(new SettingChange<T>(this));
  48. m_value = value;
  49. return pChange;
  50. }
  51. class SettingChanges {
  52. public:
  53. SettingChanges() : m_settingChanges{} {}
  54. SettingChanges(const SettingChanges&) = delete;
  55. SettingChanges(SettingChanges&&) YAML_CPP_NOEXCEPT = default;
  56. SettingChanges& operator=(const SettingChanges&) = delete;
  57. SettingChanges& operator=(SettingChanges&& rhs) YAML_CPP_NOEXCEPT {
  58. if (this == &rhs)
  59. return *this;
  60. clear();
  61. std::swap(m_settingChanges, rhs.m_settingChanges);
  62. return *this;
  63. }
  64. ~SettingChanges() { clear(); }
  65. void clear() YAML_CPP_NOEXCEPT {
  66. restore();
  67. m_settingChanges.clear();
  68. }
  69. void restore() YAML_CPP_NOEXCEPT {
  70. for (const auto& setting : m_settingChanges)
  71. setting->pop();
  72. }
  73. void push(std::unique_ptr<SettingChangeBase> pSettingChange) {
  74. m_settingChanges.push_back(std::move(pSettingChange));
  75. }
  76. private:
  77. using setting_changes = std::vector<std::unique_ptr<SettingChangeBase>>;
  78. setting_changes m_settingChanges;
  79. };
  80. } // namespace YAML
  81. #endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66