# char_producer

Category: containers | Component type: type

### Description

`Char_producter<charT>` is a helper class for `rope`. Its only purpose is for the creation of `rope`s that use lazy evaluation. A `rope` that uses lazy evaluation is one that does not store the value of the `n`th 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_producer`s can be stored inside a `rope` data structure. All char producers must be derived from the single base class `char_producer`.

For performance reasons, 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 `n`th 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);
    }

### Definition

Defined in rope, and in the backward-compatibility header rope.h. The `char_producer` class is an SGI extension; it is not part of the C++ standard.

### Template parameters

Parameter | Description | Default
--- | --- | ---
`charT` | The character type |

### Model of

Assignable

### Type requirements

`charT` is a model of Assignable.

### Members

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`.

### Notes

### See also

`rope`, Function object

Copyright © 1999 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation