Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
setting.h
Go to the documentation of this file.
1 
18 #ifndef ION_BASE_SETTING_H_
19 #define ION_BASE_SETTING_H_
20 
21 #include <functional>
22 #include <map>
23 #include <sstream>
24 #include <string>
25 
26 #include "base/macros.h"
27 #include "ion/base/serialize.h"
28 #include "ion/base/shareable.h"
29 #include "ion/base/sharedptr.h"
30 #include "ion/base/stringutils.h"
31 #include "ion/port/atomic.h"
32 #include "ion/port/environment.h"
33 
34 namespace ion {
35 namespace base {
36 
43 class ION_API SettingBase {
44  public:
46  typedef std::function<void(SettingBase* setting)> Listener;
47  struct ListenerInfo {
48  ListenerInfo() : enabled(false) {}
49  ListenerInfo(const Listener& listener_in, bool enabled_in)
50  : listener(listener_in), enabled(enabled_in) {}
52  bool enabled;
53  };
54 
56  const std::string& GetName() const { return name_; }
57 
59  const std::string& GetDocString() const { return doc_string_; }
60 
65  void SetTypeDescriptor(const std::string& desc) { type_descriptor_ = desc; }
66  const std::string& GetTypeDescriptor() const { return type_descriptor_; }
67 
71  void RegisterListener(const std::string& key, const Listener& listener);
73  void EnableListener(const std::string& key, bool enable);
75  void UnregisterListener(const std::string& key);
76 
78  void NotifyListeners();
79 
82  virtual const std::string ToString() const = 0;
86  virtual bool FromString(const std::string& str) = 0;
87 
88  protected:
91  SettingBase(const std::string& name, const std::string& doc_string);
92  virtual ~SettingBase();
93 
94  private:
95  typedef std::map<std::string, ListenerInfo> ListenerMap;
96 
97  std::string name_;
98  std::string doc_string_;
99  std::string type_descriptor_;
100  ListenerMap listeners_;
101 
104  friend class SettingManager;
105  SharedPtr<Shareable> data_ref_;
106 
107  DISALLOW_IMPLICIT_CONSTRUCTORS(SettingBase);
108 };
109 
115 class ION_API SettingGroup {
116  public:
117  explicit SettingGroup(const std::string& name) : group_(name) {
118  while (base::EndsWith(group_, "/"))
119  base::RemoveSuffix("/", &group_);
120  }
121  SettingGroup(const SettingGroup& parent_group, std::string name) {
122  while (base::StartsWith(name, "/"))
123  base::RemovePrefix("/", &name);
124  while (base::EndsWith(name, "/"))
125  base::RemoveSuffix("/", &name);
126  group_ = parent_group.GetGroupName() + "/" + name;
127  }
129 
131  const std::string GetGroupName() const { return group_; }
132 
133  private:
134  std::string group_;
135 };
136 
138 template <typename T> class Setting;
139 template <typename SettingType>
140 void SetTypeDescriptorForType(SettingType* setting);
141 
154 template <typename T>
155 class Setting : public SettingBase {
156  public:
159  Setting(const std::string& name, const T& value,
160  const std::string& doc_string)
161  : SettingBase(name, doc_string), value_(value) {
163  }
164 
166  Setting(const SettingGroup* group, const std::string& name, const T& value,
167  const std::string& doc_string)
168  : SettingBase(group->GetGroupName() + '/' + name, doc_string),
169  value_(value) {
171  }
172 
174  Setting(const std::string& name, const T& value)
175  : SettingBase(name, std::string()), value_(value) {
177  }
178 
180  Setting(const SettingGroup* group, const std::string& name, const T& value)
181  : SettingBase(group->GetGroupName() + '/' + name, std::string()),
182  value_(value) {
184  }
185 
186  ~Setting() override {}
187 
188  const std::string ToString() const override { return ValueToString(value_); }
189 
190  bool FromString(const std::string& str) override {
191  T value = T();
192  std::istringstream in(str);
193  if (StringToValue(in, &value)) {
194  SetValue(value);
195  return true;
196  }
197  return false;
198  }
199 
201  T* GetMutableValue() { return &value_; }
202  const T& GetValue() const { return value_; }
203  void SetValue(const T& value) {
204  value_ = value;
205  NotifyListeners();
206  }
207  operator T() const { return value_; }
208  void operator=(const T& value) {
209  value_ = value;
210  NotifyListeners();
211  }
212 
214  bool operator==(const T& value) const { return value_ == value; }
215  friend bool operator==(const T& value, const Setting<T>& setting) {
216  return setting.value_ == value;
217  }
218 
219  private:
220  T value_;
221 
222  DISALLOW_IMPLICIT_CONSTRUCTORS(Setting<T>);
223 };
224 
226 template <typename T>
227 class Setting<std::atomic<T> > : public SettingBase {
228  public:
231  Setting(const std::string& name, const T& value,
232  const std::string& doc_string)
233  : SettingBase(name, doc_string), value_(value) {
235  }
236 
238  Setting(const SettingGroup* group, const std::string& name, const T& value,
239  const std::string& doc_string)
240  : SettingBase(group->GetGroupName() + '/' + name, doc_string),
241  value_(value) {
243  }
244 
246  Setting(const std::string& name, const T& value)
247  : SettingBase(name, std::string()), value_(value) {
249  }
250 
252  Setting(const SettingGroup* group, const std::string& name, const T& value)
253  : SettingBase(group->GetGroupName() + '/' + name, std::string()),
254  value_(value) {
256  }
257 
258  ~Setting() override {}
259 
260  const std::string ToString() const override {
261  return ValueToString(value_.load());
262  }
263 
264  bool FromString(const std::string& str) override {
265  T value = T();
266  std::istringstream in(str);
267  if (StringToValue(in, &value)) {
268  SetValue(value);
269  return true;
270  }
271  return false;
272  }
273 
275  std::atomic<T>* GetMutableValue() { return &value_; }
276  const std::atomic<T>& GetValue() const { return value_; }
277  void SetValue(const T& value) {
278  value_ = value;
279  NotifyListeners();
280  }
281  operator T() const { return value_.load(); }
282  void operator=(const T& value) {
283  value_ = value;
284  NotifyListeners();
285  }
286 
288  bool operator==(const T& value) const { return value_ == value; }
289  friend bool operator==(const T& value,
290  const Setting<std::atomic<T> >& setting) {
291  return setting.value_ == value;
292  }
293 
294  private:
295  std::atomic<T> value_;
296 
297  DISALLOW_IMPLICIT_CONSTRUCTORS(Setting<std::atomic<T> >);
298 };
299 
304 template <typename T>
305 class EnvironmentSetting : public Setting<T> {
306  public:
311  EnvironmentSetting(const std::string& setting_name,
312  const std::string& env_var_name,
313  const T& default_value,
314  const std::string& doc_string)
315  : Setting<T>(setting_name, default_value, doc_string) {
316  const std::string env_value =
317  port::GetEnvironmentVariableValue(env_var_name);
318  this->FromString(env_value);
319  }
320 
322  bool operator==(const T& value) const {
323  return Setting<T>::operator==(value);
324  }
325  friend bool operator==(const T& value, const EnvironmentSetting<T>& setting) {
326  return setting == value;
327  }
328 
329  private:
330  DISALLOW_IMPLICIT_CONSTRUCTORS(EnvironmentSetting<T>);
331 };
332 
336 template <typename T>
338  public:
341  : setting_(setting) {
342  if (setting_) {
343  original_value_ = setting_->GetValue();
344  setting_->SetValue(value);
345  }
346  }
347 
350  if (setting_) {
351  setting_->SetValue(original_value_);
352  }
353  }
354 
355  private:
357  Setting<T>* setting_;
358 
362  T original_value_;
363 };
364 
367 template <typename SettingType>
368 inline void SetTypeDescriptorForType(SettingType* setting) {
369 }
370 
372 template <>
374  setting->SetTypeDescriptor("bool");
375 }
376 
377 template <>
378 inline void SetTypeDescriptorForType(Setting<std::atomic<bool> >* setting) {
379  setting->SetTypeDescriptor("bool");
380 }
381 
382 } // namespace base
383 } // namespace ion
384 
385 #endif // ION_BASE_SETTING_H_
const std::string & GetDocString() const
Returns the documentation string associated with this.
Definition: setting.h:59
Setting(const std::string &name, const T &value, const std::string &doc_string)
Creates a new setting with the passed name, initial value, and documentation string.
Definition: setting.h:231
void NotifyListeners()
Notify listeners that this setting has changed.
Definition: setting.cc:50
const std::string GetEnvironmentVariableValue(const std::string &name)
Returns the value of the named environment variable.
Definition: environment.cc:29
bool operator==(const T &value) const
Equality testers.
Definition: setting.h:214
bool StartsWith(const std::string &target, const std::string &start)
Returns whether target begins with start.
Definition: stringutils.h:76
bool FromString(const std::string &str) override
Parses the passed string to set the value of this and returns whether the parsing was successful...
Definition: setting.h:190
Setting(const std::string &name, const T &value)
Convenience constructor that does not require a documentation string.
Definition: setting.h:174
Setting(const SettingGroup *group, const std::string &name, const T &value, const std::string &doc_string)
Same as above, but places the setting in the passed group.
Definition: setting.h:166
const std::string & str
friend bool operator==(const T &value, const EnvironmentSetting< T > &setting)
Definition: setting.h:325
EnvironmentSetting(const std::string &setting_name, const std::string &env_var_name, const T &default_value, const std::string &doc_string)
Creates a new setting with the passed setting_name and attempts to set its initial value from the env...
Definition: setting.h:311
SettingGroup(const SettingGroup &parent_group, std::string name)
Definition: setting.h:121
Base class for Setting, which encapsulates the name of the setting and any functors that should be ca...
Definition: setting.h:43
Setting(const std::string &name, const T &value)
Convenience constructor that does not require a documentation string.
Definition: setting.h:246
Setting(const std::string &name, const T &value, const std::string &doc_string)
Creates a new setting with the passed name, initial value, and documentation string.
Definition: setting.h:159
T * GetMutableValue()
Direct value mutators.
Definition: setting.h:201
double value
SettingGroup(const std::string &name)
Definition: setting.h:117
bool operator==(const T &value) const
Equality testers.
Definition: setting.h:322
const std::atomic< T > & GetValue() const
Definition: setting.h:276
const std::string ToString() const override
Returns a string version of this setting.
Definition: setting.h:260
friend bool operator==(const T &value, const Setting< std::atomic< T > > &setting)
Definition: setting.h:289
bool RemovePrefix(const std::string &prefix, std::string *target)
Removes prefix from the beginning of target if target starts with it.
Definition: stringutils.h:102
Setting(const SettingGroup *group, const std::string &name, const T &value)
Same as above, but places the setting in the passed group.
Definition: setting.h:252
void SetValue(const T &value)
Definition: setting.h:203
bool FromString(const std::string &str) override
Parses the passed string to set the value of this and returns whether the parsing was successful...
Definition: setting.h:264
void SetTypeDescriptorForType(SettingType *setting)
Sets the type descriptor string of a setting based on its type.
Definition: setting.h:368
const std::string GetGroupName() const
Returns the name of the group that this wraps.
Definition: setting.h:131
void SetValue(const T &value)
Definition: setting.h:277
void SetTypeDescriptor(const std::string &desc)
Sets/returns a string containing information about the Setting's type.
Definition: setting.h:65
bool StringToValue(std::istringstream &in, T *val)
This file defines two public functions: StringToValue() and ValueToString().
Definition: serialize.h:45
bool RemoveSuffix(const std::string &suffix, std::string *target)
Removes suffix from the end of target if target ends with it.
Definition: stringutils.h:113
std::string ValueToString(const T &val)
ValueToString.
Definition: serialize.h:209
~Setting() override
Definition: setting.h:186
bool operator==(const T &value) const
Equality testers.
Definition: setting.h:288
const std::string & GetName() const
Returns the name associated with this.
Definition: setting.h:56
std::string name
Definition: printer.cc:324
const std::string & GetTypeDescriptor() const
Definition: setting.h:66
const std::string ToString() const override
Returns a string version of this setting.
Definition: setting.h:188
std::function< void(SettingBase *setting)> Listener
A function that is called when the value changes.
Definition: setting.h:46
const T & GetValue() const
Definition: setting.h:202
Setting(const SettingGroup *group, const std::string &name, const T &value)
Same as above, but places the setting in the passed group.
Definition: setting.h:180
Setting(const SettingGroup *group, const std::string &name, const T &value, const std::string &doc_string)
Same as above, but places the setting in the passed group.
Definition: setting.h:238
~ScopedSettingValue()
Restore the original value to the Setting<T>.
Definition: setting.h:349
friend bool operator==(const T &value, const Setting< T > &setting)
Definition: setting.h:215
bool EndsWith(const std::string &target, const std::string &end)
Returns whether target ends with end.
Definition: stringutils.h:81
SettingManager tracks all existing SettingBase instances, and allows callers to obtain a map of all s...
A SettingGroup is a convenience class to hold Settings that are in the same hierarchical group...
Definition: setting.h:115
void operator=(const T &value)
Definition: setting.h:282
ListenerInfo(const Listener &listener_in, bool enabled_in)
Definition: setting.h:49
Sets a Setting<T> to a new value.
Definition: setting.h:337
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Definition: sharedptr.h:60
void operator=(const T &value)
Definition: setting.h:208
Forward references.
Definition: setting.h:138
An EnvironmentSetting is a Setting can take its initial value from the named system environment varia...
Definition: setting.h:305
ScopedSettingValue(Setting< T > *setting, const T &value)
Save the original setting value, and change to the new value.
Definition: setting.h:340
std::atomic< T > * GetMutableValue()
Direct value mutators.
Definition: setting.h:275