setting.h (2689B)
1 #ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 #define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 4 #if defined(_MSC_VER) || \ 5 (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 #pragma once 8 #endif 9 10 #include "yaml-cpp/noexcept.h" 11 #include <memory> 12 #include <utility> 13 #include <vector> 14 15 namespace YAML { 16 17 class SettingChangeBase { 18 public: 19 virtual ~SettingChangeBase() = default; 20 virtual void pop() = 0; 21 }; 22 23 template <typename T> 24 class Setting { 25 public: 26 Setting() : m_value() {} 27 Setting(const T& value) : m_value() { set(value); } 28 29 const T get() const { return m_value; } 30 std::unique_ptr<SettingChangeBase> set(const T& value); 31 void restore(const Setting<T>& oldSetting) { m_value = oldSetting.get(); } 32 33 private: 34 T m_value; 35 }; 36 37 template <typename T> 38 class SettingChange : public SettingChangeBase { 39 public: 40 SettingChange(Setting<T>* pSetting) 41 : m_pCurSetting(pSetting), 42 m_oldSetting(*pSetting) // copy old setting to save its state 43 {} 44 SettingChange(const SettingChange&) = delete; 45 SettingChange(SettingChange&&) = delete; 46 SettingChange& operator=(const SettingChange&) = delete; 47 SettingChange& operator=(SettingChange&&) = delete; 48 49 void pop() override { m_pCurSetting->restore(m_oldSetting); } 50 51 private: 52 Setting<T>* m_pCurSetting; 53 Setting<T> m_oldSetting; 54 }; 55 56 template <typename T> 57 inline std::unique_ptr<SettingChangeBase> Setting<T>::set(const T& value) { 58 std::unique_ptr<SettingChangeBase> pChange(new SettingChange<T>(this)); 59 m_value = value; 60 return pChange; 61 } 62 63 class SettingChanges { 64 public: 65 SettingChanges() : m_settingChanges{} {} 66 SettingChanges(const SettingChanges&) = delete; 67 SettingChanges(SettingChanges&&) YAML_CPP_NOEXCEPT = default; 68 SettingChanges& operator=(const SettingChanges&) = delete; 69 SettingChanges& operator=(SettingChanges&& rhs) YAML_CPP_NOEXCEPT { 70 if (this == &rhs) 71 return *this; 72 73 clear(); 74 std::swap(m_settingChanges, rhs.m_settingChanges); 75 76 return *this; 77 } 78 ~SettingChanges() { clear(); } 79 80 void clear() YAML_CPP_NOEXCEPT { 81 restore(); 82 m_settingChanges.clear(); 83 } 84 85 void restore() YAML_CPP_NOEXCEPT { 86 for (const auto& setting : m_settingChanges) 87 setting->pop(); 88 } 89 90 void push(std::unique_ptr<SettingChangeBase> pSettingChange) { 91 m_settingChanges.push_back(std::move(pSettingChange)); 92 } 93 94 private: 95 using setting_changes = std::vector<std::unique_ptr<SettingChangeBase>>; 96 setting_changes m_settingChanges; 97 }; 98 } // namespace YAML 99 100 #endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66