/src/skia/tools/Registry.h
Line | Count | Source |
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: |
23 | 142 | explicit Registry(T value, bool condition = true) : fValue(value) { |
24 | 142 | if (condition) { |
25 | 142 | this->linkToRegistryHead(); |
26 | 142 | } |
27 | 142 | } |
28 | | |
29 | | static const Registry* Head() { return gHead; } |
30 | | |
31 | | const Registry* next() const { return fChain; } |
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 | | }; |
42 | | Iterator begin() const { return Iterator{Registry::Head()}; } |
43 | | Iterator end() const { return Iterator{nullptr}; } |
44 | | }; |
45 | | |
46 | | private: |
47 | 142 | void linkToRegistryHead() { |
48 | 142 | fChain = gHead; |
49 | 142 | gHead = this; |
50 | 142 | } |
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 |