36 #ifndef RERANKER_FACTORY_H_
37 #define RERANKER_FACTORY_H_
42 #include <unordered_map>
43 #include <unordered_set>
55 using std::ostringstream;
56 using std::shared_ptr;
57 using std::unordered_map;
58 using std::unordered_set;
128 template <
typename T>
143 template <
typename T>
176 template <
typename T>
186 if (typed_var_map != NULL) {
207 typedef unordered_map<string, MemberInitializer *>::const_iterator
211 typedef unordered_map<string, MemberInitializer *>::iterator
iterator;
217 for (
iterator init_it = initializers_.begin();
218 init_it != initializers_.end();
220 delete init_it->second;
225 void Add(
const string &name, T *member,
bool required =
false) {
255 return initializers_.find(name);
263 return initializers_.find(name);
266 unordered_map<string, MemberInitializer *> initializers_;
279 virtual void Clear() = 0;
281 virtual const string BaseName()
const = 0;
305 factories_ =
new vector<FactoryBase *>();
308 factories_->push_back(factory);
313 for (vector<FactoryBase *>::iterator it = factories_->begin();
314 it != factories_->end();
326 if (factories_ == NULL) {
327 cerr <<
"FactoryContainer::begin: error: no FactoryBase instances!"
330 return factories_->begin();
333 if (factories_ == NULL) {
334 cerr <<
"FactoryContainer::begin: error: no FactoryBase instances!"
337 return factories_->end();
347 cerr <<
"Number of factories: " << factories_->size() <<
"." << endl;
348 for (vector<FactoryBase *>::iterator factory_it = factories_->begin();
349 factory_it != factories_->end();
351 unordered_set<string> registered;
352 (*factory_it)->CollectRegistered(registered);
353 os <<
"Factory<" << (*factory_it)->BaseName() <<
"> can construct:\n";
354 for (unordered_set<string>::const_iterator it = registered.begin();
355 it != registered.end();
357 os <<
"\t" << *it <<
"\n";
363 static int initialized_;
364 static vector<FactoryBase *> *factories_;
373 template <
typename T>
395 template <
typename T>
563 shared_ptr<Environment> env_ptr(env == NULL ?
568 (st.
Peek() ==
"nullptr" || st.
Peek() ==
"NULL")) {
569 return shared_ptr<T>();
572 ostringstream err_ss;
573 err_ss <<
"Factory<" <<
BaseName() <<
">: "
574 <<
"error: expected type specifier token but found "
576 throw std::runtime_error(err_ss.str());
580 string type = st.
Next();
583 if (st.
Peek() !=
"(") {
584 ostringstream err_ss;
585 err_ss <<
"Factory<" <<
BaseName() <<
">: "
586 <<
"error: expected '(' at stream position "
588 throw std::runtime_error(err_ss.str());
593 typename unordered_map<string, const Constructor<T> *>::iterator cons_it =
594 cons_table_->find(type);
595 if (cons_it == cons_table_->end()) {
596 ostringstream err_ss;
597 err_ss <<
"Factory<" <<
BaseName() <<
">: "
598 <<
"error: unknown type: \"" << type <<
"\"";
599 throw std::runtime_error(err_ss.str());
601 shared_ptr<T> instance(cons_it->second->NewInstance());
605 instance->RegisterInitializers(initializers);
608 while (st.
Peek() !=
")") {
611 ostringstream err_ss;
612 err_ss <<
"Factory<" <<
BaseName() <<
">: "
613 <<
"error: expected token of type IDENTIFIER at "
616 << st.
Peek() <<
"\"";
617 throw std::runtime_error(err_ss.str());
620 string member_name = st.
Next();
622 if (init_it == initializers.end()) {
623 ostringstream err_ss;
624 err_ss <<
"Factory<" <<
BaseName() <<
">: "
625 <<
"error: unknown member name \"" << member_name
626 <<
"\" in initializer list for type " << type <<
" at stream "
627 <<
"position " << member_name_start;
628 throw std::runtime_error(err_ss.str());
633 if (st.
Peek() !=
"(") {
634 ostringstream err_ss;
635 err_ss <<
"Factory<" <<
BaseName() <<
">: "
636 <<
"error: expected '(' at stream position "
638 throw std::runtime_error(err_ss.str());
643 member_initializer->
Init(st, env_ptr.get());
646 if (st.
Peek() !=
")") {
647 ostringstream err_ss;
648 err_ss <<
"Factory<" <<
BaseName() <<
">: "
649 <<
"error: expected ')' at stream position "
651 throw std::runtime_error(err_ss.str());
657 if (st.
Peek() !=
"," && st.
Peek() !=
")") {
658 ostringstream err_ss;
659 err_ss <<
"Factory<" <<
BaseName() <<
">: "
660 <<
"error: expected ',' or ')' at stream position "
662 throw std::runtime_error(err_ss.str());
665 if (st.
Peek() ==
",") {
671 if (st.
Peek() !=
")") {
672 ostringstream err_ss;
673 err_ss <<
"Factory<" <<
BaseName() <<
">: "
674 <<
"error: expected ')' at stream position "
676 throw std::runtime_error(err_ss.str());
683 init_it != initializers.end();
686 if (member_initializer->
Required() &&
688 ostringstream err_ss;
689 err_ss <<
"Factory<" <<
BaseName() <<
">: "
690 <<
"error: initialization for member with name \""
691 << init_it->first <<
"\" required but not found (current "
692 <<
"stream position: " << st.
tellg() <<
")";
693 throw std::runtime_error(err_ss.str());
697 size_t end = st.
tellg();
699 string stream_str = st.
str();
701 string init_str = stream_str.substr(start, end - start);
703 instance->Init(env_ptr.get(), init_str);
708 shared_ptr<T>
CreateOrDie(
const string &spec,
const string err_msg,
716 virtual const string BaseName()
const {
return base_name_; }
726 return initialized_ && cons_table_->find(type) != cons_table_->end();
732 for (
typename unordered_map<
string,
const Constructor<T> *>::iterator it =
733 cons_table_->begin();
734 it != cons_table_->end();
736 registered.insert(it->first);
742 bool is_primitive =
false;
748 bool is_primitive =
false;
760 cons_table_ =
new unordered_map<string, const Constructor<T> *>();
764 (*cons_table_)[type] = p;
775 for (
typename unordered_map<
string,
const Constructor<T> *>::iterator it =
776 cons_table_->begin();
777 it != cons_table_->end();
788 static int initialized_;
790 static unordered_map<string, const Constructor<T> *> *cons_table_;
791 static const char *base_name_;
800 #define DEFINE_CONS_CLASS(TYPE,NAME,BASE) \
801 class NAME ## Constructor : public Constructor<BASE> { \
802 public: virtual BASE *NewInstance() const { return new TYPE(); } };
814 #define REGISTER_NAMED(TYPE,NAME,BASE) \
815 DEFINE_CONS_CLASS(TYPE,NAME,BASE) \
816 const Constructor<BASE> *NAME ## _my_protoype = \
817 Factory<BASE>::Register(string(#NAME), new NAME ## Constructor());
821 #define IMPLEMENT_FACTORY(BASE) \
822 template<> int Factory<BASE>::initialized_ = 0; \
823 template<> unordered_map<string, const Constructor<BASE> *> * \
824 Factory<BASE>::cons_table_ = 0; \
825 template<> const char *Factory<BASE>::base_name_ = #BASE;
virtual VarMapBase * CreateVectorVarMap(Environment *env) const =0
virtual Environment * Copy() const =0
Returns a copy of this environment.
A container to hold the mapping between named variables of a specific type and their values...
unordered_map< string, MemberInitializer * >::const_iterator const_iterator
Forward the const_iterator typedef of the internal data structure, to make code compact and readable...
static void Add(FactoryBase *factory)
Adds the specified factory to this container of factories.
string name_
The name of this member.
iterator end()
Returns an iterator pointing to the end of the map from member names to pointers to TypedMemberInitia...
virtual VarMapBase * CreateVarMap(Environment *env) const
A simple class for tokenizing a stream of tokens for the formally specified language used to construc...
Initializers()
Constructs a new instance.
int initialized_
The number of times this member initializer’s Init method has been invoked.
bool Get(const string &varname, T *value) const
Assigns the value of the specified variable to the object pointed to by the value parameter...
string str()
Returns the entire sequence of characters read so far by this stream tokenizer as a newly constructed...
An interface for initializers of members of a Factory-constructible object.
virtual void Clear()
Clears this factory of all (possibly static) data.
virtual T * NewInstance() const =0
virtual bool Required() const
bool required_
Whether this member is required to be initialized.
A base class for a mapping from variables of a specific type to their values.
virtual void CollectRegistered(unordered_set< string > ®istered) const
Collects the names of types registered with this factory.
virtual const string BaseName() const =0
Returns the name of the base type of objects constructed by this factory.
size_t PeekTokenStart() const
Returns the next token’s start position, or the byte position of the underlying byte stream if there ...
virtual void Clear()=0
Clears the (possibly static) data of this factory.
virtual void Init(StreamTokenizer &st, Environment *env)
Factory()
Constructs a new factory.
Provides an interface for an Environment, which contains a map from variables of a specific type (pri...
A class to hold all Factory instances that have been created.
static const char * TypeName(TokenType token_type)
Returns a string type name for the specified TokenType constant.
void Add(const string &name, T *member, bool required=false)
static bool IsRegistered(const string &type)
Returns whether the specified type has been registered with this factory (where registration happens ...
Factory for dynamically created instance of the specified type.
static const Constructor< T > * Register(const string &type, const Constructor< T > *p)
The method used by the REGISTER_NAMED macro to ensure that subclasses add themselves to the factory...
Provides the StreamTokenizer class.
static void Print(ostream &os)
Prints the base typenames for all factories along with a list of all concrete subtypes those factorie...
string Next()
Returns the next token in the token stream.
const_iterator end() const
Returns a const iterator pointing to the end of the map from member names to pointers to TypedMemberI...
virtual void Init(StreamTokenizer &st, Environment *env)=0
virtual ~FactoryConstructible()
size_t tellg() const
Returns the number of bytes read from the underlying byte stream just after scanning the most recent ...
virtual VarMapBase * CreateVarMap(Environment *env) const =0
virtual void ReadAndSet(const string &varname, StreamTokenizer &st, const string type="")=0
Sets the specified variable to the value obtained from the following tokens available from the specif...
We use the templated class TypeName to be able to take an actual C++ type and get the type name strin...
unordered_map< string, MemberInitializer * >::iterator iterator
Forward the iterator typedef of the internal data structure, to make code compact and readable...
virtual const string BaseName() const
Returns the name of the base type of objects constructed by this factory.
TypedMemberInitializer(const string &name, T *member, bool required=false)
shared_ptr< T > CreateOrDie(StreamTokenizer &st, Environment *env=NULL)
Dynamically creates an object, whose type and initialization are contained in a specification string...
An interface with a single virtual method that constructs a concrete instance of the abstract type T...
An interface for an environment in which variables of various types are mapped to their values...
virtual void RegisterInitializers(Initializers &initializers)
shared_ptr< T > CreateOrDie(const string &spec, const string err_msg, Environment *env=NULL)
virtual void Init(const Environment *env, const string &arg)
vector< FactoryBase * >::iterator iterator
MemberInitializer(const string &name, bool required)
const_iterator find(const string &name) const
Returns a const_iterator pointing to the MemberInitializer associated with the specified name...
virtual void CollectRegistered(unordered_set< string > ®istered) const =0
Collects the names of types registered with this factory.
virtual ~Initializers()
Destroys this instance.
An interface for all Factory instances, specifying a few pure virtual methods.
TokenType
The set of types of tokens read by this stream tokenizer.
string Peek() const
Returns the next token that would be returned by the Next method.
virtual ~TypedMemberInitializer()
An interface to make it easier to implement Factory-constructible types by implementing both required...
virtual VarMapBase * CreateVectorVarMap(Environment *env) const
static void ClearStatic()
Clears all static data associated with this class.
static Environment * CreateEmpty()
A static factory method to create a new, empty Environment instance.
virtual ~MemberInitializer()
virtual int Initialized() const
Returns the number of times this member initializer’s Init method has been invoked.
static void Clear()
Clears this container of factories.
virtual VarMapBase * GetVarMap(const string &varname)=0
Retrieves the VarMap instance for the specified variable.
iterator begin()
Returns an iterator pointing to the beginning of the map from member names to pointers to TypedMember...
iterator find(const string &name)
Returns an iterator pointing to the MemberInitializer associated with the specified name...
const_iterator begin() const
Returns a const iterator pointing to the beginning of the map from member names to pointers to TypedM...
A container for all the member initializers for a particular Factory-constructible instance...
TokenType PeekTokenType() const
Returns the type of the next token, or EOF_TYPE if there is no next token.