Calling function during runtime based on function name match - c++

Apologies in advance the possibly vague Title, best I could come up with.
I have the following C++ and text file:
cpp file:
class Test
{
int var1;
int var2;
public:
bool set_var1();
bool set_var1();
bool set(string var_name);
void process_file();
}
text file:
var1 value1
var2 value2
Objective - In process_file(), read/parse the text file, and for each varX in file call the corresponding set_varX().
One option, in function set(), compare var_name to "var1" / "var2" / etc, and
call corresponding set_varX(). The issue I have with this approach, as more
lines are added to the text file, the code becomes...ugly, with the long "if-else"
code block in set().
Another option, create a static map
"var1" set_var1()
"var2" set_var2()
set() will iterate over the map, and upon a string compare match call the corresponding func_ptr. This option requires maintaining a map structure.
Though I prefer the second option, less code changes as the test file increases, is there another option. Just thinking out loud, in set(), can I take the string var_name, and prepend set_, and call set_var_name(), basically somehow avoid the string compare, which is done in both the cases above. My gut feeling, in C++, that is not possible to do during runtime
Thank you,
Ahmed.

It sounds like you're asking about reflection, which is not a feature of C++, so this won't be possible. As you pointed out there are solutions to the problem, but all of them will involve a mapping of string names to functions, and you'll have to construct/maintain that mapping yourself. The language won't do this for you.

You can improve option 2 by making var1, var2.. self registering types. New keywords cause no code changes, only new types. Therefor the map has to be some kind of global object, singleton etc.
A very simple example:
struct Setter
{
virtual ~Setter() = default;
virtual void Process(std::string content) const = 0;
};
class SetterMap
{
public:
bool RegisterSetter(std::string keyword, std::unique_ptr<Setter> setter) {
setters[keyword] = move(setter);
return true;
}
const Setter& GetSetter(const std::string& keyword) const {
return *(setters.at(keyword));
}
private:
std::map<std::string, std::unique_ptr<Setter>> setters;
};
inline SetterMap& GetSetterMap() {
static SetterMap map;
return map;
}
Define and register some setters:
struct Var1 : Setter {
void Process(std::string content) const override {
}
};
namespace {
bool var1registered = GetSetterMap().RegisterSetter(
"var1", std::make_unique<Var1>());
}
struct Var2 : Setter {
void Process(std::string content) const override {
}
};
namespace {
bool var2registered = GetSetterMap().RegisterSetter(
"var2", std::make_unique<Var2>());
}
Use the setter map:
int main()
{
std::string line = "var1: blablab";
GetSetterMap().GetSetter("var1").Process(line);
}

