| // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SHILL_PROPERTY_ACCESSOR_ |
| #define SHILL_PROPERTY_ACCESSOR_ |
| |
| #include <base/basictypes.h> |
| #include <base/logging.h> |
| |
| #include "shill/accessor_interface.h" |
| |
| namespace shill { |
| |
| // Templated implementations of AccessorInterface<>. |
| // PropertyAccessor<> and ConstPropertyAccessor<> respectively provide |
| // R/W and R/O access to the value pointed to by |property|. |
| // this allows a class to easily map strings to member variables, so that |
| // pieces of state stored in the class can be queried or updated by name. |
| // |
| // bool foo = true; |
| // map<string, BoolAccessor> accessors; |
| // accessors["foo"] = BoolAccessor(new PropertyAccessor<bool>(&foo)); |
| // bool new_foo = accessors["foo"]->Get(); // new_foo == true |
| // accessors["foo"]->Set(false); // returns true, because setting is allowed. |
| // // foo == false, new_foo == true |
| // new_foo = accessors["foo"]->Get(); // new_foo == false |
| template <class T> |
| class PropertyAccessor : public AccessorInterface<T> { |
| public: |
| explicit PropertyAccessor(T *property) : property_(property) { |
| DCHECK(property); |
| } |
| virtual ~PropertyAccessor() {} |
| |
| const T &Get() { return *property_; } |
| bool Set(const T &value) { |
| *property_ = value; |
| return true; |
| } |
| |
| private: |
| T * const property_; |
| DISALLOW_COPY_AND_ASSIGN(PropertyAccessor); |
| }; |
| |
| template <class T> |
| class ConstPropertyAccessor : public AccessorInterface<T> { |
| public: |
| explicit ConstPropertyAccessor(const T *property) : property_(property) { |
| DCHECK(property); |
| } |
| virtual ~ConstPropertyAccessor() {} |
| |
| const T &Get() { return *property_; } |
| bool Set(const T &value) { return false; } |
| |
| private: |
| const T * const property_; |
| DISALLOW_COPY_AND_ASSIGN(ConstPropertyAccessor); |
| }; |
| |
| // CustomAccessor<> allows custom getter and setter methods to be provided. |
| // Thus, if the state to be returned is to be derived on-demand, we can |
| // still fit it into the AccessorInterface<> framework. |
| template<class C, class T> |
| class CustomAccessor : public AccessorInterface<T> { |
| public: |
| // |target| is the object on which to call the methods |getter| and |setter| |
| // |setter| is allowed to be NULL, in which case we will simply reject |
| // attempts to set via the accessor. |
| // It is an error to pass NULL for either of the other two arguments. |
| CustomAccessor(C *target, T(C::*getter)(), bool(C::*setter)(const T&)) |
| : target_(target), |
| getter_(getter), |
| setter_(setter) { |
| DCHECK(target); |
| DCHECK(getter); |
| } |
| virtual ~CustomAccessor() {} |
| |
| const T &Get() { return storage_ = (target_->*getter_)(); } |
| bool Set(const T &value) { return setter_ && (target_->*setter_)(value); } |
| |
| private: |
| C * const target_; |
| // Get() returns a const&, so we need to have internal storage to which to |
| // return a reference. |
| T storage_; |
| T(C::*getter_)(void); |
| bool(C::*setter_)(const T&); |
| DISALLOW_COPY_AND_ASSIGN(CustomAccessor); |
| }; |
| |
| } // namespace shill |
| |
| #endif // SHILL_PROPERTY_ACCESSOR_ |