#ifndef __NAMEDVAL_H__
#define __NAMEDVAL_H__
#include <string>
#include <iostream>
#include <strstream>
#include <vector>
// Minimal INI file or registry interface. Console I/O for
// testing will be overridden by real I/O functions
class SimpleDB {
public:
virtual void Write(const char *section, const char *key,
const char *valStr) {
std::cout << "[" << section << "] " << key << "="
<< valStr << std::endl;
}
virtual void Read(const char *section, const char *key,
char *valStr, int maxBufLen) {
std::cout << "enter value for [" << section << "] key="
<< key << std::endl;
std::cin >> valStr;
}
};
class IOAble {
public:
virtual void Write(SimpleDB &db, const char *section)=0;
virtual void Read(SimpleDB &db, const char *section)=0;
};
class IOParamBlock
{
public:
std::vector<IOAble *> ioVars;
void AddVar(IOAble *v) { ioVars.push_back(v); }
void WriteAll(SimpleDB &db, const char *section) {
int i;
for (i=0; i<ioVars.size(); i++)
ioVars[i]->Write(db, section);
}
void ReadAll(SimpleDB &db, const char *section) {
int i;
for (i=0; i<ioVars.size(); i++)
ioVars[i]->Read(db, section);
}
};
// Template class that wraps a value of type T and has a string
// as its name. Can also be inserted into IOParamBlock for
// automatic IO
template <class T> class NamedVal : public IOAble {
protected:
std::string name;
T val;
public:
NamedVal(const char *varName, const T& initialVal=T())
: name(varName), val(initialVal) {}
NamedVal(const NamedVal &rhs) {
name = rhs.name; val = rhs.val; }
NamedVal(IOParamBlock *parent, const char *varName,
const T& initialVal=T()) : name(varName), val(initialVal)
{ parent->AddVar(this); }
// conversion operators to make this class look like T
operator T & () { return val; }
T* operator & () { return &val; }
// allow assignment of a value of type T
NamedVal<T> & operator = (const T& rhs) {
val=rhs; return *this; }
const char *Name() { return name.c_str(); }
virtual void Write(SimpleDB &db, const char *section) {
char buf[100]; std::strstream strs;
strs << val; strs >> buf; db.Write(section, Name(), buf);
}
virtual void Read(SimpleDB &db, const char *section) {
char buf[100]; db.Read(section, Name(), buf, 100);
std::strstream strs; strs << buf; strs >> val;
}
};
// declare a named variable
#define DECL_NAMED_VAL(type,name) NamedVal<type> name
// define, construct, allocate a named variable
#define DEF_NAMED_VAL(type,name) NamedVal<type> name(#name)
#define DEF_NAMED_VAL_I(type,name,val) \
NamedVal<type> name(#name,val)
#define CONSTRUCT_NAMED_VAL(name) name(#name)
#define CONSTRUCT_NAMED_VAL_I(name, val) name(#name, val)
#define NEW_NAMED_VAL(type,name) name=new NamedVal<type>(#name)
#define NEW_NAMED_VAL_I(type,name,val) \
name=new NamedVal<type> (#name,val)
// construct a NamedVal and insert into IOParamBlock
#define CONSTRUCT_AUTOIO_VAL(name, val) name(this, #name, val)
#endif //__NAMEDVAL_H__