1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
Coroutines do not have to be free functions (i.e., outside of classes). They
can also very well be defined as class members, in which case they have full
access to the members of their class.
In this section we develop a class tt(Floats) that can either write or read
binary tt(float) values to or from files. An object of this
class is used in tt(main), calling its member tt(run) to either write or read
a binary file+footnote(the full program is available in the distribution's
tt(coroutines/demo/readbinary) directory):
verbinsert(-s4 //+main demo/readbinary/main.cc)
The program is called with two arguments: tt(r) for reading, or tt(w) for
writing, and the name of the binary file as its second argument.
The member tt(Floats:run) uses pointers to members to call either tt(read) or
tt(write):
verbinsert(-s4 //floats demo/readbinary/floats/floats.h)
The member tt(read) reads the binary file, using the coroutine
tt(coRead). When tt(coRead) is called the usual actions are performed:
implicitly the coroutine tt(Reader's State) member tt(get_return_object) is
called to obtain the coroutine's handler, and the coroutine is suspended. Next
the handler returned by tt(get_return_object) is made available as the
tt(read) function's tt(reader) object:
verbinsert(-s4 //read demo/readbinary/floats/read.cc)
Once the tt(reader) object is available the member tt(read) enters a tt(while)
loop repeatedly calling tt(reader.next()). At this point the following
happens:
itemization(
it() the coroutine is resumed, reading the next value from the binary file
(if it's available);
it() the coroutine suspends itself again, returning the just obtained
value (or it indicates that all values have been processed);
it() once tt(next) has returned, the tt(read) function again continues,
either ending its tt(while-)statement or showing the retrieved
tt(float).
)
When resumed for the first time (so when tt(reader.next()) is called for the
first time) the tt(coRead) coroutine opens the file, and then, in a
tt(while-)statement, determines the next available value. If that succeeds the
coroutine is again suspended, using tt(co_yield) to pass the just read value
on to tt(read), or (if no value could be obtained) the coroutine ends by
calling tt(co_return). Here is the tt(Floats::coRead) coroutine:
verbinsert(-s4 //read demo/readbinary/floats/coread.cc)
Since tt(coRead) doesn't have to access any of tt(Float's) members it
can be declared as a tt(static) member.
Likewise, the member tt(write) (re)writes the binary file, using the coroutine
tt(coWrite), following the same procedure as used by tt(read) to obtain the
tt(writer) coroutine handler:
verbinsert(-s4 //write demo/readbinary/floats/write.cc)
The member tt(Floats::coWrite) behaves like tt(Floats::coRead), but writes
instead of reads values to the binary file. Here is tt(coWrite), defined as a
normal (non-static) member, as it uses tt(Floats::d_filename):
verbinsert(-s4 //write demo/readbinary/floats/cowrite.cc)
The tt(Reader) and tt(Writer) handler classes are covered next.
|