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