InFact
Interpreter and factory for easily creating C++ objects at run-time
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
factory.h
Go to the documentation of this file.
1 // Copyright 2014, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 // -----------------------------------------------------------------------------
30 //
31 //
35 
36 #ifndef INFACT_FACTORY_H_
37 #define INFACT_FACTORY_H_
38 
39 #include <iostream>
40 #include <sstream>
41 #include <memory>
42 #include <unordered_map>
43 #include <unordered_set>
44 #include <vector>
45 #include <stdexcept>
46 
47 #include "environment.h"
48 #include "error.h"
49 #include "stream-tokenizer.h"
50 
62 #define INFACT_ADD_PARAM(param) initializers.Add(#param, &_ ## param)
63 
75 #define INFACT_ADD_PARAM_(param) initializers.Add(#param, &param ## _)
76 
79 #define INFACT_ADD_REQUIRED_PARAM(param) \
80  initializers.Add(#param, &_ ## param, true)
81 
83 #define INFACT_ADD_REQUIRED_PARAM_(param) \
84  initializers.Add(#param, &param ## _, true)
85 
93 #define INFACT_ADD_TEMPORARY(type, var) \
94  initializers.Add(#var, static_cast<type *>(nullptr))
95 
124 #define INFACT_ADD_REQUIRED_TEMPORARY(type, var) \
125  initializers.Add(#var, static_cast<type *>(nullptr), true)
126 
127 namespace infact {
128 
129 using std::cerr;
130 using std::endl;
131 using std::ostream;
132 using std::ostringstream;
133 using std::shared_ptr;
134 using std::unordered_map;
135 using std::unordered_set;
136 using std::vector;
137 
153 template <typename T>
154 class TypeName {
155  public:
156  string ToString() {
157  return Factory<T>().BaseName();
158  }
159 };
160 
163 template <>
164 class TypeName<bool> {
165  public:
166  string ToString() {
167  return "bool";
168  }
169 };
170 
173 template <>
174 class TypeName<int> {
175  public:
176  string ToString() {
177  return "int";
178  }
179 };
180 
183 template <>
184 class TypeName<double> {
185  public:
186  string ToString() {
187  return "double";
188  }
189 };
190 
193 template <>
194 class TypeName<string> {
195  public:
196  string ToString() {
197  return "string";
198  }
199 };
200 
205 template <typename T>
206 class TypeName<shared_ptr<T> > {
207  public:
208  string ToString() {
209  return TypeName<T>().ToString();
210  }
211 };
212 
220 template <typename T>
221 class TypeName<vector<T> > {
222  public:
223  string ToString() {
224  return TypeName<T>().ToString() + "[]";
225  }
226 };
227 
233  public:
237  // appear in spec strings parsed by the
241  MemberInitializer(const string &name, bool required) :
242  name_(name), initialized_(0), required_(required) { }
243 
245  virtual ~MemberInitializer() { }
246 
253  virtual string Name() { return name_; }
254 
262  virtual void Init(StreamTokenizer &st, Environment *env) = 0;
263 
266  virtual int Initialized() const { return initialized_; }
267 
269  virtual bool Required() const { return required_; }
270 
271  protected:
273  string name_;
278  bool required_;
279 };
280 
289 template <typename T>
291  public:
296  // appear in spec strings parsed by the
306  TypedMemberInitializer(const string &name, T *member, bool required = false) :
307  MemberInitializer(name, required), member_(member) { }
309  virtual void Init(StreamTokenizer &st, Environment *env) {
310  env->ReadAndSet(Name(), st, TypeName<T>().ToString());
311  if (member_ != nullptr) {
312  VarMapBase *var_map = env->GetVarMap(Name());
313  VarMap<T> *typed_var_map = dynamic_cast<VarMap<T> *>(var_map);
314  if (typed_var_map != nullptr) {
315  bool success = typed_var_map->Get(Name(), member_);
316  if (success) {
317  ++initialized_;
318  }
319  }
320  } else {
321  // When the goal is simply to modify the environment, we say that this
322  // "non-member" has been successfully initialized when we've modified
323  // the environment.
324  ++initialized_;
325  }
326  }
327  protected:
329 };
330 
338  public:
341  typedef unordered_map<string, MemberInitializer *>::const_iterator
345  typedef unordered_map<string, MemberInitializer *>::iterator iterator;
346 
350  virtual ~Initializers() {
351  for (iterator init_it = initializers_.begin();
352  init_it != initializers_.end();
353  ++init_it) {
354  delete init_it->second;
355  }
356  }
357 
375  template<typename T>
376  void Add(const string &name, T *member, bool required = false) {
377  if (initializers_.find(name) != initializers_.end()) {
378  ostringstream err_ss;
379  err_ss << "Initializers::Add: error: two members have the same name: "
380  << name;
381  Error(err_ss.str());
382  }
383  initializers_[name] = new TypedMemberInitializer<T>(name, member, required);
384  }
385 
389  const_iterator begin() const { return initializers_.begin(); }
394  const_iterator end() const { return initializers_.end(); }
395 
400  iterator begin() { return initializers_.begin(); }
404  iterator end() { return initializers_.end(); }
405 
411  const_iterator find(const string &name) const {
412  return initializers_.find(name);
413  }
419  iterator find(const string &name) {
420  return initializers_.find(name);
421  }
422  private:
423  unordered_map<string, MemberInitializer *> initializers_;
424 };
425 
428 class FactoryBase {
429  public:
430  virtual ~FactoryBase() { }
436  virtual void Clear() = 0;
438  virtual const string BaseName() const = 0;
445  virtual void CollectRegistered(unordered_set<string> &registered) const = 0;
446 
447  virtual VarMapBase *CreateVarMap(Environment *env) const = 0;
448 
449  virtual VarMapBase *CreateVectorVarMap(Environment *env) const = 0;
450 };
451 
454  public:
455  typedef vector<FactoryBase *>::iterator iterator;
456 
460  static void Add(FactoryBase *factory) {
461  if (!initialized_) {
462  factories_ = new vector<FactoryBase *>();
463  initialized_ = 1;
464  }
465  factories_->push_back(factory);
466  }
468  static void Clear() {
469  if (initialized_) {
470  for (vector<FactoryBase *>::iterator it = factories_->begin();
471  it != factories_->end();
472  ++it) {
473  (*it)->Clear();
474  delete *it;
475  }
476  delete factories_;
477  }
478  }
479 
480  // Provide two methods to iterate over the FactoryBase instances
481  // held by this FactoryContainer.
482  static iterator begin() {
483  if (factories_ == nullptr) {
484  cerr << "FactoryContainer::begin: error: no FactoryBase instances!"
485  << endl;
486  }
487  return factories_->begin();
488  }
489  static iterator end() {
490  if (factories_ == nullptr) {
491  cerr << "FactoryContainer::begin: error: no FactoryBase instances!"
492  << endl;
493  }
494  return factories_->end();
495  }
496 
500  static void Print(ostream &os) {
501  if (!initialized_) {
502  return;
503  }
504  cerr << "Number of factories: " << factories_->size() << "." << endl;
505  for (vector<FactoryBase *>::iterator factory_it = factories_->begin();
506  factory_it != factories_->end();
507  ++factory_it) {
508  unordered_set<string> registered;
509  (*factory_it)->CollectRegistered(registered);
510  os << "Factory<" << (*factory_it)->BaseName() << "> can construct:\n";
511  for (unordered_set<string>::const_iterator it = registered.begin();
512  it != registered.end();
513  ++it) {
514  os << "\t" << *it << "\n";
515  }
516  }
517  os.flush();
518  }
519  private:
520  static int initialized_;
521  static vector<FactoryBase *> *factories_;
522 };
523 
529 // \tparam T the abstract type that this <tt>Constructor</tt> constructs
530 template <typename T>
531 class Constructor {
532  public:
533  virtual ~Constructor() { }
534  virtual T *NewInstance() const = 0;
535 };
536 
550  public:
552  virtual ~FactoryConstructible() { }
553 
570  virtual void RegisterInitializers(Initializers &initializers) { }
571 
583  virtual void PostInit(const Environment *env, const string &init_str) { }
584 };
585 
592 template <typename T>
593 class Factory : public FactoryBase {
594  public:
596  Factory() { }
597 
603  virtual void Clear() {
604  ClearStatic();
605  }
606 
766  shared_ptr<T> CreateOrDie(StreamTokenizer &st, Environment *env = nullptr) {
767  shared_ptr<Environment> env_ptr(env == nullptr ?
768  Environment::CreateEmpty() : env->Copy());
769  size_t start = st.PeekTokenStart();
770  StreamTokenizer::TokenType token_type = st.PeekTokenType();
771  if (token_type == StreamTokenizer::RESERVED_WORD &&
772  (st.Peek() == "nullptr" || st.Peek() == "NULL")) {
773  // Consume the nullptr.
774  st.Next();
775  return shared_ptr<T>();
776  }
777  if (token_type != StreamTokenizer::IDENTIFIER) {
778  ostringstream err_ss;
779  err_ss << "Factory<" << BaseName() << ">: "
780  << "error: expected type specifier token but found "
781  << StreamTokenizer::TypeName(token_type);
782  Error(err_ss.str());
783  }
784 
785  // Read the concrete type of object to be created.
786  string type = st.Next();
787 
788  // Read the open parenthesis token.
789  if (st.Peek() != "(") {
790  ostringstream err_ss;
791  err_ss << "Factory<" << BaseName() << ">: "
792  << "error: expected '(' at stream position "
793  << st.PeekTokenStart() << " but found \"" << st.Peek() << "\"";
794  Error(err_ss.str());
795  }
796  st.Next();
797 
798  // Attempt to create an instance of type.
799  typename unordered_map<string, const Constructor<T> *>::iterator cons_it =
800  cons_table_->find(type);
801  if (cons_it == cons_table_->end()) {
802  ostringstream err_ss;
803  err_ss << "Factory<" << BaseName() << ">: "
804  << "error: unknown type: \"" << type << "\"";
805  Error(err_ss.str());
806  }
807  shared_ptr<T> instance(cons_it->second->NewInstance());
808 
809  // Ask new instance to set up member initializers.
810  Initializers initializers;
811  instance->RegisterInitializers(initializers);
812 
813  // Parse initializer list.
814  while (st.Peek() != ")") {
815  token_type = st.PeekTokenType();
816  if (token_type != StreamTokenizer::IDENTIFIER) {
817  ostringstream err_ss;
818  err_ss << "Factory<" << BaseName() << ">: "
819  << "error: expected token of type IDENTIFIER at "
820  << "stream position " << st.PeekTokenStart() << " but found "
821  << StreamTokenizer::TypeName(token_type) << ": \""
822  << st.Peek() << "\"";
823  Error(err_ss.str());
824  }
825  size_t member_name_start = st.PeekTokenStart();
826  string member_name = st.Next();
827  typename Initializers::iterator init_it = initializers.find(member_name);
828  if (init_it == initializers.end()) {
829  ostringstream err_ss;
830  err_ss << "Factory<" << BaseName() << ">: "
831  << "error: unknown member name \"" << member_name
832  << "\" in initializer list for type " << type << " at stream "
833  << "position " << member_name_start;
834  Error(err_ss.str());
835  }
836  MemberInitializer *member_initializer = init_it->second;
837 
838  // Read open parenthesis or equals sign.
839  size_t member_init_start = st.PeekTokenStart();
840  bool saw_member_init_open_paren = st.Peek() == "(";
841  bool saw_member_init_equals_sign = st.Peek() == "=";
842  if (!saw_member_init_open_paren && !saw_member_init_equals_sign) {
843  ostringstream err_ss;
844  err_ss << "Factory<" << BaseName() << ">: "
845  << "error initializing member " << member_name << ": "
846  << "expected '(' or '=' at stream position "
847  << st.PeekTokenStart() << " but found \"" << st.Peek() << "\"";
848  Error(err_ss.str());
849  }
850  st.Next();
851 
852  // Initialize member based on following token(s).
853  member_initializer->Init(st, env_ptr.get());
854 
855  // If an open parenthesis was seen, read close parenthesis.
856  if (saw_member_init_open_paren) {
857  if (st.Peek() != ")") {
858  ostringstream err_ss;
859  err_ss << "Factory<" << BaseName() << ">: "
860  << "error initializing member " << member_name << ": "
861  << "saw '(' at stream position " << member_init_start
862  << "; expected ')' at stream position "
863  << st.PeekTokenStart() << " but found \"" << st.Peek() << "\"";
864  Error(err_ss.str());
865  }
866  st.Next();
867  }
868 
869  // Each member initializer must be followed by a comma or the final
870  // closing parenthesis.
871  if (st.Peek() != "," && st.Peek() != ")") {
872  ostringstream err_ss;
873  err_ss << "Factory<" << BaseName() << ">: "
874  << "error initializing member " << member_name << ": "
875  << "expected ',' or ')' at stream position "
876  << st.PeekTokenStart() << " but found \"" << st.Peek() << "\"";
877  Error(err_ss.str());
878  }
879  // Read comma, if present.
880  if (st.Peek() == ",") {
881  st.Next();
882  }
883  }
884 
885  // Read the close parenthesis token for this factory type specification.
886  if (st.Peek() != ")") {
887  ostringstream err_ss;
888  err_ss << "Factory<" << BaseName() << ">: "
889  << "error at initializer list end: "
890  << "expected ')' at stream position "
891  << st.PeekTokenStart() << " but found \"" << st.Peek() << "\"";
892  Error(err_ss.str());
893  }
894  st.Next();
895 
896  // Run through all member initializers: if any are required but haven't
897  // been invoked, it is an error.
898  for (typename Initializers::const_iterator init_it = initializers.begin();
899  init_it != initializers.end();
900  ++init_it) {
901  MemberInitializer *member_initializer = init_it->second;
902  if (member_initializer->Required() &&
903  member_initializer->Initialized() == 0) {
904  ostringstream err_ss;
905  err_ss << "Factory<" << BaseName() << ">: "
906  << "error: initialization for member with name \""
907  << init_it->first << "\" required but not found (current "
908  << "stream position: " << st.tellg() << ")";
909  Error(err_ss.str());
910  }
911  }
912 
913  size_t end = st.tellg();
914  // Invoke new instance's Init method.
915  string stream_str = st.str();
916  //cerr << "Full stream string is: \"" << stream_str << "\"" << endl;
917  string init_str = stream_str.substr(start, end - start);
918  //cerr << "PostInit string is: \"" << init_str << "\"" << endl;
919  instance->PostInit(env_ptr.get(), init_str);
920 
921  return instance;
922  }
923 
924  shared_ptr<T> CreateOrDie(const string &spec, const string err_msg,
925  Environment *env = nullptr) {
926  StreamTokenizer st(spec);
927  return CreateOrDie(st, env);
928  }
929 
930 
932  virtual const string BaseName() const { return base_name_; }
933 
941  static bool IsRegistered(const string &type) {
942  return initialized_ && cons_table_->find(type) != cons_table_->end();
943  }
944 
946  virtual void CollectRegistered(unordered_set<string> &registered) const {
947  if (initialized_) {
948  for (typename unordered_map<string, const Constructor<T> *>::iterator it =
949  cons_table_->begin();
950  it != cons_table_->end();
951  ++it) {
952  registered.insert(it->first);
953  }
954  }
955  }
956 
957  virtual VarMapBase *CreateVarMap(Environment *env) const {
958  bool is_primitive = false;
959  return new VarMap<shared_ptr<T> >(BaseName(), env, is_primitive);
960  }
961 
963  string name = BaseName() + "[]";
964  bool is_primitive = false;
965  return new VarMap<vector<shared_ptr<T> > >(name, BaseName(), env,
966  is_primitive);
967  }
968 
974  static const Constructor<T> *Register(const string &type,
975  const Constructor<T> *p) {
976  if (!initialized_) {
977  cons_table_ = new unordered_map<string, const Constructor<T> *>();
978  initialized_ = 1;
980  }
981  typename unordered_map<string, const Constructor<T> *>::iterator cons_it =
982  cons_table_->find(type);
983  if (cons_it == cons_table_->end()) {
984  (*cons_table_)[type] = p;
985  return p;
986  } else {
987  delete p;
988  return cons_it->second;
989  }
990  }
991 
997  static void ClearStatic() {
998  if (initialized_) {
999  for (typename unordered_map<string, const Constructor<T> *>::iterator it =
1000  cons_table_->begin();
1001  it != cons_table_->end();
1002  ++it) {
1003  delete it->second;
1004  }
1005  delete cons_table_;
1006  initialized_ = 0;
1007  }
1008  }
1009  private:
1010  // data members
1012  static int initialized_;
1014  static unordered_map<string, const Constructor<T> *> *cons_table_;
1015  static const char *base_name_;
1016 };
1017 
1018 // Initialize the templated static data member cons_table_ right here,
1019 // since the compiler will happily remove the duplicate definitions.
1020 template <typename T>
1021 unordered_map<string, const Constructor<T> *> *
1022 Factory<T>::cons_table_ = 0;
1023 
1030 #define DEFINE_CONS_CLASS(TYPE,NAME,BASE) \
1031  class NAME ## Constructor : public infact::Constructor<BASE> { \
1032  public: virtual BASE *NewInstance() const { return new TYPE(); } };
1033 
1044 #define REGISTER_NAMED(TYPE,NAME,BASE) \
1045  DEFINE_CONS_CLASS(TYPE,NAME,BASE) \
1046  static const infact::Constructor<BASE> *NAME ## _my_protoype = \
1047  infact::Factory<BASE>::Register(string(#NAME), new NAME ## Constructor());
1048 
1051 #define IMPLEMENT_FACTORY(BASE) \
1052  template<> int infact::Factory<BASE>::initialized_ = 0; \
1053  template<> const char *infact::Factory<BASE>::base_name_ = #BASE;
1054 
1055 } // namespace infact
1056 
1057 #endif
virtual VarMapBase * CreateVarMap(Environment *env) const =0
TypedMemberInitializer(const string &name, T *member, bool required=false)
A concrete implementation of the MemberInitializer base class, holding a pointer to a typed member th...
Definition: factory.h:306
MemberInitializer(const string &name, bool required)
Initializes this base class.
Definition: factory.h:241
virtual VarMapBase * CreateVectorVarMap(Environment *env) const =0
unordered_map< string, MemberInitializer * >::iterator iterator
Forward the iterator typedef of the internal data structure, to make code compact and readable...
Definition: factory.h:345
virtual void Init(StreamTokenizer &st, Environment *env)
Initializes this instance based on the following tokens obtained from the specified StreamTokenizer...
Definition: factory.h:309
static void Clear()
Clears this container of factories.
Definition: factory.h:468
virtual ~FactoryConstructible()
Destroys this instance.
Definition: factory.h:552
iterator find(const string &name)
Returns an iterator pointing to the MemberInitializer associated with the specified name...
Definition: factory.h:419
iterator end()
Returns an iterator pointing to the end of the map from member names to pointers to TypedMemberInitia...
Definition: factory.h:404
An interface with a single virtual method that constructs a concrete instance of the abstract type T...
Definition: factory.h:531
shared_ptr< T > CreateOrDie(const string &spec, const string err_msg, Environment *env=nullptr)
Definition: factory.h:924
virtual void Clear()=0
Clears the (possibly static) data of this factory.
const_iterator find(const string &name) const
Returns a const_iterator pointing to the MemberInitializer associated with the specified name...
Definition: factory.h:411
virtual bool Required() const
Whether this member is required to be initialized in a spec string.
Definition: factory.h:269
vector< FactoryBase * >::iterator iterator
Definition: factory.h:455
virtual void PostInit(const Environment *env, const string &init_str)
Does any additional initialization after an instance of this class has been constructed, crucially giving access to the Environment that was in use and modified during construction by the Factory::CreateOrDie method.
Definition: factory.h:583
virtual void RegisterInitializers(Initializers &initializers)
Registers data members of this class for initialization when an instance is constructed via the Facto...
Definition: factory.h:570
static void Print(ostream &os)
Prints the base typenames for all factories along with a list of all concrete subtypes those factorie...
Definition: factory.h:500
We use the templated class TypeName to be able to take an actual C++ type and get the type name strin...
Definition: factory.h:154
string Next()
Returns the next token in the token stream.
virtual int Initialized() const
Returns the number of times this member initializer’s Init method has been invoked.
Definition: factory.h:266
virtual T * NewInstance() const =0
unordered_map< string, MemberInitializer * >::const_iterator const_iterator
Forward the const_iterator typedef of the internal data structure, to make code compact and readable...
Definition: factory.h:342
Initializers()
Constructs a new instance.
Definition: factory.h:348
Provides an error handling function that optionally throws an exception.
string name_
The name of this member.
Definition: factory.h:273
int initialized_
The number of times this member initializer’s Init method has been invoked.
Definition: factory.h:276
iterator begin()
Returns an iterator pointing to the beginning of the map from member names to pointers to TypedMember...
Definition: factory.h:400
const_iterator end() const
Returns a const iterator pointing to the end of the map from member names to pointers to TypedMemberI...
Definition: factory.h:394
string ToString()
Definition: factory.h:156
const_iterator begin() const
Returns a const iterator pointing to the beginning of the map from member names to pointers to TypedM...
Definition: factory.h:389
Factory for dynamically created instance of the specified type.
Definition: factory.h:593
bool Get(const string &varname, T *value) const
Assigns the value of the specified variable to the object pointed to by the value parameter...
Definition: environment.h:280
Factory()
Constructs a new factory.
Definition: factory.h:596
A container to hold the mapping between named variables of a specific type and their values...
Definition: environment.h:384
TokenType PeekTokenType() const
Returns the type of the next token, or EOF_TYPE if there is no next token.
A container for all the member initializers for a particular Factory-constructible instance...
Definition: factory.h:337
virtual Environment * Copy() const =0
Returns a copy of this environment.
virtual ~MemberInitializer()
Destroys this instance.
Definition: factory.h:245
A concrete, typed implementation of the MemberInitializer base class.
Definition: factory.h:290
string str()
Returns the entire sequence of characters read so far by this stream tokenizer as a newly constructed...
A simple class for tokenizing a stream of tokens for the formally specified language used to construc...
static Environment * CreateEmpty()
A static factory method to create a new, empty Environment instance.
Definition: environment.cc:43
static iterator begin()
Definition: factory.h:482
Provides the StreamTokenizer class.
virtual const string BaseName() const
Returns the name of the base type of objects constructed by this factory.
Definition: factory.h:932
static bool IsRegistered(const string &type)
Returns whether the specified type has been registered with this factory (where registration happens ...
Definition: factory.h:941
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...
Definition: factory.h:974
virtual ~Initializers()
Destroys this instance.
Definition: factory.h:350
An interface for an environment in which variables of various types are mapped to their values...
Definition: environment.h:126
static const char * TypeName(TokenType token_type)
Returns a string type name for the specified TokenType constant.
size_t PeekTokenStart() const
Returns the next token’s start position, or the byte position of the underlying byte stream if there ...
virtual void CollectRegistered(unordered_set< string > &registered) const
Collects the names of types registered with this factory.
Definition: factory.h:946
static iterator end()
Definition: factory.h:489
Provides an interface for an Environment, which contains a map from variables of a specific type (pri...
virtual const string BaseName() const =0
Returns the name of the base type of objects constructed by this factory.
void Error(const std::string &message)
Reports an error encountered during parsing and/or construction of an object.
Definition: error.cc:47
string Peek() const
Returns the next token that would be returned by the Next method.
An interface simply to make it easier to implement Factory-constructible types by implementing both r...
Definition: factory.h:549
shared_ptr< T > CreateOrDie(StreamTokenizer &st, Environment *env=nullptr)
Dynamically creates an object, whose type and initialization are contained in a specification string...
Definition: factory.h:766
virtual VarMapBase * CreateVectorVarMap(Environment *env) const
Definition: factory.h:962
TokenType
The set of types of tokens read by this stream tokenizer.
bool required_
Whether this member is required to be initialized.
Definition: factory.h:278
static void Add(FactoryBase *factory)
Adds the specified factory to this container of factories.
Definition: factory.h:460
static void ClearStatic()
Clears all static data associated with this class.
Definition: factory.h:997
A class to hold all Factory instances that have been created.
Definition: factory.h:453
virtual string Name()
Returns the name of the member initialized by this instance, as it should appear in a spec string par...
Definition: factory.h:253
An interface for all Factory instances, specifying a few pure virtual methods.
Definition: factory.h:428
An interface for data member initializers of members of a Factory-constructible object.
Definition: factory.h:232
virtual VarMapBase * GetVarMap(const string &varname)=0
Retrieves the VarMap instance for the specified variable.
void Add(const string &name, T *member, bool required=false)
This method is the raison d'etre of this class: a method to make it easy to add all supported types o...
Definition: factory.h:376
virtual void CollectRegistered(unordered_set< string > &registered) const =0
Collects the names of types registered with this factory.
size_t tellg() const
Returns the number of bytes read from the underlying byte stream just after scanning the most recent ...
virtual ~FactoryBase()
Definition: factory.h:430
virtual void Init(StreamTokenizer &st, Environment *env)=0
Initializes this instance based on the following tokens obtained from the specified StreamTokenizer...
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...
A base class for a mapping from variables of a specific type to their values.
Definition: environment.h:66
virtual void Clear()
Clears this factory of all (possibly static) data.
Definition: factory.h:603
virtual ~Constructor()
Definition: factory.h:533
virtual VarMapBase * CreateVarMap(Environment *env) const
Definition: factory.h:957