How can I implement a TableView like thing in C++?
I want to emulating a tiny relation database like thing in C++. I have data tables, and I want to transform it somehow, so I need a TableView like class. I want filtering, sorting, freely add and remove items and transforming (ex. view as UPPERCASE and so on). The whole thing is inside a GUI application, so datatables and views are attached to a GUI (or HTML or something).
So how can I identify an item in the view? How can I signal it when the table is changed? Is there some design pattern for this?
Here is a simple table, and a simple data item:
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
using boost::multi_index_container;
using namespace boost::multi_index;
struct Data
{
Data() {}
int id;
std::string name;
};
struct row{};
struct id{};
struct name{};
typedef boost::multi_index_container<
Data,
indexed_by<
random_access<tag<row> >,
ordered_unique<tag<id>, member<Data, int, &Data::id> >,
ordered_unique<tag<name>, member<Data, std::string, &Data::name> >
>
> TDataTable;
class DataTable
{
public:
typedef Data item_type;
typedef TDataTable::value_type value_type;
typedef TDataTable::const_reference const_reference;
typedef TDataTable::index<row>::type TRowIndex;
typedef TDataTable::index<id>::type TIdIndex;
typedef TDataTable::index<name>::type TNameIndex;
typedef TRowIndex::iterator iterator;
DataTable() :
row_index(rule_table.get<row>()),
id_index(rule_table.get<id>()),
name_index(rule_table.get<name>()),
row_index_writeable(rule_table.get<row>())
{
}
TDataTable::const_reference operator[](TDataTable::size_type n) const
{ return rule_table[n]; }
std::pair<iterator,bool> push_back(const value_type& x)
{ return row_index_writeable.push_back(x); }
iterator erase(iterator position)
{ return row_index_writeable.erase(position); }
bool replace(iterator position,const value_type& x)
{ return row_index_writeable.replace(position, x); }
template<typename InputIterator> void rearrange(InputIterator first)
{ return row_index_writeable.rearrange(first); }
void print_table() const;
unsigned size() const
{ return row_index.size(); }
TDataTable rule_table;
const TRowIndex& row_index;
const TIdIndex& id_index;
const TNameIndex& name_index;
private:
TRowIndex& row_index_writeable;
};
class DataTableView
{
DataTableView(const DataTable& source_table) {}
// How can I implement this?
// I want filtering, sorting, signaling upper GUI layer, and sorting, and ...
};
int main()
{
Data data1;
data1.id = 1;
data1.name = "name1";
Data data2;
data2.id = 2;
data2.name = "name2";
DataTable table;
table.push_back(data1);
DataTable::iterator it1 = table.row_index.iterator_to(table[0]);
table.erase(it1);
table.push_back(data1);
Data new_data(table[0]);
new_data.name = "new_name";
table.replace(table.row_index.iterator_to(table[0]), new_data);
for (unsigned i = 0; i < table.size(); ++i)
std::cout << table[i].name << std::endl;
#if 0
// using scenarios:
DataTableView table_view(table);
table_view.fill_from_source(); // synchronization with source
table_view.remove(data_item1); // remove item from view
table_view.add(data_item2); // add item from source table
table_view.filter(filterfunc); // filtering
table_view.sort(sortfunc); // sorting
// modifying from source_able, hot to signal the table_view?
// FYI: Table view is atteched to a GUI item
table.erase(data);
table.replace(data);
#endif
return 0;
}