I have implemented the following code which will be used to read in what are essentially key-value pairs from a file.
an example input file may look like
max_search_depth 10
enable_recursion false
job_name Khalessi
my main issue with this code is that I wish to return variables of different types based on the text in the file. max search depth is best suited as an int, while job name is a string, and enable recursion is a bool
currently I solve this issue by sub classing the declaration struct, but i wonder if there are other options for achieving this which put less onus on the calling function to know what variable type it will be receiving with any given key.
I am hoping to purpose this code for a few different areas in my application, so I would like to keep it as generic as possible.
my secondary concern is with the section involving if(key == a_particular_key) { //do whatever } There are potentially 100's of possibilities of what a key could be, so I am sure there must be a more elegant way of finding the key and directing program flow accordingly, but as of yet I have not learned a more elegant solution
tertiary concern of minor importance: do i really need void v() in the parent class to use polymorphism?
Thanks a ton for looking at my code!
#include <algorithm>
#include <iostream>
#include <string>
struct declaration {
std::string key;
// need at least one virtual method to enable polymorphism?
// compiler errors will result if v() is not present.
virtual void v(){}
};
// Specializations of the declaration struct for their respective types
struct declaration_int : public declaration { int value; };
struct declaration_string : public declaration { std::string value; };
struct declaration_bool : public declaration { bool value; };
declaration* readLine(){
std::string key, value;
// Irrelevent code. Simulates reading in a line from a file. It's only
// here to keep the code consise and relevent.
static unsigned int count = 0;
count++;
if( count % 3 == 0){
key = "max_search_depth";
value = "10";
}
else if( count % 3 == 1){
key = "enable_recursion";
value = "false";
}
else {
key = "job_name";
value = "Khaleesi";
}
// key and value have now been set
// based on what was parsed in from the file
// check if value is numeric
char *numeric_check;
int numeric_value = static_cast<int>(strtod( value.c_str(), &numeric_check ));
// value is a boolean
if( value == "true" || value == "false") {
//initalize object and return it
declaration_bool *d_bool = new declaration_bool;
d_bool->key = key;
d_bool->value = (value == "true");
return dynamic_cast<declaration*>(d_bool);
}
// value is a number
else if( *numeric_check == '\0' ) {
declaration_int *d_int = new declaration_int;
d_int->key = key;
d_int->value = numeric_value;
return dynamic_cast<declaration*>(d_int);
}
// value is a string
else {
declaration_string *d_string = new declaration_string;
d_string->key = key;
d_string->value = value;
return dynamic_cast<declaration*>(d_string);
}
// side note: I am aware of this memory leak. For sake of simplicity
// I have not worried about deleting the declaration structs. In acctual
// code this would be properly handled.
}
// irrelevent and used only for illustrative purposes
void setRecursion( bool enabled ){}
void setDepth( int levels ){}
void statusReport( std::string job_name ){}
int main (){
/*shhhh*/int lines_remaining = 3;/* Again, only to keep it simple. Not real code*/
// while file still has lines to read in
while( lines_remaining-- ){
declaration *line = readLine();
if(line->key == "enable_recursion" ){
// I know I can expect a bool value next due to the "enable_recursion" key,
// so I can check to ensure it is indeed a bool and be safe, but the general
// idea now is to just:
declaration_bool *db = dynamic_cast<declaration_bool*>(line);
// and just do whatever I wanted to do with that value;
setRecursion( db->value );
}
else if(line->key == "max_search_depth" ){
declaration_int *di = dynamic_cast<declaration_int*>(line);
setDepth( di->value );
}
else if(line->key == "job_name" ){
declaration_string *ds = dynamic_cast<declaration_string*>(line);
statusReport( ds->value );
}
else {
// unknown/bad key found. deal with it.
}
}
}