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