Depending on your needs, you might consider embedding Lua and changing the syntax of the text file to something like:
test.var1 = 1234
test.var2 = 42
Here, test would be a global Lua table that you instantiate from the C++ side and assign a metatable to using lua_setmetatable(). The metatable would have a __newindex method as described here. If you're familiar with Python, this is sort of like providing a __setattr__ metamethod—i.e., it intercepts assignment of non-existent fields and executes some user-specified magic.
The 'trick' in your case is to create a metatable in Lua that re-routes access to the var1, var2, etc. fields of test to a lua_CFunction wrapper that sets the corresponding field on the underlying Test object. After that, you can simply 'run' the file using luaL_dofile().
A quick-n-dirty example (tested against Lua 5.1.5) that illustrates the gist of the idea is appended below. (It needs to be compiled with -std=c++11 due to the use of a raw string literal.)
This approach is certainly overkill if your needs are very specific/targeted. However, if you want/need scripting in your app, anyway, embedding Lua is a great solution.
NOTE: It is not strictly required to use a separate table (e.g., test in the example). Lua stores global variables in a table named _G, so you could instead set a metatable for _G. However, doing so is a bit of a hack; it makes the example harder to follow, and would limit some of the other ways you can use Lua in your host application.
#include <cassert>
#include <iostream>
#include <string>
#include <cstdlib>
#include <lua.hpp>
static const char* regkey = "Test";
class Test
{
public:
Test();
virtual ~Test();
void set_var1(int value);
void set_var2(int value);
void process_file(std::string const& filepath);
private:
int var1, var2;
lua_State* L_;
};
static int set_var(lua_State* L)
{
// Get the table, key and value
std::string key = lua_tostring(L, 1);
int value = lua_tointeger(L, 2);
// Get the Test instance pointer from the Lua registry
lua_pushlightuserdata(L, (void*)regkey);
lua_gettable(L, LUA_REGISTRYINDEX);
Test* test = (Test*) lua_touserdata(L, -1);
// Execute set_XXX() as appropriate
if (test == NULL) {
std::cerr << "Pointer in registry is missing or NULL, aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
if (key == "var1") {
test->set_var1(value);
}
else if (key == "var2") {
test->set_var2(value);
}
else {
std::string errmsg = "No such variable '" + key + "'";
lua_pushstring(L, errmsg.c_str());
lua_error(L);
}
return 0;
}
Test::Test()
{
L_ = luaL_newstate();
assert(L_);
luaL_openlibs(L_);
// Point the Lua global '_set_var' at our C set_var() function
lua_pushcfunction(L_, &set_var);
lua_setglobal(L_, "_set_var");
// Store our `this' pointer in the Lua registry
lua_pushlightuserdata(L_, (void*)regkey);
lua_pushlightuserdata(L_, this);
lua_settable(L_, LUA_REGISTRYINDEX);
// Set up the metatable to re-route "foo = X" to "_set_var('foo', X)"
std::string script = R"SCRIPT(
test = {}
local mt = {}
mt.__newindex = function(tbl, key, value)
_set_var(key, value)
end
setmetatable(test, mt)
)SCRIPT";
int retval = luaL_dostring(L_, script.c_str());
if (retval != 0) {
std::cerr << "luaL_dostring() failed (\""
<< lua_tostring(L_, -1)
<< "\"), aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
}
Test::~Test()
{
lua_close(L_);
}
void Test::set_var1(int value)
{
std::cout << "Setting var1 to " << value << std::endl;
var1 = value;
}
void Test::set_var2(int value)
{
std::cout << "Setting var2 to " << value << std::endl;
var2 = value;
}
void Test::process_file(std::string const& filepath)
{
int retval = luaL_dofile(L_, filepath.c_str());
if (retval != 0) {
std::cerr << "luaL_dofile() failed (\""
<< lua_tostring(L_, -1)
<< "\"), aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
}
int main()
{
Test().process_file("config.ini");
return 0;
}

Related

Class design - use optionals? variants? be opaque?

I want to have a class for PCI bus locations. For the sake of discussion, these come in three forms:
[domain]:[bus]:[device].[function]
[domain]:[bus]:[device]
[bus]:[device].[function]
and let's say each field is a non-negative integral value (let's even say unsigned just to make things simple).
I'm scratching my head regarding how to define this class. I could use std::optionals for the domain and function fields; but then, they're not both optional. I could use a variant with 3 types, but then I need to define separate types, which overlap a lot. I could just hold 4 unsigneds and a 3-value enum for which format is in effect - but that's quite a bit of hassle, and I'd need getter and to make the class opaque. Same thing if I try to use a union somehow.
It seems like every choice I make, it's going to be an iffy class. How can I minimize my displeasure with it?
Note: Any language standard version is ok for the answer, although I doubt C++20 would give you anything.
Building upon my comment, I was wondering if something like this could work:
enum class pci_format { domain_function, domain, function };
template <pci_format E> struct tag { };
class pci_location {
public:
pci_location (tag<pci_format::domain_function>, unsigned domain, unsigned bus,
unsigned device, unsigned function)
: format_(pci_format::domain_function)
, domain_(domain)
, bus_(bus)
, device_(device)
, function_(function)
{ }
// Repeat for other values of pci_format.
pci_format format () const { return format_; }
bool has_domain () const {
return (format_ == pci_format::domain_function)
or (format_ == pci_format::domain);
}
unsigned domain () const {
if (not has_domain()) { throw std::runtime_error("Domain not available."); }
return domain_;
}
// Repeat for other fields.
private:
pci_format format_;
unsigned domain_;
unsigned bus_;
unsigned device_;
unsigned function_
};
You would basically create a specific constructor for each PCI "format". Of course you could also store each unsigned as an std::optional<unsigned>, but that would force users to "dereference" each optional even if they knew for sure that it must contain a value.
One way or another, they'll have to check what "format" the location is in, so it seems to me that using an enum for this is more user friendly. Then users only have to check once and know exactly which fields are available.
I guess you could layer a visitor on top of all this so they can simply provide code to execute for each "format":
struct pci_location_visitor {
virtual void visit (tag<pci_format::domain_function>, pci_location const & obj) = 0;
// Repeat for other enum values.
};
// Add to pci_location:
void accept (pci_location_visitor & visitor) {
switch (format_) {
case pci_format::domain_function:
return visitor.visit(tag<pci_format::domain_function>{}, *this);
default: throw std::runtime_error("Format not supported for visitation.");
}
}
Then on top of that you could create a visitor that can be constructed from a bunch of callables, i.e. lambdas, so that this all can be used like below:
pci_location const & loc = getIt();
auto printSomething = make_pci_location_visitor(
[](tag<pci_format::domain_function>, pci_location const & e) { std::cout << e.domain(); }
, [](tag<pci_format::domain>, pci_location const & e) { std::cout << e.bus(); }
, [](tag<pci_format::function>, pci_location const & e) { std::cout << e.function(); }
);
loc.accept(printSomething);
For an example of how such a visitor could be constructed, see the overloaded class in the std::visit example on cppreference.com.
As requested in comments... given that I have no particular requirements how the users would prefer to use this class, given C++14, I would be doing something generic along the lines of:
#include <array>
#include <climits>
#include <iostream>
#include <stdexcept>
class pci_location_t {
public:
struct dbdf {
unsigned int domain;
unsigned int bus;
unsigned int device;
unsigned int function;
};
struct dbd {
unsigned int domain;
unsigned int bus;
unsigned int device;
};
struct bdf {
unsigned int bus;
unsigned int device;
unsigned int function;
};
pci_location_t(dbdf v) : domain(v.domain), bus(v.bus), device(v.device), function(v.function) {}
pci_location_t(dbd v) : domain(v.domain), bus(v.bus), device(v.device), function(INVALID) {}
pci_location_t(bdf v) : domain(INVALID), bus(v.bus), device(v.device), function(v.function) {}
template <typename dbdf_f, typename dbd_f, typename bdf_f>
auto visit(dbdf_f dbdf_fun, dbd_f dbd_fun, bdf_f bdf_fun) const {
if (domain == INVALID) {
if (function == INVALID) {
throw std::domain_error("Wrong PCI location format");
}
return bdf_fun(bdf{bus, device, function});
} else if (function == INVALID) {
return dbd_fun(dbd{domain, bus, device});
} else {
return dbdf_fun(dbdf{domain, bus, device, function});
}
}
private:
friend pci_location_t invalid_location();
pci_location_t() : domain(INVALID), bus(INVALID), device(INVALID), function(INVALID) {}
const static unsigned int INVALID = UINT_MAX;
unsigned int domain;
unsigned int bus;
unsigned int device;
unsigned int function;
};
pci_location_t invalid_location() { return pci_location_t{}; }
int main() {
std::array<pci_location_t, 4> locations = {
pci_location_t(pci_location_t::dbdf{1, 2, 3, 4}),
pci_location_t(pci_location_t::dbd{1, 2, 3}),
pci_location_t(pci_location_t::bdf{2, 3, 4}),
invalid_location()
};
try {
for (auto& l : locations) {
l.visit(
[] (auto dbdf) {
std::cout << dbdf.domain << ":" << dbdf.bus << ":" << dbdf.device << "." << dbdf.function << std::endl;
},
[] (auto dbd) {
std::cout << dbd.domain << ":" << dbd.bus << ":" << dbd.device << std::endl;
},
[] (auto bdf) {
std::cout << bdf.bus << ":" << bdf.device << "." << bdf.function << std::endl;
}
);
}
std::cout << "Done!" << std::endl;
} catch(const std::exception& e) {
std::cout << e.what() << std::endl;
}
return 0;
}
(you can check it on Coliru).
Feel free to use optionals or a separate format field if you don't like special values.
I'd make both the domain and the function optional (I don't really care how, as long as it's effective), and just enforce the only-one-missing condition as a class invariant. That is, only the functions that can change any of the fields need to perform the check and signal possible errors back to the user. No need to bloat your code with variants, or with dynamically interpreted unsigned int arrays. KISS.

Accessor Method to view private variable based on argument in a class in c++?

My problem is that I have many variables in my class and I want them to be accessed via an accessor method. Of course I could have several accessor functions to output my private variables but how can I make it so I can access any of them via an argument. My class:
class Character {
public:
void setAttr(string Sname,int Shealth,int SattackLevel,int SdefenseLevel) {
name = Sname;
health = Shealth;
attackLevel = SattackLevel;
defenseLevel = SdefenseLevel;
}
int outputInt(string whatToOutput) {
return whatToOutput //I want this to either be health, attackLevel or defenseLevel
}
private:
string name;
int health;
int attackLevel;
int defenseLevel;
};
Basically what I want to know is how do I return a private variable in regards to the outputInt function. Most OOP tutorials have one function to return each variable which seems like a very unhealthy thing to do in a large program.
C++ doesn't support what you try to accomplish: reflection or detailed runtime information about objects. There is something called "Run-Time Type Information" in C++, but it can't provide information about your variable name: the reason is because, in the compiled and linked binary this information (names of your variables) will not be necessarily present anymore.
However, you can accomplish something close to that, using i.e. std::unordered_map instead of plain integer variables. So it's possible to access values by their names, as strings.
Please consider the following code:
#include <string>
#include <iostream>
#include <unordered_map>
using namespace std;
class Character {
public:
void setAttr(const string& Sname, int Shealth, int SattackLevel, int SdefenseLevel) {
name = Sname;
values.insert(std::make_pair("health", Shealth));
values.insert(std::make_pair("attackLevel", SattackLevel));
values.insert(std::make_pair("defenseLevel", SdefenseLevel));
}
int outputInt(const string& whatToOutput) {
return values.at(whatToOutput);
}
private:
string name;
std::unordered_map<std::string, int> values;
};
int main(int argc, char* argv[]) {
Character yourCharacter;
yourCharacter.setAttr("yourName", 10, 100, 1000);
std::cout << "Health: " << yourCharacter.outputInt("health") <<std::endl;
std::cout << "Attack level: " << yourCharacter.outputInt("attackLevel") << std::endl;
std::cout << "Defense level: " << yourCharacter.outputInt("defenseLevel") << std::endl;
return 0;
}
It will output as expected:
Health: 10
Attack level: 100
Defense level: 1000
Another option without dependency on unordered_map would be, to use predefined static strings for your variable names and an array or vector for your values. So we could replace the class Character above with something like:
static std::string variableNames[3] = {
"health",
"attackLevel",
"defenseLevel"
};
class Character {
public:
void setAttr(const string& Sname, int Shealth, int SattackLevel, int SdefenseLevel) {
name = Sname;
variableValues[0] = Shealth;
variableValues[1] = SattackLevel;
variableValues[2] = SdefenseLevel;
}
int outputInt(const string& whatToOutput) {
int retVal = 0;
for (size_t i = 0; i < sizeof(variableNames)/sizeof(std::string); ++i) {
if (!whatToOutput.compare(variableNames[i])) {
retVal = variableValues[i];
}
}
return retVal;
}
private:
string name;
int variableValues[3];
};
And getting still same output. However, here you have to manage a list with all your variable names inside the string array manually - I don't like this solution and would prefer one of the others above personally.
Most common ways in C++ to handle such a design is to have seperate getHealth(), getAttackLevel(), getDefenseLevel() functions instead. However, this will miss one use-case, which is: if you want to let the user input a string, like i.e. "health" and display the corresponding variable then, you would need to write code by yourself to call the corresponding getXXX() function. If this is not a issue in your case, consider the following code which is much cleaner:
#include <string>
#include <iostream>
using namespace std;
class Character {
public:
void setAttr(const string& Sname, int Shealth, int SattackLevel, int SdefenseLevel) {
name = Sname;
health = Shealth;
attackLevel = SattackLevel;
defenseLevel = SdefenseLevel;
}
int getHealth() const { return health; }
int getAttackLevel() const { return attackLevel; }
int getDefenseLevel() const { return defenseLevel; }
private:
string name;
int health, attackLevel, defenseLevel;
};
int main(int argc, char* argv[]) {
Character yourCharacter;
yourCharacter.setAttr("yourName", 10, 100, 1000);
std::cout << "Health: " << yourCharacter.getHealth() <<std::endl;
std::cout << "Attack level: " << yourCharacter.getAttackLevel() << std::endl;
std::cout << "Defense level: " << yourCharacter.getDefenseLevel() << std::endl;
return 0;
}
One other unrelated advice: Instead of using string as parameter types for your functions, use const string& (const reference to string; see my example code above). This allows easier calling of your functions (they can be called directly with an string literal without the need to create additional variables in the calling code) and they will not make a additional unnecessary copy. The only copy then will take place at: name = Sname; (in your code two copies took place).
I don't know if it can be a good idea for you, but you can use a public typedef struct that you pass by reference and set your value.
class Character {
public:
//...
typedef struct allvalues{
string vname;
int vhealth;
int vattackLevel;
int vdefenseLevel;
}allvalues;
void getValues(allvalues& val){
val.vname = name;
val.vhealth = health;
val.vattackLevel = attackLevel;
val.vdefenseLevel = detenseLevel;
}
//...
};
//...
//somewhere in the code
Character myCarac;
//...
//Here how to use it
Character::allvalues values;
myCarac.getValues(values);

Best stl container for sql parameters

I have to build a dynamic sql query. To proper execute it I have to do it in 3 steps:
Prepare statement
Bind Parameters with functions: bindString(string value, int index); bindInt(int value, int index);
Execute it
Because of the fact, that this query is build dynamically I have to store somewhere proper values for given index.
For example:
SELECT * FROM Table WHERE A = ? AND E = '?';
SELECT * FROM Table WHERE A = ? AND B = ? AND E = '?';
During building query I have to store somewhere that:
In the first case:
index 0 is for int A,
index 1 is for string E
In the second case:
index 0 is for int A
index 1 is for int B
index 2 is for string E
My best idea is to create two maps: < int, string >, < int, int > and during creating query set in first place indexes and in second place values and then creating two loops, one for strings, the second one for integers and binding parameters in them and it works fine.
However I wonder if is it possible to do everything in one loop using succeeding indexes and in type safety way.
Thank You.
I would consider creating a class to wrap SQL parameters.
In fact I would create an abstract class like that :
SQLParameterBase
{
std::string toString() = 0;
void print()
{
std::cout << toString();
}
}
And then a template class :
template<class ParamType>
SQLParameter : public SQLParameterBase
{
private:
ParamType value;
public:
std::string toString()
{
// You can use std::ostringstream to convert to string,
// or create another class (derivated from SQLParameterBase) with very specific values
}
}
And you could use it like that :
SQLParameterBase * params[10];
maps[0] = new SQLParameter<int>();
Hope that will help
Actually it is modified AMDG solution. Thanks to him!
class SQLParam {
public:
virtual ~SqlParam(){}
void bind(DatabaseHandler &db, int index) = 0;
};
class SQLParamInt {
private:
int value;
public:
SqlParamInt(int p_value) : value(p_value) {
}
~SqlParamInt() {}
int bind(DatabaseHandler &db, int index) {
return db.bindInt(value, index);
}
};
class SQLParamString {
private:
string value;
public:
SqlParamString(std::string p_value) : value(p_value) {
}
~SqlParamString() {}
int bind(DatabaseHandler &db, int index) {
return db.bindString(value, index);
}
};
typedef std::vector<std::unique_ptr<SqlParam>> SqlParamsContainer;
typedef std::unique_ptr<SqlParamInt> SqlParamIntPtr;
typedef std::unique_ptr<SqlParamString> SqlParamStringPtr;
In my function, building query:
int buildQuery(RequestHandler &request) {
SqlParamsContainer params;
stringstream query << "SELECT * FROM Table WHERE A = ?";
params.push_back(SqlParamIntPtr(new SqlParamInt(request.A())));
if(request.has_B()) {
params.push_back(SqlParamIntPtr(new SqlParamInt(request.B())));
query << " AND B = ?";
}
if(request.has_C()) {
params.push_back(SqlParamStringPtr(new SqlParamString(request.C())));
query << " AND C = ?";
}
query << ";";
db.prepare(query.str());
for(int i = 0; i < v_container.size(); i++)
v_container.at(i)->bind(db,i);
}
There is Boost::Any while it is more general than what you ask for and does not prevent the user from storing unsupported types you do not need to worry about creating the according subclasses.
If you want to return results as well from your DB Boost::Any might be the answer as well.
I suggest limiting the types in your bind function rather than in the storage. If you work with a variadic bind function this is necessary anyways.

C++ Dynamically Define Function

I am on visual c++ working on a console calculator, I am creating a way to let the user define a custom linear function. Here is where I am stumped: Once I get the users desired name of the function, the slope, and the y-intercept, I need to use that data to create a callable function that I can pass to muParser.
In muParser, you define custom functions like this:
double func(double x)
{
return 5*x + 7; // return m*x + b;
}
MyParser.DefineFun("f", func);
MyParser.SetExpr("f(9.5) - pi");
double dResult = MyParser.Eval();
How could I dynamically create a function like this based on the users input for the values 'm' and 'b' and pass that to the 'DefineFun()' method?
This is what I have so far:
void cb_SetFunc(void)
{
string FuncName, sM, sB;
double dM, dB;
bool GettingName = true;
bool GettingM = true;
bool GettingB = true;
regex NumPattern("[+-]?(?:0|[1-9]\\d*)(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?");
EchoLn(">>> First, enter the functions name. (Enter 'cancel' to abort)");
EchoLn(">>> Only letters, numbers, and underscores can be used.");
try
{
do // Get the function name
{
Echo(">>> Enter name: ");
FuncName = GetLn();
if (UserCanceled(FuncName)) return;
if (!ValidVarName(FuncName))
{
EchoLn(">>> Please only use letters, numbers, and underscores.");
continue;
}
GettingName = false;
} while (GettingName);
do // Get the function slope
{
Echo(">>> Enter slope (m): ");
sM = GetLn();
if (UserCanceled(sM)) return;
if (!regex_match(sM, NumPattern))
{
EchoLn(">>> Please enter any constant number.");
continue;
}
dM = atof(sM.c_str());
GettingM = false;
} while (GettingM);
do // Get the function y-intercept
{
Echo(">>> Enter y-intercept (b): ");
sB = GetLn();
if (UserCanceled(sB)) return;
if (!regex_match(sB, NumPattern))
{
EchoLn(">>> Please enter any constant number.");
continue;
}
dB = atof(sB.c_str());
GettingB = false;
} while (GettingB);
// ------------
// TODO: Create function from dM (slope) and
// dB (y-intercept) and pass to 'DefineFun()'
// ------------
}
catch (...)
{
ErrMsg("An unexpected error occured while trying to set the function.");
}
}
I was thinking that there isn't a way to define an individual method for each user-defined-function. Would I need to make a vector<pair<double, double>> FuncArgs; to keep track of the appropriate slopes and y-intercepts then call them dynamically from the function? How would I specify which pair to use when I pass it to DefineFun(FuncStrName, FuncMethod)?
What you need (in addition to a script language interpreter) is called a "trampoline". There is no standard solution to create those, in particular since it involves creating code at runtime.
Of course, if you accept a fixed number of trampolines, you can create them at compile time. And if they're all linear, this might be even easier:
const int N = 20; // Arbitrary
int m[N] = { 0 };
int b[N] = { 0 };
template<int I> double f(double x) { return m[I] * x + b; }
This defines a set of 20 functions f<0>...f<19> which use m[0]...m[19] respectively.
Edit:
// Helper class template to instantiate all trampoline functions.
double (*fptr_array[N])(double) = { 0 };
template<int I> struct init_fptr<int I> {
static const double (*fptr)(double) = fptr_array[I] = &f<I>;
typedef init_fptr<I-1> recurse;
};
template<> struct init_fptr<-1> { };
I would keep it simple:
#include <functional>
std::function<double(double)> f; // this is your dynamic function
int slope, yintercept; // populate from user input
f = [=](double x) -> double { return slope * x + yintercept; };
Now you can pass the object f to your parser, which can then call f(x) at its own leisure. The function object packages the captured values of slope and yintercept.
GiNaC is C++ lib which can parse and evaluate math expressions.
Generating a fixed array of functions bindable to boost function.
Someone else already said about a similar method, but since I'd taken the time to write the code, here it is anyway.
#include <boost/function.hpp>
enum {
MAX_FUNC_SLOTS = 255
};
struct FuncSlot
{
double (*f_)(double);
boost::function<double(double)> closure_;
};
FuncSlot s_func_slots_[MAX_FUNC_SLOTS];
template <int Slot>
struct FuncSlotFunc
{
static void init() {
FuncSlotFunc<Slot-1>::init();
s_func_slots_[Slot - 1].f_ = &FuncSlotFunc<Slot>::call;
}
static double call(double v) {
return s_func_slots_[Slot - 1].closure_(v);
}
};
template <> struct FuncSlotFunc<0> {
static void init() {}
};
struct LinearTransform
{
double m_;
double c_;
LinearTransform(double m, double c)
: m_(m)
, c_(c)
{}
double operator()(double v) const {
return (v * m_) + c_;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
FuncSlotFunc<MAX_FUNC_SLOTS>::init();
s_func_slots_[0].closure_ = LinearTransform(1, 0);
s_func_slots_[1].closure_ = LinearTransform(5, 1);
std::cout << s_func_slots_[0].f_(1.0) << std::endl; // should print 1
std::cout << s_func_slots_[1].f_(1.0) << std::endl; // should print 6
system("pause");
return 0;
}
So, you can get the function pointer with: s_func_slots_[xxx].f_
And set your action with s_func_slots_[xxx].closure_
Try to embed to your application some script language. Years ago I was using Tcl for similar purpose - but I do not know what is the current time best choice.
Either you can start from Tcl or search yourself for something better:
See: Adding Tcl/Tk to a C application

What is good practice for generating verbose output?

what is good practice for generating verbose output? currently, i have a function
bool verbose;
int setVerbose(bool v)
{
errormsg = "";
verbose = v;
if (verbose == v)
return 0;
else
return -1;
}
and whenever i want to generate output, i do something like
if (debug)
std::cout << "deleting interp" << std::endl;
however, i don't think that's very elegant. so i wonder what would be a good way to implement this verbosity switch?
The simplest way is to create small class as follows(here is Unicode version, but you can easily change it to single-byte version):
#include <sstream>
#include <boost/format.hpp>
#include <iostream>
using namespace std;
enum log_level_t {
LOG_NOTHING,
LOG_CRITICAL,
LOG_ERROR,
LOG_WARNING,
LOG_INFO,
LOG_DEBUG
};
namespace log_impl {
class formatted_log_t {
public:
formatted_log_t( log_level_t level, const wchar_t* msg ) : fmt(msg), level(level) {}
~formatted_log_t() {
// GLOBAL_LEVEL is a global variable and could be changed at runtime
// Any customization could be here
if ( level <= GLOBAL_LEVEL ) wcout << level << L" " << fmt << endl;
}
template <typename T>
formatted_log_t& operator %(T value) {
fmt % value;
return *this;
}
protected:
log_level_t level;
boost::wformat fmt;
};
}//namespace log_impl
// Helper function. Class formatted_log_t will not be used directly.
template <log_level_t level>
log_impl::formatted_log_t log(const wchar_t* msg) {
return log_impl::formatted_log_t( level, msg );
}
Helper function log was made template to get nice call syntax. Then it could be used in the following way:
int main ()
{
// Log level is clearly separated from the log message
log<LOG_DEBUG>(L"TEST %3% %2% %1%") % 5 % 10 % L"privet";
return 0;
}
You could change verbosity level at runtime by changing global GLOBAL_LEVEL variable.
int threshold = 3;
class mystreambuf: public std::streambuf
{
};
mystreambuf nostreambuf;
std::ostream nocout(&nostreambuf);
#define log(x) ((x >= threshold)? std::cout : nocout)
int main()
{
log(1) << "No hello?" << std::endl; // Not printed on console, too low log level.
log(5) << "Hello world!" << std::endl; // Will print.
return 0;
}
You could use log4cpp
You can wrap your functionality in a class that supports the << operator which allows you to do something like
class Trace {
public:
enum { Enable, Disable } state;
// ...
operator<<(...)
};
Then you can do something like
trace << Trace::Enable;
trace << "deleting interp"
1. If you are using g++ you could use the -D flag, this allows the compilator to define a macro of your choice.
Defining the
For instance :
#ifdef DEBUG_FLAG
printf("My error message");
#endif
2. I agree this isn't elegant either, so to make it a bit nicer :
void verbose(const char * fmt, ... )
{
va_list args; /* Used as a pointer to the next variable argument. */
va_start( args, fmt ); /* Initialize the pointer to arguments. */
#ifdef DEBUG_FLAG
printf(fmt, &args);
#endif
/*This isn't tested, the point is to be able to pass args to
printf*/
}
That you could use like printf :
verbose("Error number %d\n",errorno);
3. A third solution easier, and more C++ and Unix like is to pass an argument to your program that is going to be used - as the macro earlier - to initialize a particular variable (that could be a global const).
Example :
$ ./myprogram -v
if(optarg('v')) static const verbose = 1;