In this section a coroutine-based implementation of a program recursively
showing all directory entries is discussed. The program was based on
facilities offered by Lewis Baker's 
    url(cppcoro library)(https://github.com/lewissbaker/cppcoro).

The source files of this program are available  in the distribution's
tt(yo/coroutines/demo/corodir) directory. It uses the same tt(DirEntry)
type definition as used in the previous section, and specifies
    tt(using Pair = std::pair<DirEntry, char const *>) to access a
tt(DirEntry) and its path name.

The program's tt(main) function strongly resembles the tt(main) function using
the class tt(Dir), but this time tt(main) uses the tt(visitAllEntries)
coroutine:
    verbinsert(-s4 //main demo/corodir/main.cc)

The tt(main) function uses a range-based for-loop to show the entries produced
by the tt(visitAllEntries) coroutine, which are the files and directories that
are (recursively) found in a specified starting directory. 

    Three coroutines are used to process directories. The tt(visitAllEntries)
coroutine returns a tt(RecursiveGenerator<Pair>) as its handler.  Like
tt(main), the tt(visitAllEntries) coroutine also uses a range-based for-loop
(line 3) to retrieve directory entries. The coroutine yields tt(Pair) objects
(line 5) or the results from nested directories (line 9). Its handler (a
tt(RecursiveGenerator)) is a class template, defined in Lewis Baker's
tt(cppcoro) library:
        verbinsert(-ns4 //+allentries demo/corodir/main.cc)
    Directory entries are made available by a second coroutine,
tt(dirPathEntries). At each entry tt(visitAllEntries) is suspended (line 5),
allowing tt(main) to show its full path. At lines 7 and 8 the types of the
entries are inspected. If the received entry refers to a sub-directory then
tt(visitAllEntries) yields, recursively calling itself, and thus yielding the
sub-directory's entries. Once all entries have been processed the range-based
for-loop ends, and the coroutine ends by automatically calling tt(co_return).

The coroutine yielding directory entries is tt(dirPathEntries), whose handler
is an object of another tt(cppcoro) class, tt(Generator<Pair>):
        verbinsert(-ns4 //+path demo/corodir/main.cc)
    The tt(dirPathEntries) coroutine performs a cosmetic task: it receives the
path name of a directory, and calls a third coroutine (tt(dirEntries)) to
retrieve the successive elements of that directory (line 3). As long as there
are entries the coroutine is suspended, yielding tt(Pair) objects consisting
of the values returned by tt(dirEntry) and the full path names of those
entries (lines 4 and 5). Eventually, as with tt(visitAllEntries, co_return)
ends the coroutine.

The third coroutine is tt(dirEntries), returning a tt(Generator<DirEntry)
handler:
        verbinsert(-ns4 //+dir demo/corodir/main.cc)
    This coroutine, like the tt(Dir) class from the previous section, uses
bf(C)'s tt(opendir, readdir), and tt(closedir) triplet of functions. As
coroutines resume their actions beyond their suspension points these functions
can now all be used in a single coroutine. When tt(dirEntries) starts, it
calls tt(opendir) (line 3). Then, as long as there are entries (line 5) and
those entries are neither the current nor the parent directory (line 7,
checked by tt(accept), not listed here), the coroutine is suspended, yielding
the obtained entry (line 8). Its while-loop ends once all entries have been
retrieved. At that point tt(closedir) is called (line 10), and the coroutine
ends.
