Paavo Helde
11/17/2008 7:49:00 AM
ma740988 <ma740988@gmail.com> kirjutas:
>> Ypu would be better off by directly calling
>> the member functions by reading the file, or by storing the read
strings
>> to call them later.
>
> The latter I understand, the former - "You would be better off by
> directly calling the member functions by reading the file" - I'm not
> following. I understanding reading and storing a string then invoking
> the member functions. I'm not understanding how I could read a file
> then invoke the member functions directly.
> Worse case show me an example in source.
Here you are, it got a bit longer than I thought, and the parser is not
very smart, and error handling is lacking, and this most probably is not
what you want, but anyway, I figure as I already wrote this for fun, I
can as well post it. (Tested by cygwin g++ 3.4.4.)
Cheers, Paavo
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
typedef std::string::size_type indx_t;
typedef unsigned int word_type ;
class foo {
public:
void set_mx_digits_1 ( word_type wt ) {
std::cout << "set_mx_digits_1(" << wt << ") called\n";
}
void set_mx_digits_2 ( double dt ) {
std::cout << "set_mx_digits_2(" << dt << ") called\n";
}
// lots more.
};
std::string FindFuncName(const std::string& buffer) {
indx_t k = buffer.find("foo::*");
if (k==buffer.npos) return "";
k += strlen("foo::*");
k = buffer.find_first_not_of(" \t", k);
if (k==buffer.npos) return "";
indx_t l = buffer.find_first_of(" \t)", k);
if (l==buffer.npos) return "";
return buffer.substr(k, l-k);
}
std::string FindArgType(const std::string& buffer) {
indx_t k = buffer.rfind("(");
if (k==buffer.npos) return "";
++k;
k = buffer.find_first_not_of(" \t", k);
if (k==buffer.npos) return "";
indx_t l = buffer.find_first_of(" \t)", k);
if (l==buffer.npos) return "";
return buffer.substr(k, l-k);
}
std::string FindArgument(const std::string& buffer) {
indx_t k = buffer.rfind(",");
if (k==buffer.npos) return "";
++k;
k = buffer.find_first_not_of(" \t", k);
if (k==buffer.npos) return "";
return buffer.substr(k);
}
// Something to silence compiler warnings and errors on invalid
// function and argument combinations.
template<typename T> T ConvertForDigits1(T x) {return x;}
int ConvertForDigits1(double x) {/* should be never called*/ return 0;}
template<typename T> T ConvertForDigits2(T x) {return x;}
template<typename T>
void CallMemberFunc(const std::string& funcname, const std::string&
argstring, foo& myfoo) {
std::istringstream argstream(argstring);
T arg1;
if (argstream >> arg1) {
if (funcname=="set_mx_digits_1") {
myfoo.set_mx_digits_1(ConvertForDigits1(arg1));
} else if (funcname=="set_mx_digits_2") {
myfoo.set_mx_digits_2(ConvertForDigits2(arg1));
} // lots more
}
}
void ReadParseAndExecute(const std::string& filename, foo& myfoo) {
std::ifstream is(filename.c_str());
std::string buffer;
while(std::getline(is, buffer)) {
// Parse the input line
std::string funcname = FindFuncName(buffer);
std::string argstring = FindArgument(buffer);
std::string argtype = FindArgType(buffer);
// dispatch to template according to argument type
if (argtype=="word_type") {
CallMemberFunc<word_type>(funcname, argstring, myfoo);
} else if (argtype=="double") {
CallMemberFunc<double>(funcname, argstring, myfoo);
} // some more
}
}
int main() {
{
// Prepare an example file
std::ofstream os("input_file.dat");
os <<
"typedef void ( foo::*set_mx_digits_1 )( word_type wt ), 15\n";
os <<
"typedef void ( foo::*set_mx_digits_2 )( double dt ), 3.6\n";
}
foo myfoo;
ReadParseAndExecute("input_file.dat", myfoo);
}