blob: cb391825ff19f55670225d35d01a50d8e9771046 [file] [log] [blame]
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_PROPERTY_ACCESSOR_
6#define SHILL_PROPERTY_ACCESSOR_
7
8#include <base/basictypes.h>
9
10#include "shill/accessor_interface.h"
11
12namespace shill {
13
14// Templated implementations of AccessorInterface<>.
15// PropertyAccessor<> and ConstPropertyAccessor<> respectively provide
16// R/W and R/O access to the value pointed to by |property|.
17// this allows a class to easily map strings to member variables, so that
18// pieces of state stored in the class can be queried or updated by name.
19//
20// bool foo = true;
21// map<string, BoolAccessor> accessors;
22// accessors["foo"] = BoolAccessor(new PropertyAccessor<bool>(&foo));
23// bool new_foo = accessors["foo"]->Get(); // new_foo == true
24// accessors["foo"]->Set(false); // returns true, because setting is allowed.
25// // foo == false, new_foo == true
26// new_foo = accessors["foo"]->Get(); // new_foo == false
27template <class T>
28class PropertyAccessor : public AccessorInterface<T> {
29 public:
30 explicit PropertyAccessor(T *property) : property_(property) {
31 DCHECK(property);
32 }
33 virtual ~PropertyAccessor() {}
34
35 const T &Get() { return *property_; }
36 bool Set(const T &value) {
37 *property_ = value;
38 return true;
39 }
40
41 private:
42 T * const property_;
43 DISALLOW_COPY_AND_ASSIGN(PropertyAccessor);
44};
45
46template <class T>
47class ConstPropertyAccessor : public AccessorInterface<T> {
48 public:
49 explicit ConstPropertyAccessor(const T *property) : property_(property) {
50 DCHECK(property);
51 }
52 virtual ~ConstPropertyAccessor() {}
53
54 const T &Get() { return *property_; }
55 bool Set(const T &value) { return false; }
56
57 private:
58 const T * const property_;
59 DISALLOW_COPY_AND_ASSIGN(ConstPropertyAccessor);
60};
61
62// CustomAccessor<> allows custom getter and setter methods to be provided.
63// Thus, if the state to be returned is to be derived on-demand, we can
64// still fit it into the AccessorInterface<> framework.
65template<class C, class T>
66class CustomAccessor : public AccessorInterface<T> {
67 public:
68 // |target| is the object on which to call the methods |getter| and |setter|
69 // |setter| is allowed to be NULL, in which case we will simply reject
70 // attempts to set via the accessor.
71 // It is an error to pass NULL for either of the other two arguments.
72 CustomAccessor(C *target, T(C::*getter)(), bool(C::*setter)(const T&))
73 : target_(target),
74 getter_(getter),
75 setter_(setter) {
76 DCHECK(target);
77 DCHECK(getter);
78 }
79 virtual ~CustomAccessor() {}
80
81 const T &Get() { return storage_ = (target_->*getter_)(); }
82 bool Set(const T &value) { return setter_ && (target_->*setter_)(value); }
83
84 private:
85 C * const target_;
86 // Get() returns a const&, so we need to have internal storage to which to
87 // return a reference.
88 T storage_;
89 T(C::*getter_)(void);
90 bool(C::*setter_)(const T&);
91 DISALLOW_COPY_AND_ASSIGN(CustomAccessor);
92};
93
94} // namespace shill
95
96#endif // SHILL_PROPERTY_ACCESSOR_