1 /* 2 * Copyright 2009 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef sk_tools_Registry_DEFINED 9 #define sk_tools_Registry_DEFINED 10 11 #include "include/core/SkTypes.h" 12 #include "include/private/base/SkNoncopyable.h" 13 14 namespace sk_tools { 15 16 /** 17 * Template class that registers itself (in the constructor) into a linked-list 18 * and provides a function-pointer. This can be used to auto-register a set of 19 * services, e.g. a set of image codecs. 20 */ 21 template <typename T> class Registry : SkNoncopyable { 22 public: fValue(value)23 explicit Registry(T value, bool condition = true) : fValue(value) { 24 if (condition) { 25 this->linkToRegistryHead(); 26 } 27 } 28 Head()29 static const Registry* Head() { return gHead; } 30 next()31 const Registry* next() const { return fChain; } get()32 const T& get() const { return fValue; } 33 34 // for (const T& t : sk_tools::Registry<T>::Range()) { process(t); } 35 struct Range { 36 struct Iterator { 37 const Registry* fPtr; 38 const T& operator*() { return SkASSERT(fPtr), fPtr->get(); } 39 void operator++() { if (fPtr) { fPtr = fPtr->next(); } } 40 bool operator!=(const Iterator& other) const { return fPtr != other.fPtr; } 41 }; beginRange42 Iterator begin() const { return Iterator{Registry::Head()}; } endRange43 Iterator end() const { return Iterator{nullptr}; } 44 }; 45 46 private: linkToRegistryHead()47 void linkToRegistryHead() { 48 fChain = gHead; 49 gHead = this; 50 } 51 52 T fValue; 53 Registry* fChain; 54 55 static Registry* gHead; 56 }; 57 58 // The caller still needs to declare an instance of this somewhere 59 template <typename T> Registry<T>* Registry<T>::gHead; 60 61 } // namespace sk_tools 62 63 #endif 64