Listing 5
// The search class
template <typename R>
class search: public std::iterator<std::input_iterator_tag, R,
std::ptrdiff_t, const R *, const R&>
{
public:
// To conform to compiler that uses 2-phase lookup because
// iterator is dependent base
typedef std::input_iterator_tag iterator_category;
typedef R value_type;
typedef const R& reference;
typedef const R* pointer;
typedef std::ptrdiff_t difference_type;
search( database & db, const std::string & sqlStmt)
: binder_( db, sqlStmt )
{
typename R::template create_bindings<R>( *this );
binder_.bind_all_values_to_db();
binder_.get_next( &record_ );
}
search() { }
search end() { return search(); };
reference operator*() const { return record_; }
pointer operator->() const { return &record_; }
bool operator== ( const search & rhs ) const
{ return binder_ == rhs.binder_; }
bool operator!= ( const search & rhs ) const
{ return binder_ != rhs.binder_; }
search& operator++() // pre-decrement
{
binder_.get_next( &record_ );
return *this;
}
search operator++( int ) // post-decrement
{
search s = *this;
++( *this );
return s;
}
// index is by call order
template <typename T> void bind( R & r, field_attributes fa, T & t )
{ binder_.bind( &r, fa, t);}
template <typename T>
void bind( R & r, field_attributes fa, T & t, std::size_t max_size )
{ binder_.bind( &r, fa, t, max_size );}
// index is fetched from metadata
template <typename T>
void bind(R & r,field_attributes fa,T & t,const std::string & column_name)
{ binder_.bind( &r, fa, t, column_name ); }
template <typename T>
void bind(R & r,field_attributes fa,T & t,const std::string & column_name,
std::size_t max_size )
{ binder_.bind( &r, fa, t, column_name, max_size ); }
// static binding
template <typename T>
void bind( R & r, field_attributes fa, T & t, int column_idx )
{ binder_.bind( &r, fa, t, column_idx ); }
template <typename T>
void bind( R & r, field_attributes fa, T & t, int column_idx,
std::size_t max_size)
{ binder_.bind( &r, fa, t, column_idx, max_size ); }
private:
search_binder binder_;
R record_;
};