39 #ifndef INFACT_ENVIRONMENT_H_
40 #define INFACT_ENVIRONMENT_H_
42 #define VAR_MAP_DEBUG 0
56 using std::ostringstream;
57 using std::shared_ptr;
58 using std::unordered_map;
59 using std::unordered_set;
86 virtual const string &
Name()
const {
return name_; }
90 virtual bool Defined(
const string &varname)
const = 0;
101 virtual void Print(ostream &os)
const = 0;
132 virtual bool Defined(
const string &varname)
const = 0;
137 const string type =
"") = 0;
140 virtual const string &
GetType(
const string &varname)
const = 0;
167 virtual void Print(ostream &os)
const = 0;
185 template <
typename T>
201 return "\"" + value +
"\"";
211 return value ?
"true" :
"false";
221 string ToString(
const shared_ptr<T> &value)
const {
223 oss <<
"<" <<
typeid(shared_ptr<T>).name() <<
":" << value.get() <<
">";
232 template <
typename T>
238 typename vector<T>::const_iterator it = value.begin();
240 if (it != value.end()) {
244 for (; it != value.end(); ++it) {
245 oss <<
", " << value_string.
ToString(*it);
265 template <
typename T,
typename Derived>
280 bool Get(
const string &varname, T *value)
const {
281 typename unordered_map<string, T>::const_iterator it = vars_.find(varname);
282 if (it == vars_.end()) {
291 virtual bool Defined(
const string &varname)
const {
292 return vars_.find(varname) != vars_.end();
296 void Set(
const string &varname, T value) {
297 vars_[varname] = value;
301 virtual void Print(ostream &os)
const {
303 for (
typename unordered_map<string, T>::const_iterator it = vars_.begin();
304 it != vars_.end(); ++it) {
305 const T& value = it->second;
318 const Derived *derived =
dynamic_cast<const Derived *
>(
this);
319 if (derived ==
nullptr) {
320 Error(
"bad dynamic cast");
322 Derived *var_map_copy =
new Derived(*derived);
333 Derived *typed_var_map =
dynamic_cast<Derived *
>(var_map);
334 if (typed_var_map !=
nullptr) {
336 string rhs_variable = st.
Next();
339 bool success = typed_var_map->Get(rhs_variable, &value);
342 cerr <<
"VarMap<" <<
Name() <<
">::ReadAndSet: "
343 <<
"setting variable "
344 << varname <<
" to same value as rhs variable " << rhs_variable
352 cerr <<
"VarMap<" <<
Name() <<
">::ReadAndSet: no variable "
353 << rhs_variable <<
" found " << endl;
360 cerr <<
"VarMap<" <<
Name() <<
">::ReadAndSet: variable "
361 << st.
Peek() <<
" is of type " << var_map->
Name()
362 <<
" but expecting " <<
typeid(T).name() << endl;
376 unordered_map<string, T> vars_;
383 template <
typename T>
396 Base(name, env, is_primitive) { }
403 cerr <<
"VarMap<" <<
Base::Name() <<
">::ReadAndSet: "
404 <<
"about to set varname " << varname <<
" of type "
406 <<
"; prev_token=" << st.
PeekPrev() <<
"; next_tok=" << st.
Peek()
414 this->
Set(varname, value);
418 cerr <<
"VarMap<" <<
Base::Name() <<
">::ReadAndSet: set varname "
419 << varname <<
" to value " << value_string.
ToString(value)<< endl;
439 template <
typename T>
454 bool is_primitive =
true)
455 :
Base(name, env, is_primitive), element_typename_(element_typename) { }
468 if (st.
Peek() ==
"{") {
472 ostringstream err_ss;
473 err_ss <<
"VarMap<vector<T>>: "
474 <<
"error: expected '{' at stream position "
482 while (st.
Peek() !=
"}") {
485 ostringstream element_name_oss;
486 element_name_oss <<
"____" << varname <<
"_" << (element_idx++)
488 string element_name = element_name_oss.str();
490 env_ptr->ReadAndSet(element_name, st, element_typename_);
492 env_ptr->GetVarMapForType(element_typename_);
494 dynamic_cast<VarMap<T> *
>(element_var_map);
496 if (typed_element_var_map->
Get(element_name, &element)) {
497 value.push_back(element);
499 ostringstream err_ss;
500 err_ss <<
"VarMap<" <<
Base::Name() <<
">::ReadAndSet: trouble "
501 <<
"initializing element " << (element_idx - 1)
502 <<
" of variable " << varname;
507 if (st.
Peek() !=
"," && st.
Peek() !=
"}") {
508 ostringstream err_ss;
509 err_ss <<
"Initializer<vector<T>>: "
510 <<
"error: expected ',' or '}' at stream position "
515 if (st.
Peek() ==
",") {
524 this->
Set(varname, value);
528 string element_typename_;
virtual void Print(ostream &os) const
Prints out a human-readable string to the specified output stream containing the variables, their type and, if primitive, their values.
virtual VarMapBase * GetVarMapForType(const string &type)=0
Retrieves the VarMap instance for the specified type, or nullptr if there is no such VarMap...
Provides a generic dynamic object factory.
string name_
The type name of this VarMap.
virtual void Init(StreamTokenizer &st, Environment *env=nullptr)
virtual bool Defined(const string &varname) const =0
Returns whether the specified variable has a definition in this environment.
virtual void PrintFactories(ostream &os) const =0
Prints out a human-readable string with the names of all abstract base types and their concrete imple...
void Set(const string &varname, T value)
Sets the specified variable to the specified value.
VarMapImpl< T, VarMap< T > > Base
VarMapBase(const string &name, Environment *env, bool is_primitive)
Constructs a base class for a concrete implementation providing a mapping from variables of a particu...
virtual void ReadAndSet(const string &varname, StreamTokenizer &st)
Reads the next value (primitive or spec for constructing a Factory-constructible object) from the spe...
string Next()
Returns the next token in the token stream.
virtual void ReadAndSet(const string &varname, StreamTokenizer &st)=0
Reads the next value (primitive or spec for constructing a Factory-constructible object) from the spe...
virtual void Print(ostream &os) const =0
Prints a human-readable string of all the variables in this environment, their types and...
size_t PeekPrevTokenStart() const
A template class that helps print out values with ostream& operator support and vectors of those valu...
Provides an error handling function that optionally throws an exception.
string ToString(const T &value) const
VarMap(const string &name, const string &element_typename, Environment *env, bool is_primitive=true)
Constructs a mapping from variables of a particular type to their values.
void SetMembers(const string &name, Environment *env, bool is_primitive)
To allow proper implementation of Copy in VarMapBase implementation, since we don't get copying of ba...
string ToString(const bool &value) const
bool Get(const string &varname, T *value) const
Assigns the value of the specified variable to the object pointed to by the value parameter...
A container to hold the mapping between named variables of a specific type and their values...
VarMapImpl(const string &name, Environment *env, bool is_primitive=true)
string ToString(const string &value) const
string ToString(const vector< T > &value) const
A partial implementation of the VarMapBase interface that is common to both VarMap<T> and the VarMap<...
Environment * env_
The Environment that holds this VarMap instance.
virtual Environment * Copy() const =0
Returns a copy of this environment.
virtual VarMapBase * Copy(Environment *env) const =0
Returns a newly constructed copy of this VarMap.
virtual bool IsPrimitive() const
Returns whether this instance contains primitive or primtive vector variables.
virtual const string & Name() const
Returns the type name of the variables of this instance.
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.
Provides the StreamTokenizer class.
virtual bool Defined(const string &varname) const
Returns whether the specified variable has a definition in this environment.
A class to initialize a Factory-constructible object.
An interface for an environment in which variables of various types are mapped to their values...
bool is_primitive_
Whether this VarMap instance holds variables of primitive type or vector of primitives.
VarMapImpl< vector< T >, VarMap< vector< T > > > Base
size_t PeekTokenStart() const
Returns the next token’s start position, or the byte position of the underlying byte stream if there ...
virtual void Print(ostream &os) const =0
Prints out a human-readable string to the specified output stream containing the variables, their type and, if primitive, their values.
Environment * env()
A protected method to access the environment contained by this VarMapBase instance, for the two concrete VarMap implementations, below.
virtual VarMapBase * Copy(Environment *env) const
Returns a newly constructed copy of this VarMap.
bool ReadAndSetFromExistingVariable(const string &varname, StreamTokenizer &st)
Checks if the next token is an identifier and is a variable in the environment, and, if so, sets varname to the variable’s value.
void Error(const std::string &message)
Reports an error encountered during parsing and/or construction of an object.
string Peek() const
Returns the next token that would be returned by the Next method.
VarMap(const string &name, Environment *env, bool is_primitive=true)
Constructs a mapping from variables of a particular type to their values.
virtual void ReadAndSet(const string &varname, StreamTokenizer &st)
Reads the next value (primitive or spec for constructing a Factory-constructible object) from the spe...
string ToString(const shared_ptr< T > &value) const
virtual VarMapBase * GetVarMap(const string &varname)=0
Retrieves the VarMap instance for the specified variable.
virtual const string & GetType(const string &varname) const =0
Retrieves the type name of the specified variable.
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.
virtual bool Defined(const string &varname) const =0
Returns whether the specified variable has been defined in this environment.