Listing 2: Specialization of rangebuf for ordinary pointers

template<>
class rangebuf<char*> : public std::streambuf {
public:
  rangebuf(const char* f, const char* l);
protected:
  pos_type seekoff(off_type off, std::ios::seekdir way,
                   std::ios::openmode which);
  pos_type seekpos(pos_type pos, std::ios::openmode which);
};

rangebuf<char*>::rangebuf(const char* f, const char* l) {
  setg(const_cast<char*>(f),
       const_cast<char*>(f),
       const_cast<char*>(l));
}

std::streambuf::pos_type
rangebuf<char*>::seekoff(off_type off, std::ios::seekdir way,
                               std::ios::openmode which) {
  switch(way) {
  case std::ios::beg:
    return seekpos(pos_type(off), which);
  case std::ios::cur:
    return seekpos(pos_type(off) + (gptr() - eback()), which);
  case std::ios::end:
    return seekpos(pos_type(off) + (egptr() - eback()), which);
  default:
    return pos_type(off_type(-1));
  }
}

std::streambuf::pos_type
rangebuf<char*>::seekpos(pos_type pos, std::ios::openmode which) {
  if (which != std::ios::in)
    return pos_type(off_type(-1));

  off_type offset = off_type(pos);
  if (offset < 0 || offset > egptr() - eback())
    return pos_type(off_type(-1));

  setg(eback(), eback() + offset, egptr());
  return pos;
}