Bonjour,
Je dois écrire une classe (sql::table) qui contient deux séquences d'éléments : une séquence d'instances de la classe sql::column et une séquence d'instances de la classe sql::row. L'utilisateur de la classe sql::table doit être à même d'ajouter, de supprimer et de parcourir les éléments des deux séquences.

La question que je me pose est au niveau de l'interface à offrir. Voici ce que j'ai pour l'instant :

Comme le cas le plus fréquent est celui où l'on veut parcourir les sql::row, les méthodes sql::table::begin() et sql::table::end() retourne respectivement l'itérateur de début et de fin de la séquence. Pour les sql::column, ce sont les méthodes sql::table::column_begin() et sql::table::column_end() qui s'en chargent.

Reste l'ajout/suppression, la surcharge des paramètre permet d'écrire une fonction sql::table::insert() qui ajoute dans la séquence de sql::row et une surcharge ajoutant dans la séquence de sql::column. Il serait aussi possible de faire de même pour la fonction sql::table::erase().

Voici un exemple de code :

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
#include <algorithm>
#include <vector>
 
namespace sql {
	class column { };
	class row { };
 
	class table {
		public:
			std::vector<row>::iterator begin() { return std::begin(m_rows); }
			std::vector<row>::iterator end() { return std::end(m_rows); }
 
			std::vector<column>::iterator column_begin() { return std::begin(m_columns); }
			std::vector<column>::iterator column_end() { return std::end(m_columns); }
 
			std::vector<row>::iterator insert(std::vector<row>::iterator position, const row& x) { m_rows.insert(position, x); }
			std::vector<column>::iterator insert(std::vector<column>::iterator position, const column& x) { m_columns.insert(position, x); }
 
			void push_back(const row& x) { m_rows.push_back(x); }
			void push_back(const column& x) { m_columns.push_back(x); }
 
		private:
			std::vector<column> m_columns;
			std::vector<row> m_rows;
	};
}
 
int main() {
	sql::table t;
 
	sql::column column1, column2, column3;
 
	t.insert(t.column_begin(), column1);
	t.push_back(column2);
	t.push_back(column3);
 
	sql::row row1, row2, row3;
 
	t.insert(t.begin(), row1);
	t.push_back(row2);
	t.push_back(row3);
 
	std::for_each(t.column_begin(), t.column_end(), [](sql::column& c) {
		// Do something
	});
 
	for(sql::row& r : t) {
		// Do something
	}
}
Est-ce que cette interface est viable et, si non, quelles modifications devraient y être apportées?

Je cherche une solution qui :
  • Soit simple d'utilisation pour l'utilisateur;
  • N'expose pas l'implémentation interne (remarquez que je n'ai jamais précisé comment sont stockées les séquences);
  • Soit flexible (permet de faire toute manipulation souhaité);
  • S'intègre bien à du code tel que la STL ou Boost.