I want to have a Storage interface(abstract class) and a set of Storage implementations (SQLite, MySQL, Memcached..) for storing objects of a known class and retrieving subsets from the Storage.
To me the clear interface would be:
class Storable{int id; blah; blah; blah; string type;};
class Storage{
virtual Storage::iterator get_subset_of_type(string type) = 0;
virtual Storage::iterator end)_ = 0;
virtual void add_storable(Storable storable) = 0;
};
And then create implementations of Storage that fulfill the interface. Now, my problem is the following:
Any hint?
If you want a virtual interface for iteration, something like this?
#include <iostream>
#include <iterator>
struct Iterable {
virtual int current() = 0;
virtual void advance() = 0;
protected:
~Iterable() {}
};
struct Iterator : std::iterator<std::input_iterator_tag,int> {
struct Proxy {
int value;
Proxy(const Iterator &it) : value(*it) {}
int operator*() { return value; }
};
Iterable *container;
Iterator(Iterable *a) : container(a) {}
int operator*() const { return container->current(); }
Iterator &operator++() { container->advance(); return *this; }
Proxy operator++(int) { Proxy cp(*this); ++*this; return cp; }
};
struct AbstractStorage : private Iterable {
Iterator iterate() {
return Iterator(this);
}
// presumably other virtual member functions...
virtual ~AbstractStorage() {}
};
struct ConcreteStorage : AbstractStorage {
int i;
ConcreteStorage() : i(0) {}
virtual int current() { return i; }
virtual void advance() { i += 10; }
};
int main() {
ConcreteStorage c;
Iterator x = c.iterate();
for (int i = 0; i < 10; ++i) {
std::cout << *x++ << "\n";
}
}
This isn't a complete solution - I haven't implemented Iterator::operator==
, or Iterator::operator->
(the latter is needed if the contained type is a class type).
I'm storing state in the ConcreteStorage class, which means we can't have multiple iterators on the same Storage at the same time. So probably rather than Iterable
being a base class of Storage, there needs to be another virtual function of Storage to return a new Iterable
. The fact that it's only an input iterator means that copies of an iterator can all point to the same Iterable
, so that can be managed with a shared_ptr
(and either Itertable
should have a virtual destructor, or the newIterator function should return the shared_ptr
, or both).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With