Listing 4: Storing the predicate inside the selection object.

template <class Table, class Pred>class selection_t;
template <class Table, class Pred>
class selection_iterator
{
public:
  typedef std::bidirectional_iterator_tag iterator_category;
  typedef typename selection_t<Table,Pred>::value_type
    value_type;
  typedef typename selection_t<Table,Pred>::arg::const_iterator
    arg_iterator;
  typedef selection_t<Table,Pred> relation_type;
  ...
  selection_iterator(arg_iterator itr, const relation_type* rel)
    : itr_(itr), relation_(rel) {}
  selection_iterator operator++()
  {
    ++itr_;
    move_to_next();
    return *this;
  }
  selection_iterator::value_type operator*() const
  {
    return *itr_;
  }
private:
  void move_to_next()
  {
    while (itr_ != relation_->arg_.end()
      && !(relation_->pred_)(*itr_))
    ++itr_;
  }
private:
  arg_iterator itr_;
  const relation_type* relation_;
};
template <class Table, class Pred>
class selection_t
{
  friend class selection_iterator<Table,Pred>;
public:
  typedef typename Table::field_list field_list;
  typedef typename Table::sort_list sort_list;
  typedef typename Table::value_type value_type;
  typedef selection_iterator<Table,Pred> const_iterator;
  typedef Table arg;
  enum {is_distinct = arg::is_distinct};

  selection_t(const arg& t, const Pred P) : arg_(t), pred_(p) {}
  const_iterator begin() const
  {
    const_iterator i(arg_.begin(), this);
    i.move_to_next();
    return i;
  }
  const_iterator end() const
  {
    return const_iterator(arg_.end(), this);
  }
  ...
private:
  const arg* arg_;
  Pred pred_;
};
template <class Arg, class Pred>
selection_t<Arg, Pred> selection(const Arg& t, Pred p)
{
  return selection_t<Arg, Pred>(t, p);
}