1*993b0882SAndroid Build Coastguard Worker /* 2*993b0882SAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project 3*993b0882SAndroid Build Coastguard Worker * 4*993b0882SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*993b0882SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*993b0882SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*993b0882SAndroid Build Coastguard Worker * 8*993b0882SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*993b0882SAndroid Build Coastguard Worker * 10*993b0882SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*993b0882SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*993b0882SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*993b0882SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*993b0882SAndroid Build Coastguard Worker * limitations under the License. 15*993b0882SAndroid Build Coastguard Worker */ 16*993b0882SAndroid Build Coastguard Worker 17*993b0882SAndroid Build Coastguard Worker // Mechanism to instantiate classes by name. 18*993b0882SAndroid Build Coastguard Worker // 19*993b0882SAndroid Build Coastguard Worker // This mechanism is useful if the concrete classes to be instantiated are not 20*993b0882SAndroid Build Coastguard Worker // statically known (e.g., if their names are read from a dynamically-provided 21*993b0882SAndroid Build Coastguard Worker // config). 22*993b0882SAndroid Build Coastguard Worker // 23*993b0882SAndroid Build Coastguard Worker // In that case, the first step is to define the API implemented by the 24*993b0882SAndroid Build Coastguard Worker // instantiated classes. E.g., 25*993b0882SAndroid Build Coastguard Worker // 26*993b0882SAndroid Build Coastguard Worker // // In a header file function.h: 27*993b0882SAndroid Build Coastguard Worker // 28*993b0882SAndroid Build Coastguard Worker // // Abstract function that takes a double and returns a double. 29*993b0882SAndroid Build Coastguard Worker // class Function : public RegisterableClass<Function> { 30*993b0882SAndroid Build Coastguard Worker // public: 31*993b0882SAndroid Build Coastguard Worker // virtual ~Function() {} 32*993b0882SAndroid Build Coastguard Worker // virtual double Evaluate(double x) = 0; 33*993b0882SAndroid Build Coastguard Worker // }; 34*993b0882SAndroid Build Coastguard Worker // 35*993b0882SAndroid Build Coastguard Worker // // Should be inside namespace libtextclassifier3::mobile. 36*993b0882SAndroid Build Coastguard Worker // SAFTM_DECLARE_CLASS_REGISTRY_NAME(Function); 37*993b0882SAndroid Build Coastguard Worker // 38*993b0882SAndroid Build Coastguard Worker // Notice the inheritance from RegisterableClass<Function>. RegisterableClass 39*993b0882SAndroid Build Coastguard Worker // is defined by this file (registry.h). Under the hood, this inheritanace 40*993b0882SAndroid Build Coastguard Worker // defines a "registry" that maps names (zero-terminated arrays of chars) to 41*993b0882SAndroid Build Coastguard Worker // factory methods that create Functions. You should give a human-readable name 42*993b0882SAndroid Build Coastguard Worker // to this registry. To do that, use the following macro in a .cc file (it has 43*993b0882SAndroid Build Coastguard Worker // to be a .cc file, as it defines some static data): 44*993b0882SAndroid Build Coastguard Worker // 45*993b0882SAndroid Build Coastguard Worker // // Inside function.cc 46*993b0882SAndroid Build Coastguard Worker // // Should be inside namespace libtextclassifier3::mobile. 47*993b0882SAndroid Build Coastguard Worker // SAFTM_DEFINE_CLASS_REGISTRY_NAME("function", Function); 48*993b0882SAndroid Build Coastguard Worker // 49*993b0882SAndroid Build Coastguard Worker // Now, let's define a few concrete Functions: e.g., 50*993b0882SAndroid Build Coastguard Worker // 51*993b0882SAndroid Build Coastguard Worker // class Cos : public Function { 52*993b0882SAndroid Build Coastguard Worker // public: 53*993b0882SAndroid Build Coastguard Worker // double Evaluate(double x) override { return cos(x); } 54*993b0882SAndroid Build Coastguard Worker // SAFTM_DEFINE_REGISTRATION_METHOD("cos", Cos); 55*993b0882SAndroid Build Coastguard Worker // }; 56*993b0882SAndroid Build Coastguard Worker // 57*993b0882SAndroid Build Coastguard Worker // class Exp : public Function { 58*993b0882SAndroid Build Coastguard Worker // public: 59*993b0882SAndroid Build Coastguard Worker // double Evaluate(double x) override { return exp(x); } 60*993b0882SAndroid Build Coastguard Worker // SAFTM_DEFINE_REGISTRATION_METHOD("sin", Sin); 61*993b0882SAndroid Build Coastguard Worker // }; 62*993b0882SAndroid Build Coastguard Worker // 63*993b0882SAndroid Build Coastguard Worker // Each concrete Function implementation should have (in the public section) the 64*993b0882SAndroid Build Coastguard Worker // macro 65*993b0882SAndroid Build Coastguard Worker // 66*993b0882SAndroid Build Coastguard Worker // SAFTM_DEFINE_REGISTRATION_METHOD("name", implementation_class); 67*993b0882SAndroid Build Coastguard Worker // 68*993b0882SAndroid Build Coastguard Worker // This defines a RegisterClass static method that, when invoked, associates 69*993b0882SAndroid Build Coastguard Worker // "name" with a factory method that creates instances of implementation_class. 70*993b0882SAndroid Build Coastguard Worker // 71*993b0882SAndroid Build Coastguard Worker // Before instantiating Functions by name, we need to tell our system which 72*993b0882SAndroid Build Coastguard Worker // Functions we may be interested in. This is done by calling the 73*993b0882SAndroid Build Coastguard Worker // Foo::RegisterClass() for each relevant Foo implementation of Function. It is 74*993b0882SAndroid Build Coastguard Worker // ok to call Foo::RegisterClass() multiple times (even in parallel): only the 75*993b0882SAndroid Build Coastguard Worker // first call will perform something, the others will return immediately. 76*993b0882SAndroid Build Coastguard Worker // 77*993b0882SAndroid Build Coastguard Worker // Cos::RegisterClass(); 78*993b0882SAndroid Build Coastguard Worker // Exp::RegisterClass(); 79*993b0882SAndroid Build Coastguard Worker // 80*993b0882SAndroid Build Coastguard Worker // Now, let's instantiate a Function based on its name. This get a lot more 81*993b0882SAndroid Build Coastguard Worker // interesting if the Function name is not statically known (i.e., 82*993b0882SAndroid Build Coastguard Worker // read from an input proto: 83*993b0882SAndroid Build Coastguard Worker // 84*993b0882SAndroid Build Coastguard Worker // std::unique_ptr<Function> f(Function::Create("cos")); 85*993b0882SAndroid Build Coastguard Worker // double result = f->Evaluate(arg); 86*993b0882SAndroid Build Coastguard Worker // 87*993b0882SAndroid Build Coastguard Worker // NOTE: the same binary can use this mechanism for different APIs. E.g., one 88*993b0882SAndroid Build Coastguard Worker // can also have (in the binary with Function, Sin, Cos, etc): 89*993b0882SAndroid Build Coastguard Worker // 90*993b0882SAndroid Build Coastguard Worker // class IntFunction : public RegisterableClass<IntFunction> { 91*993b0882SAndroid Build Coastguard Worker // public: 92*993b0882SAndroid Build Coastguard Worker // virtual ~IntFunction() {} 93*993b0882SAndroid Build Coastguard Worker // virtual int Evaluate(int k) = 0; 94*993b0882SAndroid Build Coastguard Worker // }; 95*993b0882SAndroid Build Coastguard Worker // 96*993b0882SAndroid Build Coastguard Worker // SAFTM_DECLARE_CLASS_REGISTRY_NAME(IntFunction); 97*993b0882SAndroid Build Coastguard Worker // 98*993b0882SAndroid Build Coastguard Worker // SAFTM_DEFINE_CLASS_REGISTRY_NAME("int function", IntFunction); 99*993b0882SAndroid Build Coastguard Worker // 100*993b0882SAndroid Build Coastguard Worker // class Inc : public IntFunction { 101*993b0882SAndroid Build Coastguard Worker // public: 102*993b0882SAndroid Build Coastguard Worker // int Evaluate(int k) override { return k + 1; } 103*993b0882SAndroid Build Coastguard Worker // SAFTM_DEFINE_REGISTRATION_METHOD("inc", Inc); 104*993b0882SAndroid Build Coastguard Worker // }; 105*993b0882SAndroid Build Coastguard Worker // 106*993b0882SAndroid Build Coastguard Worker // RegisterableClass<Function> and RegisterableClass<IntFunction> define their 107*993b0882SAndroid Build Coastguard Worker // own registries: each maps string names to implementation of the corresponding 108*993b0882SAndroid Build Coastguard Worker // API. 109*993b0882SAndroid Build Coastguard Worker // 110*993b0882SAndroid Build Coastguard Worker // NOTE: the mechanism described above requires you to explicitly call 111*993b0882SAndroid Build Coastguard Worker // RegisterClass() for all relevant classes before instantiating them. You can 112*993b0882SAndroid Build Coastguard Worker // do this in the main() function or in any other function that is guaranteed to 113*993b0882SAndroid Build Coastguard Worker // run before the code that instantiates those classes. Alternatively, you can 114*993b0882SAndroid Build Coastguard Worker // use the macro SAFTM_STATIC_REGISTRATION to perform this registration in a 115*993b0882SAndroid Build Coastguard Worker // decentralized fashion. Just use that macro in a .cc file, outside any 116*993b0882SAndroid Build Coastguard Worker // function / class, e.g., 117*993b0882SAndroid Build Coastguard Worker // 118*993b0882SAndroid Build Coastguard Worker // SAFTM_STATIC_REGISTRATION(Cos); 119*993b0882SAndroid Build Coastguard Worker // 120*993b0882SAndroid Build Coastguard Worker // and make sure you link in all symbols from that .cc file; e.g., in bazel, use 121*993b0882SAndroid Build Coastguard Worker // alwayslink = 1 for the corresponding cc_library. Still, please be aware that 122*993b0882SAndroid Build Coastguard Worker // using alwayslink = 1 limits the ability of the linker to perform dead code 123*993b0882SAndroid Build Coastguard Worker // elimination. 124*993b0882SAndroid Build Coastguard Worker 125*993b0882SAndroid Build Coastguard Worker #ifndef NLP_SAFT_COMPONENTS_COMMON_MOBILE_REGISTRY_H_ 126*993b0882SAndroid Build Coastguard Worker #define NLP_SAFT_COMPONENTS_COMMON_MOBILE_REGISTRY_H_ 127*993b0882SAndroid Build Coastguard Worker 128*993b0882SAndroid Build Coastguard Worker #include <stdlib.h> 129*993b0882SAndroid Build Coastguard Worker #include <string.h> 130*993b0882SAndroid Build Coastguard Worker 131*993b0882SAndroid Build Coastguard Worker #include <string> 132*993b0882SAndroid Build Coastguard Worker #include <vector> 133*993b0882SAndroid Build Coastguard Worker 134*993b0882SAndroid Build Coastguard Worker #include "lang_id/common/lite_base/logging.h" 135*993b0882SAndroid Build Coastguard Worker #include "lang_id/common/lite_base/macros.h" 136*993b0882SAndroid Build Coastguard Worker 137*993b0882SAndroid Build Coastguard Worker namespace libtextclassifier3 { 138*993b0882SAndroid Build Coastguard Worker namespace mobile { 139*993b0882SAndroid Build Coastguard Worker 140*993b0882SAndroid Build Coastguard Worker namespace internal { 141*993b0882SAndroid Build Coastguard Worker // Registry that associates keys (zero-terminated array of chars) with values. 142*993b0882SAndroid Build Coastguard Worker // Values are pointers to type T (the template parameter). This is used to 143*993b0882SAndroid Build Coastguard Worker // store the association between component names and factory methods that 144*993b0882SAndroid Build Coastguard Worker // produce those components; the error messages are focused on that case. 145*993b0882SAndroid Build Coastguard Worker // 146*993b0882SAndroid Build Coastguard Worker // Internally, this registry uses a linked list of (key, value) pairs. We do 147*993b0882SAndroid Build Coastguard Worker // not use an STL map, list, etc because we aim for small code size. 148*993b0882SAndroid Build Coastguard Worker template <class T> 149*993b0882SAndroid Build Coastguard Worker class ComponentRegistry { 150*993b0882SAndroid Build Coastguard Worker public: ComponentRegistry(const char * name)151*993b0882SAndroid Build Coastguard Worker explicit ComponentRegistry(const char *name) : name_(name), head_(nullptr) {} 152*993b0882SAndroid Build Coastguard Worker 153*993b0882SAndroid Build Coastguard Worker // Adds a the (key, value) pair to this registry (if the key does not already 154*993b0882SAndroid Build Coastguard Worker // exists in this registry) and returns true. If the registry already has a 155*993b0882SAndroid Build Coastguard Worker // mapping for key, returns false and does not modify the registry. NOTE: the 156*993b0882SAndroid Build Coastguard Worker // error (false) case happens even if the existing value for key is equal with 157*993b0882SAndroid Build Coastguard Worker // the new one. 158*993b0882SAndroid Build Coastguard Worker // 159*993b0882SAndroid Build Coastguard Worker // This method does not take ownership of key, nor of value. Add(const char * key,T * value)160*993b0882SAndroid Build Coastguard Worker bool Add(const char *key, T *value) { 161*993b0882SAndroid Build Coastguard Worker const Cell *old_cell = FindCell(key); 162*993b0882SAndroid Build Coastguard Worker if (old_cell != nullptr) { 163*993b0882SAndroid Build Coastguard Worker SAFTM_LOG(ERROR) << "Duplicate component: " << key; 164*993b0882SAndroid Build Coastguard Worker return false; 165*993b0882SAndroid Build Coastguard Worker } 166*993b0882SAndroid Build Coastguard Worker Cell *new_cell = new Cell(key, value, head_); 167*993b0882SAndroid Build Coastguard Worker head_ = new_cell; 168*993b0882SAndroid Build Coastguard Worker return true; 169*993b0882SAndroid Build Coastguard Worker } 170*993b0882SAndroid Build Coastguard Worker 171*993b0882SAndroid Build Coastguard Worker // Returns the value attached to a key in this registry. Returns nullptr on 172*993b0882SAndroid Build Coastguard Worker // error (e.g., unknown key). Lookup(const char * key)173*993b0882SAndroid Build Coastguard Worker T *Lookup(const char *key) const { 174*993b0882SAndroid Build Coastguard Worker const Cell *cell = FindCell(key); 175*993b0882SAndroid Build Coastguard Worker if (cell == nullptr) { 176*993b0882SAndroid Build Coastguard Worker SAFTM_LOG(ERROR) << "Unknown " << name() << " component: " << key; 177*993b0882SAndroid Build Coastguard Worker } 178*993b0882SAndroid Build Coastguard Worker return (cell == nullptr) ? nullptr : cell->value(); 179*993b0882SAndroid Build Coastguard Worker } 180*993b0882SAndroid Build Coastguard Worker Lookup(const std::string & key)181*993b0882SAndroid Build Coastguard Worker T *Lookup(const std::string &key) const { return Lookup(key.c_str()); } 182*993b0882SAndroid Build Coastguard Worker 183*993b0882SAndroid Build Coastguard Worker // Returns name of this ComponentRegistry. name()184*993b0882SAndroid Build Coastguard Worker const char *name() const { return name_; } 185*993b0882SAndroid Build Coastguard Worker 186*993b0882SAndroid Build Coastguard Worker // Fills *names with names of all components registered in this 187*993b0882SAndroid Build Coastguard Worker // ComponentRegistry. Previous content of *names is cleared out. GetComponentNames(std::vector<std::string> * names)188*993b0882SAndroid Build Coastguard Worker void GetComponentNames(std::vector<std::string> *names) { 189*993b0882SAndroid Build Coastguard Worker names->clear(); 190*993b0882SAndroid Build Coastguard Worker for (const Cell *c = head_; c!= nullptr; c = c->next()) { 191*993b0882SAndroid Build Coastguard Worker names->emplace_back(c->key()); 192*993b0882SAndroid Build Coastguard Worker } 193*993b0882SAndroid Build Coastguard Worker } 194*993b0882SAndroid Build Coastguard Worker 195*993b0882SAndroid Build Coastguard Worker private: 196*993b0882SAndroid Build Coastguard Worker // Cell for the singly-linked list underlying this ComponentRegistry. Each 197*993b0882SAndroid Build Coastguard Worker // cell contains a key, the value for that key, as well as a pointer to the 198*993b0882SAndroid Build Coastguard Worker // next Cell from the list. 199*993b0882SAndroid Build Coastguard Worker class Cell { 200*993b0882SAndroid Build Coastguard Worker public: 201*993b0882SAndroid Build Coastguard Worker // Constructs a new Cell. Cell(const char * key,T * value,Cell * next)202*993b0882SAndroid Build Coastguard Worker Cell(const char *key, T *value, Cell *next) 203*993b0882SAndroid Build Coastguard Worker : key_(key), value_(value), next_(next) {} 204*993b0882SAndroid Build Coastguard Worker key()205*993b0882SAndroid Build Coastguard Worker const char *key() const { return key_; } value()206*993b0882SAndroid Build Coastguard Worker T *value() const { return value_; } next()207*993b0882SAndroid Build Coastguard Worker Cell *next() const { return next_; } 208*993b0882SAndroid Build Coastguard Worker 209*993b0882SAndroid Build Coastguard Worker private: 210*993b0882SAndroid Build Coastguard Worker const char *const key_; 211*993b0882SAndroid Build Coastguard Worker T *const value_; 212*993b0882SAndroid Build Coastguard Worker Cell *const next_; 213*993b0882SAndroid Build Coastguard Worker }; 214*993b0882SAndroid Build Coastguard Worker 215*993b0882SAndroid Build Coastguard Worker // Finds Cell for indicated key in the singly-linked list pointed to by head_. 216*993b0882SAndroid Build Coastguard Worker // Returns pointer to that first Cell with that key, or nullptr if no such 217*993b0882SAndroid Build Coastguard Worker // Cell (i.e., unknown key). 218*993b0882SAndroid Build Coastguard Worker // 219*993b0882SAndroid Build Coastguard Worker // Caller does NOT own the returned pointer. FindCell(const char * key)220*993b0882SAndroid Build Coastguard Worker const Cell *FindCell(const char *key) const { 221*993b0882SAndroid Build Coastguard Worker const Cell *c = head_; 222*993b0882SAndroid Build Coastguard Worker while (c != nullptr && strcmp(key, c->key()) != 0) { 223*993b0882SAndroid Build Coastguard Worker c = c->next(); 224*993b0882SAndroid Build Coastguard Worker } 225*993b0882SAndroid Build Coastguard Worker return c; 226*993b0882SAndroid Build Coastguard Worker } 227*993b0882SAndroid Build Coastguard Worker 228*993b0882SAndroid Build Coastguard Worker // Human-readable description for this ComponentRegistry. For debug purposes. 229*993b0882SAndroid Build Coastguard Worker const char *const name_; 230*993b0882SAndroid Build Coastguard Worker 231*993b0882SAndroid Build Coastguard Worker // Pointer to the first Cell from the underlying list of (key, value) pairs. 232*993b0882SAndroid Build Coastguard Worker Cell *head_; 233*993b0882SAndroid Build Coastguard Worker }; 234*993b0882SAndroid Build Coastguard Worker } // namespace internal 235*993b0882SAndroid Build Coastguard Worker 236*993b0882SAndroid Build Coastguard Worker // Base class for registerable classes. 237*993b0882SAndroid Build Coastguard Worker template <class T> 238*993b0882SAndroid Build Coastguard Worker class RegisterableClass { 239*993b0882SAndroid Build Coastguard Worker public: 240*993b0882SAndroid Build Coastguard Worker // Factory function type. 241*993b0882SAndroid Build Coastguard Worker typedef T *(Factory)(); 242*993b0882SAndroid Build Coastguard Worker 243*993b0882SAndroid Build Coastguard Worker // Registry type. 244*993b0882SAndroid Build Coastguard Worker typedef internal::ComponentRegistry<Factory> Registry; 245*993b0882SAndroid Build Coastguard Worker 246*993b0882SAndroid Build Coastguard Worker // Creates a new instance of T. Returns pointer to new instance or nullptr in 247*993b0882SAndroid Build Coastguard Worker // case of errors (e.g., unknown component). 248*993b0882SAndroid Build Coastguard Worker // 249*993b0882SAndroid Build Coastguard Worker // Passes ownership of the returned pointer to the caller. Create(const std::string & name)250*993b0882SAndroid Build Coastguard Worker static T *Create(const std::string &name) { // NOLINT 251*993b0882SAndroid Build Coastguard Worker auto *factory = registry()->Lookup(name); 252*993b0882SAndroid Build Coastguard Worker if (factory == nullptr) { 253*993b0882SAndroid Build Coastguard Worker SAFTM_LOG(ERROR) << "Unknown RegisterableClass " << name; 254*993b0882SAndroid Build Coastguard Worker return nullptr; 255*993b0882SAndroid Build Coastguard Worker } 256*993b0882SAndroid Build Coastguard Worker return factory(); 257*993b0882SAndroid Build Coastguard Worker } 258*993b0882SAndroid Build Coastguard Worker 259*993b0882SAndroid Build Coastguard Worker // Returns registry for class. registry()260*993b0882SAndroid Build Coastguard Worker static Registry *registry() { 261*993b0882SAndroid Build Coastguard Worker static Registry *registry_for_type_t = new Registry(kRegistryName); 262*993b0882SAndroid Build Coastguard Worker return registry_for_type_t; 263*993b0882SAndroid Build Coastguard Worker } 264*993b0882SAndroid Build Coastguard Worker 265*993b0882SAndroid Build Coastguard Worker protected: 266*993b0882SAndroid Build Coastguard Worker // Factory method for subclass ComponentClass. Used internally by the static 267*993b0882SAndroid Build Coastguard Worker // method RegisterClass() defined by SAFTM_DEFINE_REGISTRATION_METHOD. 268*993b0882SAndroid Build Coastguard Worker template <class ComponentClass> _internal_component_factory()269*993b0882SAndroid Build Coastguard Worker static T *_internal_component_factory() { 270*993b0882SAndroid Build Coastguard Worker return new ComponentClass(); 271*993b0882SAndroid Build Coastguard Worker } 272*993b0882SAndroid Build Coastguard Worker 273*993b0882SAndroid Build Coastguard Worker private: 274*993b0882SAndroid Build Coastguard Worker // Human-readable name for the registry for this class. 275*993b0882SAndroid Build Coastguard Worker static const char kRegistryName[]; 276*993b0882SAndroid Build Coastguard Worker }; 277*993b0882SAndroid Build Coastguard Worker 278*993b0882SAndroid Build Coastguard Worker // Defines the static method component_class::RegisterClass() that should be 279*993b0882SAndroid Build Coastguard Worker // called before trying to instantiate component_class by name. Should be used 280*993b0882SAndroid Build Coastguard Worker // inside the public section of the declaration of component_class. See 281*993b0882SAndroid Build Coastguard Worker // comments at the top-level of this file. 282*993b0882SAndroid Build Coastguard Worker #define SAFTM_DEFINE_REGISTRATION_METHOD(component_name, component_class) \ 283*993b0882SAndroid Build Coastguard Worker static void RegisterClass() { \ 284*993b0882SAndroid Build Coastguard Worker static bool once = registry()->Add( \ 285*993b0882SAndroid Build Coastguard Worker component_name, &_internal_component_factory<component_class>); \ 286*993b0882SAndroid Build Coastguard Worker if (!once) { \ 287*993b0882SAndroid Build Coastguard Worker SAFTM_LOG(ERROR) << "Problem registering " << component_name; \ 288*993b0882SAndroid Build Coastguard Worker } \ 289*993b0882SAndroid Build Coastguard Worker SAFTM_DCHECK(once); \ 290*993b0882SAndroid Build Coastguard Worker } 291*993b0882SAndroid Build Coastguard Worker 292*993b0882SAndroid Build Coastguard Worker // Defines the human-readable name of the registry associated with base_class. 293*993b0882SAndroid Build Coastguard Worker #define SAFTM_DECLARE_CLASS_REGISTRY_NAME(base_class) \ 294*993b0882SAndroid Build Coastguard Worker template <> \ 295*993b0882SAndroid Build Coastguard Worker const char ::libtextclassifier3::mobile::RegisterableClass<base_class>::kRegistryName[] 296*993b0882SAndroid Build Coastguard Worker 297*993b0882SAndroid Build Coastguard Worker // Defines the human-readable name of the registry associated with base_class. 298*993b0882SAndroid Build Coastguard Worker #define SAFTM_DEFINE_CLASS_REGISTRY_NAME(registry_name, base_class) \ 299*993b0882SAndroid Build Coastguard Worker template <> \ 300*993b0882SAndroid Build Coastguard Worker const char \ 301*993b0882SAndroid Build Coastguard Worker ::libtextclassifier3::mobile::RegisterableClass<base_class>::kRegistryName[] \ 302*993b0882SAndroid Build Coastguard Worker = registry_name 303*993b0882SAndroid Build Coastguard Worker 304*993b0882SAndroid Build Coastguard Worker // Register component_name, by calling component_class::RegisterClass() on 305*993b0882SAndroid Build Coastguard Worker // program start-up, before main. NOTE: this macro should be used in 306*993b0882SAndroid Build Coastguard Worker // conjunction with something like alwayslink = 1 from bazel. That is 307*993b0882SAndroid Build Coastguard Worker // discouraged, as it prevents the linker from doing dead code elimination, so 308*993b0882SAndroid Build Coastguard Worker // please use this macro only in special cases. Instead, if you care about code 309*993b0882SAndroid Build Coastguard Worker // size, then you should aim to explicitly call RegisterClass from your code 310*993b0882SAndroid Build Coastguard Worker // (e.g., from the main method, or from the constructor of the class that may 311*993b0882SAndroid Build Coastguard Worker // need those registered components). 312*993b0882SAndroid Build Coastguard Worker #define SAFTM_STATIC_REGISTRATION(component_class) \ 313*993b0882SAndroid Build Coastguard Worker static bool SAFTM_UNIQUE_ID(_kRegistrationDummy) = [] { \ 314*993b0882SAndroid Build Coastguard Worker component_class::RegisterClass(); \ 315*993b0882SAndroid Build Coastguard Worker return true; \ 316*993b0882SAndroid Build Coastguard Worker }() 317*993b0882SAndroid Build Coastguard Worker 318*993b0882SAndroid Build Coastguard Worker } // namespace mobile 319*993b0882SAndroid Build Coastguard Worker } // namespace nlp_saft 320*993b0882SAndroid Build Coastguard Worker 321*993b0882SAndroid Build Coastguard Worker #endif // NLP_SAFT_COMPONENTS_COMMON_MOBILE_REGISTRY_H_ 322