Code:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <map>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
struct vafb
{
struct association
{
static const unsigned long vfv = 0;
static const unsigned long sfv = 1;
static const unsigned long sfs = 2;
static const unsigned long sfss = 3;
static const unsigned long sfm = 4;
};
vafb(){}
virtual ~vafb(){}
virtual void vfv(){throw std::runtime_error("Invalid Function!");}
virtual std::string sfv(){throw std::runtime_error("Invalid Function!");}
virtual std::string sfs(const std::string &){throw std::runtime_error("Invalid Function!");}
virtual std::string sfss(const std::string &, const std::string &){throw std::runtime_error("Invalid Function!");}
virtual std::string sfm(const std::vector<std::string> &){throw std::runtime_error("Invalid Function!");}
virtual unsigned long vafb_type() = 0;
};
template <typename return_t, typename parameter_1_t, typename parameter_2_t> struct auto_vafb: public vafb
{
typedef return_t (*function_type)(parameter_1_t, parameter_2_t);
auto_vafb(function_type function): function_m(function)
{
}
virtual std::string sfss(const std::string & parameter_1, const std::string & parameter_2)
{
std::istringstream parameter_1_stream(parameter_1);
std::istringstream parameter_2_stream(parameter_2);
parameter_1_t modified_parameter_1;
parameter_2_t modified_parameter_2;
std::ostringstream return_value_stream;
parameter_1_stream >> modified_parameter_1;
parameter_2_stream >> modified_parameter_2;
return_value_stream << function_m(modified_parameter_1, modified_parameter_2);
return(return_value_stream.str());
}
virtual unsigned long vafb_type()
{
return(vafb::association::sfss);
}
function_type function_m;
};
template <typename return_t, typename parameter_1_t> struct auto_vafb<return_t, std::vector<parameter_1_t>, void>: public vafb
{
typedef return_t (*function_type)(const std::vector<parameter_1_t> &);
auto_vafb(function_type function): function_m(function)
{
}
virtual std::string sfm(const std::vector<std::string> & parameter_1)
{
const std::vector<std::string>::size_type size(parameter_1.size());
std::vector<parameter_1_t> values(size);
for(std::vector<std::string>::size_type cursor(0); cursor < size; ++cursor)
{
std::istringstream parameter_stream(parameter_1[cursor]);
parameter_1_t modified_parameter;
parameter_stream >> modified_parameter;
values[cursor] = modified_parameter;
}
std::ostringstream return_value_stream;
return_value_stream << function_m(values);
return(return_value_stream.str());
}
virtual unsigned long vafb_type()
{
return(vafb::association::sfm);
}
function_type function_m;
};
template <typename return_t, typename parameter_1_t> struct auto_vafb<return_t, parameter_1_t, void>: public vafb
{
typedef return_t (*function_type)(parameter_1_t);
auto_vafb(function_type function): function_m(function)
{
}
virtual std::string sfs(const std::string & parameter_1)
{
std::istringstream parameter_1_stream(parameter_1);
parameter_1_t modified_parameter_1;
std::ostringstream return_value_stream;
parameter_1_stream >> modified_parameter_1;
return_value_stream << function_m(modified_parameter_1);
return(return_value_stream.str());
}
virtual unsigned long vafb_type()
{
return(vafb::association::sfs);
}
function_type function_m;
};
template <typename return_t> struct auto_vafb<return_t, void, void>: public vafb
{
typedef return_t (*function_type)();
auto_vafb(function_type function): function_m(function)
{
}
virtual std::string sfv()
{
std::ostringstream return_value_stream;
return_value_stream << function_m();
return(return_value_stream.str());
}
virtual unsigned long vafb_type()
{
return(vafb::association::sfv);
}
function_type function_m;
};
template <> struct auto_vafb<void, void, void>: public vafb
{
typedef void (*function_type)();
auto_vafb(function_type function): function_m(function)
{
}
virtual void vfv()
{
function_m();
}
virtual unsigned long vafb_type()
{
return(vafb::association::vfv);
}
function_type function_m;
};
template <typename return_t, typename parameter_1_t, typename parameter_2_t> vafb * craft_vafb(return_t (*function)(parameter_1_t, parameter_2_t))
{
return(new auto_vafb<return_t, parameter_1_t, parameter_2_t>(function));
};
template <typename return_t, typename parameter_1_t> vafb * craft_vafb(return_t (*function)(const std::vector<parameter_1_t> &))
{
return(new auto_vafb<return_t, std::vector<parameter_1_t>, void>(function));
};
template <typename return_t, typename parameter_1_t> vafb * craft_vafb(return_t (*function)(parameter_1_t))
{
return(new auto_vafb<return_t, parameter_1_t, void>(function));
};
template <typename return_t> vafb * craft_vafb(return_t (*function)())
{
return(new auto_vafb<return_t, void, void>(function));
};
vafb * craft_vafb(void (*function)())
{
return(new auto_vafb<void, void, void>(function));
};
struct vafb_manager
{
vafb_manager()
{
}
~vafb_manager()
{
std::map<std::string, vafb *>::const_iterator cursor(vafb_m.begin());
std::map<std::string, vafb *>::const_iterator end(vafb_m.end());
while(cursor != end)
{
delete cursor->second;
++cursor;
}
}
template <typename function_type_t> bool add(const std::string & name, std::string & output, function_type_t function)
{
const std::map<std::string, vafb *>::iterator fun(vafb_m.find(name));
if(fun != vafb_m.end())
{
output = "function already exists";
return(false);
}
vafb_m[name] = craft_vafb(function);
return(true);
}
bool process(const std::string & line, std::string & output)
{
const std::string::const_iterator cursor_line(line.begin());
const std::string::const_iterator end_line(line.end());
const std::string::const_iterator cursor_function_name(cursor_line);
const std::string::const_iterator end_function_name(std::find(cursor_function_name, end_line, ' '));
const std::string function_name(cursor_function_name, end_function_name);
const std::map<std::string, vafb *>::iterator function(vafb_m.find(function_name));
if(function == vafb_m.end())
{
output = "function not in library";
return(false);
}
const unsigned long vafb_type(function->second->vafb_type());
if(vafb::association::vfv == vafb_type)
{
output = "";
function->second->vfv();
}
if(vafb::association::sfv == vafb_type)
{
output = function->second->sfv();
}
if(vafb::association::sfs == vafb_type)
{
if(end_line == end_function_name)
{
output = "function takes one argument";
return(false);
}
const std::string::const_iterator cursor_parameter(end_function_name);
const std::string::const_iterator end_parameter(end_line);
const std::string parameter_1(cursor_parameter + 1, end_parameter);
output = function->second->sfs(parameter_1);
}
if(vafb::association::sfss == vafb_type)
{
if(end_line == end_function_name)
{
output = "function takes two arguments";
return(false);
}
const std::string::const_iterator cursor_parameter_1(end_function_name);
const std::string::const_iterator end_parameter_1(std::find(cursor_parameter_1 + 1, end_line, ' '));
const std::string::const_iterator cursor_parameter_2(end_parameter_1);
const std::string::const_iterator end_parameter_2(end_line);
const std::string parameter_1(cursor_parameter_1 + 1, end_parameter_1);
const std::string parameter_2(cursor_parameter_2 + 1, end_parameter_2);
output = function->second->sfss(parameter_1, parameter_2);
}
if(vafb::association::sfm == vafb_type)
{
std::vector<std::string> parameters;
std::string::const_iterator cursor_parameter(end_function_name);
std::string::const_iterator end_parameter(std::find(cursor_parameter + 1, end_line, ' '));
while(end_line != cursor_parameter)
{
parameters.push_back(std::string(cursor_parameter + 1, end_parameter));
cursor_parameter = end_parameter;
end_parameter = std::find(cursor_parameter + 1, end_line, ' ');
}
output = function->second->sfm(parameters);
}
return(true);
}
std::map<std::string, vafb *> vafb_m;
};
void clear_vafb()
{
std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
}
unsigned long random_vafb()
{
return(std::rand());
}
unsigned long gid_vafb(unsigned long value)
{
return(value ^ 0xFF00FF00);
}
double devide_vafb(double numerator, double denominato)
{
return(numerator / denominato);
}
struct my_short_test
{
friend std::ostream & operator << (std::ostream & out, const my_short_test & value)
{
out << value.value_m;
return(out);
}
friend std::istream & operator >> (std::istream & in, my_short_test & value)
{
short temp(0);
in >> temp;
value = temp;
return(in);
}
my_short_test(): value_m(0)
{
}
explicit my_short_test(short value): value_m(value)
{
}
my_short_test(const my_short_test & value): value_m(value.value_m)
{
}
my_short_test & operator = (short value)
{
value_m = value;
return(*this);
}
my_short_test & operator = (const my_short_test & value)
{
value_m = value.value_m;
return(*this);
}
my_short_test & operator += (short value)
{
value_m += value;
return(*this);
}
my_short_test & operator += (const my_short_test & value)
{
value_m += value.value_m;
return(*this);
}
short value_m;
};
my_short_test sum_vafb(const std::vector<my_short_test> & values)
{
const std::vector<std::string>::size_type size(values.size());
my_short_test temp(0);
if(0 == size)
{
return(temp);
}
for(std::vector<std::string>::size_type cursor(0); cursor < size; ++cursor)
{
temp += values[cursor];
}
return(temp);
}
int main(int argc, char ** argv)
{
std::string line;
std::string output;
vafb_manager manager;
manager.add("clear", output, clear_vafb);
manager.add("random", output, random_vafb);
manager.add("gid", output, gid_vafb);
manager.add("devide", output, devide_vafb);
manager.add("sum", output, sum_vafb);
while(std::getline(std::cin, line))
{
if(!manager.process(line, output))
{
std::cout << "error::manager:" << output << '\n';
}
else
{
if("" != output)
{
std::cout << " -> " << output << '\n';
}
}
}
return(0);
}