Category: containers | Component type: type |
Char_producter<charT> is a helper class for rope. Its only purpose is for the creation of ropes that use lazy evaluation. A rope that uses lazy evaluation is one that does not store the value of the nth character until the value of that particular character is actually needed. This is sometimes a useful optimization.
Char_producer<charT> is an abstract base class; it provides an empty virtual destructor and a pure virtual operator(). Only subclasses of char_producer can be used, not char_producer directly.
Classes derived from char_producer define a method for computing the characters in a rope lazily, whenever those characters are needed. Unlike Function Objects, char_producers can be stored inside a rope data structure. All char producers must be derived from the single base class char_producer.
For performance resons, the operator() inside char_producer is invoked to fill a buffer with a sequence of characters rather than producing a single character at a time. Its declaration is
virtual void operator()(size_t start_pos, size_t len, charT* buffer) = 0;
An invocation of operator() requests that len characters starting at start_pos should be deposited into buffer. If the character at the nth position is requested twice, the same character must be returned both times. (That is, a char_producer must represent a specific, deterministic sequence of characters.)
The following is an example of how to use char_producer and lazy evaluation: it is a (somewhat naive implementation of a) char_producer subclass, which allows an entire file to be treated as a rope. A rope constructed from file_char_prod will contain the same character sequence as the file specified in the constructor. The file will be read only when the rope is accessed, not when the rope is constructed.
void fail(char* s) { fprintf(stderr, "%s errno = %d\n", s, errno); exit(1); } class file_char_prod : public char_producer<char> { public: FILE* f; file_char_prod(char *file_name) { if (NULL == (f = fopen(file_name, "rb"))) fail("Open failed"); } ~file_char_prod() { fclose(f); } virtual void operator()(size_t start_pos, size_t len, char* buffer) { if (fseek(f, start_pos, SEEK_SET)) fail("Seek failed"); if (fread(buffer, sizeof(char), len, f) < len) fail("Read failed"); } long len() { // Return the length of a file; this is the only // mechanism that the standard C library makes possible. if (fseek(f, 0, SEEK_END)) fail("Seek failed"); return ftell(f); } };The following program uses the above class to extract and write the middle 200 characters of a file. Note that even if it is invoked on a gigabyte file, it will still only read approximately 200 characters from the file. Likewise, the rope will only require a small amount of memory.
int main(int argc, char** argv) { if (argc != 2) fail("wrong number of arguments"); file_char_prod* fcp = new file_char_prod(argv[1]); crope s(fcp, fcp -> len(), true); size_t len = s.size(); crope middle = s.substr(len/2 - 100, 200) + "\n"; fwrite(middle.c_str(), sizeof(char), middle.size(), stdout); }
Parameter | Description | Default |
---|---|---|
charT | The character type |
Member | Where defined | Description |
---|---|---|
virtual ~char_producer() | char_producer | A virtual destructor. |
virtual void operator()(size_t start_pos, size_t len, charT* buffer) |
Copy len characters starting at position start_pos in the string into buffer. If a character at a particular position is requested more than once, each request must result in the same character. Note that this is a pure virtual function; it must be overridden by every subclass of char_producer. |