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

    return *this; 
  } 
 
 private: 
  typedef std::vector<std::unique_ptr<SettingChangeBase>> setting_changes;
  setting_changes m_settingChanges; 
}; 
} 
 
#endif  // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66