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);
}