Bonjour tout le monde

J'espere que le pere noël a été sympa avec vous

Je developpe une appli qui charge des données typées (depuis une BdD). Je souhaiterai créer un framework qui permet de simplifier au max le travail de l'utilisateur de ce framework.

J'ai donc commencer par me créer une class Value :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
struct NoCheckValidator
{
	template <typename T>
	static bool Check(const T& /*value*/)
	{
		return true;
	}
};
 
template <typename T, typename C, typename V = NoCheckValidator>
class Value
{
public:
	typedef T value_t;
	typedef C convert_functor;
	typedef V validator_t;
 
private:
	value_t   m_value;
 
public:
	Value(const value_t& v = value_t())
	: m_value(v)
	{
	}
 
	Value(wxSQLite3ResultSet& res, const wxString& colName, const value_t& defaultValue = value_t())
	{
		load(res, colName, defaultValue);
	}
 
	virtual ~Value()
	{
	}
 
	const value_t& operator()() const 
	{
		return m_value;
	}
 
	bool operator()(const value_t& v) 
	{
		return set(v);
	}
 
	bool load(wxSQLite3ResultSet& res, const wxString& colName, const value_t& defaultValue = value_t())
	{
		return set( convert_functor::load(res, colName, defaultValue) );
	}
 
protected:
	bool set(const value_t& v)
	{
		if (validator_t::Check(v) == false) {
			return false;
		}
		m_value = v;
		return true;
	}
};
Je peux donc créer des types de valeur, par exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
struct int_converter
{
	static
	int load(wxSQLite3ResultSet& res, const wxString& colName, int defaultValue)
	{
		return res.GetInt(colName, defaultValue);
	}
};
typedef Value<int, int_converter>    integer;
A présent, je peux donc me créer des classes contenant ces Value :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Cost : public db::Table
{
public:
	db::real   unit_cost;
	db::real   quantity;
	db::text   name;
	db::date   date;
	db::ID     id_task;
 
	static const wxString TABLE_NAME;
 
public:
	Cost();
	Cost(wxSQLite3ResultSet& res);
 
	double cost() const { return unit_cost() * quantity(); }
 
	// DB
	virtual db::update_value_type prepare_insert(wxSQLite3Database& db);
	virtual db::update_value_type prepare_update(wxSQLite3Database& db);
};
Avec ceci, je suis tout de même obligé de charger dans le constructeur qui possede le resultat de la requete, l'ensemble des variables. Ce que j'aimerai, c'est pouvoir créer une variable static, permettant de connaitre les variables et donc de les charger automatiquement dans la classe de base (db::Table dans mon cas). Un truc du genre :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <typename T>
class Table
{
    static ColumnsContainer m_columns; // oui mais quoi ?
    ...
 
    bool load(...); // il ferait tout
};
 
bool Table::load(...)
{
    BOOST_FOREACH(var, m_columns) {
        var.load(...);
    }
}
 
class Cost : public Table<Cost>
{
    ...
}
 
Table<Cost>:: ColumnsContainer Table<Cost>::m_columns = { &Cost::name, ... }; // un truc a base de boost::assign
// ou mieux, avec un define
DEFINE_DB_VARS_nn(Cost, name, ...); // avec nn parametres
Je comprends qu'on ne peut pas créer un pointeur sur une variable membre sans avoir instancié l'objet, mais y a t il une solution à ce que je souhaite ?