1 // Copyright 2022 The Chromium Authors 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 BASE_SCOPED_OBSERVATION_TRAITS_H_ 6 #define BASE_SCOPED_OBSERVATION_TRAITS_H_ 7 8 namespace base { 9 10 // `ScopedObservationTraits` is used to control the behavior of 11 // `ScopedObservation` on sources without AddObserver()/RemoveObserver() 12 // methods. 13 // 14 // The implementation of `ScopedObservation<Source, Observer>` will look up the 15 // most specialized version of `ScopedObservationTraits<Source, Observer>` and 16 // use the corresponding `Traits::AddObserver` and `Traits::RemoveObserver`. 17 // 18 // The default specialization takes care of any Source that exposes 19 // `AddObserver(Observer*)` and `RemoveObserver(Observer*)` methods -- if that's 20 // the case, then `ScopedObservation<Source, Observer>` will work out of the 21 // box. 22 // 23 // However, if your `CustomSource` features custom method names -- say, 24 // `AddFoo(FooObserver*)` and `RemoveFoo(FooObserver*)`, then you'll have to 25 // define a new traits specialization like this: 26 // 27 // `custom_source.h`: 28 // #include "base/scoped_observation_traits.h" 29 // 30 // class FooObserver; 31 // class CustomSource { 32 // public: 33 // void AddFoo(FooObserver*); 34 // void RemoveFoo(FooObserver*); 35 // }; 36 // 37 // namespace base { 38 // 39 // template<> 40 // struct ScopedObservationTraits<CustomSource, FooObserver> { 41 // static void AddObserver(CustomSource* source, 42 // FooObserver* observer) { 43 // source->AddFoo(observer); 44 // } 45 // static void RemoveObserver(CustomSource* source, 46 // FooObserver* observer) { 47 // source->RemoveFoo(observer); 48 // } 49 // }; 50 // 51 // } // namespace base 52 // 53 // `some_important_file.cc`: 54 // // Now this works out of the box. 55 // base::ScopedObservation<CustomSource, FooObserver> obs... 56 // 57 58 template <class Source, class Observer> 59 struct ScopedObservationTraits { 60 static_assert( 61 requires(Source& source, Observer* observer) { 62 source.AddObserver(observer); 63 source.RemoveObserver(observer); 64 }, 65 "The given Source is missing " 66 "AddObserver(Observer*) and/or RemoveObserver(Observer*) " 67 "methods. Please provide a custom specialization of " 68 "ScopedObservationTraits<> for this Source/Observer pair."); 69 AddObserverScopedObservationTraits70 static void AddObserver(Source* source, Observer* observer) { 71 source->AddObserver(observer); 72 } RemoveObserverScopedObservationTraits73 static void RemoveObserver(Source* source, Observer* observer) { 74 source->RemoveObserver(observer); 75 } 76 }; 77 78 } // namespace base 79 80 #endif // BASE_SCOPED_OBSERVATION_TRAITS_H_ 81