#include <vector>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
using namespace std;
using namespace boost;
struct Contact{
int n;
Contact(int x) : n(x) {}
bool isReal(){ return n%2; } // the role of isReal will be played by isOdd
};
struct ContactContainer{
// this is the underlying container
typedef vector<shared_ptr<Contact> > ContainerT;
ContainerT data;
// predicate defining whether we skip this contact or not
struct IsReal{
bool operator()(shared_ptr<Contact>& c){ return c && c->isReal(); }
bool operator()(const shared_ptr<Contact>& c){ return c && c->isReal(); }
};
typedef boost::filter_iterator<IsReal,ContainerT::iterator> iterator;
typedef boost::filter_iterator<IsReal,ContainerT::const_iterator> const_iterator;
// return proxy iterator
iterator begin(){ return iterator(data.begin(), data.end()); }
iterator end(){ return iterator(data.end(), data.end());}
const_iterator begin() const { return const_iterator(data.begin(), data.end()); }
const_iterator end() const { return const_iterator(data.end(), data.end()); }
size_t size() const { return data.size(); }
};
int main()
{
ContactContainer contacts;
contacts.data.push_back(make_shared<Contact>(1));
contacts.data.push_back(make_shared<Contact>(2));
contacts.data.push_back(make_shared<Contact>(3));
contacts.data.push_back(make_shared<Contact>(4));
contacts.data.push_back(make_shared<Contact>(5));
contacts.data.push_back(make_shared<Contact>(6));
BOOST_FOREACH(const shared_ptr<Contact>& c, contacts){
std::cout << "Iterating, c->n = " << c->n << "\n";
};
}