home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cset21v3.zip
/
INF
/
DDE4SCL.INF
(
.txt
)
< prev
next >
Wrap
OS/2 Help File
|
1993-10-19
|
387KB
|
12,985 lines
ΓòÉΓòÉΓòÉ <hidden> attach Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o filebuf::attach
o fstream::attach
ΓòÉΓòÉΓòÉ <hidden> cancel Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o sched::cancel
o task::cancel
ΓòÉΓòÉΓòÉ <hidden> close Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o fstreambase::close
o filebuf::close
ΓòÉΓòÉΓòÉ <hidden> cut Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o qhead::cut
o qtail::cut
ΓòÉΓòÉΓòÉ <hidden> doallocate Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o streambuf::doallocate
o strstreambuf::doallocate
ΓòÉΓòÉΓòÉ <hidden> draw Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o randint::draw
o urand::draw
o erand::draw
ΓòÉΓòÉΓòÉ <hidden> get Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o istream::get - Extract characters and store in array
o istream::get - Extract characters and store in stream
o istream::get - Extract character and store in char
o istream::get - Extract character and return it
o qhead::get - Extract object from queue
ΓòÉΓòÉΓòÉ <hidden> o_type Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o object::o_type - return class object type
o task::o_type - return class object type
o timer::o_type - return class object type
o qhead::o_type - return class type
o qtail::o_type - return class type
o Interrupt_handler::o_type - return class
ΓòÉΓòÉΓòÉ <hidden> open Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o filebuf::open
o fstream::open
o ifstream::open
o ofstream::open
ΓòÉΓòÉΓòÉ <hidden> overflow Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o streambuf::overflow - Clear Put Area
o strstreambuf::overflow - Clear Put Area
ΓòÉΓòÉΓòÉ <hidden> pending Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o object::pending - Return object state
o sched::pending - Return state
o qhead::pending - Is queue empty?
o qtail::pending - Is queue full?
o Interrupt_handler::pending - Did a signal occur
ΓòÉΓòÉΓòÉ <hidden> print Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o object::print
o sched::print
o task::print
o timer::print
o qhead::print
o qtail::print
o Interrupt_handler::print
o histogram::print
ΓòÉΓòÉΓòÉ <hidden> put Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o streambuf::put
o qtail::put
ΓòÉΓòÉΓòÉ <hidden> putback Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o istream::putback
o qhead::putback
ΓòÉΓòÉΓòÉ <hidden> rdbuf Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o ios::rdbuf
o fstream::rdbuf
o ifstream::rdbuf
o ofstream::rdbuf
o strstreambase::rdbuf
o stdiobuf::rdbuf
ΓòÉΓòÉΓòÉ <hidden> rdmax Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o qhead::rdmax
o qtail::rdmax
ΓòÉΓòÉΓòÉ <hidden> rdmode Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o qhead::rdmode
o qtail::rdmode
ΓòÉΓòÉΓòÉ <hidden> rdstate Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o ios::rdstate
o sched::rdstate
ΓòÉΓòÉΓòÉ <hidden> seekoff Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o streambuf::seekoff
o filebuf::seekoff
o strstreambuf::seekoff
ΓòÉΓòÉΓòÉ <hidden> setbuf Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o streambuf::setbuf
o filebuf::setbuf
o fstreambase::setbuf
o strstreambuf::setbuf
ΓòÉΓòÉΓòÉ <hidden> setmax Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o qhead::setmax
o qtail::setmax
ΓòÉΓòÉΓòÉ <hidden> setmode Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o qhead::setmode
o qtail::setmode
ΓòÉΓòÉΓòÉ <hidden> setwho Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o sched::setwho
o task::setwho
o timer::setwho
ΓòÉΓòÉΓòÉ <hidden> splice Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o qhead::splice
o qtail::splice
ΓòÉΓòÉΓòÉ <hidden> str Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o strstream::str
o ostrstream::str
ΓòÉΓòÉΓòÉ <hidden> sync Selection ΓòÉΓòÉΓòÉ
Please select one of the following functions:
o streambuf::sync
o istream::sync
o filebuf::sync
ΓòÉΓòÉΓòÉ 1. How to Use the Online Standard Class Library Guide ΓòÉΓòÉΓòÉ
The IBM C/C++ Tools Standard Class Library Guide is a guide for C++
programmers. It provides information about three standard libraries of
predefined C++ classes, including code examples, to enable you to use the
classes in your C++ programs.
This document is a reference rather than a tutorial. It assumes you are already
familiar with C++ programming concepts.
The information contained within this document correspond to the three basic
class libraries:
o The Complex Mathematics Library
o The I/O Stream Library
o The Task Library
Before you begin to use this information, it would be helpful to understand how
you can:
o Expand the Contents to see all available topics
o Obtain additional information for a highlighted word or phrase
o Use action bar choices
How to Use the Contents
When the Contents window first appears, some topics have a plus (+) sign beside
them. The plus sign indicates that additional topics are available.
To expand the Contents if you are using a mouse, click on the plus sign. If you
are using the keyboard, use the Up or Down Arrow key to highlight the topic,
and press the plus (+) key. To see additional topics for those headings, click
on the plus sign or highlight that topic and press the plus (+) key.
To view a topic, double-click on the topic (or press the Up or Down Arrow key
to highlight the topic, and then press the Enter key).
How to Obtain Additional Information
After you select a topic, the information for that topic appears in a window.
Highlighted words or phrases indicate that additional information is available.
You will notice that certain words and phrases are highlighted in green
letters, or in white letters on a black background. These are called hypertext
terms. If you are using a mouse, double-click on the highlighted word. If you
are using a keyboard, press the Tab key to move to the highlighted word, and
then press the Enter key. Additional information then appears in a window.
How to Use Action Bar Choices
Several choices are available for managing information presented in the C/C++
Tools Online Standard Class Library Guide. There are three pull-down menus on
the action bar: the Services menu, the Options menu, and the Help menu.
The actions that are selectable from the Services menu operate on the active
window currently displayed on the screen. These actions include the following:
Bookmark
Allows you to set a placeholder so you can retrieve information of interest
to you.
When you place a bookmark on a topic, it is added to a list of bookmarks you
have previously set. You can view the list, and you can remove one or all
bookmarks from the list. If you have not set any bookmarks, the list is
empty.
To set a bookmark, do the following:
1. Select a topic from the Contents.
2. When that topic appears, choose the Bookmark option from the Services
pull-down.
3. If you want to change the name used for the bookmark, type the new name
in the field.
4. Click on the Place radio button (or press the Up or Down Arrow key to
select it).
5. Click on OK (or select it and press Enter). The bookmark is then added
to the bookmark list.
Search
Allows you to find occurrences of a word or phrase in the current topic,
selected topics, or all topics.
You can specify a word or phrase to be searched. You can also limit the
search to a set of topics by first marking the topics in the Contents list.
To search for a word or phrase in all topics, do the following:
1. Choose the Search option from the Services pull-down.
2. Type the word or words to be searched for.
3. Click on All sections (or press the Up or Down Arrow keys to select it).
4. Click on Search (or select it and press Enter) to begin the search.
5. The list of topics where the word or phrase appears is displayed.
Print
Allows you to print one or more topics. You can also print a set of topics by
first marking the topics in the Contents list.
To print the document Contents list, do the following:
1. Choose Print from the Services pull-down.
2. Click on Contents (or press the Up or Down Arrow key to select it).
3. Click on Print (or select it and press Enter).
4. The Contents list is printed on your printer.
Copy
Allows you to copy a topic that you are viewing to the System Clipboard or to
a file that you can edit. This is particularly useful for copying program
samples into the application that you are developing.
You can copy a topic that you are viewing in two ways:
o Copy copies the topic that you are viewing into the System Clipboard. If
you are using a Presentation Manager* (PM) editor (for example, the
Enhanced Editor) that copies or cuts (or both) to the System Clipboard,
and pastes to the System Clipboard, you can easily add the copied
information to your program source module.
o Copy to file copies the topic that you are viewing into a temporary file
named TEXT.TMP. You can later edit that file by using any editor. TEXT.TMP
is placed in the directory where your viewable document resides.
To copy a topic, do the following:
1. Expand the Contents list and select a topic.
2. When the topic appears, choose Copy to file from the Services pull-down.
3. The system puts the text pertaining to that topic into the temporary
file TEXT.TMP.
For information on any of the choices in the Services pull-down, highlight the
choice and press the F1 key.
The actions that are selectable from the Options menu allow you to change the
way your Contents list is displayed. To expand the Contents and show all levels
for all topics, choose Expand all from the Options pull-down. You can also
press the Ctrl and * keys together.
For information on any of the choices in the Options pull-down, highlight the
choice and press the F1 key.
The actions that are selectable from the Help menu allow you to select
different types of help information. You can also press the F1 key for help
information about the Information Presentation Facility (IPF).
ΓòÉΓòÉΓòÉ 1.1. Related Information ΓòÉΓòÉΓòÉ
o Copyright
o Edition Notice
o Notices
o Trademarks and Service Marks
ΓòÉΓòÉΓòÉ 1.2. Copyright ΓòÉΓòÉΓòÉ
Copyright International Business Machines Corporation, 1993. All rights
reserved.
Note to U.S. Government Users - Documentation related to restricted rights -
Use, duplication, or disclosure is subject to restrictions set forth in GSA ADP
Schedule Contract with IBM* Corp.
ΓòÉΓòÉΓòÉ 1.3. Edition Notice ΓòÉΓòÉΓòÉ
Second Edition, November 1993.
This edition applies to Version 2.01 of IBM C/C++ Tools (82G3745, 82G3746,
82G3747) and to all subsequent releases and modifications until otherwise
indicated in new editions. This publication could include technical
inaccuracies or typographical errors. Changes are periodically made to the
information herein; any such changes will be reported in subsequent revisions.
Requests for publications and for technical information about IBM* products
should be made to your IBM Authorized Dealer or your IBM Marketing
Representative.
When you send information to IBM, you grant IBM a nonexclusive right to use or
distribute the information in any ways it believes appropriate without
incurring any obligation to you.
ΓòÉΓòÉΓòÉ 1.4. Notices ΓòÉΓòÉΓòÉ
References in this publication to IBM* products, programs, or services do not
imply that IBM intends to make these available in all countries in which IBM
operates. Any reference to an IBM product, program, or service is not intended
to state or imply that only IBM's product, program, or service may be used. Any
functionally equivalent product, program, or service that does not infringe any
of IBM's intellectual property rights may be used instead of the IBM product,
program, or service. Evaluation and verification of operation in conjunction
with other products, programs, or services, except those expressly designated
by IBM, are the user's responsibility.
IBM may have patents or pending patent applications covering subject matter in
this document. The furnishing of this document does not give you any license to
these patents. You can send license inquiries, in writing, to the IBM Director
of Commercial Relations, IBM Corporation, Purchase, NY 10577.
This online information may contain coding examples of programs used in daily
business operations. To illustrate them as completely as possible, the
examples may include the names of individuals, companies, brands, and products.
Any such names are fictitious and any similarity to the names and addresses
used by an actual business enterprise is entirely coincidental.
ΓòÉΓòÉΓòÉ 1.5. Trademarks and Service Marks ΓòÉΓòÉΓòÉ
The following terms, denoted by an asterisk (*) in this publication, are
trademarks or service marks of IBM* Corporation in the United States or other
countries:
C/2
C/C++ Tools
C Set ++
C Set/2
CUA
IBM
Operating System/2
OS/2
Presentation Manager
SAA
Systems Application Architecture
The following terms, denoted by a double asterisk (**) in this publication, are
trademarks of another company as follows:
AT&T AT&T Corporation
UNIX UNIX System Laboratories, Inc.
ΓòÉΓòÉΓòÉ <hidden> IBM Trademark ΓòÉΓòÉΓòÉ
Trademark of the IBM Corporation.
ΓòÉΓòÉΓòÉ <hidden> Non-IBM Trademarks ΓòÉΓòÉΓòÉ
AT&T is a trademark of AT&T Corporation.
ΓòÉΓòÉΓòÉ 2. General Information ΓòÉΓòÉΓòÉ
Introduction Introduction to the book's organization, with guidance on how to
use the book. Related books are also identified.
What Are the Class Libraries? Introduction to the three class libraries that
are described in this book: the Complex Mathematics, I/O Stream,
and Task Libraries.
ΓòÉΓòÉΓòÉ 2.1. Introduction ΓòÉΓòÉΓòÉ
This book describes the standard class libraries included with IBM C/C++ Tools.
They provide sets of predefined classes that you can use to perform common
functions such as input and output or complex arithmetic.
The following information is contained in this chapter:
o Who should use this book
o How to use this book
o A note about examples
o Related documentation
The three class libraries are:
o The Complex Mathematics Library
o The I/O Stream Library
o The Task Library
ΓòÉΓòÉΓòÉ 2.1.1. Who Should Use This Book ΓòÉΓòÉΓòÉ
This book is a reference for people who are experienced in using the C++
language, and understand the characteristics of C++ classes. This book should
help you to use the class libraries that are included with C/C++ Tools.
ΓòÉΓòÉΓòÉ 2.1.2. How to Use This Book ΓòÉΓòÉΓòÉ
This book has four parts. Part 1 gives general information. Part 2 describes
the Complex Mathematics Library. Part 3 describes the I/O Stream Library. Part
4 describes the Task Library. Each of these parts can be read independently.
If you need information about the I/O Stream Library, begin by reading
Introduction to the I/O Stream Library. It contains important information about
the organization of the I/O Stream Library, as well as some essential
definitions. This chapter is especially important for you if you are familiar
with the AT&T** or UNIX** System Laboratories C++ Language System Iostream
Library. New terms are defined in Introduction to the I/O Stream Library to
describe certain aspects of the I/O Stream Library. These terms are not used in
the corresponding AT&T** documentation for the Iostream Library.
ΓòÉΓòÉΓòÉ 2.1.2.1. Organization of Chapters ΓòÉΓòÉΓòÉ
o Part 1. General Information
- Introduction, (the chapter you are reading now) describes the organization
of the book and how to use it.
- What Are the Class Libraries?, introduces the three basic class libraries
that are described in this book.
o Part 2. The Complex Mathematics Library
- complex Class, provides a review of complex arithmetic, and describes
complex, the class that lets you manipulate complex numbers.
- c_exception Class, describes c_exception, the class that provides runtime
error-handling facilities for the Complex Mathematics Library.
o Part 3. The I/O Stream Library
- Introduction to the I/O Stream Library, lists the classes that make up the
I/O Stream Library and the header files that contain their declarations.
It also describes the key concept of stream buffers.
- streambuf Protected Interface, describes those members of the streambuf
class that you need to know about to create your own classes derived from
streambuf.
- streambuf Public Interface, describes those members of the streambuf class
that you can use directly to manipulate an object of filebuf, stdiobuf, or
strstreambuf, the predefined classes that are derived from streambuf.
- ios Class, describes ios, the base class for the classes that format data
that comes from the stream buffer.
- istream and istream_withassign Class, describes istream, the class that
lets you extract data from a stream buffer. This chapter also describes
istream_withassign, a class derived from istream that includes an
assignment operator.
- ostream and ostream_withassign Classes, describes ostream, the class that
lets you insert data into a stream buffer. This chapter also describes
ostream_withassign, a class derived from ostream that includes an
assignment operator.
- iostream and iostream_withassign Classes, describes iostream, the class
that is derived from istream and ostream, and iostream_withassign, the
class that is derived from istream_withassign and ostream_withassign.
- filebuf Class, describes filebuf, the class that adapts streambuf to use
files.
- fstream, ifstream, and ofstream Classes, describes fstream, ifstream, and
ofstream, the classes that adapt istream, ostream, and iostream,
respectively, to use files.
- strstreambuf Class, describes strstreambuf, the class that adapts
streambuf to use an array of bytes in memory as the source or target of
data.
- strstream, istrstream, and ostrstream Classes, describes istrstream,
ostrstream, and strstream, the classes that adapt istream, ostream, and
iostream, respectively, to use an array of bytes in memory as the source
or target of data.
- stdiobuf and stdiostream Classes, describes stdiobuf, the class that lets
you mix standard C input and output functions with the C++ I/O Stream
Library input and output functions.
- Manipulators, describes the manipulators that allow you to use the input
operator or the output operator to change the state of the stream that is
being used as the source or target of data.
o Part 4. The Task Library
- Introduction to the Task Library, gives an overview of the Task Library
and lists the run-time error messages generated by the Task Library.
- Task Handling Classes, describes object, sched, task, and timer, the task
handling classes. These classes give you the facilities to create and
manage tasks.
- Queue Management Classes, describes qhead and qtail, the queue management
classes. These classes let you implement a wide range of message-passing
and data-buffering schemes.
- Interrupt_handler Class, describes Interrupt_handler, the class that
allows your tasks to handle external events in the form of signals from
the operating system.
- Simulation Classes, describes histogram, randint, urand, and erand, the
simulation classes. These classes provide utilities for writing program
simulations and gathering statistics about them.
o Part 5. Appendixes, Glossary, and Index
- Extended Complex Mathematics Library Examples, contains examples of how to
determine the roots of a complex number and how to define your own
complex_error function.
- Extended Task Library Examples, contains examples of how to use the Task
Library to implement a parallel algorithm and an event-driven simulation.
ΓòÉΓòÉΓòÉ 2.1.2.2. Organization of Class Descriptions ΓòÉΓòÉΓòÉ
The chapters that contain detailed descriptions of classes have the following
format:
o An introduction.
o A discussion of how to use the classes, if appropriate.
o An excerpt from the appropriate header files that shows the relevant
declarations for the classes being described. These excerpts supplement the
member function descriptions; they are not complete listings of the header
files. If you need to know the value of an element in an enumeration, or any
other specific detail about the declaration of a class, you should look at
the header file itself.
o A description of each member function of each class that the chapter
describes. This begins with a description of the constructor and destructor,
if they exist. Descriptions of the remaining members follow in alphabetical
order. For the more complicated classes like streambuf, the descriptions of
members with related operations are grouped together. In most classes, only
public and protected members are described. Private members are only
described if they are needed to describe a public member. In addition, none
of the inherited members in a derived class is described in the discussion of
that class, except for virtual functions that do not use the inherited
function definition.
ΓòÉΓòÉΓòÉ 2.1.2.3. How to Find the Description of a Particular Function ΓòÉΓòÉΓòÉ
The organization of the class libraries can be difficult to understand. The I/O
Stream Library, especially, has a complicated hierarchy of classes. A function
may be defined in more than one class, and it may be overloaded in a single
class. Function name overloading gives C++ many advantages, but it also makes
it difficult to describe the functions in a simple, linear fashion.
If you know the class in which a function is defined, you can go directly to
the chapter where that class is described. There, the functions are grouped
according to their purpose and listed alphabetically within each group. If a
class has more than one version of a function, all of the versions are
described in one section.
ΓòÉΓòÉΓòÉ 2.1.2.4. Fonts Used in This Book ΓòÉΓòÉΓòÉ
In this book, C++ code and code fragments appear in special font. Variables
that are not used in actual examples, and for which other variable names can be
substituted, appear in italics.
ΓòÉΓòÉΓòÉ 2.1.3. A Note about Examples ΓòÉΓòÉΓòÉ
The examples in this book explain elements of the C++ class libraries. They are
coded in a simple style. They do not try to conserve storage, check for errors,
achieve fast run times, or demonstrate all possible uses of a language element.
ΓòÉΓòÉΓòÉ 2.1.4. Related Documentation ΓòÉΓòÉΓòÉ
You might want to refer to the following publications for additional
information:
IBM Publications:
IBM C/C++ Tools: C++ Language Reference, S61G-1185, describes the C++ language.
IBM C/C++ Tools: Collection Class Library Reference, S61G-1178, describes the
C++ collection classes, a set of C++ classes that implement commonly used
abstract data types such as sets, stacks, and queues.
IBM C/C++ Tools: Application Support Class Library Reference, S82G-3905,
describes the C++ application support classes, a set of C++, classes that
provide string handling, exception handling, and date and time capabilities to
C++ applications.
IBM C/C++ Tools: User Interface Class Library Reference, S61G-1179, describes
the C++ user interface classes, a set of C++ classes that you can use to create
C++ applications with a graphical user interface that conforms to the Common
User Access (CUA) interface design.
IBM C/C++ Tools: Class Libraries Reference Summary, S61G-1186, lists the member
functions of the Standard, Collection, and User Interface class libraries. For
each member function, the declaration is provided and the class the function
belongs to is indicated.
IBM C/C++ Tools: Programming Guide, S61G-1181, describes the C++ component of
the common programming interface.
The following is a sample of some non-IBM C++ publications that are generally
available. It is not an exhaustive list. IBM does not specifically recommend
any of these books, and other C++ publications may be available in your
locality.
C++ Language System Release 3.0 Library Manual, UNIX** System Laboratories.
The Annotated C++ Reference Manual by Margaret A. Ellis and Bjarne Stroustrup,
Addison-Wesley Publishing Company.
The C++ Programming Language (Second Edition) by Bjarne Stroustrup,
Addison-Wesley Publishing Company.
C++ Primer (Second Edition) by Stanley B. Lippman, Addison-Wesley Publishing
Company.
ΓòÉΓòÉΓòÉ 2.2. What Are the Class Libraries? ΓòÉΓòÉΓòÉ
This chapter introduces the three class libraries that are described in this
book:
o The Complex Mathematics Library provides you with the facilities to
manipulate complex numbers and perform standard mathematical operations on
them.
o The I/O Stream Library (also known as the Iostream Library, see History of
the Class Libraries). provides you with the facilities to deal with many
varieties of input and output. You can derive classes from this library to
customize the input and output facilities for your own particular needs.
o The Task Library provides you with the facilities to write programs that are
made up of tasks. Tasks are lightweight (that is, they require fewer
processor resources than standard OS/2 processes) and are nonpreemptive. The
Task Library follows the coroutine paradigm.
The following sections provide information on using the class libraries:
o History of the class libraries
o Including a class library in your source code
o Other class libraries
ΓòÉΓòÉΓòÉ 2.2.1. History of the Class Libraries ΓòÉΓòÉΓòÉ
The basic class libraries described in this book are based on the class
libraries from the UNIX** System Laboratories C++ Language System Release 3.0.
(Earlier releases of this product are known as the AT&T** C++ Language System.)
In the Unix System Laboratories product, the class library that corresponds to
the I/O Stream Library is called the Iostream Library. Prior to Release 2.0 of
the AT&T** C++ Language System, a class library called the Stream Library
provided input and output facilities. The I/O Stream Library includes obsolete
functions, described in this book, in order to provide compatibility with the
Stream Library.
ΓòÉΓòÉΓòÉ 2.2.2. Including a Class Library ΓòÉΓòÉΓòÉ
A class library is a collection of header and library files. The header files
provide the interface to the class libraries.
To use the classes, functions, and operators available in a class library, you
must include the parts of the library's interface that you need in your C++
source program. To include an interface, use the directive #include <filename>,
where filename is the name of the header file. Place this statement at the
beginning of the program that requires any of the classes, functions, or
operators defined in the header file. Then, in the body of your program, you
can use a class, function, or operator defined in the header file as well as
derive new classes and overload the functions and operators.
ΓòÉΓòÉΓòÉ 2.2.3. Other Class Libraries ΓòÉΓòÉΓòÉ
In addition to the three standard class libraries, OS/2 C/C++ also supports the
Collection Class Library. This library provides you with the facilities to
create objects of common data structures such as sets, maps, sequences, trees,
and sorted collections. See the Collection Class Library Reference for details
about this class library.
The C/C++ Tools product also supports the User Interface Class Library, a class
library that can be used to create C++ applications with a graphical user
interface that conforms to the Common User Access (CUA) interface design. The
User Interface Class Library is described in the User Interface Class Library
Reference.
ΓòÉΓòÉΓòÉ 3. The Complex Mathematics Library ΓòÉΓòÉΓòÉ
complex Class
Introduction to the Complex Mathematics Library and review of complex
numbers. It describes complex, the class that lets you manipulate complex
numbers.
c_exception Class
Describes c_exception, the class that provides runtime error-handling
facilities for the functions and operations in the complex class.
ΓòÉΓòÉΓòÉ 3.1. complex Class ΓòÉΓòÉΓòÉ
This chapter reviews the concept of complex numbers, and then describes
complex, the class that provides you with the facilities to manipulate complex
numbers.
Appendix A, "Extended Complex Mathematics Library Examples" contains examples
of how you might use the Complex Mathematics Library.
The following topics are described in this chapter:
o Review of complex numbers
o Declarations for the complex class in the complex.h header file
o Complex constructors
o Complex mathematical operators
o Complex input and output operators
o Complex mathematical functions
o Complex trigonometric functions
o Complex magnitude
o Complex conversions
o Linking to the Complex Library
ΓòÉΓòÉΓòÉ 3.1.1. Review of Complex Numbers ΓòÉΓòÉΓòÉ
A complex number is made up of two parts: a real part and an imaginary part. A
complex number can be represented by an ordered pair (a,b), where a is the
value of the real part of the number and b is the value of the imaginary part.
If (a,b) and (c,d) are imaginary numbers, then the following statements are
true:
o (a,b) + (c,d) = (a+c,b+d)
o (a,b) - (c,d) = (a-c,b-d)
o (a,b) * (c,d) = (ac-bd,ad+bc)
o (a,b) / (c,d) = ((ac+bd) / (c¤+d¤), (bc-ad) / (c¤+d¤))
o The conjugate of a complex number (a,b) is (a,-b)
o The absolute value or magnitude of a complex number (a,b) is the positive
square root of the value a¤ + b¤
o The polar representation of (a,b) is (r,theta), where r is the distance from
the origin to the point (a,b) in the complex plane, and theta is the angle
from the real axis to the vector (a,b) in the complex plane. The angle theta
can be positive or negative. illustrates the polar representation (r,theta)
of the complex number (a,b).
Polar Representation of Complex Number (a,b)
ΓòÉΓòÉΓòÉ 3.1.2. Declarations for complex in complex.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses the complex
class:
#include <complex.h>
The following is an excerpt from the complex.h header file that shows the
relevant declarations for the member functions of the complex class:
#include <iostream.h>
#include <errno.h>
#include <math.h>
#define DOMAIN 1
#define SING 2
#define OVERFLOW 3
#define UNDERFLOW 4
#define M_E 2.7182818284590452354
#define M_LOG2E 1.4426950408889634074
#define M_LOG10E 0.43429448190325182765
#define M_LN2 0.69314718055994530942
#define M_LN10 2.30258509299404568402
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.78539816339744830962
#define M_1_PI 0.31830988618379067154
#define M_2_PI 0.63661977236758134308
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2 1.41421356237309504880
#define M_SQRT1_2 0.70710678118654752440
class complex {
double re, im;
public:
complex();.
complex(double r, double i = 0.0);
friend double real(const complex&);
friend double imag(const complex&);
friend double abs(complex);
friend double norm(complex);
friend double arg(complex);
friend complex conj(complex);
friend complex cos(complex);
friend complex cosh(complex);
friend complex exp(complex);
friend complex log(complex);
friend complex pow(double, complex);
friend complex pow(complex, int);
friend complex pow(complex, double);
friend complex pow(complex, complex);
friend complex polar(double, double = 0);
friend complex sin(complex);
friend complex sinh(complex);
friend complex sqrt(complex);
friend complex operator+(complex, complex);
friend complex operator-(complex);
friend complex operator-(complex, complex);
friend complex operator*(complex, complex);
friend complex operator/(complex, complex);
friend int operator==(complex, complex);
friend int operator!=(complex, complex);
void operator+=(complex);
void operator-=(complex);
void operator*=(complex);
void operator/=(complex);
};
istream& operator>>(istream&, complex&);
ostream& operator<<(ostream&, complex);
extern const complex complex_zero(0,0);
Note: This header file excerpt, and all of the other header file excerpts in
this book, are unpublished proprietary source code of AT&T** and UNIX** System
Laboratories. (C) Copyright 1991 AT&T** and UNIX** System Laboratories, Inc.
(C)Copyright 1984, 1989, 1990 AT&T**. All rights reserved.
ΓòÉΓòÉΓòÉ 3.1.2.1. Constants Defined in complex.h ΓòÉΓòÉΓòÉ
The following table lists the mathematical constants that the Complex
Mathematics Library defines (if they have not been previously defined):
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Constants Defined in complex.h Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé CONSTANT NAME Γöé DESCRIPTION Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_E Γöé The constant e Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_LOG2E Γöé The logarithm of e to the base of 2 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_LOG10E Γöé The logarithm of e to the base of 10 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_LN2 Γöé The natural logarithm of 2 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_LN10 Γöé The natural logarithm of 10 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_PI Γöé pi Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_PI_2 Γöé pi / 2 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_PI_4 Γöé pi / 4 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_1_PI Γöé 1 / pi Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_2_PI Γöé 2 / pi Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_2_SQRTPI Γöé 2 divided by the square root of pi Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_SQRT2 Γöé The square root of 2 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé M_SQRT1_2 Γöé The square root of 1 / 2 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 3.1.2.2. Constructors for complex ΓòÉΓòÉΓòÉ
Class: complex
There are two versions of the complex constructor:
complex();
complex(double r, double i=0.0);
If you declare a complex object without specifying any values for the real or
imaginary part of the complex value, the constructor that takes no arguments is
used and the complex value is initialized to (0, 0). For example, the following
declaration gives the object comp the value (0, 0):
complex comp;
If you give either one or two values in your declaration, the constructor that
takes two arguments is used. If you only give one value, the real part of the
complex object is initialized to that value, and the imaginary part is
initialized to 0.
For example, the following declaration gives the object comp2 the value
(3.14, 0):
complex comp2(3.14);
If you give two values in the declaration, the real part of the complex object
is initialized to the first value and the imaginary part is initialized to the
second value. For example, the following declaration gives the object comp3 the
value (3.14, 6.44):
complex comp3(3.14, 6.44);
There is no explicit complex destructor.
ΓòÉΓòÉΓòÉ 3.1.2.3. Using the Complex Constructor to Initialize Arrays ΓòÉΓòÉΓòÉ
You can use the complex constructor to initialize arrays of complex numbers. If
the list of initial values is made up of complex values, each array element is
initialized to the corresponding value in the list of initial values. If the
list of initial values is not made up of complex values, the real parts of the
array elements are initialized to these initial values and the imaginary parts
of the array elements are initialized to 0. In the following example, the
elements of array b are initialized to the values in the initial value list,
but only the real parts of elements of array a are initialized to the values in
the initial value list.
#include <complex.h>
void main() {
complex a[3] = {1.0, 2.0, 3.0};
complex b[3] = {complex(1.0, 1.0), complex(2.0, 2.0),
complex(3.0, 3.0)};
cout << "Here is the first element of a: " << a[0] << endl;
cout << "Here is the first element of b: " << b[0] << endl;
}
This example produces the following output:
Here is the first element of a: ( 1, 0)
Here is the first element of b: ( 1, 1)
ΓòÉΓòÉΓòÉ 3.1.3. Mathematical Operators for complex ΓòÉΓòÉΓòÉ
The complex operators described in this section have the same precedence as the
corresponding real operators.
The following operators are described:
o Addition operator
o Subtraction operator
o Negation operator
o Multiplication operator
o Division operator
o Equality operator
o Inequality operator
o Mathematical assignment operators
ΓòÉΓòÉΓòÉ 3.1.3.1. Addition ΓòÉΓòÉΓòÉ
Class: complex
friend complex operator+(complex x, complex y);
The addition operator returns the sum of x and y.
ΓòÉΓòÉΓòÉ 3.1.3.2. Subtraction ΓòÉΓòÉΓòÉ
Class: complex
friend complex operator-(complex x, complex y);
The subtraction operator returns the difference between x and y.
ΓòÉΓòÉΓòÉ 3.1.3.3. Negation ΓòÉΓòÉΓòÉ
Class: complex
friend complex operator-(complex x);
The negation operator returns (- a, - b) when its argument is (a, b).
ΓòÉΓòÉΓòÉ 3.1.3.4. Multiplication ΓòÉΓòÉΓòÉ
Class: complex
friend complex operator*(complex x, complex y)
The multiplication operator returns the product of x and y.
ΓòÉΓòÉΓòÉ 3.1.3.5. Division ΓòÉΓòÉΓòÉ
Class: complex
friend complex operator/(complex x, complex y)
The division operator returns the quotient of x divided by y.
ΓòÉΓòÉΓòÉ 3.1.3.6. Equality ΓòÉΓòÉΓòÉ
Class: complex
friend int operator==(complex x, complex y);
The equality operator "==" returns a nonzero value if x equals y. This
operator tests for equality by testing that the two real components are equal
and that the two imaginary components are equal.
Because both components are double values, the equality operator tests for an
exact match between the two sets of values. If you want an equality operator
that can test for an absolute difference within a certain tolerance between the
two pairs of corresponding components, you can use a function such as the
is_equal function defined in Inequality.
ΓòÉΓòÉΓòÉ 3.1.3.7. Inequality ΓòÉΓòÉΓòÉ
Class: complex
friend int operator!=(complex x, complex y);
The inequality operator "! =" returns a nonzero value if x does not equal y.
This operator tests for inequality by testing that the two real components are
not equal and that the two imaginary components are not equal.
Because both components are double values, the inequality operator returns
false only when both the real and imaginary components of the two values are
identical. If you want an inequality operator that can test for an absolute
difference within a certain tolerance between the two pairs of corresponding
components, you can use a function such as the is_not_equal function defined in
the following example. In the example, the functions is_equal and is_not_equal
are defined to test whether two complex values are equal or not equal,
respectively, within a certain tolerance. You should use functions like
is_equal and is_not_equal, rather than the equality and inequality operators,
if you want a reliable comparison between two complex values.
#include <complex.h>
int is_equal(const complex &a, const complex &b,
const double tol=0.0001)
{
return (abs(real(a) - real(b)) < tol &&
abs(imag(a) - imag(b)) < tol);
}
int is_not_equal(const complex &a, const complex &b,
const double tol=0.0001)
{
return !is_equal(a, b, tol);
}
void main()
{
complex c1 = complex(1.0, 2.0);
complex c2 = c1;
complex c3 = complex(3.0, 4.0);
if (is_equal(c1, c2))
cout << "c1 is equal to c2" << endl;
else
cout << "c1 is not equal to c2 - not possible!" << endl;
if (is_not_equal(c1, c3))
cout << "c1 is not equal to c3" << endl;
else
cout << "c1 is equal to c3 - not possible!" << endl;
}
This example produces the following output:
c1 is equal to c2
c1 is not equal to c3
ΓòÉΓòÉΓòÉ 3.1.3.8. Mathematical Assignment Operators ΓòÉΓòÉΓòÉ
Class: complex
void operator+=(complex x);
void operator-=(complex x);
void operator*=(complex x);
void operator/=(complex x);
The following list describes the functions of the mathematical assignment
operators:
o x + = y assigns the value of x + y to x.
o x - = y assigns the value of x - y to x.
o x * = y assigns the value of x * y to x.
o x / = y assigns the value of x / y to x.
Note: The assignment operators do not produce a value that can be used in an
expression. The following code, for example, produces a compile-time error:
complex x, y, z; // valid declaration
x = (y += z); // invalid assignment causes a
// compile-time error
ΓòÉΓòÉΓòÉ 3.1.3.9. Example of Using the Complex Mathematical Operators ΓòÉΓòÉΓòÉ
The following example shows how you can use the complex mathematical operators:
#include <complex.h>
void main() {
complex a, b;
cout << "enter two complex values" << endl;
cin >> a >> b;
cout << "The sum of these two numbers is " << a+b << endl;
cout << "The difference between these two numbers is "
<< a-b << endl;
cout << "The product of these two numbers is "
<< a*b << endl;
cout << "The first number divided by the second is "
<< a/b << endl;
}
If you run this program with the values (1,1) and (2,2) for input, the output
will look like this:
enter two complex values
The sum of these two numbers is ( 3, 3)
The difference between these two numbers is ( -1, -1)
The product of these two numbers is ( 0, 4)
The first number divided by the second is ( 0.5, 0)
ΓòÉΓòÉΓòÉ 3.1.4. Input and Output Operators for complex ΓòÉΓòÉΓòÉ
The following topics are described:
o The input operator
o The output operator
o An example of using the input and output operators.
ΓòÉΓòÉΓòÉ 3.1.4.1. Input Operator ΓòÉΓòÉΓòÉ
Class: complex
istream& operator>>(istream& is, complex& c);
The input (or extraction) operator >> takes complex value c from the stream is
in the form (a,b). The parentheses and comma are mandatory delimiters for input
when the imaginary part of the complex number being read is nonzero. Otherwise,
they are optional. In both cases, whitespace is optional.
ΓòÉΓòÉΓòÉ 3.1.4.2. Output Operator ΓòÉΓòÉΓòÉ
Class: complex
ostream& operator<<(ostream& os, complex c);
The output (or insertion) operator << writes complex value c to the stream os
in the form (a,b).
ΓòÉΓòÉΓòÉ 3.1.4.3. Example of Using the Complex Input and Output Operators ΓòÉΓòÉΓòÉ
#include <complex.h>
void main(){
complex x;
cout << "Enter a complex number in the form (a,b):" << endl;
cin >> x;
cout << "Here is the complex value: " << x << endl;
}
This example produces the following output if you enter the complex value (3,4)
at the prompt:
Enter a complex number in the form (a,b):
Here is the complex value: (3,4)
ΓòÉΓòÉΓòÉ 3.1.5. Mathematical Functions for complex ΓòÉΓòÉΓòÉ
The following mathematical functions are described:
o exp - Exponent
o log - Logarithm
o pow - Power
o sqrt - Square Root
There is also an example of using the complex mathematical functions.
ΓòÉΓòÉΓòÉ 3.1.5.1. exp - Exponent ΓòÉΓòÉΓòÉ
Class: complex
friend complex exp(complex x);
exp() returns the complex value equal to e to the power of x where x is the
argument. Results of the Default Error-Handling Procedures shows the values
returned by the default error-handling procedure for exp().
ΓòÉΓòÉΓòÉ 3.1.5.2. log - Logarithm ΓòÉΓòÉΓòÉ
Class: complex
friend complex log(complex x);
log() returns the natural logarithm of the argument x. Results of the Default
Error-Handling Procedures shows the values returned by the default
error-handling procedure for log().
ΓòÉΓòÉΓòÉ 3.1.5.3. pow - Power ΓòÉΓòÉΓòÉ
Class: complex
friend complex pow(double d, complex z);
friend complex pow(complex c, int i);
friend complex pow(complex c, double d);
friend complex pow(complex c, complex z);
Note: Exponents in the following text are shown in square brackets.
pow() returns the complex value x[y], where x is the first argument and y is
the second argument. pow() is overloaded four times. If d is a double value, i
is an integer value, and c and z are complex values, then pow() can produce any
of the following results:
o d[z]
o c[i]
o c[d]
o c[z]
ΓòÉΓòÉΓòÉ 3.1.5.4. sqrt - Square Root ΓòÉΓòÉΓòÉ
Class: complex
friend complex sqrt(complex x)
sqrt() returns the square root of its argument. If c and d are real values,
then every complex number (a,b), where:
o a = c¤ - d¤
o b = 2cd
has two square roots:
o (c,d)
o (-c,-d )
sqrt() returns the square root that has a positive real part, that is, the
square root that is contained in the first or fourth quadrants of the complex
plane.
ΓòÉΓòÉΓòÉ 3.1.5.5. Example of Using the Complex Mathematical Functions ΓòÉΓòÉΓòÉ
The following program shows how you can use the complex mathematical functions:
#include <complex.h>
void main() {
complex a, b;
int i;
double f;
//
// prompt the user for an argument for calls to
// exp(), log(), and sqrt()
//
cout << "Enter a complex value" << endl;
cin >> a;
cout << "The value of exp() for " << a << " is: "
<< exp(a) << endl;
cout << "The natural logarithm of " << a << " is: "
<< log(a) << endl;
cout << "The square root of " << a << " is: "
<< sqrt(a) << endl << endl;
//
// prompt the user for arguments for calls to pow()
//
cout << "Enter 2 complex values (a and b), an integer (i),";
cout << " and a floating point value (f)" << endl;
cin >> a >> b >> i >> f;
cout << "a is " << a << ", b is " << b << ", i is " << i;
cout << ", f is " << f << endl;
cout << "The value of f**a is: " << pow(f, a) << endl;
cout << "The value of a**i is: " << pow(a, i) << endl;
cout << "The value of a**f is: " << pow(a, f) << endl;
cout << "The value of a**b is: " << pow(a, b) << endl;
}
This program produces the following output when you give it (1,1), (1,1),
(1,0), 1, and 1.0 as input:
Enter a complex value
The value of exp() for ( 1, 1) is: ( 1.46869, 2.28736)
The natural logarithm of ( 1, 1) is: ( 0.346574, 0.785398)
The square root of ( 1, 1) is: ( 1.09868, 0.45509)
Enter 2 complex values (a and b), an integer (i),
and a floating point value (f)
a is ( 1, 1), b is ( 1, 0), i is 1, f is 1
The value of f**a is: ( 1, 0)
The value of a**i is: ( 1, 1)
The value of a**f is: ( 1, 1)
The value of a**b is: ( 1, 1)
ΓòÉΓòÉΓòÉ 3.1.6. Trigonometric Functions for complex ΓòÉΓòÉΓòÉ
The following trigonometric functions are described:
o cos - Cosine
o cosh - Hyperbolic cosine
o sin - Sine
o sinh - Hyperbolic sine
There is also an example of using the complex trigonometric functions.
ΓòÉΓòÉΓòÉ 3.1.6.1. cos - Cosine ΓòÉΓòÉΓòÉ
Class: complex
friend complex cos(complex x);
cos() returns the cosine of x.
ΓòÉΓòÉΓòÉ 3.1.6.2. cosh - Hyperbolic Cosine ΓòÉΓòÉΓòÉ
Class: complex
friend complex cosh(complex x);
cosh() returns the hyperbolic cosine of x. Results of the Default
Error-Handling Procedures shows the values returned by the default
error-handling procedure for cosh().
ΓòÉΓòÉΓòÉ 3.1.6.3. sin - Sine ΓòÉΓòÉΓòÉ
Class: complex
friend complex sin(complex x);
sin() returns the sine of x.
ΓòÉΓòÉΓòÉ 3.1.6.4. sinh - Hyperbolic Sine ΓòÉΓòÉΓòÉ
Class: complex
friend complex sinh(complex x);
sinh() returns the hyperbolic sine of x. Results of the Default Error-Handling
Procedures shows the values returned by the default error-handling procedure
for sinh().
ΓòÉΓòÉΓòÉ 3.1.6.5. Example of Using the Complex Trigonometric Functions ΓòÉΓòÉΓòÉ
The following example shows how you can use the complex trigonometric
functions:
#include <complex.h>
void main() {
complex a = (M_PI, M_PI_2); // a = (pi,pi/2)
// display the values of cos(), cosh(), sin(), and sinh()
// for (pi,pi/2)
cout << "The value of cos() for (pi,pi/2) is: " << cos(a) << endl;
cout << "The value of cosh() for (pi,pi/2) is: " << cosh(a) << endl;
cout << "The value of sin() for (pi,pi/2) is: " << sin(a) << endl;
cout << "The value of sinh() for (pi,pi/2) is: " << sinh(a) << endl;
}
This program produces the following output:
The value of cos() for (pi,pi/2) is: ( 6.12323e-17, 0)
The value of cosh() for (pi,pi/2) is: ( 2.50918, 0)
The value of sin() for (pi,pi/2) is: ( 1, -0)
The value of sinh() for (pi,pi/2) is: ( 2.3013, 0)
ΓòÉΓòÉΓòÉ 3.1.7. Magnitude Functions for complex ΓòÉΓòÉΓòÉ
The following magnitude functions are described:
o abs - Absolute value
o norm - Square magnitude
ΓòÉΓòÉΓòÉ 3.1.7.1. abs - Absolute Value ΓòÉΓòÉΓòÉ
Class: complex
friend double abs(complex x);
abs() returns the absolute value or magnitude of its argument. The absolute
value of a complex value (a,b) is the positive square root of a¤+b¤.
ΓòÉΓòÉΓòÉ 3.1.7.2. norm - Square Magnitude ΓòÉΓòÉΓòÉ
Class: complex
friend double norm(complex x);
norm() returns the square of the magnitude of its argument. If the argument x
is equal to the complex number (a,b), norm() returns the value a¤+b¤. norm() is
faster than abs(), but it is more likely to cause overflow errors.
ΓòÉΓòÉΓòÉ 3.1.8. Conversion Functions for complex ΓòÉΓòÉΓòÉ
The conversion functions in the Complex Mathematics Library allow you to
convert between the polar and standard complex representations of a value and
to extract the real and imaginary parts of a complex value.
The following conversion functions are described:
o arg - Angle in radians
o conj - Conjugation
o polar - Polar to complex
o real - Extract real part
o imag - Extract imaginary part
There is also an example of using the complex conversion functions.
ΓòÉΓòÉΓòÉ 3.1.8.1. arg - Angle in Radians ΓòÉΓòÉΓòÉ
Class: complex
friend double arg(complex x);
arg() returns the angle (in radians) of the polar representation of its
argument. If the argument x is equal to the complex number (a,b), the angle
returned is the angle in radians on the complex plane between the real axis and
the vector (a,b). The return value has a range of -pi to pi . See for an
illustration of the polar representation of complex numbers.
ΓòÉΓòÉΓòÉ 3.1.8.2. conj - Conjugation ΓòÉΓòÉΓòÉ
Class: complex
friend complex conj(complex x);
conj() returns the complex value equal to (a,-b) if the input argument x is
equal to (a,b).
ΓòÉΓòÉΓòÉ 3.1.8.3. polar - Polar to Complex ΓòÉΓòÉΓòÉ
Class: complex
friend complex polar(double a, double b= 0);
polar() returns the standard complex representation of the complex number that
has a polar representation (a,b).
ΓòÉΓòÉΓòÉ 3.1.8.4. real - Extract Real Part ΓòÉΓòÉΓòÉ
Class: complex
friend double real(const complex& x);
real() extracts the real part of the complex number x.
ΓòÉΓòÉΓòÉ 3.1.8.5. imag - Extract Imaginary Part ΓòÉΓòÉΓòÉ
Class: complex
friend double imag(const complex& x);
imag() extracts the imaginary part of the complex number x.
ΓòÉΓòÉΓòÉ 3.1.8.6. Example of Using the Complex Conversion Functions ΓòÉΓòÉΓòÉ
The following program shows how you can use the complex conversion functions:
#include <complex.h>
void main() {
complex a;
// for a value supplied by the user, display the real part,
// the imaginary part, and the polar representation
cout << "enter a complex value" << endl;
cin >> a;
cout << "the real part of this value is " << real(a) << endl;
cout << "the imaginary part of this value is " << imag(a) << endl;
cout << "the polar representation of this value is "
<< "("<< abs(a)<< ","<< arg(a)<< ")"<< endl; }
This program produces the following output for an input of (1,1):
enter a complex value
the real part of this value is 1
the imaginary part of this value is 1
the polar representation of this value is (1.41421,0.785398)
ΓòÉΓòÉΓòÉ 3.1.9. Linking to the Complex Library ΓòÉΓòÉΓòÉ
You must specify the following library names when compiling or linking programs
that use the Complex Library:
o COMPLEX.LIB - for single-tasking programs
o COMPLEXM.LIB - for multitasking programs.
No dynamically linkable version of this library is provided.
ΓòÉΓòÉΓòÉ 3.2. c_exception Class ΓòÉΓòÉΓòÉ
This chapter describes c_exception, the class that lets you handle errors that
are created by the functions and operations in the complex class.
o Declarations for c_exception in the complex.h header file
o Constructor for c_exception
o Data members of c_exception
o Errors handled by the Complex Mathematics Library
o Errors handled outside of the Complex Mathematics Library
Note: The c_exception class is not related to the C++ exception handling
mechanism that uses the try, catch and throw statements.
ΓòÉΓòÉΓòÉ 3.2.1. Declarations for c_exception in complex.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses members of the
c_exception class:
#include <complex.h>
The following is an excerpt from the complex.h header file that shows the
relevant declarations for the members of c_exception:
#define DOMAIN 1
#define SING 2
#define OVERFLOW 3
#define UNDERFLOW 4
class c_exception {
int type;
char *name;
complex arg1;
complex arg2;
complex retval;
public:
c_exception( char *n, const complex& a1, const complex& a2 = complex_zero);
friend int complex_error( c_exception& );
friend complex exp( complex );
friend complex sinh( complex );
friend complex cosh( complex );
friend complex log( complex );
};
ΓòÉΓòÉΓòÉ 3.2.2. Constructor for c_exception ΓòÉΓòÉΓòÉ
c_exception(char *n, const complex& a1,
const complex& a2 = complex_zero);
The c_exception constructor creates a c_exception object with name member equal
to n, arg1 member equal to a1, and arg2 member equal to a2.
ΓòÉΓòÉΓòÉ 3.2.3. Data Members of c_exception ΓòÉΓòÉΓòÉ
The following data members are described:
o arg1, arg2 - Arguments of the function that caused the error
o name - Name of the function that caused the error
o retval - Value returned by the default definition of the error handling
function
o type - Type of error that has occurred
ΓòÉΓòÉΓòÉ 3.2.3.1. arg1, arg2 - Arguments of the Function that Caused the Error ΓòÉΓòÉΓòÉ
Class: c_exception
complex arg1;
complex arg2;
arg1 and arg2 are the arguments with which the function that caused the error
was called.
ΓòÉΓòÉΓòÉ 3.2.3.2. name - Name of the Function that Caused the Error ΓòÉΓòÉΓòÉ
Class: c_exception
char *name;
name is a string that contains the name of the function where the error
occurred.
ΓòÉΓòÉΓòÉ 3.2.3.3. retval - Value Returned by the Default Definition of the Error Handling Function ΓòÉΓòÉΓòÉ
Class: c_exception
complex retval;
retval is the value that the default definition of the error handling function
complex_error() returns. You can make your own definition of complex_error()
return a different value.
ΓòÉΓòÉΓòÉ 3.2.3.4. type - Type of Error that Has Occurred ΓòÉΓòÉΓòÉ
Class: c_exception
int type;
type describes the type of error that has occurred. It can take the following
values that are defined in the complex.h header file:
o SING argument singularity
o OVERFLOW overflow range error
o UNDERFLOW underflow range error
ΓòÉΓòÉΓòÉ 3.2.4. Errors Handled by the Complex Mathematics Library ΓòÉΓòÉΓòÉ
The following topics are described:
o complex_error - the error-handling function
o Results of the default error-handling procedures.
ΓòÉΓòÉΓòÉ 3.2.4.1. complex_error - the Error-Handling Function ΓòÉΓòÉΓòÉ
Class: c_exception
friend int complex_error(c_exception& ce);
complex_error() is invoked by member functions of the Complex Mathematics
Library when errors are detected. The argument ce refers to the c_exception
object that contains information about the error. You can define your own
procedures for handling errors by defining a function called complex_error with
return type int and a single parameter of type c_exception&.
If you define your own complex_error function and this function returns a
nonzero value, no error message will be generated and the external variable
errno will not be set. If this function returns zero, errno is given the value
of one of the following constants:
o ERANGE if the result is too large or too small
o EDOM if there is a domain error within a mathematical function.
These constants are defined in errno.h.
If you define your own version of complex_error, when you compile your program
you must:
o Ensure that the name of the source file or .OBJ that contains your version of
complex_error appears on the command line before complex.lib.
o Use the /NOE linker option
For example, if the source file containing your definition of complex_error is
source1.cpp, then you would invoke the compiler like this:
icc source1.cpp complex.lib /B"/NOE"
ΓòÉΓòÉΓòÉ 3.2.4.2. Results of the Default Error-Handling Procedures ΓòÉΓòÉΓòÉ
Class: c_exception
If you do not define your own complex_error, the default error-handling
procedures will be invoked when an error occurs. The results for a given input
complex value (a, b) depend on the kind of error and the sign of the cosine and
sine of b. The following table shows the return value of the default
error-handling procedure and the value given to errno for each function with
input equal to the complex value (a, b).
Note: The following symbols appear in this table:
1. NA - not applicable. The result of the error depends on the sign of the
cosine and sine of b (the imaginary part of the argument) unless "NA"
appears in the Cosine b or Sine b columns.
2. HUGE - the maximum double value. This value is defined in math.h.
Function Error Cosine b Sine b Return Value errno Value
cosh a too large nonneg. nonneg. (+HUGE,+HUGE) ERANGE
cosh a too large nonneg. nenneg. (+HUGE,-HUGE) ERANGE
cosh a too small nonneg. nonneg. (+HUGE,-HUGE) ERANGE
cosh a too small nonneg. nenneg. (+HUGE,+HUGE) ERANGE
cosh a too small negative nonneg. (-HUGE,-HUGE) ERANGE
cosh a too small negative nenneg. (-HUGE,+HUGE) ERANGE
cosh b too large negative nonneg. (-HUGE,+HUGE) ERANGE
cosh b too large negative nenneg. (-HUGE,-HUGE) ERANGE
cosh b too small NA NA (0,0) ERANGE
exp a too large positive positive (+HUGE,+HUGE) ERANGE
exp a too large positive positive (+HUGE,-HUGE) ERANGE
exp a too large nonpos. positive (-HUGE,+HUGE) ERANGE
exp a too large nonpos. positive (-HUGE,-HUGE) ERANGE
exp a too small NA NA (0,0) ERANGE
exp b too large NA NA (0,0) ERANGE
exp b too small NA NA (0,0) ERANGE
log a too large positive positive (+HUGE,0) EDOM
(a message is also produced)
sinh a too large nonneg. nonneg. (+HUGE,+HUGE) ERANGE
sinh a too large nonneg. negative (+HUGE,-HUGE) ERANGE
sinh a too large negative nonneg. (-HUGE,+HUGE) ERANGE
sinh a too large negative negative (-HUGE,-HUGE) ERANGE
sinh a too small nonneg. nonneg. (-HUGE,+HUGE) ERANGE
sinh a too small nonneg. negative (-HUGE,-HUGE) ERANGE
sinh a too small negative nonneg. (+HUGE,+HUGE) ERANGE
sinh a too small negative negative (+HUGE,-HUGE) ERANGE
sinh b too large NA NA (0,0) ERANGE
sinh b too small NA NA (0,0) ERANGE
Note: errno is set to EDOM when the error for log() is detected. The message
is stored in DDE4.MSG. The message number in DDE4.MSG is 90. When this message
is displayed by the C/C++ Runtime Library, it is changed to 5090. For
information on binding this message, see "Binding Runtime Messages" in the IBM
C/C++ Tools: Programming Guide.
ΓòÉΓòÉΓòÉ 3.2.5. Errors Handled Outside of the Complex Mathematics Library ΓòÉΓòÉΓòÉ
There are some cases where member functions of the Complex Mathematics Library
call functions in the math library. These calls can cause underflow and
overflow conditions that are handled by the matherr() function that is declared
in the math.h header file. For example, the overflow conditions that are caused
by the following calls are handled by matherr():
o exp(complex(MAXDOUBLE, MAXDOUBLE))
o pow(complex(MAXDOUBLE, MAXDOUBLE), INT_MAX)
o norm(complex(MAXDOUBLE, MAXDOUBLE))
MAXDOUBLE is the maximum valid double value. INT_MAX is the maximum int value.
Both these constants are defined in limits.h.
If you do not want the default error-handling defined by matherr(), you should
define your own version of matherr().
ΓòÉΓòÉΓòÉ 4. The I/O Stream Library ΓòÉΓòÉΓòÉ
Introduction to the I/O Stream Library
Introduces the I/O Stream Library, its classes and header files, and
describes stream buffers.
streambuf Protected Interface
Describes the protected members of the streambuf class. You can use these
members to create classes derived from streambuf.
streambuf Public Interface
Describes the public members of the streambuf class. You can use these
members to manipulate objects of filebuf, stdiobuf, or strstreambuf, the
predefined classes derived from streambuf.
ios Class
Describes ios, the base class for the classes that format data that comes
from the stream buffer.
istream and istream_withassign Class
Describes istream, the class that lets you extract data from a stream buffer,
and istream_withassign, a class derived from istream that includes an
assignment operator.
ostream and ostream_withassign Classes
Describes ostream, the class that lets you insert data into a stream buffer,
and ostream_withassign, a class derived from ostream that includes an
assignment operator.
iostream and iostream_withassign Classes
Describes iostream, the class derived from istream and ostream, and
iostream_withassign, the class derived from istream_withassign and
ostream_withassign.
filebuf Class
Describes filebuf, the class that specializes streambuf to use files.
fstream, ifstream, and ofstream Classes
Describes fstream, ifstream, and ofstream, the classes that adapt istream,
ostream, and iostream, respectively, to use files.
strstreambuf Class
Describes strstreambuf, the class that specializes streambuf to use an array
of bytes in memory as the source or target of data.
strstream, istrstream, and ostrstream Classes
Describes istrstream, ostrsteam, and strstream, the classes that adapt
istream, ostream, and iostream, respectively, to use an array of bytes in
memory as the source or target of data.
stdiobuf and stdiostream Classes
Describes stdiobuf, the class that lets you mix standard C input and output
functions with C++ I/O Stream Library functions.
Manipulators
Describes the parameterized manipulators that allow you to use the input or
output operator to change the state of a stream.
ΓòÉΓòÉΓòÉ 4.1. Introduction to the I/O Stream Library ΓòÉΓòÉΓòÉ
This chapter describes the overall structure of the I/O Stream Library. This
class library provides you with the facilities to deal with many varieties of
input and output.
The following topics are described in this chapter:
o Linking to the I/O Stream Library
o The I/O Stream Library and stdio.h in C
o Overview of the I/O Stream Library
o The I/O Stream Library class hierarchy
o The I/O Stream Library header files
o Predefined streams
o Anonymous streams
o Stream buffers
ΓòÉΓòÉΓòÉ 4.1.1. Linking to the I/O Stream Library ΓòÉΓòÉΓòÉ
The I/O Stream Library is part of the C/C++ libraries and is linked in
automatically unless you specify the /Gn option.
ΓòÉΓòÉΓòÉ 4.1.2. The I/O Stream Library and stdio.h ΓòÉΓòÉΓòÉ
In both C++ and C, input and output are described in terms of sequences of
characters, or streams. The I/O Stream Library provides the same facilities in
C++ that stdio.h provides in C, but it also has the following advantages over
stdio.h:
o The input or extraction (>>) operator and the output or insertion (<<)
operator are typesafe. They are also easy to use.
o You can define input and output for your own types or classes by overloading
the input and output operators. This gives you a uniform way of performing
input and output for different types of data.
o The input and output operators are more efficient than scanf() and printf(),
the analogous C functions defined in stdio.h. Both scanf() and printf() take
format strings as arguments, and these format strings have to be parsed at
run time. The bindings for the output and input operators are performed at
compile time.
ΓòÉΓòÉΓòÉ 4.1.3. Overview of the I/O Stream Library ΓòÉΓòÉΓòÉ
The I/O Stream Library is the standard input and output library for C++. In
C++, input and output are described in terms of sequences of characters, or
streams. The processing of these streams is done at two levels. The first level
treats the data as sequences of characters; the second level treats it as a
series of values of a particular type.
There are two primary base classes for the I/O Stream Library:
1. The streambuf class and the classes derived from it (strstream, stdiobuf,
and filebuf) implement the stream buffers. Stream buffers act as temporary
repositories for characters that are coming from the ultimate producers of
input or are being sent to the ultimate consumers of output. See Stream
Buffers for more details.
2. The ios class maintains formatting and error state information for these
streams. The classes derived from ios implement the formatting of these
streams. This formatting involves converting sequences of characters from
the stream buffer into values of a particular type and converting values of
a particular type into their external display format.
The I/O Stream Library predefines streams for standard input, standard output,
and standard error. See Predefined Streams for more details on the predefined
streams. If you want to open your own streams for input or output, you must
create an iostream object. The iostream constructor takes as an argument a
pointer to a streambuf object. This object is associated with the device, file,
or array of bytes in memory that is going to be the ultimate producer of input
or the ultimate consumer of output.
ΓòÉΓòÉΓòÉ 4.1.3.1. Combining Input and Output of Different Types ΓòÉΓòÉΓòÉ
The I/O Stream Library overloads the input (>>) and output (<<) operators for
the built-in types. As a result, you can combine input or output of values with
different types in a single statement without having to state the type of the
values. The following example shows how values with a variety of types can be
combined in a single output statement:
#include <iostream.h>
void main(){
int i = 3;
long l = 88888888L;
double d = 3.14;
float f = 2.1F;
char c = 'b';
cout << "A variety of values: int " << i
<< ", long " << l << ", double "<< d << ",\n"
<< "float " << f << ", char " << c<< "." << endl;
}
This example produces the following output:
A variety of values: int 3, long 88888888, double 3.14,
float 2.1, char b.
ΓòÉΓòÉΓòÉ 4.1.3.2. Input and Output for User-Defined Classes ΓòÉΓòÉΓòÉ
You can overload the input and output operators for the classes that you create
yourself. Once you have overloaded the input and output operators for a class,
you can perform input and output operations on objects of that class in the
same way that you would perform input and output on char, int, double, and the
other built-in types.
The following example shows how you can overload the input and output operators
for your own classes. The class circle has two private members that record the
center and radius of a circle. In the example, the value of a circle object is
printed using the overloaded output operator. The user is then prompted to
supply values that are assigned to another circle object. The value of this
circle object is then printed.
#include <iostream.h>
class Circle {
public:
Circle(double c=0.0, double r=0.0): center(c), radius(r){}
private:
double center;
double radius;
friend ostream& operator<<(ostream& o, const Circle& c);
friend istream& operator>>(istream& i, Circle& c);
};
ostream& operator<<(ostream& o, const Circle& c)
{
o << c.center << " " << c.radius << endl;
return o;
}
istream& operator>>(istream& i, Circle& c)
{
i >> c.center >> c.radius;
return i;
}
void main()
{
Circle c(1.5, 3.0);
Circle d;
cout << "Circle c " << c << endl;
cout << "Enter the center and radius of yourcircle: " << endl;
cin >> d;
cout << "Here is your circle " << d << endl;
}
If you supply the values 3.0, 5.6 to this program, the following output is
produced:
Circle c 1.5 3
Enter the center and radius of your circle:
Here is your circle 3 5.6
ΓòÉΓòÉΓòÉ 4.1.4. The I/O Stream Library Class Hierarchy ΓòÉΓòÉΓòÉ
The I/O Stream Library has two base classes that correspond to the two levels
of processing described in "Overview of the Stream Library":
o The streambuf class implements stream buffers (see Stream Buffers). It is
the base class for the following classes:
- strstreambuf
- stdiobuf
- filebuf
o The ios class maintains formatting and error state information for streams.
Streams are implemented as objects of the following classes that are derived
from ios:
- stdiostream
- istream
- ostream
The classes that are derived from ios are themselves base classes:
o istream is the input stream class. It implements stream buffer input, or
input operations. The following classes are derived from istream:
- istrstream
- ifstream
- istream_withassign
- iostream
o ostream is the output stream class. It implements stream buffer output, or
output operations. The following classes are derived from ostream:
- ostrsteam
- ofstream
- ostream_withassign
- iostream
o iostream is the class that combines istream and ostream to implement input
and output to stream buffers. The following classes are derived from
iostream:
- strstream
- iostream_withassign
- fstream
Note: The I/O Stream Library defines other classes in addition to those listed
above. These classes include fstreambase and strstreambase. These classes are
meant for the internal use of the I/O Stream Library. They are described in
this book because their member functions are used directly by one or more of
the classes listed above. You should not use these internal classes directly.
Derivation Relationships in the I/O Stream Library shows the relationship
between the two base classes, ios and streambuf, and their derived classes. In
the figure, two classes are connected by an arrow if the class at the pointed
end of the arrow is derived from the class at the other end of the arrow.
ios
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿΓöéΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
istream stdiostream ostream
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ Γöé Γöé ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ Γöé Γöé ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Γöé ΓööΓöÇΓöÇΓöÇΓöÉ Γöé Γöé ΓöîΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇΓöÉ Γöé
istream_ Γöé ifstream Γöé Γöé ostream_ Γöé ofstream
withassign Γöé Γöé Γöé withassign Γöé
istrstream Γöé Γöé ostrstream
iostream
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿΓöéΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
iostream_ strstream fstream
withassign
streambuf
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿΓöéΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
strstreambuf stdiobuf filebuf
Derivation Relationships in the I/O Stream Library
ΓòÉΓòÉΓòÉ 4.1.5. The I/O Stream Library Header Files ΓòÉΓòÉΓòÉ
To use a class in the I/O Stream Library, you must include the appropriate
header files for that class. The following is a list of the I/O Stream Library
header files and the classes that they cover:
o iostream.h contains declarations for the basic classes of the library:
- streambuf
- ios
- istream
- istream_withassign
- ostream
- ostream_withassign
- iostream
- iostream_withassign
o fstream.h contains declarations for the classes that deal with files:
- filebuf
- ifstream
- ofstream
- fstream
o stdiostr.h contains declarations for stdiobuf and stdiostream, the classes
that specialize streambuf and ios, respectively, to use the FILE structures
defined in the C header file stdio.h.
o strstrea.h contains declarations for the classes that deal with character
strings. The first "str" in each of these names stands for "string":
- istrstream
- ostrsteam
- strstream
- strstreambuf
o iomanip.h contains declarations for the parameterized manipulators.
Manipulators are values that you can insert into streams or extract from
streams to affect or query the behavior of the streams.
o stream.h is used for compatibility with earlier versions of the I/O Stream
Library. It includes iostream.h, fstream.h, stdiostr.h, and iomanip.h, along
with some definitions needed for compatibility with the AT&T** C++ Language
System Release 1.2. Only use this header file with existing code; do not use
it with new C++ code.
Note: If you use the obsolete function form() declared in stream.h, there is
a limit to the size of the format specifier. If you call form() with a
format specifier string longer than this limit, a runtime message (EDC5091)
will be generated and the program will terminate.
ΓòÉΓòÉΓòÉ 4.1.6. Predefined Streams ΓòÉΓòÉΓòÉ
In addition to giving you the facilities to define your own streams for input
and output, the I/O Stream Library also provides the following predefined
streams:
o cin is the standard input stream.
o cout is the standard output stream.
o cerr is the standard error stream. Output to this stream is unit-buffered.
Characters that are sent to this stream are flushed after each output
operation.
o clog is also an error stream, but unlike the output to cerr, the output to
clog is buffered.
The predefined streams are initialized before the constructors for any static
objects are called. You can use the predefined streams in the constructors for
static objects.
The predefined streams cin, cerr, and clog are tied to cout. As a result, if
you use cin, cerr, or clog, cout is flushed. That is, the contents of cout are
sent to their ultimate consumer.
ΓòÉΓòÉΓòÉ 4.1.7. Anonymous Streams ΓòÉΓòÉΓòÉ
An anonymous stream is a stream that is created as a temporary object. Because
it is a temporary object, an anonymous stream requires a const type modifier
and is not a modifiable lvalue. Unlike the AT&T** C++ Language System Release
2.1., the C/C++ Tools does not allow a non-const reference argument to be
matched with a temporary object. User-defined input and output operators
usually accept a non-const reference (such as a reference to an istream or
ostream object) as an argument. Such an argument cannot be initialized by an
anonymous stream, and thus an attempt to use an anonymous stream as an argument
to a user-defined input or output operator will usually result in a
compile-time error.
In the following example, an object of the class Circle (defined in Input and
Output for User-Defined Classes) is declared, and the value of an anonymous
stream is assigned to it using the input operator. The following statement:
Circle c;
istrstream("10 15") >> c;
causes the following compile-time error:
CIRCLE.C(32:1) : error EDC3070: Call does not match any argument list for
"istream::operator>>".
ΓòÉΓòÉΓòÉ 4.1.8. Stream Buffers ΓòÉΓòÉΓòÉ
One of the most important concepts in the I/O Stream Library is the stream
buffer. The streambuf class implements some of the member functions that define
stream buffers, but other specialized member functions are left to the classes
that are derived from streambuf: strstreambuf, stdiobuf, and filebuf.
Note: The AT&T** and UNIX** System Laboratories C++ Language System
documentation use the terms reserve area and buffer instead of stream buffer.
ΓòÉΓòÉΓòÉ 4.1.8.1. What Does a Stream Buffer Do? ΓòÉΓòÉΓòÉ
A stream buffer acts as a buffer between the ultimate producer (the source of
data) or ultimate consumer (the target of data) and the member functions of the
classes derived from ios that format this raw data. The ultimate producer can
be a file, a device, or an array of bytes in memory. The ultimate consumer can
also be a file, a device, or an array of bytes in memory.
ΓòÉΓòÉΓòÉ 4.1.8.2. Why Use a Stream Buffer? ΓòÉΓòÉΓòÉ
In most operating systems, a system call to read data from the ultimate
producer or write it to the ultimate consumer is an expensive operation. If
your applications can reduce the number of system calls they have to make, they
will usually be more efficient. By acting as a buffer between the ultimate
producer or ultimate consumer and the formatting functions, a stream buffer can
reduce the number of system calls that are made.
Consider, for example, an application that is reading data from the ultimate
producer. If there is no buffer, the application has to make a system call for
each character that is read. However, if the application uses a stream buffer,
system calls will only be made when the buffer is empty. Each system call will
read enough characters from the ultimate producer (if they are available) to
fill the buffer again.
ΓòÉΓòÉΓòÉ 4.1.8.3. How Is a Stream Buffer Implemented? ΓòÉΓòÉΓòÉ
A stream buffer is implemented as an array of bytes. For each stream buffer,
pointers are defined that point to elements in this array to define the get
area, or the space that is available to accept bytes from the ultimate
producer, and the put area, or the space that is available to store bytes that
are on their way to the ultimate consumer.
A stream buffer does not necessarily have separate get and put areas. A stream
buffer that is used for input, such as one that is attached to an istream
object, has a get area. A stream buffer that is used for output, such as one
that is attached to an ostream object, has a put area. A stream buffer that is
used for both input and output, such as one that is attached to an iostream
object, has both a get area and a put area. In stream buffers implemented by
the filebuf class that are specialized to use files as an ultimate producer or
ultimate consumer, the get and put areas overlap.
The following member functions of the streambuf class return pointers to
boundaries of areas in a stream buffer:
o base() returns a pointer to the beginning of the stream buffer.
o eback() returns a pointer to the beginning of the space available for
putback. Characters that are putback are returned to the get area of the
stream buffer.
o gptr() returns the get pointer, a pointer to the beginning of the get area.
The space between gptr() and egptr() has been filled by the ultimate
producer. These characters are waiting to be extracted from the stream
buffer. The space between eback() and gptr() is available for putback.
o egptr() returns a pointer to the end of the get area.
o pbase() returns a pointer to the beginning of the space available for the put
area.
o pptr() returns the put pointer, a pointer to the beginning of the put area.
The space between pbase() and pptr() is filled with bytes that are waiting to
be sent to the ultimate consumer. The space between pptr() and epptr() is
available to accept characters from the application program that are on their
way to the ultimate consumer.
o epptr() returns a pointer to the end of the put area.
o ebuf() returns a pointer to the end of the stream buffer.
Note: In the actual implementation of stream buffers, the pointers returned by
these functions point at char values. In the abstract concept of stream
buffers, on the other hand, these pointers point to the boundary between char
values. To establish a correspondence between the abstract concept and the
actual implementation, you should think of the pointers as pointing just before
the character that they actually point at.
The Structure of Stream Buffers shows how the pointers returned by these
functions delineate the stream buffer.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöÇΓöÇΓöÇΓöÇbase()
Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Γöé ΓöÇΓöÇΓöÇΓöÇ Γöé
Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöÇΓöÇΓöÇΓöÇeback()
Γöé ΓöîΓöÇΓöÇ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöÇΓöÇΓöÇΓöÇgptr()
Γöé Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé get area Γöñ Γöé ΓöÇΓöÇΓöÇΓöÇ Γöé ΓöÇULTIMATE PRODUCER
Γöé Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ΓööΓöÇΓöÇ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöÇΓöÇΓöÇΓöÇegptr()
stream Γöñ Γöé ΓöÇΓöÇΓöÇΓöÇ Γöé
buffer Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöÇΓöÇΓöÇΓöÇpbase()
Γöé ΓöîΓöÇΓöÇ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöÇΓöÇΓöÇΓöÇpptr()
Γöé Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé put area Γöñ Γöé ΓöÇΓöÇΓöÇΓöÇ Γöé ΓöÇULTIMATE CONSUMER
Γöé Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ΓööΓöÇΓöÇ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓöÇΓöÇΓöÇΓöÇepptr()
Γöé Γöé ΓöÇΓöÇΓöÇΓöÇ Γöé
Γöé Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓöÇΓöÇΓöÇΓöÇebuf()
The Structure of Stream Buffers
ΓòÉΓòÉΓòÉ 4.2. streambuf Protected Interface ΓòÉΓòÉΓòÉ
This chapter describes the protected interface of the streambuf class. The
protected interface consists of the member functions of streambuf that you need
to use to derive your own classes from streambuf. See What Is the streambuf
Protected Interface? for more details.
The streambuf class implements the concept of stream buffers. A stream buffer
acts as a buffer between the ultimate producer or ultimate consumer of data and
the member functions of the classes derived from ios (such as istream and
ostream) that format this data. See Stream Buffers for a more detailed
description of stream buffers.
The following topics are described in this chapter:
o What is the streambuf protected interface?
o Declarations for the streambuf protected interface in iostream.h
o Examining pointers in the protected interface
o Setting pointers in the protected interface
o Other nonvirtual members
o Virtual member functions
ΓòÉΓòÉΓòÉ 4.2.1. What Is the streambuf Protected Interface? ΓòÉΓòÉΓòÉ
Although streambuf is not defined as a virtual base class, you can think of it
as one. You should not create objects of the streambuf class itself, but you
can use it in the following ways:
o As a base class to implement your own specialized stream buffers. In this
sense you can think of streambuf as a virtual base class. The streambuf class
only provides the basic functions needed to manipulate characters in a stream
buffer. The filebuf, strstreambuf, and stdiobuf classes contain functions
that handle the interface with the standard ultimate consumers and producers.
If you want to perform more sophisticated operations, or if you want to use
other ultimate consumers and ultimate producers, you will have to create your
own class derived from streambuf. This chapter describes the members of the
streambuf class that you need to know about if you want to create a class
derived from streambuf. Collectively, these members are called the protected
interface of the streambuf class.
o Through a predefined class derived from streambuf. This use of the streambuf
class is described in streambuf Public Interface.
There are two kinds of functions in the protected interface described in this
chapter:
o Nonvirtual member functions, which manipulate streambuf objects at a level of
detail that would be inappropriate in the public interface.
o Virtual member functions, which permit classes that you derive from streambuf
to customize their operations depending on the ultimate producer or ultimate
consumer. When you define the virtual functions in your derived classes, you
must ensure that these definitions fulfill the conditions stated in the
descriptions of the virtual functions. If your definitions of the virtual
functions do not fulfill these conditions, objects of the derived class may
have unspecified behavior. Although most virtual functions are declared as
public members, they are described with the protected interface (with the
exception of the destructor for the streambuf class) because they are meant
to be overridden in the classes that you derive from streambuf.
ΓòÉΓòÉΓòÉ 4.2.2. Declarations for the streambuf Protected Interface in iostream.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses the streambuf
protected interface:
#include <iostream.h>
The following is an excerpt from the iostream.h header file that shows the
relevant declarations for the protected interface of streambuf. Note that this
excerpt only shows the declarations in the streambuf class that are relevant to
the protected interface. The declarations for the public interface are listed
in Declarations for the streambuf Public Interface in iostream.h.
class ios {
public:
enum io_state { goodbit, eofbit, failbit, badbit,
hardfail};
enum open_mode { in, out, ate, app, trunc,
nocreate, noreplace, bin, binary=bin} ;
enum seek_dir { beg, cur, end } ;
// .
// .
// .
};
class streambuf {
public:
void dbp();
virtual int overflow(int c = EOF);
virtual int underflow();
virtual int pbackfail(int c);
virtual int sync();
virtual streambuf* setbuf(char* p, int len);
streambuf* setbuf(unsigned char* p, int len);
streambuf* setbuf(char* p, int len, int count);
virtual streampos seekoff(streamoff, seek_dir,
int=ios::in|ios::out);
virtual streampos seekpos(streampos,
int = ios::in|ios::out);
virtual int xsgetn(char* s, int n);
virtual int xsputn(const char* s, int n);
protected:
char* base();
char* pbase();
char* pptr();
char* epptr();
char* gptr();
char* egptr();
char* eback();
char* ebuf();
int blen() const;
void setp(char* p, char* ep);
void setg(char* eb,char* g, char* eg);
void pbump(int n);
void gbump(int n);
void setb(char* b, char* eb, int a = 0 );
int unbuffered() const;
void unbuffered(int unb);
int allocate();
virtual int doallocate();
};
Note: xsgetn() and xsputn() are for the internal use of the I/O Stream
Library. They are declared in iostream.h and listed above, but you should not
use them directly.
ΓòÉΓòÉΓòÉ 4.2.3. Functions That Return Pointers in the Protected Interface ΓòÉΓòÉΓòÉ
This section describes the functions in the protected interface of streambuf
that return pointers to boundaries of areas in a stream buffer.
Note: The following descriptions assume that the functions are called as part
of an object called dsb which is an object of a class that is derived from
streambuf.
The following functions are described:
o base - Return pointer to beginning of stream buffer
o eback - Return pointer to beginning of putback area
o ebuf - Return pointer to end of stream buffer
o egptr - Return pointer to end of get area
o epptr - Return pointer to end of put area
o gptr - Return pointer to beginning of get area
o pbase - Return pointer to beginning of space available for put area
o pptr - Return pointer to beginning of put area
ΓòÉΓòÉΓòÉ 4.2.3.1. base - Return Pointer to Beginning of Stream Buffer ΓòÉΓòÉΓòÉ
Class: streambuf (protected interface)
char* base();
base() returns a pointer to the first byte of the stream buffer. The stream
buffer consists of the space between the pointer returned by base() and the
pointer returned by ebuf().
ΓòÉΓòÉΓòÉ 4.2.3.2. eback - Return Pointer to Beginning of Putback Area ΓòÉΓòÉΓòÉ
Class: streambuf (protected interface)
char* eback();
eback() returns a pointer to the lower bound of the space available for the get
area of dsb. The space between the pointer returned by eback() and the pointer
returned by gptr() is available for putback.
ΓòÉΓòÉΓòÉ 4.2.3.3. ebuf - Return Pointer to End of Stream Buffer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
char* ebuf();
ebuf() returns a pointer to the byte after the last byte of the stream buffer.
ΓòÉΓòÉΓòÉ 4.2.3.4. egptr - Return Pointer to End of Get Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
char* egptr();
egptr() returns a pointer to the byte after the last byte of the get area of
dsb.
ΓòÉΓòÉΓòÉ 4.2.3.5. epptr - Return Pointer to End of Put Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
char* epptr();
epptr() returns a pointer to the byte after the last byte of the put area of
dsb.
ΓòÉΓòÉΓòÉ 4.2.3.6. gptr - Return Pointer to Beginning of Get Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
char* gptr();
gptr() returns a pointer to the first byte of the get area of dsb. The get area
consists of the space between the pointer returned by gptr() and the pointer
returned by egptr(). Characters are extracted from the stream buffer beginning
at the character pointed to by gptr().
ΓòÉΓòÉΓòÉ 4.2.3.7. pbase - Return Pointer to Beginning of Space Available for Put Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
char* pbase();
pbase() returns a pointer to the beginning of the space available for the put
area of dsb. Characters between the pointer returned by pbase() and the pointer
returned by pptr() have been stored in the stream buffer, but they have not
been consumed by the ultimate consumer.
ΓòÉΓòÉΓòÉ 4.2.3.8. pptr - Return Pointer to Beginning of Put Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
char* pptr();
pptr() returns a pointer to the beginning of the put area of dsb. The put area
consists of the space between the pointer returned by pptr() and the pointer
returned by epptr().
ΓòÉΓòÉΓòÉ 4.2.4. Functions That Set Pointers in the Protected Interface ΓòÉΓòÉΓòÉ
This section describes the functions in the protected interface of streambuf
that set the boundaries of areas in a stream buffer. The values of these
boundaries are returned by the functions described in Functions That Return
Pointers in the Protected Interface.
Note: The following descriptions assume that the functions are called as part
of an object called dsb which is an object of a class that is derived from
streambuf.
The following functions are described:
o setb - Set boundaries of stream buffer
o setp - Set boundaries of put area
o setg - Set boundaries of get area
ΓòÉΓòÉΓòÉ 4.2.4.1. setb - Set Boundaries of Stream Buffer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
void setb(char* startbuf, char* endbuf, int delbuf = 0);
setb() sets the beginning of the stream buffer (the pointer returned by
dsb.pbase()) to the position pointed to by startbuf, and sets the end of the
stream buffer (the pointer returned by dsb.ebuf()) to the position pointed to
by endbuf. If delbuf is a nonzero value, the stream buffer will be deleted when
setb() is called again. If startbuf and endbuf are both equal to 0, no stream
buffer is established. If startbuf is not equal to 0, a stream buffer is
established, even if endbuf is less than startbuf. If this is the case, the
stream buffer has length zero.
ΓòÉΓòÉΓòÉ 4.2.4.2. setp - Set Boundaries of Put Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
void setp(char* startput, char* endput);
setp() sets the beginning of the put area of dsb (the pointer returned by
dsb.pptr()) to the position pointed to by startput, and sets the end of the put
area (the pointer returned by dsb.epptr()) to the position pointed to by
endput.
ΓòÉΓòÉΓòÉ 4.2.4.3. setg - Set Boundaries of Get Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
void setg(char* startput, char* startget, char* endget);
setg() sets the beginning of the get area of dsb (the pointer returned by
dsb.gptr()) to startget, and sets the end of the get area (the pointer returned
by dsb.egptr()) to endget. setg() also sets the beginning of the area available
for putback (the pointer returned by dsb.eback()) to startput.
ΓòÉΓòÉΓòÉ 4.2.5. Other NonVirtual Member Functions in the Protected Interface ΓòÉΓòÉΓòÉ
This section describes the remaining nonvirtual member functions that make up
the protected interface of streambuf.
Note: The following descriptions assume that the functions are called as part
of an object called dsb which is an object of a class that is derived from
streambuf.
The following functions are described:
o allocate - Set up a stream buffer
o blen - Return length of stream buffer
o dbp - Record stream buffer status
o gbump - Move beginning of get area
o pbump - Move beginning of put area
o unbuffered - Buffering state
ΓòÉΓòÉΓòÉ 4.2.5.1. allocate - Set Up a Stream Buffer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
int allocate();
allocate() attempts to set up a stream buffer. allocate() returns the following
values:
o 0 if dsb already has a stream buffer set up (that is, dsb->base() returns a
nonzero value), or if unbuffered() returns a nonzero value. allocate() does
not do any further processing if it returns 0.
o 1 if allocate() does set up a stream buffer.
o EOF if the attempt to allocate space for the stream buffer fails.
allocate() is not called by any other nonvirtual member function of streambuf.
ΓòÉΓòÉΓòÉ 4.2.5.2. blen - Return Length of Stream Buffer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
int blen() const;
blen() returns the length (in bytes) of the stream buffer.
ΓòÉΓòÉΓòÉ 4.2.5.3. dbp - Record Stream Buffer Status ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
void dbp();
dbp() writes to standard output the values returned by the following functions:
o base()
o eback()
o ebuf()
o egptr()
o epptr()
o gptr()
o pptr()
dbp() is intended for debugging. streambuf does not specify anything about the
form of the output. dbp() is considered part of the protected interface because
the information that it prints can only be understood in relation to that
interface. It is declared as a public function so that it can be called
anywhere during debugging.
The following example shows the output produced by dbp() when it is called as
part of a filebuf object:
#include <iostream.h>
void main()
{
cout << "Here is some sample output." << endl;
cout.rdbuf()->dbp();
}
If you compile and run this example, your output will look like this:
Here is some sample output.
buf at 0x90210, base=0x91010, ebuf=0x91410,
pptr=0x91010, epptr=0x91410, eback=0, gptr=0, egptr=0
ΓòÉΓòÉΓòÉ 4.2.5.4. gbump - Move Beginning of Get Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
void gbump(int offset);
gbump() offsets the beginning of the get area by the value of offset. The value
of offset can be positive or negative. gbump() does not check to see if the new
value returned by gptr() is valid.
The beginning of the get area is equal to the value returned by gptr().
ΓòÉΓòÉΓòÉ 4.2.5.5. pbump - Move Beginning of Put Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
void pbump(int offset);
pbump() offsets the beginning of the put area by the value of offset. The value
of offset can be positive or negative. pbump() does not check to see if the new
value returned by pptr() is valid.
The beginning of the put area is equal to the value returned by pptr().
ΓòÉΓòÉΓòÉ 4.2.5.6. unbuffered - Buffering State ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
int unbuffered() const;
void unbuffered(int buffstate);
unbuffered() manipulates the private streambuf variable called the buffering
state. If the buffering state is nonzero, a call to allocate() does not set up
a stream buffer.
There are two versions of unbuffered(). The version of unbuffered() that takes
no arguments returns the current value of the buffering state. The version that
takes an argument, buffstate, changes the value of the buffering state to
buffstate.
ΓòÉΓòÉΓòÉ 4.2.6. Virtual Member Functions in the Protected Interface ΓòÉΓòÉΓòÉ
This section describes the virtual functions in the protected interface of
streambuf. Although these virtual functions have default definitions in
streambuf, they can be overridden in classes that are derived from streambuf.
The following descriptions state the default definition of each function and
the expected behavior for these functions in classes where they are overridden.
Note: The following descriptions assume that the functions are called as part
of an object called dsb, which is an object of a class that is derived from
streambuf.
The following functions are described:
o doallocate - Allocate space for a stream buffer
o overflow - Clear put area
o pbackfail - Deal with full putback area
o seekoff - Reposition external get or put pointer
o seekpos - Reposition external get or put pointer
o setbuf - Set up stream buffer
o sync - Synchronize stream buffer and ultimate producer or ultimate consumer
o underflow - Fill get area.
ΓòÉΓòÉΓòÉ 4.2.6.1. doallocate - Allocate Space for a Stream Buffer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
virtual int doallocate();
doallocate() is called when allocate() determines that space is needed for a
stream buffer.
The default definition of doallocate() attempts to allocate space for a stream
buffer using the operator new.
If you define your own version of doallocate(), it must call setb() to provide
space for a stream buffer or return EOF if it cannot allocate space.
doallocate() should only be called if unbuffered() and base() return zero.
ΓòÉΓòÉΓòÉ 4.2.6.2. overflow - Clear Put Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
virtual int overflow(int c = EOF);
overflow() is called when the put area is full, and an attempt is made to store
another character in it. overflow() may be called at other times.
The default definition of overflow() is compatible with the AT&T C++ Language
System Release 1.2 version of the stream package, but it is not considered part
of the current I/O Stream Library. Thus, the default definition of overflow()
should not be used, and every class derived from streambuf should define
overflow() itself.
The definition of overflow() in your classes derived from streambuf should
cause the ultimate consumer to consume the characters in the put area, call
setp() to establish a new put area, and store the argument c in the put area if
c does not equal EOF. overflow() should return EOF if an error occurs, and it
should return a value not equal to EOF otherwise.
ΓòÉΓòÉΓòÉ 4.2.6.3. pbackfail - Deal With Full Putback Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
virtual int pbackfail(int c);
pbackfail() is called when both of the following conditions are true:
o An attempt has been made to put back a character.
o There is no room in the putback area. The pointer returned by eback() equals
the pointer returned by gptr().
The default definition of pbackfail() returns EOF.
If you define pbackfail() in your own classes, your definition of pbackfail()
should attempt to deal with the full putback area by, for instance,
repositioning the get pointer of the ultimate producer. If this is possible,
pbackfail() should return the argument c. If not, pbackfail() should return
EOF.
ΓòÉΓòÉΓòÉ 4.2.6.4. seekoff - Reposition External Get or Put Pointer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
virtual streampos seekoff(streamoff so, seek_dir dir,
int mode = ios::in|ios::out);
seekoff() repositions the get or put pointer of the ultimate producer or
ultimate consumer. seekoff() does not change the values returned by dsb.gptr()
or dsb.pptr().
The default definition of seekoff() returns EOF.
If you define your own seekoff() function, it should return EOF if the derived
class does not support repositioning. If the class does support repositioning,
seekoff() should return the new position of the affected pointer, or EOF if an
error occurs. so is an offset from a position in the ultimate producer or
ultimate consumer. dir is a position in the ultimate producer or ultimate
consumer. dir can have the following values:
o ios::beg: the beginning of the ultimate producer or ultimate consumer
o ios::cur: the current position in the ultimate producer or ultimate consumer
o ios::end: the end of the ultimate producer or ultimate consumer.
The new position of the affected pointer is the position specified by dir
offset by the value of so. If you derive your own classes from streambuf,
certain values of dir may not be valid depending on the nature of the ultimate
consumer or producer.
If ios::in is set in mode, the seekoff() should modify the get pointer. If
ios::out is set in mode, the put pointer should be modified. If both ios::in
and ios::out are set, both the get pointer and the put pointer should be
modified.
ΓòÉΓòÉΓòÉ 4.2.6.5. seekpos - Reposition External Get or Put Pointer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
virtual streampos seekpos(streampos pos,
int mode = ios::in|ios::out);
seekpos() repositions the get or put pointer of the ultimate producer or
ultimate consumer to the position pos. If ios::in is set in mode, the get
pointer is repositioned. If ios::out is set in mode, the put pointer is
repositioned. If both ios::in and ios::out are set, both the get pointer and
the put pointer are affected. seekpos() does not change the values returned by
dsb.gptr() or dsb.pptr().
The default definition of seekpos() returns the return value of the function
seekoff(streamoff(pos), ios::beg, mode). Thus, if you want to define seeking
operations in a class derived from streambuf, you can define seekoff() and use
the default definition of seekpos().
If you define seekpos() in a class derived from streambuf, seekpos() should
return EOF if the class does not support repositioning or if pos points to a
position equal to or greater than the end of the stream. If not, seekpos()
should return pos.
ΓòÉΓòÉΓòÉ 4.2.6.6. setbuf - Set Up Stream Buffer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
virtual streambuf* setbuf(char* ptr, int len);
streambuf* setbuf(unsigned char* ptr, int len);
streambuf* setbuf(char* ptr, int len, int count);
There are three versions of setbuf(). The two versions that take two arguments
set up a stream buffer consisting of the array of bytes starting at ptr with
length len. The version of setbuf() that takes three arguments is obsolete. The
I/O Stream Library includes it to be compatible with AT&T C++ Language System
Release 1.2.
The default definition of setbuf() sets up the stream buffer if the streambuf
object does not already have a stream buffer.
If you define setbuf() in a class derived from streambuf, setbuf() can either
accept or ignore a request for an unbuffered streambuf object. The call to
setbuf() is a request for an unbuffered streambuf object if ptr equals 0 or len
equals 0. setbuf() should return a pointer to sb if it accepts the request, and
0 otherwise.
ΓòÉΓòÉΓòÉ 4.2.6.7. sync - Synchronize Stream Buffer and Ultimate Producer or Ultimate Consumer ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
virtual int sync();
sync() synchronizes the stream buffer with the ultimate producer or the
ultimate consumer.
The default definition of sync() returns 0 if either of the following
conditions is true:
o The get area is empty and there are no characters waiting to go to the
ultimate consumer
o No stream buffer has been allocated for sb.
Otherwise, sync() returns EOF.
If you define sync() in a class derived from streambuf, it should send any
characters that are stored in the put area to the ultimate consumer, and (if
possible) send any characters that are waiting in the get area back to the
ultimate producer. When sync() returns, both the put area and the get area
should be empty. sync() should return EOF if an error occurs.
ΓòÉΓòÉΓòÉ 4.2.6.8. underflow - Fill Get Area ΓòÉΓòÉΓòÉ
Class: streambuf (Protected interface)
virtual int underflow();
underflow() takes characters from the ultimate producer and puts them in the
get area.
The default definition of underflow() is compatible with the AT&T C++ Language
System Release 1.2 version version of the stream package, but it is not
considered part of the current I/O Stream Library. Thus, the default definition
of underflow() should not be used, and every class derived from streambuf
should define underflow() itself.
If you define underflow() in a class derived from streambuf, it should return
the first character in the get area if the get area is not empty. If the get
area is empty, underflow() should create a get area that is not empty and
return the next character. If no more characters are available in the ultimate
producer, underflow() should return EOF and leave the get area empty.
ΓòÉΓòÉΓòÉ 4.3. streambuf Public Interface ΓòÉΓòÉΓòÉ
This chapter describes the public interface of the streambuf class. The public
interface consists of the public member functions of streambuf that give you
direct access to the predefined classes that are derived from streambuf.
The streambuf class implements the concept of stream buffers. A stream buffer
acts as a buffer between the source or target of data and the member functions
of the classes derived from ios (such as istream and ostream) that format this
data. See Stream Buffers for a more detailed description of stream buffers.
The following topics are described in this chapter:
o What Is the streambuf Public Interface
o Declarations for the streambuf public interface in iostream.h
o Public members of the streambuf public interface
ΓòÉΓòÉΓòÉ 4.3.1. What Is the streambuf Public Interface? ΓòÉΓòÉΓòÉ
Although streambuf is not defined as a virtual base class, you can think of it
as one. You should not create objects of the streambuf class itself, but you
can use it in the following ways:
o Through a predefined class derived from streambuf. You can use objects of
filebuf, strstreambuf and stdiobuf (the predefined classes that are derived
from streambuf) directly as implementations of stream buffers. The public
interface consists of the streambuf public member functions that can be
called on objects of these predefined classes. This chapter describes the
members of the streambuf class that you need to know about if you want to use
the predefined classes derived from streambuf to implement stream buffers
directly. streambuf itself does not have any facilities for taking characters
from the ultimate producer or sending them to the ultimate consumer. The
specialized member functions that handle the interface with the ultimate
producer and the ultimate consumer are defined in the filebuf, strstreambuf,
and stdiobuf classes.
o As a base class to implement your own specialized stream buffers. This use of
the streambuf class is described in streambuf Protected Interface.
o Through a predefined class derived from streambuf. You can use objects of
filebuf strstreambuf, and stdiobuf (the predefined classes that are derived
from streambuf) directly as implementations of stream buffers. The public
interface consists of the streambuf public member functions that can be
called on objects of these predefined classes. This chapter describes the
members of the streambuf class that you need to know about if you want to use
the predefined classes derived from streambuf to implement stream buffers
directly. streambuf itself does not have any facilities for taking characters
from the ultimate producer or sending them to the ultimate consumer. The
specialized member functions that handle the interface with the ultimate
producer and the ultimate consumer are defined in the filebuf, strstreambuf,
and stdiobuf classes.
Except for the destructor for the streambuf class, the virtual functions are
described as part of the protected interface. Although most virtual functions
are declared public, they are meant to be overloaded in the classes that you
derive from streambuf, and thus they are part of the protected interface.
ΓòÉΓòÉΓòÉ 4.3.2. Declarations for the streambuf Public Interface in iostream.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses member functions
of the public interface of streambuf:
#include <iostream.h>
The following is an excerpt from the iostream.h header file that shows the
relevant declarations for the members of the public interface. Note that this
excerpt only shows the declarations in the streambuf class that are relevant to
the public interface. The declarations for the protected interface are listed
in Declarations for the streambuf Protected Interface in iostream.h.
class ios {
public:
enum io_state { goodbit, eofbit, failbit, badbit,
hardfail};
enum open_mode { in, out, ate, app, trunc,
nocreate, noreplace, bin, binary=bin} ;
enum seek_dir { beg, cur, end} ;
// .
// .
// .
};
class streambuf {
public :
streambuf();
streambuf(char* p, int l);
streambuf(char* p, int l,int c);
virtual ~streambuf();
int in_avail();
int out_waiting();
int sgetc();
int snextc();
int sbumpc();
void stossc();
int sputbackc(char c);
int sputc(int c);
int sputn(const char* s,int n);
int sgetn(char* s,int n);
virtual streambuf* setbuf(char* p, int len);
streambuf* setbuf(unsigned char* p, int len);
streambuf* setbuf(char* p, int len, int count);
int optim_in_avail();
int optim_sbumpc();
int pptr_non_null();
};
Note:
1. pptr_non_null(), optim_in_avail(), and optim_sbumpc() are internal
implementation functions. They are declared in iostream.h and listed above,
but you should not use them directly.
2. Because setbuf() has both virtual and nonvirtual declarations, it is
described as part of the protected interface. See setbuf - Set Up Stream
Buffer for more details.
ΓòÉΓòÉΓòÉ 4.3.3. Public Members of the streambuf Public Interface ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of an object fb of a class derived from streambuf. fb could, for example, be an
object of the class filebuf. It could also be an strstreambuf object or an
stdiobuf object.
The following member functions are described:
o Constructors for streambuf
o Destructor for streambuf
o in_avail - Return Number of Characters in Get Area
o out_waiting - Return Number of Characters in Put Area
o sbumpc - Move Get Pointer One Character
o sgetc - Return Character After Get Pointer
o sgetn - Return Characters Following Get Pointer
o snextc - Return Character Following Get Pointer
o sputbackc - Move Get Pointer Back One Character
o sputc - Store Character After Put Pointer
o sputn - Store Characters After Put Pointer
o stossc - Move Get Pointer Forward One Character
ΓòÉΓòÉΓòÉ 4.3.3.1. Constructors for streambuf ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
streambuf();
streambuf(char* buffer, int len);
streambuf(char* buffer, int len, int c);
There are three versions of the constructor for streambuf. The version with no
arguments constructs an empty stream buffer corresponding to an empty sequence.
The values returned by base(), eback(), ebuf(), egptr(), epptr(), pptr(),
gptr(), and pbase() are initially all zero for this stream buffer.
The version with two arguments constructs an empty stream buffer of length len
starting at the position pointed to by buffer.
The version of the constructor with three arguments is obsolete. It is included
in the I/O Stream Library for compatibility with the AT&T C++ Language System
Release 1.2.
ΓòÉΓòÉΓòÉ 4.3.3.2. Destructor for streambuf ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
virtual ~streambuf();
The destructor for streambuf calls sync(). If a stream buffer has been set up
and ios::alloc is set, sync() deletes the stream buffer.
ΓòÉΓòÉΓòÉ 4.3.3.3. in_avail - Return Number of Characters in Get Area ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int in_avail();
in_avail() returns the number of characters that are available to be extracted
from the get area of fb. You can extract the number of characters equal to the
value that in_avail() returns without causing an error.
ΓòÉΓòÉΓòÉ 4.3.3.4. out_waiting - Return Number of Characters in Put Area ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int out_waiting();
out_waiting() returns the number of characters that are in the put area waiting
to be sent to the ultimate consumer.
ΓòÉΓòÉΓòÉ 4.3.3.5. sbumpc - Move Get Pointer One Character ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int sbumpc();
sbumpc() moves the get pointer past one character and returns the character
that it moved past. sbumpc() returns EOF if the get pointer is already at the
end of the get area.
ΓòÉΓòÉΓòÉ 4.3.3.6. sgetc - Return Character After Get Pointer ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int sgetc();
sgetc() returns the character after the get pointer without moving the get
pointer itself. If no character is available, sgetc() returns EOF.
Note: sgetc() does not change the position of the get pointer.
ΓòÉΓòÉΓòÉ 4.3.3.7. sgetn - Return Characters Following Get Pointer ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int sgetn(char* ptr, int n);
sgetn() extracts the n characters following the get pointer, and copies them to
the area starting at the position pointed to by ptr. If there are fewer than n
characters following the get pointer, sgetn() takes the characters that are
available and stores them in the position pointed to by ptr. sgetn()
repositions the get pointer following the extracted characters and returns the
number of extracted characters.
ΓòÉΓòÉΓòÉ 4.3.3.8. snextc - Return Character Following Get Pointer ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int snextc();
snextc() moves the get pointer forward one character and returns the character
following the new position of the get pointer. snextc() returns EOF if the get
pointer is at the end of the get area either before or after it is moved
forward.
ΓòÉΓòÉΓòÉ 4.3.3.9. sputbackc - Move Get Pointer Back One Character ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int sputbackc(char c);
sputbackc() moves the get pointer back one character. The get pointer may
simply move, or the ultimate producer may rearrange the internal data
structures so that the character c is saved. The argument c must equal the
character that precedes the get pointer in the stream buffer. The effect of
sputbackc() is undefined if c is not equal to the character before the get
pointer. sputbackc() returns EOF if an error occurs. The conditions that cause
errors depend on the derived class.
ΓòÉΓòÉΓòÉ 4.3.3.10. sputc - Store Character After Put Pointer ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int sputc(int c);
sputc() stores the argument c after the put pointer and moves the put pointer
past the stored character. If there is enough space in the stream buffer, this
will extend the size of the put area. sputc() returns EOF if an error occurs.
The conditions that cause errors depend on the derived class.
ΓòÉΓòÉΓòÉ 4.3.3.11. sputn - Store Characters After Put Pointer ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
int sputn(const char* s, int n);
sputn() stores the n characters starting at s after the put pointer and moves
the put pointer to the end of the series. sputn() returns the number of
characters successfully stored. If an error occurs, sputn() returns a value
less than n.
ΓòÉΓòÉΓòÉ 4.3.3.12. stossc - Move Get Pointer Forward One Character ΓòÉΓòÉΓòÉ
Class: streambuf (Public interface)
void stossc();
stossc() moves the get pointer forward one character. If the get pointer is
already at the end of the get area, stossc() does not move it.
ΓòÉΓòÉΓòÉ 4.4. ios Class ΓòÉΓòÉΓòÉ
The ios class maintains the error and format state information for the classes
that are derived from it. See The I/O Stream Library Class Hierarchy for a
list of these classes. The derived classes support the movement of formatted
and unformatted data to and from the stream buffer. This chapter describes the
members of the ios class, and thus describes the operations that are common to
all the classes that are derived from ios.
The following topics are described in this chapter:
o Declarations for ios in the iostream.h header file
o Constructors and assignment operator for ios
o The format state and the error state
o Format state variables
o Format state flags
o Public members of ios for the format state
o Public members of ios for user-defined format flags
o Public members of ios for the error state
o Other ios member functions
o Built-in manipulators
ΓòÉΓòÉΓòÉ 4.4.1. Declarations for ios in iostream.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses members of the
ios class:
#include <iostream.h>
The following is an excerpt from the iostream.h header file that shows the
relevant declarations for the members of ios.
Note: In the following excerpt, the values of the enumerators have been
omitted. Look at the iostream.h header file if you need to use these values
explicitly.
class ios {
public:
enum io_state {goodbit, eofbit, failbit, badbit,
hardfail};
enum open_mode { in, out, ate, app, trunc,
nocreate, noreplace, bin, binary=bin} ;
enum seek_dir {beg, cur, end } ;
enum {skipws,
left, right, internal,
dec, oct, hex,
showbase,
showpoint,
uppercase,
showpos,
scientific, fixed,
unitbuf, stdio
};
ios(streambuf*);
virtual ~ios() ;
static const long
basefield; /* dec|oct|hex */
static const long
adjustfield; /* left|right|internal */
static const long
floatfield; /* scientific|fixed */
long flags() const;
long flags(long f);
long setf(long newset, long field);
long setf(long);
long unsetf(long)
int width() const;
int width(int w);
ostream* tie(ostream* s);
ostream* tie();
char fill(char);
char fill() const;
int precision(int);
int precision() const;
int rdstate() const;
operator void*();
operator const void*() const;
int operator!() const;
int eof() const;
int fail() const;
int bad() const;
int good() const;
void clear(int i =0);
streambuf* rdbuf();
long & iword(int);
void* & pword(int);
static long bitalloc()
static int xalloc();
static void sync_with_stdio();
int skip(int i);
protected:
ios();
void init(streambuf* isb);
ostream* x_tie;
short x_precision;
char x_fill;
short x_width;
private:
ios(ios& ioa);
void operator=(ios& iob);
};
ios& dec(ios&);
ios& hex(ios&);
ios& oct(ios&);
istream& ws(istream&);
ostream& endl(ostream& i);
ostream& ends(ostream& i);
ostream& flush(ostream&);
Note: iostream.h contains private declarations for an assignment operator and
a copy constructor. iostream.h includes these declaration for compatibility
with AT&T C++ Language System Release 1.2. The declarations are private to
prevent ios objects from being copied.
ΓòÉΓòÉΓòÉ 4.4.2. Constructors and Assignment Operator for ios ΓòÉΓòÉΓòÉ
public:
ios(streambuf* sb);
protected:
ios();
init(streambuf* isb);
private:
ios(ios& ioa);
void operator=(ios& iob);
There are three versions of the ios constructor. The version that is declared
public takes a single argument that is a pointer to the streambuf object that
becomes associated with the constructed ios object. If this pointer is equal to
0, the result is undefined.
The version of the ios constructor that is declared protected takes no
arguments. This version is needed because ios is used as a virtual base class
for iostream, and therefore the ios class must have a constructor that takes no
arguments. If you use this constructor in a derived class, you must use the
init() function to associate the constructed ios object with the streambuf
object pointed to by the argument isb.
Copying of ios objects is not well defined, and for this reason, both the
assignment operator and the copy constructor are declared private. Assignment
between streams is supported by the istream_withassign, ostream_withassign, and
iostream_withassign classes. See istream_withassign Assignment Operator and
ostream_withassign Assignment Operator for more details. None of the predefined
classes derived from ios has a copy constructor or an assignment operator.
Unless you define your own copy constructor or assignment operator for a class
that you derive from ios, your class will have neither a copy constructor nor
an assignment operator.
ΓòÉΓòÉΓòÉ 4.4.3. The Format State and the Error State ΓòÉΓòÉΓòÉ
Each ios object has a format state and an error state. The format state is a
collection of flags and variables that can be set to control the details of
formatting operations for input and output. The error state is a collection of
flags that records whether any errors have taken place in the processing of the
ios object. It also records whether the end of an input stream has been
reached. You can view and set the format state and the error state using the
functions described in this chapter.
ΓòÉΓòÉΓòÉ 4.4.4. Format State Variables ΓòÉΓòÉΓòÉ
The format state is a collection of format flags and format variables that
control the details of formatting for input and output operations. This section
describes the format variables.
The format variables have the following declarations:
short x_precision;
char x_fill;
short x_width;
They are used in the following manner:
o x_precision is the number of significant digits in the representation of
floating-point values. Its default value is 6.
o x_fill is the character that is used to pad values that do not require the
width of an entire field for their representation. Its default value is a
space character.
o x_width is the minimum width of a field. Its default value is 0.
ΓòÉΓòÉΓòÉ 4.4.5. Format State Flags ΓòÉΓòÉΓòÉ
The format flags have the following declaration in iostream.h:
enum { skipws,
left, right, internal,
dec, oct, hex,
showbase,
showpoint,
uppercase,
showpos,
scientific, fixed,
unitbuf, stdio
} ;
The following list shows the formatting features and the format flags that
control them:
o Whitespace and padding: ios::skipws, ios::left, ios::right, ios::internal
o Base conversion: ios::dec, ios::hex, ios::oct, ios::showbase
o Integral formatting: ios::showpos
o Floating-point formatting: ios::fixed, ios::scientific, ios::showpoint
o Uppercase and lowercase: ios::uppercase
o Buffer flushing: ios::stdio, ios::unitbuf
The following sections describe these formatting features in detail. Mutually
Exclusive Format Flags describes the flags that produce unpredictable results
if they are set at the same time.
ΓòÉΓòÉΓòÉ 4.4.5.1. Whitespace and Padding ΓòÉΓòÉΓòÉ
Class: ios
The following format state flags control whitespace and padding characters:
o skipws: if ios::skipws is set, whitespace will be skipped on input. If it is
not set, whitespace is not skipped. If ios::skipws is not set, the arithmetic
extractors will signal an error if you attempt to read an integer or
floating-point value that is preceded by whitespace. ios::failbit is set, and
extraction ceases until it is cleared. This is done to avoid the looping
problems that could occur otherwise. If the following program is run with an
input file that contains integer values separated by spaces, ios::failbit is
set after the first integer value is read, and the program halts. If the
program did not call fail() at the beginning of the while loop to test if
ios::failbit is set, it would loop indefinitely.
#include <fstream.h>
void main()
{
fstream f("spadina.dat", ios::in);
f.unsetf(ios::skipws);
int i;
while (!f.eof() && !f.fail()) {
f >> i;
cout << i;
}
}
o left: if ios::left is set, the value is left-justified. Fill characters are
added after the value.
o right: if ios::right is set, the value is right-justified. Fill characters
are added before the value.
o internal: if ios::internal is set, the fill characters are added after any
leading sign or base notation, but before the value itself.
ΓòÉΓòÉΓòÉ 4.4.5.2. Base Conversion ΓòÉΓòÉΓòÉ
Class: ios
The manipulators ios::dec, ios::oct, and ios::hex (see Built-In Manipulators
for ios for more details) have the same effect as the flags ios::dec, ios::oct,
and ios::hex, respectively.
o dec: if ios::dec is set, the conversion base is 10.
o oct: if ios::oct is set, the conversion base is 8.
o hex: if ios::hex is set, the conversion base is 16.
o showbase: if ios::showbase is set, the operation that inserts values converts
them to an external form that can be read according to the C++ lexical
conventions for integral constants. By default, ios::showbase is unset.
ΓòÉΓòÉΓòÉ 4.4.5.3. Integral Formatting ΓòÉΓòÉΓòÉ
Class: ios
o showpos: if ios::showpos is set, the operation that inserts values places a
positive sign "+" into decimal conversions of positive integral values.
ΓòÉΓòÉΓòÉ 4.4.5.4. Floating-Point Formatting ΓòÉΓòÉΓòÉ
Class: ios
The following format flags control the formatting of floating-point values:
o showpoint: if ios::showpoint is set, trailing zeros and a decimal point
appear in the result of a floating-point conversion. This flag has no effect
if either ios::scientific or ios::fixed is set.
o scientific: if ios::scientific is set, the value is converted using
scientific notation. In scientific notation, there is one digit before the
decimal point and the number of digits following the decimal point depends on
the value of ios::x_precision. The default value for ios::x_precision is 6.
If ios::uppercase is set, an uppercase "E" precedes the exponent. Otherwise,
a lowercase "e" precedes the exponent.
o fixed: if ios::fixed is set, floating point values are converted to fixed
notation with the number of digits after the decimal point equal to the value
of ios::x_precision (or 6 by default).
If neither ios::fixed nor ios::scientific is set, the representation of
floating-point values depends on their values and the number of significant
digits in the representation equals ios::x_precision. Floating-point values are
converted to scientific notation if the exponent resulting from a conversion to
scientific notation is less than -4 or greater than or equal to the value of
ios::x_precision. Otherwise, floating-point values are converted to fixed
notation. If ios::showpoint is not set, trailing zeros are removed from the
result and a decimal point appears only if it is followed by a digit.
ios::scientific and ios::fixed are collectively identified by the static member
ios::floatfield.
The following example shows some of the possibilities for formatting a
floating-point value:
#include
<iomanip.h>
void main()
{
float fp = 3.14f;
//
// print the value with an uppercase "E" in the exponent
//
cout << setiosflags(ios::scientific|ios::uppercase);
cout << "Here is a floating-point value " << fp << endl;
//
// print the value with a lowercase "e" in the exponent
//
cout << resetiosflags(ios::uppercase);
cout << "Here is a floating-point value "
<< fp << endl;
//
// print the value in fixed format
//
cout << resetiosflags(ios::scientific)
<< setiosflags(ios::fixed);
cout << "Here is a floating-point value "
<< fp << endl;
}
This program produces the following output:
Here is a floating-point value 3.140000E+00
Here is a floating-point value 3.140000e+00
Here is a floating-point value 3.140000
ΓòÉΓòÉΓòÉ 4.4.5.5. Uppercase and Lowercase ΓòÉΓòÉΓòÉ
Class: ios
o uppercase: if ios::uppercase is set, the operation that inserts values uses
an uppercase "E" for floating point values in scientific notation. In
addition, the operation that inserts values stores hexadecimal digits "A" to
"F" in uppercase and places an uppercase "X" before hexadecimal values when
ios::showbase is set. If ios::uppercase is not set, a lowercase "e"
introduces the exponent in floating-point values, hexadecimal digits "a" to
"f" are stored in lowercase, and a lowercase "x" is inserted before
hexadecimal values when ios::showbase is set.
ΓòÉΓòÉΓòÉ 4.4.5.6. Buffer Flushing ΓòÉΓòÉΓòÉ
Class: ios
o unitbuf: if ios::unitbuf is set, ostream::osfx() performs a flush after each
insertion. The attached stream buffer is unit buffered.
o stdio: this flag is used internally by sync_with_stdio(). You should not use
ios::stdio directly. If you want to combine I/O Stream Library input and
output with stdio.h input and output, you should use sync_with_stdio(). See
sync_with_stdio - Attach stdiobuf Object to Predefined Streams for more
details on sync_with_stdio().
ΓòÉΓòÉΓòÉ 4.4.5.7. Mutually Exclusive Format Flags ΓòÉΓòÉΓòÉ
Class: ios
If you specify conflicting flags the results are unpredictable. For example,
the results will be unpredictable if you set both ios::left and ios::right in
the format state of iosobj. You should set only one flag in each set of the
following three sets:
o ios::left, ios::right, ios::internal
o ios::dec, ios::oct, ios::hex
o ios::scientific, ios::fixed.
ΓòÉΓòÉΓòÉ 4.4.6. Public Members of ios for the Format State ΓòÉΓòÉΓòÉ
You can use the member functions listed below to control the format state of an
ios object.
Note: The following descriptions assume that the functions are called as part
of an ios object called iosobj.
The following functions are described:
o fill - Set the fill character
o flags - Set format flags
o precision - Set the precision
o setf - Set specific format flags
o skip - Set ios::skipws format flag
o unsetf - Turn off format flags
o width - Set field width
ΓòÉΓòÉΓòÉ 4.4.6.1. fill - Set the Fill Character ΓòÉΓòÉΓòÉ
Class: ios
char fill() const;
char fill(char fillchar);
There are two versions of fill(). fill() with no arguments returns the value of
ios::x_fill in the format state of iosobj. fill() with an argument fillchar
sets ios::x_fill to be equal to fillchar.
ios::x_fill is the character used as padding if the field is wider than the
representation of a value. The default value for ios::x_fill is a space. The
ios::left, ios::right, and ios::internal flags determine the position of the
fill character.
You can also use the parameterized manipulator setfill to set the value of
ios::x_fill.
ΓòÉΓòÉΓòÉ 4.4.6.2. flags - Set Format Flags ΓòÉΓòÉΓòÉ
Class: ios
long flags() const;
long flags(long flagset);
There are two versions of flags(). The version that takes no arguments returns
the value of the flags that make up the current format state. The version that
takes an argument sets the flags in the format state to the settings specified
in flagset and returns the value of the previous settings of the format flags.
ΓòÉΓòÉΓòÉ 4.4.6.3. precision - Set the Precision ΓòÉΓòÉΓòÉ
Class: ios
int precision() const;
int precision(int prec);
There are two versions of precision(). The version that takes no arguments
returns the value of ios::x_precision. The version that takes one argument sets
the value of ios::x_precision to prec and returns the previous value. The value
of prec must be greater than 0. If the value is nonpositive, the value of
ios::x_precision is set to the default value, 6. ios::x_precision controls the
number of significant digits when floating-point values are inserted.
If neither ios::scientific nor ios::fixed is set, ios::x_precision specifies
the number of significant digits in the floating-point value that is being
inserted. If, in addition, ios::showpoint is not set, all trailing zeros are
removed and a decimal point only appears if it is followed by digits.
If either ios::scientific or ios::fixed is set, ios::x_precision specifies the
number of digits following the decimal point.
You can also use the parameterized manipulator setprecision to set
ios::x_precision.
ΓòÉΓòÉΓòÉ 4.4.6.4. setf - Set Specific Format Flags ΓòÉΓòÉΓòÉ
Class: ios
long setf(long newset);
long setf(long newset, long field);
There are two versions of setf(). The version that takes one argument is
accumulative. It sets the format flags that are marked in newset, without
affecting flags that are not marked in newset, and returns the previous value
of the format state. You can also use the parameterized manipulator setiosflags
to set the format flags to a specific setting.
The version of setf() that takes two arguments clears the format flags
specified in field, sets the format flags specified in newset, and returns the
previous value of the format state. For example, to change the conversion base
in the format state to ios::hex, you could use a statement like this:
s.setf(ios::hex, ios::basefield);
In this statement, ios::basefield specifies the conversion base as the format
flag that is going to be changed, and ios::hex specifies the new value for the
conversion base. If newset equals 0, all of the format flags specified in field
are cleared. You can also use the parameterized manipulator resetiosflags to
clear format flags.
The following example demonstrates the use of flags(), setf(), and unsetf().
The main() function changes the flags as follows:
1. The original settings of the format state flags are determined, using
flags().
2. ios::fixed is set, and all other flags are cleared, using
flags(ios::fixed).
3. ios::adjustfield is set to ios::right, without affecting other fields,
using setf(ios::right).
4. ios::floatfield is set to ios::scientific without affecting other fields,
using setf(ios::scientific | ios::left,ios::floatfield). ios::left does not
affect the format state here because the second argument to setf() does not
include ios::adjustfield. There would be no point in coding a call this
way in a real application, but it illustrates the effect of using a mask
for the second argument of setf().
5. The original format state is restored, by calling flags() with an argument
of originalFlags, which contains the format state determined in step 1.
The function showFlags() determines and displays the current flag settings. It
obtains the value of the settings using flags(), then excludes ios::oct from
the result before displaying the result in octal. This exclusion is done in
order to display the result in octal without causing the octal setting for
ios::basefield to show up in the program's output.
/* Program to demonstrate use of flags(), flags(long), setf(long),
and setf(long,long). */
#include <iostream.h>
void showFlags() {
// save altered flag settings, but clear ios::oct from them
long flagSettings = cout.flags() & (~ios::oct) ;
// display those flag settings in octal
cout << oct << flagSettings << endl;
}
void main () {
// get and display current flag settings using flags()
cout << "flags(): ";
long originalFlags = cout.flags();
showFlags();
// change format state using flags(long)
cout << "flags(ios::fixed): ";
cout.flags(ios::fixed);
showFlags();
// change adjust field using setf(long)
cout << "setf(ios::right): ";
cout.setf(ios::right);
showFlags();
// change floatfield using setf(long, long)
cout << "setf(ios::scientific | ios::left,\n"
<< "ios::floatfield): ";
cout.setf(ios::scientific | ios::left,ios::floatfield);
showFlags();
// reset to original setting
cout << "flags(originalFlags): ";
cout.flags(originalFlags);
showFlags();
}
This example produces the following output:
flags(): 21
flags(ios::fixed): 10000
setf(ios::right): 10004
setf(ios::scientific | ios::left,
ios::floatfield): 4004
flags(originalFlags): 21
Note: If you set conflicting flags the results are unpredictable.
ΓòÉΓòÉΓòÉ 4.4.6.5. skip - Set ios::skipws Format Flag ΓòÉΓòÉΓòÉ
Class: ios
int skip(int i);
skip() sets the format flag ios::skipws if the value of the argument i does not
equal 0. If i does equal 0, ios::skipws is cleared. skip() returns a value of 1
if ios::skipws was set prior to the call to skip(), and returns 0 otherwise.
ΓòÉΓòÉΓòÉ 4.4.6.6. unsetf - Turn Off Format Flags ΓòÉΓòÉΓòÉ
Class: ios
long unsetf(long oflags);
unsetf() turns off the format flags specified in oflags and returns the
previous format state.
ΓòÉΓòÉΓòÉ 4.4.6.7. width - Set Field Width ΓòÉΓòÉΓòÉ
Class: ios
int width() const;
int width(int fwidth);
There are two versions of width(). The version that takes no arguments returns
the value of the current setting of the format state field width variable,
ios::x_width. If the value of ios::x_width is smaller than the space needed for
the representation of the value, the full value is still inserted.
The version of width() that takes one argument fwidth sets ios::x_width to the
value of fwidth and returns the previous value. The default field width is 0.
When the value of ios::x_width is 0, the operations that insert values only
insert the characters needed to represent a value.
If the value of ios::x_width is greater than 0, the characters needed to
represent the value are inserted. Then fill characters are inserted, if
necessary, so that the representation of the value takes up the entire field.
ios::x_width only specifies a minimum width, not a maximum width. If the number
of characters needed to represent a value is greater than the field width, none
of the characters is truncated. After every insertion of a numeric value or a
string, the value of ios::x_width is reset to 0. After every extraction of a
value of one of the following types, the value of ios::x_width is reset to 0:
o char*
o unsigned char*
o signed char*
o float, double and long double values
o integral values:short, int, long
o wchar_t *
Extractions of any other types do not affect ios::x_width.
You can also use the parameterized manipulator setw to set the field width.
ΓòÉΓòÉΓòÉ 4.4.7. Public Members of ios for User-Defined Format Flags ΓòÉΓòÉΓòÉ
In addition to the flags described in Format State Flags, you can also use the
ios member functions listed in this section to define additional format flags
or variables in classes that you derive from ios.
The following member functions are described:
o bitalloc - Create bit set
o iword - Return reference to user-defined flag
o pword - Return reference to user-defined flag
o xalloc - Return index to format state variables.
ΓòÉΓòÉΓòÉ 4.4.7.1. bitalloc - Create Bit Set ΓòÉΓòÉΓòÉ
Class: ios
static long bitalloc();
bitalloc() is a static function that returns a long value with a previously
unallocated bit set. You can use this long value as an additional flag, and
pass it as an argument to the format state member functions. When all the bits
are exhausted, bitalloc() returns 0.
ΓòÉΓòÉΓòÉ 4.4.7.2. iword - Return Reference to User-Defined Flag ΓòÉΓòÉΓòÉ
Class: ios
long& iword(int i);
iword() returns a reference to the ith user-defined flag, where i is an index
returned by xalloc(). iword() allocates space for the user-defined flag. If the
allocation fails, iword() sets ios::failbit.
ΓòÉΓòÉΓòÉ 4.4.7.3. pword - Return Reference to User-Defined Flag ΓòÉΓòÉΓòÉ
Class: ios
void* & pword(int i);
pword() returns a reference to a pointer to the ith user-defined flag, where i
is an index returned by xalloc(). pword() allocates space for the user-defined
flag. If the allocation fails, pword() sets ios::failbit. pword() is the same
as iword() except that the two functions return different types.
ΓòÉΓòÉΓòÉ 4.4.7.4. xalloc - Return Index to Format State Variables ΓòÉΓòÉΓòÉ
Class: ios
static int xalloc();
xalloc() is a static function that returns an unused index into an array of
words available for use as format state variables by classes derived from ios.
xalloc() simply returns a new index; it does not do any allocation. iword() and
pword() do the allocation, and if the allocation fails, they set ios::failbit.
You should check ios::failbit after calling iword() or pword().
ΓòÉΓòÉΓòÉ 4.4.8. Public Members of ios for the Error State ΓòÉΓòÉΓòÉ
The error state is an enumeration that records the errors that take place in
the processing of ios objects. It has the following declaration:
enum io_state { goodbit, eofbit, failbit, badbit, hardfail };
The error state is manipulated using the ios member functions described in this
section.
Note:
1. hardfail is a flag used internally by the I/O Stream Library. Do not use
it.
2. The following descriptions assume that the functions are called as part of
an ios object called iosobj.
The following member functions are described:
o bad - Check ios::badbit
o clear - Clear or Set Error State
o eof - Check ios::eofbit
o fail - Check ios::failbit and ios::badbit
o good - Are Any Bits Set
o rdstate - Return Error State
o Convert ios Object to Pointer Operator void*()
o Check ios::failbit and ios::badbit Operator !
ΓòÉΓòÉΓòÉ 4.4.8.1. bad - Check ios::badbit ΓòÉΓòÉΓòÉ
Class: ios
int bad() const;
bad() returns a nonzero value if ios::badbit is set in the error state of
iosobj. Otherwise, it returns 0. ios::badbit is usually set when some operation
on the streambuf object that is associated with the ios object has failed. It
will probably not be possible to continue input and output operations on the
ios object.
ΓòÉΓòÉΓòÉ 4.4.8.2. clear - Clear or Set Error State ΓòÉΓòÉΓòÉ
Class: ios
void clear(int state=0);
clear() changes the error state of iosobj to state. If state equals 0 (its
default), all of the bits in the error state are cleared. If you want to set
one of the bits without clearing or setting the other bits in the error state,
you can bitwise OR the bit you want to set with the current error state. For
example, the following statement sets ios::badbit in iosobj and leaves all the
other error state bits unchanged:
iosobj.clear(ios::badbit|iosobj.rdstate());
ΓòÉΓòÉΓòÉ 4.4.8.3. eof - Check ios::eofbit ΓòÉΓòÉΓòÉ
Class: ios
int eof() const;
eof() returns a nonzero value if ios::eofbit is set in the error state of
iosobj. Otherwise, it returns 0. ios::eofbit is usually set when an EOF has
been encountered during an extraction operation.
ΓòÉΓòÉΓòÉ 4.4.8.4. fail - Check ios::failbit and ios::badbit ΓòÉΓòÉΓòÉ
Class: ios
int fail() const;
fail() returns a nonzero value if either ios::badbit or ios::failbit is set in
the error state. Otherwise, it returns 0.
ΓòÉΓòÉΓòÉ 4.4.8.5. good - Are Any Bits Set ΓòÉΓòÉΓòÉ
Class: ios
int good() const;
good() returns a nonzero value if no bits are set in the error state of iosobj.
Otherwise, it returns 0.
ΓòÉΓòÉΓòÉ 4.4.8.6. rdstate - Return Error State ΓòÉΓòÉΓòÉ
Class: ios
int rdstate() const;
rdstate() returns the current value of the error state of iosobj.
ΓòÉΓòÉΓòÉ 4.4.8.7. Convert ios Object to Pointer Operator void*() ΓòÉΓòÉΓòÉ
Class: ios
operator void*();
operator const void*() const;
The operator void*() converts iosobj to a pointer so that it can be compared to
0. The conversion returns 0 if ios::failbit or ios::badbit is set in the error
state of iosobj. Otherwise, a pointer value is returned. This value is not
meant to be manipulated as a pointer; the purpose of the operator is to allow
you to write statements such as the following:
if (cin)
cout << "ios::badbit and ios::failbit are not set" << endl;
if (cin >> x)
cout << "ios::badbit and ios::failbit are not set "
<< x << " was input" << endl;
ΓòÉΓòÉΓòÉ 4.4.8.8. Check ios::failbit and ios::badbit Operator ! ΓòÉΓòÉΓòÉ
Class: ios
int operator!() const;
The operator !() returns a nonzero value if ios::failbit or ios::badbit is set
in the error state of iosobj. This allows you to write statements like this:
if (!cin)
cout << "either ios::failbit or ios::badbit is set" << endl;
else
cout << "neither ios::failbit nor ios::badbit is set"
<< endl;
ΓòÉΓòÉΓòÉ 4.4.9. Other Members of ios ΓòÉΓòÉΓòÉ
This section describes the ios member functions that do not deal with the error
state or the format state. These descriptions assume that the functions are
called as part of an ios object called iosobj.
The following functions are described:
o rdbuf - Return pointer to associated streambuf object
o sync_with_stdio - Attach stdiobuf object to predefined streams
o tie - Set the tie variable
ΓòÉΓòÉΓòÉ 4.4.9.1. rdbuf - Return Pointer to Associated streambuf Object ΓòÉΓòÉΓòÉ
Class: ios
streambuf* rdbuf();
rdbuf() returns a pointer to the streambuf object that is associated with
iosobj. This is the streambuf object that was passed as an argument to the ios
constructor.
ΓòÉΓòÉΓòÉ 4.4.9.2. sync_with_stdio - Attach stdiobuf Object to Predefined Streams ΓòÉΓòÉΓòÉ
Class: ios
static void sync_with_stdio();
sync_with_stdio() is a static function that solves the problems that occur when
you call functions declared in stdio.h and I/O Stream Library functions in the
same program. The first time that you call sync_with_stdio(), it attaches
stdiobuf objects to the predefined streams cin, cout, and cerr. After that,
input and output using these predefined streams can be mixed with input and
output using the corresponding FILE objects (stdin, stdout, and stderr). This
input and output is correctly synchronized.
If you switch between the I/O Stream Library formatted extraction functions and
stdio.h functions, you may find that a byte is "lost". The reason is that the
formatted extraction functions for integers and floating-point values keep
extracting characters until a non-digit character is encountered. This
non-digit character acts as a delimiter for the value that preceded it. It is
not part of the value, so putback() is called to return it to the stream
buffer. If a C stdio library function, such as getchar(), performs the next
input operation, it will begin input at the character after this non-digit
character. Thus, this non-digit character is not part of the value extracted by
the formatted extraction function, and it is not the character extracted by the
C stdio library function. It is "lost". Therefore, you should avoid switching
between the I/O Stream Library formatted extraction functions and C stdio
library functions whenever possible.
sync_with_stdio() makes cout and cerr unit buffered. After you call
sync_with_stdio(), the performance of your program could diminish. The
performance of your program is affected adversely if you are dealing mostly
with relatively short strings.
Note: You should use I/O Stream Library functions exclusively for all new
code.
ΓòÉΓòÉΓòÉ 4.4.9.3. tie - Set the tie Variable ΓòÉΓòÉΓòÉ
Class: ios
ostream* tie();
ostream* tie(ostream* os);
There are two versions of tie(). The version that takes no arguments returns
the value of ios::x_tie, the tie variable. The version that takes one argument
os makes the tie variable, ios::x_tie, equal to os and returns the previous
value.
You can use ios::x_tie to automatically flush the stream buffer attached to an
ios object. If ios::x_tie for an ios object is not equal to 0 and the ios
object needs more characters or has characters to be consumed, the ostream
object pointed to by ios::x_tie is flushed.
By default, the tie variables of the predefined streams cin, cerr, and clog all
point to the predefined stream cout. For example, the initial return value of
cin.tie() is a pointer to cout.
ΓòÉΓòÉΓòÉ 4.4.10. Built-In Manipulators for ios ΓòÉΓòÉΓòÉ
The I/O Stream Library provides you with a set of built-in manipulators for ios
and the classes derived from it. These manipulators have a specific effect on a
stream other than inserting or extracting a value. Manipulators implicitly
invoke functions that modify the state of the stream, and they allow you to
modify the state of a stream at the same time as you are doing input and
output. The syntax for manipulators is consistent with the syntax for input and
output.
The following is a list of the manipulators and the classes that they apply to:
dec istream and ostream
hex istream and ostream
oct istream and ostream
ws istream
endl ostream
ends ostream
flush ostream
See Built-In Manipulators for istream for more details on the built-in
manipulators for istream. See Built-In Manipulators for ostream for more
details on the manipulators for ostream.
ΓòÉΓòÉΓòÉ 4.5. istream and istream_withassign Class ΓòÉΓòÉΓòÉ
This chapter describes the istream class and its derived class
istream_withassign. The istream member functions allow you to take characters
out of the stream buffer that is associated with an istream object.
istream_withassign is derived from istream and includes an assignment operator.
istream supports two kinds of input:
o Unformatted input: characters are taken as a sequence of bytes from the
stream buffer that is associated with the istream object.
o Formatted input: characters are taken from the stream buffer associated with
the istream object, converted to a given type, and stored in a variable of
that type.
The following topics are described in this chapter:
o Declarations for istream and istream_withassign in the iostream.h header file
o Constructors for istream
o Input prefix function
o Public members of istream for formatted input
o Public members of istream for unformatted input
o Public members of istream for positioning
o Other public members of istream
o Built-In Manipulators for istream
o Public members of istream_withassign
ΓòÉΓòÉΓòÉ 4.5.1. Declarations for istream and istream_withassign in iostream.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses member functions
of the istream class:
#include <iostream.h>
The following is an excerpt from the iostream.h header file that shows the
relevant declarations for the members of istream:
class istream : virtual public ios {
public:
istream(streambuf*);
istream(streambuf*, int sk, ostream* t=0);
istream(int size ,char*,int sk=1);
istream(int fd,int sk=1, ostream* t=0);
virtual ~istream();
int ipfx(int noskipws=0);
void isfx();
istream& seekg(streampos p);
istream& seekg(streamoff o, ios::seek_dir d);
streampos tellg();
istream& operator>> (istream& (*f)(istream&));
istream& operator>> (ios& (*f)(ios&) );
istream& operator>>(char*);
istream& operator>>(signed char*);
istream& operator>>(unsigned char*);
istream& operator>>(char& c);
istream& operator>>(signed char& c);
istream& operator>>(unsigned char& c);
istream& operator>>(short&);
istream& operator>>(int&);
istream& operator>>(long&);
istream& operator>>(unsigned short&);
istream& operator>>(unsigned int&);
istream& operator>>(unsigned long&);
istream& operator>>(float&);
istream& operator>>(double&);
istream& operator>>(long double&);
istream& operator>>(streambuf*);
istream& operator>>(wchar_t&);
istream& operator>>(wchar_t *);
istream& rs_complicated(char& c);
istream& rs_complicated(signed char& c);
istream& rs_complicated(unsigned char& c);
istream& get(char* , int lim, char delim='\n');
istream& get(signed char* b,int lim,
char delim='\n');
istream& get(unsigned char* b,int lim,
char delim='\n');
istream& get(streambuf& sb, char delim ='\n');
istream& get_complicated(char& c);
istream& get_complicated(signed char& c);
istream& get_complicated(unsigned char& c);
istream& get(char& c);
istream& get(signed char& c);
istream& get(unsigned char& c);
int get();
istream& getline(char* b, int lim,
char delim='\n');
istream& getline(signed char* b, int lim,
char delim='\n');
istream& getline(unsigned char* b, int lim,
char delim='\n');
istream& get(wchar_t&);
int peek();
istream& ignore(int n=1,int delim=EOF);
istream& read(char* s,int n);
istream& read(signed char* s,int n);
istream& read(unsigned char* s,int n);
int gcount();
istream& putback(char c);
int sync();
protected:
istream();
int do_ipfx(int noskipws);
void eatwhite();
};
class istream_withassign : public istream {
public:
istream_withassign();
virtual ~istream_withassign();
istream_withassign& operator=(istream&);
istream_withassign& operator=(streambuf*);
};
extern istream_withassign cin;
ios& dec(ios&);
ios& hex(ios&);
ios& oct(ios&);
istream& ws(istream&);
Note: The following functions have declarations included in the above listing
of iostream.h, but they are only for the internal use of the I/O Stream
Library. You should not use them directly:
o isfx()
o rs_complicated()
o get_complicated()
o do_ipfx()
o eatwhite().
ΓòÉΓòÉΓòÉ 4.5.2. Constructors for istream ΓòÉΓòÉΓòÉ
Class: istream
istream(streambuf* sb);
The istream constructor takes a single argument sb. The constructor creates an
istream object that is attached to the streambuf object that is pointed to by
sb. The constructor also initializes the format variables to their defaults.
The other istream constructor declarations in iostream.h are obsolete; do not
use them.
ΓòÉΓòÉΓòÉ 4.5.3. Input Prefix Function ΓòÉΓòÉΓòÉ
int ipfx(int need=0);
ipfx() checks the stream buffer attached to an istream object to determine if
it is capable of satisfying requests for characters. It returns a nonzero value
if the stream buffer is ready, and 0 if it is not.
The formatted input operator calls ipfx(0), while the unformatted input
functions call ipfx(1).
If the error state of the istream object is nonzero, ipfx() returns 0.
Otherwise, the stream buffer attached to the istream object is flushed if
either of the following conditions is true:
o need has a value of 0.
o The number of characters available in the stream buffer is fewer than the
value of need.
If ios::skipws is set in the format state of the istream object and need has a
value of 0, leading whitespace characters are extracted from the stream buffer
and discarded. If ios::hardfail is set or EOF is encountered, ipfx() returns 0.
Otherwise, it returns a nonzero value.
ΓòÉΓòÉΓòÉ 4.5.4. Public Members of istream for Formatted Input ΓòÉΓòÉΓòÉ
The istream class lets you perform formatted input from a stream buffer using
the input operator >>. Consider the following statement, where ins is a
reference to an istream object and x is a variable of a built-in type:
ins >> x;
The input operator >> calls ipfx(0). If ipfx() returns a nonzero value, the
input operator extracts characters from the streambuf object that is associated
with ins. It converts these characters to the type of x and stores the result
in x. The input operator sets ios::failbit if the characters extracted from the
stream buffer cannot be converted to the type of x. If the attempt to extract
characters fails because EOF is encountered, the input operator sets
ios::eofbit and ios::failbit. If the attempt to extract characters fails for
another reason, the input operator sets ios::badbit. Even if an error occurs,
the input operator always returns ins.
The details of conversion depend on the format state of the istream object and
the type of the variable x. The input operator may set the width variable
ios::x_width to 0, but it does not change anything else in the format state.
The input operator is defined for the following types:
o Arrays of character values (including signed char and unsigned char)
o Other integral values: short, int, long
o float, double, and long double values.
In addition, the input operator is defined for streambuf objects.
The following sections describe the input operator for these types.
Note: The following descriptions assume that the input operator is called with
the istream object ins on the left side of the operator.
ΓòÉΓòÉΓòÉ 4.5.4.1. Input Operator for Arrays of Characters ΓòÉΓòÉΓòÉ
Class: istream
istream& operator>>(char* pc);
istream& operator>>(signed char* pc);
istream& operator>>(unsigned char* pc);
istream& operator>>(wchar_t* pwc);
For pointers to char, signed char, and unsigned char, the input operator stores
characters from the stream buffer attached to ins in the array pointed to by
pc. The input operator stores characters until a whitespace character is found.
This whitespace character is left in the stream buffer, and the extraction
stops. If ios::x_width does not equal zero, a maximum of ios::x_width - 1
characters are extracted. The input operator calls ins.width(0) to reset
ios::x_width to 0.
For pointers to wchar_t, the input operator stores characters from the stream
buffer attached to ins in the array pointed to by pwc. The input operator
stores characters until a whitespace character or a wchar_t blank is found. If
the terminating character is a whitespace character, it is left in the stream
buffer. If it is a wchar_t blank, it is discarded. This is done to avoid
returning two bytes to the input stream.
For wchar_t* arrays, if ios::width does not equal zero, a maximum of
ios::width-1 characters (at 2 bytes each) are extracted. A 2-character space is
reserved for the wchar_t terminating null character.
Note: The input operators for numeric types and for pointers to char
(including pointers to signed char, unsigned char and wchar_t) reset
ios::x_width to 0. None of the other input operators affects ios::x_width. All
of the output operators, on the other hand, reset ios::x_width to 0.
The input operator always stores a terminating null character in the array
pointed to by pc or pwc, even if an error occurs. For arrays of wchar_t*, this
terminating null character is a wchar_t terminating null character.
ΓòÉΓòÉΓòÉ 4.5.4.2. Input Operator for char ΓòÉΓòÉΓòÉ
Class: istream
istream& operator>>(char& rc);
istream& operator>>(signed char& rc);
istream& operator>>(unsigned char& rc);
istream& operator>>(wchar_t& rc);
For char, signed char, and unsigned char, the input operator extracts a
character from the stream buffer attached to ins and stores it in rc.
For references to wchar_t, the input operator extracts a wchar_t character from
the stream buffer and stores it in wc. If ios::skipsw is set, the input
operator skips leading wchar_t spaces as well as leading char white spaces.
ΓòÉΓòÉΓòÉ 4.5.4.3. Input Operator for Other Integral Values - short, int, long ΓòÉΓòÉΓòÉ
Class: istream
istream& operator>>(short& ir);
istream& operator>>(unsigned short& ir);
istream& operator>>(int& ir);
istream& operator>>(unsigned int& ir);
istream& operator>>(long& ir);
istream& operator>>(unsigned long& ir);
This section describes how the input operator works for references to the
integral types: short, unsigned short, int, unsigned int, long, and unsigned
long. For these integral types, the input operator extracts characters from the
stream buffer associated with ins and converts them according to the format
state of ins. The converted characters are then stored in ir. There is no
overflow detection on conversion of integral types.
The first character extracted from the stream buffer may be a sign (+ or -).
The subsequent characters are converted until a non-digit character is
encountered. This non-digit character is left in the stream buffer. Which
characters are treated as digits depends on the setting of the following format
flags:
o ios::oct: the characters are converted to an octal value. Characters are
extracted from the stream buffer until a character that is not an octal digit
(a digit from 0 to 7) is encountered. If ios::oct is set and a signed value
is encountered, the value is converted into a decimal value. For example, if
the characters "- 45" are encountered in the input stream and ios::oct is
set, the decimal value - 37 is actually extracted.
o ios::dec: the characters are converted to a decimal value. Characters are
extracted from the stream buffer until a character that is not a decimal
digit (a digit from 0 to 9) is encountered.
o ios::hex: the characters are converted to a hexadecimal value. Characters are
extracted from the stream buffer until a character that is not a hexadecimal
digit (a digit from 0 to 9 or a letter from "A" to "F", upper or lower case)
is encountered. If ios::hex is set and a signed value is encountered, the
value is converted into a decimal value. For example, if the characters "-12"
are encountered in the input stream and ios::hex is set, the decimal value
-18 is actually extracted.
If none of these format flags is set, the characters are converted according to
the C++ lexical conventions. This conversion depends on the characters that
follow the optional sign:
o If these characters are "0x" or "0X", the subsequent characters are converted
to a hexadecimal value.
o If the first character is "0" and the second character is not "x" or "X", the
subsequent characters are converted to an octal value.
o If neither of these cases is true, the characters are converted to a decimal
value.
If no digits are available in the stream buffer (other than the "0" in "0X" or
"0x" preceding a hexadecimal value), the input operator sets ios::failbit in
the error state of ins.
ΓòÉΓòÉΓòÉ 4.5.4.4. Input Operator for float and double Values ΓòÉΓòÉΓòÉ
Class: istream
istream& operator>>(float& ref);
istream& operator>>(double& ref);
istream& operator>>(long double& ref);
For float, double, and long double values, the input operator converts
characters from the stream buffer attached to ins according to the C++ lexical
conventions.
The following conversions occur for certain string values:
o If the value consists of the character strings "inf" or "infinity" in any
combination of uppercase and lowercase letters, the string is converted to
the appropriate type's representation of infinity.
o If the value consists of the character string "nan" in any combination of
uppercase and lowercase letters, the string is converted to the appropriate
type's representation of a NaN.
The resulting value is stored in ref. The input operator sets ios::failbit if
no digits are available in the stream buffer or if the digits that are
available do not begin a floating-point number.
ΓòÉΓòÉΓòÉ 4.5.4.5. Input Operator for streambuf Objects ΓòÉΓòÉΓòÉ
Class: istream
istream& operator>>(streambuf* sb);
For pointers to streambuf objects, the input operator calls ipfx(0). If ipfx(0)
returns a nonzero value, the input operator extracts characters from the stream
buffer attached to ins and inserts them in sb. Extraction stops when an EOF
character is encountered. The input operator always returns ins.
ΓòÉΓòÉΓòÉ 4.5.5. Public Members of istream for Unformatted Input ΓòÉΓòÉΓòÉ
The functions listed in this section allow you to extract characters from a
stream buffer as a sequence of bytes. All of these functions call ipfx(1). They
only proceed with their processing if ipfx(1) returns a nonzero value.
Note: The following descriptions assume that the functions are called as part
of an istream object called ins. The following functions are described:
o get - Extract characters and store in array
o get - Extract characters and store in stream buffer
o get - Extract character and store in char
o get - Extract character and return it
o getline - Extract characters and store in array
o ignore - Extract characters and discard them
o read - Extract characters and store in array
ΓòÉΓòÉΓòÉ 4.5.5.1. get - Extract Characters and Store in Array ΓòÉΓòÉΓòÉ
Class: istream
istream& get(char* ptr, int len, char delim='\n');
istream& get(signed char* ptr, int len, char delim='\n');
istream& get(unsigned char* ptr, int len, char delim='\n');
get() with three arguments extracts characters from the stream buffer attached
to ins and stores them in the byte array beginning at the location pointed to
by ptr and extending for len bytes. The default value of the delim argument is
'\n'. Extraction stops when either of the following conditions is true:
o delim or EOF is encountered before len-1 characters have been stored in the
array. delim is left in the stream buffer and not stored in the array.
o len-1 characters are extracted without delim or EOF being encountered.
get() always stores a terminating null character in the array, even if it does
not extract any characters from the stream buffer. get() sets the ios::failbit
if it encounters an EOF character before it stores any characters.
ΓòÉΓòÉΓòÉ 4.5.5.2. get - Extract Characters and Store in Stream Buffer ΓòÉΓòÉΓòÉ
Class: istream
istream& get(streambuf& sb, char delim='\n');
get() with two arguments extracts characters from the stream buffer attached to
ins and stores them in sb. The default value of the delim argument is "\n".
Extraction stops when any of the following conditions is true:
o An EOF character is encountered.
o An attempt to store a character in sb fails. ios::failbit is set in the error
state of ins.
o delim is encountered. delim is left in the stream buffer attached to ins.
ΓòÉΓòÉΓòÉ 4.5.5.3. get - Extract Character and Store in char ΓòÉΓòÉΓòÉ
Class: istream
istream& get(char& cref);
istream& get(signed char& cref);
istream& get(unsigned char& cref);
istream& get(wchar_t& cref);
get() with a single argument extracts a single character or wchar_t from the
stream buffer attached to ins and stores this character in cref.
ΓòÉΓòÉΓòÉ 4.5.5.4. get - Extract Character and Return It ΓòÉΓòÉΓòÉ
Class: istream
int get();
get() with no arguments extracts a character from the stream buffer attached to
ins and returns it. This version of get() returns EOF if EOF is extracted.
ios::failbit is never set.
ΓòÉΓòÉΓòÉ 4.5.5.5. getline - Extract Characters and Store in Array ΓòÉΓòÉΓòÉ
Class: istream
istream& getline(char* ptr, int len, char delim='\n');
istream& getline(signed char* ptr, int len, char delim='\n');
istream& getline(unsigned char* ptr, int len, char delim='\n');
getline() extracts characters from the stream buffer attached to ins and stores
them in the byte array beginning at the location pointed to by ptr and
extending for len bytes. The default value of the delim argument is "\n".
Extraction stops when any one of the following conditions is true:
o delim or EOF is encountered before len-1 characters have been stored in the
array. getline() extracts delim from the stream buffer, but it does not store
delim in the array.
o len-1 characters are extracted before delim or EOF is encountered.
getline() always stores a terminating null character in the array, even if it
does not extract any characters from the stream buffer. getline() sets the
ios::failbit for ins if it encounters an EOF character before it stores any
characters.
getline() is like get() with three arguments, except that get() does not
extract the delim character from the stream buffer, while getline() does.
ΓòÉΓòÉΓòÉ 4.5.5.6. ignore - Extract Characters and Discard Them ΓòÉΓòÉΓòÉ
Class: istream
istream& ignore(int num=1, int delim=EOF);
ignore() extracts up to num character from the stream buffer attached to ins
and discards them. ignore() will extract fewer than num characters if it
encounters delim or EOF.
ΓòÉΓòÉΓòÉ 4.5.5.7. read - Extract Characters and Store in Array ΓòÉΓòÉΓòÉ
Class: istream
istream& read(char* s, int n);
istream& read(signed char* s, int n);
istream& read(unsigned char* s, int n);
read() extracts n characters from the stream buffer attached to ins and stores
them in an array beginning at the position pointed to by s. If EOF is
encountered before read() extracts n characters, read() sets the ios::failbit
in the error state of ins. You can determine the number of characters that
read() extracted by calling gcount() immediately after the call to read().
ΓòÉΓòÉΓòÉ 4.5.6. Public Members of istream for Positioning ΓòÉΓòÉΓòÉ
The following functions are described:
o seekg - reposition get pointer of ultimate producer
o tellg - return position of get pointer of ultimate producer
ΓòÉΓòÉΓòÉ 4.5.6.1. seekg - Reposition Get Pointer of Ultimate Producer ΓòÉΓòÉΓòÉ
Class: istream
istream& seekg(streampos sp);
istream& seekg(streamoff so, ios::seek_dir dir);
seekg() repositions the get pointer of the ultimate producer. seekg() with one
argument sets the get pointer to the position sp. seekg() with two arguments
sets the get pointer to the position specified by dir with the offset so. dir
can have the following values:
o ios::beg: the beginning of the stream
o ios::cur: the current position of the get pointer
o ios::end: the end of the stream
If you attempt to set the get pointer to a position that is not valid, seekg()
sets ios::badbit.
ΓòÉΓòÉΓòÉ 4.5.6.2. tellg - Return Position of Get Pointer of Ultimate Producer ΓòÉΓòÉΓòÉ
Class: istream
streampos tellg();
tellg() returns the current position of the get pointer of the ultimate
producer.
ΓòÉΓòÉΓòÉ 4.5.7. Other Public Members of istream ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of an istream object called ins.
The following member functions are described:
o gcount - Return number of characters extracted
o peek - Return next character without extracting it
o putback - Put extracted characters back into stream buffer
o sync - Synchronize stream buffer and ultimate producer
ΓòÉΓòÉΓòÉ 4.5.7.1. gcount - Return Number of Characters Extracted ΓòÉΓòÉΓòÉ
Class: istream
int gcount();
gcount() returns the number of characters extracted from the stream buffer
attached to ins by the last call to an unformatted input function.
The input operator >> may call unformatted input
functions, and thus formatted input may affect the value returned by gcount().
ΓòÉΓòÉΓòÉ 4.5.7.2. peek - Return Next Character Without Extracting It ΓòÉΓòÉΓòÉ
Class: istream
int peek();
peek() calls ipfx(1). If ipfx() returns zero, or if no more input is available
from the ultimate producer, peek() returns EOF. Otherwise, it returns the next
character in the stream buffer attached to ins without extracting the
character.
ΓòÉΓòÉΓòÉ 4.5.7.3. putback - Put Extracted Characters Back into Stream Buffer ΓòÉΓòÉΓòÉ
Class: istream
istream& putback(char c);
putback() attempts to put a character that was extracted from the stream buffer
attached to ins back into the stream buffer. c must equal the character before
the get pointer of the stream buffer. Unless some other activity is modifying
the stream buffer, this is the last character extracted from the stream buffer.
If c is not equal to the character before the get pointer, the result of
putback() is undefined, and the error state of ins may be set. putback() does
not call ipfx(), but if the error state of ins is nonzero, putback() returns
without doing anything.
ΓòÉΓòÉΓòÉ 4.5.7.4. sync - Synchronize Stream Buffer and Ultimate Producer ΓòÉΓòÉΓòÉ
Class: istream
int sync();
sync() establishes consistency between the ultimate producer and the stream
buffer attached to ins. sync() calls ins.rdbuf()->sync(), which is a virtual
function, so the details of its operation depend on the way the function is
defined in a given derived class. If an error occurs, sync() returns EOF.
ΓòÉΓòÉΓòÉ 4.5.8. Built-In Manipulators for istream ΓòÉΓòÉΓòÉ
istream& ws(istream&);
ios& dec(ios&);
ios& hex(ios&);
ios& oct(ios&);
The I/O Stream Library provides you with a set of built-in manipulators that
can be used with the istream class. These manipulators have a specific effect
on an istream object beyond extracting their own values. The built-in
manipulators are accepted by the following versions of the input operator:
istream& operator>> (istream& (*f) (istream&));
istream& operator>> (ios& (*f) (ios&));
If ins is a reference to an istream object, then this statement extracts
whitespace characters from the stream buffer attached to ins:
ins >> ws;
This statement sets ios::dec:
ins >> dec;
This statement sets ios::hex:
ins >> hex;
This statement sets ios::oct:
ins >> oct;
ΓòÉΓòÉΓòÉ 4.5.9. Public Members of istream_withassign ΓòÉΓòÉΓòÉ
There are two public member functions of istream_withassign:
o istream_withassign constructor
o istream_withassign assignment operator
ΓòÉΓòÉΓòÉ 4.5.9.1. istream_withassign Constructor ΓòÉΓòÉΓòÉ
Class: istream
istream_withassign();
The istream_withassign constructor creates an istream_withassign object. It
does not do any initialization of this object.
ΓòÉΓòÉΓòÉ 4.5.9.2. istream_withassign Assignment Operator ΓòÉΓòÉΓòÉ
Class: istream
istream_withassign& operator=(istream& is);
istream_withassign& operator=(streambuf* sb);
There are two versions of the istream_withassign assignment operator. The first
version takes a reference to an istream object, is, as its argument. It
associates the stream buffer attached to is with the istream_withassign object
that is on the left side of the assignment operator. The following example
shows how you can use this version of the assignment operator to redirect input
that would have come from standard input so that it comes from a file:
#include <iostream.h>
#include <fstream.h>
void main()
{
ifstream infile("eglinton.dat");
char *s=new char[10];
float f;
int i;
cin = infile;
//
// from this point on, all input from cin really
// comes from infile
//
cin >> s >> f >> i;
cout <<"Here are the values from the input file: " << endl;
cout << s << endl << f << endl << i << endl;
infile.close();
exit(0);
}
If the file eglinton.dat contains the following:
Bloor
5.5
3
The example produces the following output:
Here are the values from the input file:
Bloor
5.5
3
Note that this assignment operator gives the istream_withassign object cin the
same stream buffer as the ifstream object, but the two objects maintain
separate ios objects. Thus, if the error state is set through the common stream
buffer, it must be reset twice, once for each of the two ios objects that are
attached to the stream buffer.
The second version of the assignment operator takes a pointer to a streambuf
object, sb, as its argument. It associates this streambuf object with the
istream_withassign object that is on the left side of the assignment operator.
The following example shows how you can use this version of the assignment
operator to associate cin with the input file eglinton.dat:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
void main()
{
ifstream infile("eglinton.dat");
char *s=new char[10];
float f;
int i;
//
// from this point on, all input from cin really
// comes from infile
//
cin = infile.rdbuf();
cin >> s >> f >> i;
cout <<"Here are the values from the input file: " << endl;
cout << s << endl << f << endl << i << endl;
infile.close();
exit(0);
}
Given the same input, this example produces the same output as the preceding
example.
ΓòÉΓòÉΓòÉ 4.6. ostream and ostream_withassign Classes ΓòÉΓòÉΓòÉ
This chapter describes the ostream class and its derived class
ostream_withassign. The ostream member functions allow you to put characters
into the streambuf object that is associated with an ostream object.
ostream_withassign is derived from ostream and includes an assignment operator.
The following topics are described in this chapter:
o Declarations for ostream and ostream_withassign in the iostream.h header file
o Constructors for ostream
o Output suffix and prefix functions
o Public members of ostream for formatted output
o Public members of ostream for unformatted output
o Public members of ostream for positioning
o Other public members of ostream
o Built-in manipulators for ostream
o Public members of ostream_withassign
ΓòÉΓòÉΓòÉ 4.6.1. Declarations for ostream and ostream_withassign in iostream.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses member functions
of the ostream class:
#include <iostream.h>
The following is an excerpt from the iostream.h header file that shows the
relevant declarations for the members of ostream:
class ostream : virtual public ios {
public:
ostream(streambuf*) ;
ostream(int fd) ;
ostream(int size ,char*) ;
virtual ~ostream();
int opfx();
void osfx();
ostream& flush();
ostream& seekp(streampos p);
ostream& seekp(streamoff o,ios::seek_dir d);
streampos tellp();
ostream& put(char c);
ostream& complicated_put(char c);
ostream& operator<<(char c);
ostream& operator<<(signed char c);
ostream& operator<<(unsigned char c);
ostream& operator<<(wchar_t);
ostream& operator<<(const wchar_t *);
ostream& operator<<(const char*);
ostream& operator<<(const signed char*);
ostream& operator<<(const unsigned char*);
ostream& operator<<(int a);
ostream& operator<<(long);
ostream& operator<<(double);
ostream& operator<<(long double);
ostream& operator<<(float);
ostream& operator<<(unsigned int a);
ostream& operator<<(unsigned long);
ostream& operator<<(void*);
ostream& operator<<(streambuf*);
ostream& operator<<(short i);
ostream& operator<<(unsigned short i);
ostream& operator<<(ostream& (*f)(ostream&));
ostream& operator<<(ios& (*f)(ios&) );
ostream& ls_complicated(char);
ostream& ls_complicated(signed char);
ostream& ls_complicated(unsigned char);
ostream& write(const char* s,int n);
ostream& write(const signed char* s, int n);
ostream& write(const unsigned char* s, int n);
protected:
int do_opfx();
void do_osfx();
ostream();
};
class ostream_withassign : public ostream {
public:
ostream_withassign();
virtual ~ostream_withassign();
ostream_withassign& operator=(ostream&);
ostream_withassign& operator=(streambuf*);
};
extern ostream_withassign cout;
extern ostream_withassign cerr;
extern ostream_withassign clog;
ostream& endl(ostream& i);
ostream& ends(ostream& i);
ostream& flush(ostream&);
ios& dec(ios&);
ios& hex(ios&);
ios& oct(ios&);
Note: The following functions have declarations included in the above listing
of iostream.h, but they are only for the internal use of the I/O Stream
Library. Do not use them directly:
o complicated_put()
o ls_complicated()
o do_opfx()
o do_osfx()
ΓòÉΓòÉΓòÉ 4.6.2. Constructors for ostream ΓòÉΓòÉΓòÉ
Class: ostream
ostream(streambuf* sb);
The ostream constructor takes a single argument sb, which is a pointer to a
streambuf object. The constructor creates an ostream object that is attached to
the streambuf object pointed to by sb. The constructor also initializes the
format variables to their defaults.
The other declarations for the ostream constructor in iostream.h are obsolete;
do not use them.
ΓòÉΓòÉΓòÉ 4.6.3. Output Suffix and Prefix Functions ΓòÉΓòÉΓòÉ
The output operator calls the output prefix function opfx() before inserting
characters into a stream buffer, and calls the output suffix function osfx()
after inserting characters. The following descriptions assume the functions are
called as part of an ostream object called os.
ΓòÉΓòÉΓòÉ 4.6.3.1. osfx - Output Suffix Function ΓòÉΓòÉΓòÉ
Class: ostream
void osfx();
osfx() is called before a formatted output function returns. osfx() flushes the
streambuf object attached to os if ios::unitbuf is set.
osfx() is called by the output operator. If you overload the output operator to
handle your own classes, you should ensure that osfx() is called after any
direct manipulation of a streambuf object. Binary output functions do not call
osfx().
ΓòÉΓòÉΓòÉ 4.6.3.2. opfx - Output Prefix Function ΓòÉΓòÉΓòÉ
Class: ostream
int opfx();
opfx() checks the error state of os. If the internal flag ios::hardfail is set,
opfx() returns 0. Otherwise, opfx() flushes the stream buffer attached to the
ios object pointed to by os.tie(), if one exists, and returns the value
returned by ios::good(). ios::good() returns 0 if ios::failbit, ios::badbit, or
ios::eofbit is set. Otherwise, ios::good() returns a nonzero value.
ΓòÉΓòÉΓòÉ 4.6.4. Public Members of ostream for Formatted Output ΓòÉΓòÉΓòÉ
The ostream class lets you use the output operator << to perform formatted
output (or insertion) to a stream buffer. Consider the following statement,
where outs is a reference to an ostream object and x is a variable of a
built-in type:
outs << x;
The output operator << calls opfx() before beginning insertion. If opfx()
returns a nonzero value, the output operator converts x into a series of
characters and inserts these characters into the stream buffer attached to
outs. If an error occurs, the output operator sets ios::failbit.
The details of the conversion of x depend on the format state of the ostream
object and the type of x. For numeric and string values, the output operator
resets the width variable ios::x_width of the format state of an ostream object
to 0, but it does not affect anything else in the format state.
Note: Only the definitions of the output operator for numeric types and for
pointers to char (including signed char and unsigned char) reset ios::x_width.
The output operator is defined for the following types:
o Arrays of characters and char values, including arrays of wchar_t and wchar_t
values.
o Other integral values: short, int, long
o float, double and long double values
o Pointers to void
In addition, the output operator is defined for streambuf objects. The
following sections describe the output operators for these types.
Note: The following descriptions assume that the input operator is called with
the ostream object outs on the left side of the operator.
ΓòÉΓòÉΓòÉ 4.6.4.1. Inserting Fill Characters ΓòÉΓòÉΓòÉ
Once the representation of a value has been determined, the output operator may
insert fill characters. If ios::x_width is greater than 0 and the
representation of the value to be inserted is less than ios::x_width, the
output operator inserts enough fill characters to ensure that the
representation occupies an entire field in the stream buffer. The position of
the fill characters depends on the format state of outs.
ΓòÉΓòÉΓòÉ 4.6.4.2. Output Operator for Arrays of Characters and char Values ΓòÉΓòÉΓòÉ
Class: ostream
ostream& operator<<(const char* cp);
ostream& operator<<(const signed char* cp);
ostream& operator<<(const unsigned char* cp);
ostream& operator<<(wchar_t);
ostream& operator<<(char ch);
ostream& operator<<(signed char ch);
ostream& operator<<(unsigned char ch);
ostream& operator<<(const wchar_t *);
For a pointer to a char, signed char, or unsigned char value, the output
operator inserts all the characters in the string into the stream buffer with
the exception of the null character that terminates the string. For a pointer
to a wchar_t, the output operator converts the wchar_t string to its equivalent
multibyte character string, then inserts it into the stream buffer with the
exception of the null character that terminates the string.
If ios::x_width is greater than zero and the representation of the value to be
inserted is less than ios::x_width, the output operator inserts enough fill
characters to ensure that the representation occupies an entire field in the
stream buffer.
The output operator does not perform any conversion on char, signed char,
unsigned char, or wchar_t values.
ΓòÉΓòÉΓòÉ 4.6.4.3. Output Operator for Other Integral Values ΓòÉΓòÉΓòÉ
Class: ostream
ostream& operator<<(short iv);
ostream& operator<<(unsigned short iv);
ostream& operator<<(int iv);
ostream& operator<<(unsigned int iv);
ostream& operator<<(long iv);
ostream& operator<<(unsigned long iv);
For the integral types (short, unsigned short, int, unsigned int, long, and
unsigned long), the output operator converts the integral value iv according to
the format state of outs and inserts characters into the stream buffer
associated with outs. There is no overflow detection on conversion of integral
types.
The conversion that takes place on iv depends, in part, on the settings of the
following format flags:
o If ios::oct is set, iv is converted to a series of octal digits. If
ios::showbase is set, "0" is inserted into the stream buffer before the octal
digits. If the value being inserted is equal to 0, a single "0" is inserted,
not "00".
o If ios::dec is set, iv is converted to a series of decimal digits.
o If ios::hex is set, iv is converted to a series of hexadecimal digits. If
ios::showbase is set, "0x" (or "0X" if ios::uppercase is set) is inserted
into the stream buffer before the hexadecimal digits.
If none of these format flags is set, iv is converted to a series of decimal
digits. If iv is converted to a series of decimal digits, its sign also affects
the conversion:
o If iv is negative, a negative sign "-" is inserted before the decimal digits.
o If iv is equal to 0, the single digit 0 is inserted.
o If iv is positive and ios::showpos is set, a positive sign "+" is inserted
before the decimal digits.
ΓòÉΓòÉΓòÉ 4.6.4.4. Output Operator for float and double Values ΓòÉΓòÉΓòÉ
Class: ostream
ostream& operator<<(float val);
ostream& operator<<(double val);
ostream& operator<<(long double val);
The output operator performs a conversion operation on the value val and
inserts it into the stream buffer attached to outs. The conversion depends on
the values returned by the following functions:
o outs.precision(): returns the number of significant digits that appear after
the decimal. The default value is 6.
o outs.width(): if this returns 0, val is inserted without any fill characters.
If the return value is greater than the number of characters needed to
represent val, extra fill characters are inserted so that the total number of
characters inserted is equal to the return value.
The conversion also depends on the values of the following format flags:
o If ios::scientific is set, val is converted to scientific notation, with one
digit before the decimal, and the number of digits after the decimal equal to
the value returned by outs.precision(). The exponent begins with a lowercase
"e" unless ios::uppercase is set, in which case the exponent begins with an
uppercase "E".
o If ios::fixed is set, val is converted to fixed notation, with the number of
digits after the decimal point equal to the value returned by
outs.precision(). If neither ios::fixed nor ios::scientific is set, the
conversion depends upon the value of val. See Floating-Point Formatting for
more details.
o If ios::uppercase is set, the exponents of values in scientific notation
begin with an uppercase "E".
See Format State Flags for more details on the format state.
ΓòÉΓòÉΓòÉ 4.6.4.5. Output Operator for Pointers to void ΓòÉΓòÉΓòÉ
Class: ostream
ostream& operator<<(void* vp);
The output operator converts pointers to void to integral values and then
converts them to hexadecimal values as if ios::showbase were set. This version
of the output operator is used to print out the values of pointers.
ΓòÉΓòÉΓòÉ 4.6.4.6. Output Operator for streambuf Objects ΓòÉΓòÉΓòÉ
Class: ostream
ostream& operator<<(streambuf* sb);
If opfx() returns a nonzero value, the output operator inserts all of the
characters that can be taken from sb into the stream buffer attached to outs.
Insertion stops when no more characters can be fetched from sb. No padding is
performed. The return value is outs.
ΓòÉΓòÉΓòÉ 4.6.5. Public Members of ostream for Unformatted Output ΓòÉΓòÉΓòÉ
The functions listed in this section allow you to insert characters into a
stream buffer without regard to the type of the values that the characters
represent.
Note: The following descriptions assume that the functions are called as part
of an ostream object called outs.
The following functions are described:
o put - insert a single character
o write - insert an array of characters
ΓòÉΓòÉΓòÉ 4.6.5.1. put - Insert a Single Character ΓòÉΓòÉΓòÉ
Class: ostream
ostream& put(char c);
put() inserts c in the stream buffer attached to outs. put() sets the error
state of outs if the insertion fails.
ΓòÉΓòÉΓòÉ 4.6.5.2. write - Insert an Array of Characters ΓòÉΓòÉΓòÉ
Class: ostream
ostream& write(const char* cp, int n);
ostream& write(const signed char* cp, int n);
ostream& write(const unsigned char* cp, int n);
write() inserts the n characters that begin at the position pointed to by cp.
This array of characters does not need to end with a null character.
ΓòÉΓòÉΓòÉ 4.6.6. Public Members of ostream for Positioning ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of an ostream object called outs.
The following functions are described:
o seekp - reposition put pointer of ultimate consumer
o tellp - return position of put pointer of associated stream buffer
ΓòÉΓòÉΓòÉ 4.6.6.1. seekp - Reposition Put Pointer of Ultimate Consumer ΓòÉΓòÉΓòÉ
Class: ostream
ostream& seekp(streampos sp);
ostream& seekp(streamoff so, ios::seek_dir dir);
seekp() repositions the put pointer of the ultimate consumer. seekp() with one
argument sets the put pointer to the position sp. seekp() with two arguments
sets the put pointer to the position specified by dir with the offset so. dir
can have the following values:
o ios::beg: the beginning of the stream
o ios::cur: the current position of the put pointer
o ios::end: the end of the stream.
The new position of the put pointer is equal to the position specified by dir
offset by the value of so. If you attempt to move the put pointer to a position
that is not valid, seekp() sets ios::badbit.
ΓòÉΓòÉΓòÉ 4.6.6.2. tellp - Return Position of Put Pointer of Associated Stream Buffer ΓòÉΓòÉΓòÉ
Class: ostream
streampos tellp();
tellp() returns the current position of the put pointer of the stream buffer
that is attached to outs.
ΓòÉΓòÉΓòÉ 4.6.7. Other Public Members of ostream ΓòÉΓòÉΓòÉ
In this section, the following function is described:
flush - clear associated stream buffer
ΓòÉΓòÉΓòÉ 4.6.7.1. clear.flush - Clear Associated Stream Buffer ΓòÉΓòÉΓòÉ
Class: ostream
ostream& flush();
The ultimate consumer of characters that are stored in a stream buffer may not
necessarily consume them immediately. flush() causes any characters that are
stored in the stream buffer attached to outs to be consumed. It calls
outs.rdbuf()->sync() to accomplish this action.
ΓòÉΓòÉΓòÉ 4.6.8. Built-In Manipulators for ostream ΓòÉΓòÉΓòÉ
ostream& endl(ostream& i);
ostream& ends(ostream& i);
ostream& flush(ostream&);
ios& dec(ios&);
ios& hex(ios&);
ios& oct(ios&);
The I/O Stream Library provides you with a set of built-in manipulators that
can be used with the ostream class. These manipulators have a specific effect
on an ostream object beyond extracting their own values. The built-in
manipulators are accepted by the following versions of the output operators:
ostream& operator<<(ostream& (*f)(ostream&));
ostream& operator<<(ios& (*f)(ios&) );
If outs is a reference to an ostream object, then this statement inserts a
newline character and calls flush().
outs << endl;
This statement inserts a null character:
outs << ends;
This statement flushes the stream buffer attached to outs. It is equivalent to
flush()
outs << flush;
This statement sets ios::dec:
outs << dec;
This statement sets ios::hex:
outs << hex;
This statement sets ios::oct:
outs << oct;
ΓòÉΓòÉΓòÉ 4.6.9. Public Members of ostream_withassign ΓòÉΓòÉΓòÉ
There are two public members of ostream_withassign:
o ostream_withassign constructor
o ostream_withassign assignment operator
ΓòÉΓòÉΓòÉ 4.6.9.1. ostream_withassign Constructor ΓòÉΓòÉΓòÉ
Class: ostream
ostream_withassign();
The ostream_withassign constructor creates an ostream_withassign object. It
does not do any initialization on the object.
ΓòÉΓòÉΓòÉ 4.6.9.2. ostream_withassign Assignment Operator ΓòÉΓòÉΓòÉ
Class: ostream
ostream_withassign& operator=(ostream& os);
ostream_withassign& operator=(streambuf* sb);
There are two versions of the ostream_withassign assignment operator. The first
version takes a reference to an ostream object, os, as its argument. It
associates the streambuf attached to os with the ostream_withassign object that
is on the left side of the assignment operator. The following example shows how
this version of the assignment operator is used:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
void main()
{
ofstream outfile("sheppard.dat");
// from this point on, output sent to cout will
// actually be sent to outfile
cout = outfile;
cout << "This is going to the output file." << endl;
outfile.close();
exit(0);
}
After this program is run, the file sheppard.dat contains the following:
This is going to the output file.
The second version of the assignment operator takes a pointer to a streambuf
object, sb, as its argument. It associates sb with the ostream_withassign
object that is on the left side of the assignment operator. The following
example shows how this version of the assignment operator is used:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
void main()
{
ofstream outfile("sheppard.dat");
// from this point on, output sent to cout will
// actually be sent to outfile
cout = outfile.rdbuf();
cout << "This is going to the output file." << endl;
outfile.close();
exit(0);}
This example produces the same results as the preceding example.
ΓòÉΓòÉΓòÉ 4.7. iostream and iostream_withassign Classes ΓòÉΓòÉΓòÉ
This chapter describes the iostream class and its derived class
iostream_withassign. iostream is derived from istream and ostream
iostream_withassign is derived from iostream and includes an assignment
operator. Derivation Relationships in the I/O Stream Library shows how iostream
and iostream_withassign are derived from their base classes.
The following topics are described in this chapter:
o Declarations for iostream and iostream_withassign in iostream.h
o Public members of iostream and iostream_withassign
ΓòÉΓòÉΓòÉ 4.7.1. Declarations for iostream and iostream_withassign in iostream.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses member functions
of the iostream or iostream_withassign classes:
#include <iostream.h>
The following is an excerpt from the iostream.h header file that shows the
relevant declarations for the members of iostream and iostream_withassign:
class iostream : public istream, public ostream {
public:
iostream(streambuf*);
virtual ~iostream();
protected:
iostream();
};
class iostream_withassign : public iostream {
public:
iostream_withassign();
virtual ~iostream_withassign();
iostream_withassign& operator=(ios&);
iostream_withassign& operator=(streambuf*);
};
ΓòÉΓòÉΓòÉ 4.7.2. Public Members of iostream and iostream_withassign ΓòÉΓòÉΓòÉ
The following public member functions are described:
o iostream constructor
o iostream_withassign constructor
o iostream_withassign assignment operator
ΓòÉΓòÉΓòÉ 4.7.2.1. Constructor for iostream ΓòÉΓòÉΓòÉ
Class: iostream
iostream(streambuf* sb);
The iostream constructor takes a single argument sb. The constructor creates an
iostream object that is attached to the streambuf object that is pointed to by
sb. The constructor also initializes the format variables to their defaults.
ΓòÉΓòÉΓòÉ 4.7.2.2. iostream_withassign Constructor ΓòÉΓòÉΓòÉ
Class: iostream_withassign
iostream_withassign();
The iostream_withassign constructor creates an iostream_withassign object. It
does not do any initialization of this object.
ΓòÉΓòÉΓòÉ 4.7.2.3. iostream_withassign Assignment Operator ΓòÉΓòÉΓòÉ
Class: iostream_withassign
iostream_withassign& operator=(ios& is);
iostream_withassign& operator=(streambuf* sb);
There are two versions of the iostream_withassign assignment operator. The
first version takes a reference to an ios object, is, as its argument. It
associates the stream buffer attached to is with the iostream_withassign object
that is on the left side of the assignment operator.
The second version of the iostream_withassign assignment operator takes a
pointer to a streambuf object, sb, as its argument. It associates this
streambuf object with the iostream_withassign object that is on the left side
of the assignment operator.
ΓòÉΓòÉΓòÉ 4.8. filebuf Class ΓòÉΓòÉΓòÉ
This chapter describes the filebuf class. This class is derived from streambuf
and specializes it for using files as the ultimate producer or the ultimate
consumer.
The following topics are described in this chapter:
o Introduction to the filebuf class
o Declarations for filebuf in the fstream.h header file
o Public members of filebuf
ΓòÉΓòÉΓòÉ 4.8.1. Introduction to the filebuf Class ΓòÉΓòÉΓòÉ
In a filebuf object, characters are cleared out of the put area by doing write
operations to the file, and characters are put into the get area by doing read
operations from that file. The filebuf class supports seek operations on files
that allow seek operations. A filebuf object that is attached to a file
descriptor is said to be open.
The stream buffer is allocated automatically if one is not specified explicitly
with a constructor or a call to setbuf(). You can also create an unbuffered
filebuf object by calling the constructor or setbuf() with the appropriate
arguments. If the filebuf object is unbuffered, a system call is made for each
character that is read or written.
The get and put pointers for a filebuf object behave as a single pointer. This
single pointer is referred to as the get/put pointer. The file that is attached
to the filebuf object also has a single pointer that indicates the current
position where information is being read or written. In this chapter, this
pointer is called the file get/put pointer.
ΓòÉΓòÉΓòÉ 4.8.2. Declarations for filebuf in fstream.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses members of the
filebuf class:
#include <fstream.h>
The following is an excerpt from the fstream.h header file that shows the
relevant declarations for the members of filebuf:
class filebuf : public streambuf {
public:
filebuf();
filebuf(int fd);
filebuf(int fd, char* p, int l);
~filebuf();
int detach();
int fd() ;
int is_open();
filebuf* open(const char *name, int om, int
prot=openprot);
filebuf* attach(int fd);
filebuf* close();
virtual int overflow(int=EOF);
virtual int underflow();
virtual int sync();
virtual streampos
seekoff(streamoff,ios::seek_dir,int);
virtual streambuf*
setbuf(char* p, int len);
static const int openprot ;
};
Note: filebuf::openprot is the default protection for open(). It is equivalent
to S_IREAD | S_IWRITE.
ΓòÉΓòÉΓòÉ 4.8.3. Public Members of filebuf ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of a filebuf object called fb.
The following member functions are described:
o Constructors for filebuf
o Destructor for filebuf
o attach - attach filebuf object to file
o close - disconnect filebuf
o detach - detach filebuf object from file
o fd - return file descriptor
o is_open - return status of filebuf
o open - open file and attach to filebuf
o seekoff - move the file get/put pointer
o seekpos - move the file get/put pointer
o setbuf - set up stream buffer
o sync - synchronize file and stream buffer
ΓòÉΓòÉΓòÉ 4.8.3.1. Constructors for filebuf ΓòÉΓòÉΓòÉ
Class: filebuf
filebuf();
filebuf(int d);
filebuf(int d, char* p, int len);
filebuf() constructor with no arguments constructs an initially closed filebuf
object.
filebuf() constructor with one argument constructs a filebuf object that is
attached to file descriptor d.
filebuf() constructor with three arguments constructs a filebuf object that is
attached to file descriptor d. The object is initialized to use the stream
buffer starting at the position pointed to by p with length equal to len.
ΓòÉΓòÉΓòÉ 4.8.3.2. Destructor for filebuf ΓòÉΓòÉΓòÉ
Class: filebuf
~filebuf();
The filebuf destructor calls fb.close().
ΓòÉΓòÉΓòÉ 4.8.3.3. attach - Attach filebuf Object to File ΓòÉΓòÉΓòÉ
Class: filebuf
filebuf* attach(int d);
attach() attaches fb to the file descriptor d. If fb is already open or if d is
not open, attach() returns 0. Otherwise, attach() returns a pointer to fb.
ΓòÉΓòÉΓòÉ 4.8.3.4. detach - Detach filebuf Object from File ΓòÉΓòÉΓòÉ
Class: filebuf
int detach();
fb.detach() disconnects fb from the file without closing the file. If fb is
not open detach() returns -1. Otherwise detach() flushes any output that is
waiting in fb to be sent to the file, disconnects fb from the file, and returns
the file descriptor.
ΓòÉΓòÉΓòÉ 4.8.3.5. close - Disconnect filebuf ΓòÉΓòÉΓòÉ
Class: filebuf
filebuf* close();
close() does the following:
1. Flushes any output that is waiting in fb to be sent to the file
2. Disconnects fb from the file
3. Closes the file that was attached to fb
If an error occurs, close() returns 0. Otherwise, close() returns a pointer to
fb. Even if an error occurs, close() performs the second and third steps listed
above.
ΓòÉΓòÉΓòÉ 4.8.3.6. fd - Return File Descriptor ΓòÉΓòÉΓòÉ
Class: filebuf
int fd();
fd() returns the file descriptor that is attached to fb. If fb is closed, fd()
returns EOF.
ΓòÉΓòÉΓòÉ 4.8.3.7. is_open - Return Status of filebuf ΓòÉΓòÉΓòÉ
Class: filebuf
int is_open();
is_open() returns a nonzero value if fb is attached to a file descriptor.
Otherwise, is_open() returns zero.
ΓòÉΓòÉΓòÉ 4.8.3.8. open - Open File and Attach to filebuf ΓòÉΓòÉΓòÉ
Class: filebuf
filebuf* open(char* fname, int omode, int prot=openprot);
open() opens the file with the name fname and attaches fb to it. If fname does
not already exist and omode does not equal ios::nocreate, open() tries to
create it with protection mode equal to prot. The default value of prot is
filebuf::openprot. An error occurs if fb is already open. If an error occurs,
open() returns 0. Otherwise, open() returns a pointer to fb.
The default protection mode for the filebuf class is S_IREAD | S_IWRITE. If you
create a file with both S_IREAD and S_IWRITE set, the file is created with both
read and write permission. If you create a file with only S_IREAD set, the file
is created with read-only permission, and cannot be deleted later with the
stdio.h library function remove(). S_IREAD and S_IWRITE are defined in
sys\stat.h.
ΓòÉΓòÉΓòÉ 4.8.3.9. seekoff - Move the File Get/Put Pointer ΓòÉΓòÉΓòÉ
Class: filebuf
streampos seekoff(streamoff so, seek_dir sd, int omode);
seekoff() moves the file get/put pointer to the position specified by sd with
the offset so. sd can have the following values:
o ios::beg: the beginning of the file
o ios::cur: the current position of the file get/put pointer
o ios::end: the end of the file
seekoff() changes the position of the file get/put pointer to the position
specified by the value sd + so. The offset so can be either positive or
negative. seekoff() ignores the value of omode.
If fb is attached to a file that does not support seeking, or if the value sd +
so specifies a position before the beginning of the file, seekoff() returns EOF
and the position of the file get/put pointer is undefined. Otherwise, seekoff()
returns the new position of the file get/put pointer.
The following example shows some of the ways that you can call seekoff(). The
file dundas.dat is opened as an fstream object. Assume that this file contains
at least 101 bytes of data. rdbuf() returns the filebuf object that is
associated with this fstream object, and seekoff() is called with a variety of
arguments.
#include <fstream.h>
#define MODE ios::in
void main()
{
streampos pos;
fstream myfile("dundas.dat", MODE);
filebuf *fb = myfile.rdbuf();
// valid: so = 0, dir = ios::end
streamoff offset = 0;
pos= fb->seekoff(offset, ios::end, MODE);
// valid: so = 100, dir = ios::beg
offset = 100;
pos= fb->seekoff(offset, ios::beg, MODE);
// valid: so = -1, dir = ios::end
offset = -1;
pos= fb->seekoff(offset, ios::end, MODE);
// valid: so = 1, dir = ios::cur
offset = 1;
pos= fb->seekoff(offset, ios::cur, MODE);
// invalid: so = -1, dir = ios::beg
offset = -1;
pos= fb->seekoff(offset, ios::beg, MODE);
}
ΓòÉΓòÉΓòÉ 4.8.3.10. seekpos - Move the File Get/Put Pointer ΓòÉΓòÉΓòÉ
Class: filebuf
The filebuf class inherits the default definition of seekpos() from the
streambuf class. The default definition defines seekpos() as a call to
seekoff(). Thus, the following call to seekpos():
seekpos(pos, mode);
is converted to a call to seekoff():
seekoff(streamoff(pos), ios::beg, mode);
ΓòÉΓòÉΓòÉ 4.8.3.11. setbuf - Set Up Stream Buffer ΓòÉΓòÉΓòÉ
Class: filebuf
streambuf* setbuf(char* pbegin, int len);
setbuf() sets up a stream buffer with length in bytes equal to len beginning at
the position pointed to by pbegin. setbuf() does the following:
o If pbegin is 0 or len is nonpositive, setbuf() makes fb unbuffered.
o If fb is open and a stream buffer has been allocated, no changes are made to
this stream buffer, and setbuf() returns 0.
o If neither of these cases is true, setbuf() returns a pointer to fb.
ΓòÉΓòÉΓòÉ 4.8.3.12. sync - Synchronize File and Stream Buffer ΓòÉΓòÉΓòÉ
Class: filebuf
int sync();
sync() attempts to synchronize the get/put pointer and the file get/put
pointer. sync() may cause bytes that are waiting in the stream buffer to be
written to the file, or it may reposition the file get/put pointer if
characters that have been read from the file are waiting in the stream buffer.
If it is not possible to synchronize the get/put pointer and the file get/put
pointer, sync() returns EOF. If it is possible to synchronize them, sync()
returns zero.
ΓòÉΓòÉΓòÉ 4.9. fstream, ifstream, and ofstream Classes ΓòÉΓòÉΓòÉ
This chapter describes fstream, ifstream, and ofstream, the classes that
specialize iostream, istream, and ostream, respectively, for files. Another
class, fstreambase, is declared in the fstream.h header file. fstreambase is
the base class for fstream, ifstream, and ofstream, but it is not meant to be
used directly. fstreambase is only documented here to show the functions that
the other three classes inherit from it: attach(), close(), and setbuf().
The following topics are described in this chapter:
o Declarations in the fstream.h header file
o Public members of fstreambase
o Public members of fstream
o Public members of ifstream
o Public members of ofstream
o Example of using fstream, ifstream and ofstream
ΓòÉΓòÉΓòÉ 4.9.1. Declarations for fstream, ifstream and ofstream in fstream.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses members of the
fstream, ifstream, or ofstream classes:
#include <fstream.h>
The following is an excerpt from the fstream.h header file that shows the
relevant declarations for these three classes:
class fstreambase : virtual public ios {
public:
fstreambase();
fstreambase(const char* name,
int mode,
int prot=filebuf::openprot);
fstreambase(int fd);
fstreambase(int fd, char* p, int l);
~fstreambase();
void open(const char* name, int mode,
int prot=filebuf::openprot);
void attach(int fd);
void close();
int detach();
void setbuf(char* p, int l);
filebuf* rdbuf();
};
class ifstream : public fstreambase, public istream {
public:
ifstream();
ifstream(const char* name,
int mode=ios::in,
int prot=filebuf::openprot);
ifstream(int fd);
ifstream(int fd, char* p, int l);
~ifstream();
filebuf* rdbuf();
void open(const char* name, int mode=ios::in,
int prot=filebuf::openprot);
};
class ofstream : public fstreambase, public ostream {
public:
ofstream();
ofstream(const char* name,
int mode=ios::out,
int prot=filebuf::openprot);
ofstream(int fd);
ofstream(int fd, char* p, int l);
~ofstream();
filebuf* rdbuf();
void open(const char* name, int mode=ios::out,
int prot=filebuf::openprot);
};
class fstream : public fstreambase, public iostream {
public:
fstream();
fstream(const char* name,
int mode,
int prot=filebuf::openprot);
fstream(int fd);
fstream(int fd, char* p, int l);
~fstream();
filebuf* rdbuf();
void open(const char* name, int mode,
int prot=filebuf::openprot)
;
};
ΓòÉΓòÉΓòÉ 4.9.2. Public Members of fstreambase ΓòÉΓòÉΓòÉ
Notes
Note:
1. The fstreambase class is an internal class that provides common functions
for the classes that are derived from it. Do not use the fstreambase class
directly. The following descriptions are provided so that you can use the
functions as part of fstream, ifstream, and ofstream objects.
2. The following descriptions assume that the functions are called as part of
an fstream, ifstream, or ofstream object called fb.
The following functions are described:
o attach - connect fstream object to file descriptor
o close - close associated filebuf object
o setbuf - set up stream buffer
ΓòÉΓòÉΓòÉ 4.9.2.1. attach - Connect fstream Object to File Descriptor ΓòÉΓòÉΓòÉ
Class: fstreambase
void attach(int filedesc);
attach() attaches fb to the file descriptor filedesc. If fb is already attached
to a file descriptor, an error occurs and ios::failbit is set in the format
state of fb. attach() returns zero if the file descriptor is not already open
or if fb is already attached to a file descriptor.
ΓòÉΓòÉΓòÉ 4.9.2.2. close - Close Associated filebuf Object ΓòÉΓòÉΓòÉ
Class: fstreambase
void close();
close() closes the filebuf object, breaking the connection between fb and the
file descriptor. close() calls fb.rdbuf()->close(). If this call fails, the
error state of fb is not cleared.
ΓòÉΓòÉΓòÉ 4.9.2.3. detach - Detach Associated filebuf Object ΓòÉΓòÉΓòÉ
Class: fstreambase
int detach();
detach detaches the filebuf object by calling fb.rdbuf->detach(), and returns
the value returned by fb.rdbuf->detach().
ΓòÉΓòÉΓòÉ 4.9.2.4. setbuf - Set Up Stream Buffer ΓòÉΓòÉΓòÉ
Class: fstreambase
void setbuf(char* pbegin, int len);
setbuf() sets up a stream buffer with length in bytes equal to len beginning at
the position pointed to by pbegin. If pbegin is equal to 0 or len is
nonpositive, fb will be unbuffered. If fb is open, or the call to
fb.rdbuf()->setbuf() fails, setbuf() returns 0. Otherwise, setbuf() returns a
pointer to the stream buffer that was established.
ΓòÉΓòÉΓòÉ 4.9.3. Public Members of fstream ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of an fstream object called fs.
The following functions are described:
o Constructors for fstream
o open - open file and connect to fstream object
o rdbuf - return pointer to filebuf object
ΓòÉΓòÉΓòÉ 4.9.3.1. Constructors for fstream ΓòÉΓòÉΓòÉ
Class: fstream
fstream();
fstream(int filedesc);
fstream(const char* fname, int mode, int prot=filebuf::openprot);
fstream(int filedesc, char* bufpos, int len);
There are four versions of the fstream constructor. The first version takes no
arguments and constructs an unopened fstream object. The second version takes
two arguments and constructs an fstream object that is attached to the file
descriptor filedesc. If filedesc is not open, ios::failbit is set in the format
state of fs.
The third and fourth versions of the fstream() constructor take three
arguments. The third version constructs an fstream object and opens the file
fname with open mode equal to mode and protection mode equal to prot. The
default value for the argument prot is filebuf::openprot. If the file cannot be
opened, the error state of the constructed fstream object is set.
The fourth version constructs an fstream object that is attached to the file
descriptor filedesc. If filedesc is not open, ios::failbit is set in the format
state of fs. This constructor also sets up an associated filebuf object with a
stream buffer that has length len bytes and begins at the position pointed to
by bufpos. If bufpos is equal to 0 or len is equal to 0, the associated filebuf
object is unbuffered.
ΓòÉΓòÉΓòÉ 4.9.3.2. open - Open File and Connect to fstream Object ΓòÉΓòÉΓòÉ
Class: fstream
void open(const char* fname, int mode, int prot=filebuf::openprot);
open() opens the file with the name fname and attaches it to fs. If fname does
not already exist, open() tries to create it with protection mode equal to
prot, unless ios::nocreate is set.
The default value for prot is filebuf::openprot. If fs is already attached to a
file or if the call to fs.rdbuf()->open() fails, ios::failbit is set in the
error state for fs.
The members of the ios::open_mode enumeration are bits that can be ORed
together. The value of mode is the result of such an OR operation. This result
is an int value, and for this reason, mode has type int rather than open_mode.
The elements of the open_mode enumeration have the following meanings:
ios::app open() performs a seek to the end of the file. Data that is
written is appended to the end of the file. This value implies
that the file is open for output.
ios::ate open() performs a seek to the end of the file. Setting ios::ate
does not open the file for input or output. If you set ios::ate,
you should explicitly set ios::in, ios::out, or both.
ios::bin See ios::binary below.
ios::binary The file is opened in binary mode. In the default (text) mode,
carriage returns are discarded on input, as is an end-of-file
(0x1a) character if it is the last character in the file. This
means that a carriage return without an accompanying line feed
causes the characters on either side of the carriage return to
become adjacent. On output, a line feed is expanded to a
carriage return and line feed. If you specify ios::binary,
carriage returns and terminating end-of-file characters are not
removed on input, and a line feed is not expanded to a carriage
return and line feed on output. ios::binary and ios::bin provide
identical functionality.
ios::in The file is opened for input. If the file that is being opened
for input does not exist, the open operation will fail.
ios::noreplace is ignored if ios::in is set.
ios::out The file is opened for output.
ios::trunc If the file already exists, its contents will be discarded. If
you specify ios::out and neither ios::ate nor ios::app, you are
implicitly specifying ios::trunc. If you set ios::trunc, you
should explicitly set ios::in, ios::out, or both.
ios::nocreate If the file does not exist, the call to open() fails.
ios::noreplace If the file already exists and ios::out is set, the call to
open() fails. If ios::out is not set, ios::noreplace is ignored.
ΓòÉΓòÉΓòÉ 4.9.3.3. rdbuf - Return Pointer to filebuf Object ΓòÉΓòÉΓòÉ
Class: fstream
filebuf* rdbuf();
rdbuf() returns a pointer to the filebuf object that is attached to fs.
ΓòÉΓòÉΓòÉ 4.9.4. Public Members of ifstream ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of an ifstream object called ifs.
o Constructors for ifstream
o open - open file and connect to ifstream object
o rdbuf - return pointer to filebuf object
ΓòÉΓòÉΓòÉ 4.9.4.1. Constructors for ifstream ΓòÉΓòÉΓòÉ
Class: ifstream
ifstream();
ifstream(int filedesc);
ifstream(const char* fname,
int mode=ios::in,
int prot=filebuf::openprot);
ifstream(int filedesc, char* bufpos, int len);
There are four versions of the ifstream constructor. The first version takes no
arguments and constructs an unopened ifstream object. The second version takes
one argument and constructs an ifstream object that is attached to the file
descriptor filedesc. If filedesc is not open, ios::failbit is set in the format
state of ifs.
The third and fourth versions of the ifstream() constructor take three
arguments. The third version constructs an ifstream object and opens the file
fname with open mode equal to mode and protection mode equal to prot. The
default value for mode is ios::in, and the default value for prot is
filebuf::openprot. If the file cannot be opened, the error state of the
constructed ifstream object is set.
The fourth version constructs an ifstream object that is attached to the file
descriptor filedesc. If filedesc is not open, ios::failbit is set in the format
state of ifs. This constructor also sets up an associated filebuf object with a
stream buffer that has length len bytes and begins at the position pointed to
by bufpos. If bufpos is equal to 0 or len is equal to 0, the associated filebuf
object is unbuffered.
ΓòÉΓòÉΓòÉ 4.9.4.2. open - Open File and Connect to ifstream Object ΓòÉΓòÉΓòÉ
Class: ifstream
void open(const char* fname,
int mode=ios::in,
int prot=filebuf::openprot);
open() opens the file with the name fname and attaches it to ifs. If fname does
not already exist, open() tries to create it with protection mode equal to
prot, unless ios::nocreate is set in mode.
The default value for mode is ios::in. The default value for prot is
filebuf::openprot. If ifs is already attached to a file, or if the call to
ifs.rdbuf()->open() fails, ios::failbit is set in the error status for ifs.
The members of the ios::open_mode enumeration are bits that can be ORed
together. The value of mode is the result of such an OR operation. This result
is an int value, and for this reason mode has type int rather than type
open_mode. See open - Open File and Connect to fstream Object for a list of the
possible values for mode.
ΓòÉΓòÉΓòÉ 4.9.4.3. rdbuf - Return Pointer to filebuf Object ΓòÉΓòÉΓòÉ
Class: ifstream
filebuf* rdbuf();
rdbuf() returns a pointer to the filebuf object that is attached to ifs.
ΓòÉΓòÉΓòÉ 4.9.5. Public Members of ofstream ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of an ofstream object called ofs.
o Constructors for ofstream
o open - open file and connect to ofstream object
o rdbuf - return pointer to filebuf object
ΓòÉΓòÉΓòÉ 4.9.5.1. Constructors for ofstream ΓòÉΓòÉΓòÉ
Class: ofstream
ofstream();
ofstream(int filedesc);
ofstream(const char* fname,
int mode=ios::out,
int prot=filebuf::openprot);
ofstream(int filedesc, char* bufpos, int len);
There are four versions of the ofstream constructor. The first version takes no
arguments and constructs an unopened ofstream object. The second version takes
one argument and constructs an ofstream object that is attached to the file
descriptor filedesc. If filedesc is not open, ios::failbit is set in the format
state of ofs.
The third and fourth versions of the ofstream() constructor take three
arguments. The third version constructs an ofstream object and opens the file
fname with open mode equal to mode and protection mode equal to prot. The
default value for mode is ios::out, and the default value for prot is
filebuf::openprot. If the file cannot be opened, the error state of the
constructed ofstream object is set.
The fourth version constructs an ofstream object that is attached to the file
descriptor filedesc. If filedesc is not open, ios::failbit is set in the format
state of ofs. This constructor also sets up an associated filebuf object with a
stream buffer that has length len bytes and begins at the position pointed to
by bufpos. If p is equal to 0 or len is equal to 0, the associated filebuf
object is unbuffered.
ΓòÉΓòÉΓòÉ 4.9.5.2. open - Open File and Connect to ofstream Object ΓòÉΓòÉΓòÉ
Class: ofstream
void open(const char* fname, int mode, int prot=filebuf::openprot);
open() opens the file with the name fname and attaches it to ofs. If fname does
not already exist, open() tries to create it with protection mode equal to
prot, unless ios::nocreate is set.
The default value for mode is ios::out. The default value for the argument prot
is filebuf::openprot. If ofs is already attached to a file, or if the call to
the function ofs.rdbuf()->open() fails, ios::failbit is set in the error state
for ofs.
The members of the ios::open_mode enumeration are bits that can be ORed
together. The value of mode is the result of such an OR operation. This result
is an int value, and for this reason, mode has type int rather than open_mode.
See open - Open File and Connect to fstream Object for a list of the possible
values for mode.
ΓòÉΓòÉΓòÉ 4.9.5.3. rdbuf - Return Pointer to filebuf Object ΓòÉΓòÉΓòÉ
Class: ofstream
filebuf* rdbuf();
rdbuf() returns a pointer to the filebuf object that is attached to ofs.
ΓòÉΓòÉΓòÉ 4.9.6. Example of Using fstream, ifstream, and ofstream ΓòÉΓòÉΓòÉ
In the following example, the ifstream object source is associated with the
input file source.dat, and the ofstream object dest is associated with the
output file dest.dat. After both files have been opened, the contents of
source.dat are written to dest.dat through the associated ifstream and ofstream
objects.
#include <fstream.h>
#include <stdlib.h>
void main() {
ifstream source("source.dat");
ofstream dest("dest.dat");
//
// Check that the source file was opened correctly
if (!source)
{
cerr << "Cannot open file 'source.dat'" << endl;
exit(1);
}
//
// Check that the destination file was opened correctly
if (!dest)
{
cerr << "Cannot open file 'dest.dat'" << endl;
exit(1);
}
// Read source file and write it to the dest file.
char c = 0;
while (dest && source.get(c))
dest.put(c);
if (!source.eof())
{
cerr << "Unexpected result" << endl;
exit(1);
}
//
// Close files.
source.close();
dest.close();
exit(0);
}
ΓòÉΓòÉΓòÉ 4.10. strstreambuf Class ΓòÉΓòÉΓòÉ
This chapter describes the strstreambuf class, the class that specializes
streambuf to use an array of bytes in memory as the ultimate producer or
ultimate consumer.
The following topics are described in this chapter:
o Declarations for strstreambuf in strstrea.h header file
o Public members of strstreambuf
ΓòÉΓòÉΓòÉ 4.10.1. Declarations for strstreambuf in strstrea.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses the strstreambuf
class:
#include <strstrea.h>
The following is an excerpt from the strstrea.h header file that shows the
relevant declarations for the public, nonvirtual members of strstreambuf:
class strstreambuf : public streambuf
{
public:
strstreambuf();
strstreambuf(int)
strstreambuf(void* (*a)(long),
void (*f)(void*));
strstreambuf(char* b, int size,
char* pstart = 0 );
strstreambuf(signed char* b, int size,
signed char* pstart = 0 );
strstreambuf(unsigned char* b, int size,
unsigned char* pstart = 0 );
~strstreambuf();
int pcount();
void freeze(int n=1);
char* str();
virtual int doallocate();
virtual int overflow(int);
virtual int underflow();
virtual streampos seekoff(streamoff, ios::seek_dir, int);
virtual streambuf* setbuf(char* p, int n); };
Note: Do not use pcount(). It is declared as a public member function of the
strstreambuf class, but pcount() is meant to be used internally by the I/O
Stream Library.
ΓòÉΓòÉΓòÉ 4.10.2. Public Members of strstreambuf ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructors for strstreambuf
o Destructor for strstreambuf
o doallocate - allocate space for a stream buffer
o freeze - control deletion of stream buffer
o overflow - clear put area
o str - return pointer to beginning of stream buffer and freeze strstreambuf
Object
o seekoff - reposition get or put pointer in memory array
o setbuf - set minimum stream buffer size
o underflow - fill get area.
ΓòÉΓòÉΓòÉ 4.10.2.1. Constructors for strstreambuf ΓòÉΓòÉΓòÉ
Class: strstreambuf
strstreambuf();
strstreambuf(int bufsize);
strstreambuf(void* (*alloc) (long), void(*free)(void*));
strstreambuf(char* sp, int len, char* tp);
strstreambuf(signed char* sp, int len, signed char* tp);
strstreambuf(unsigned char* sp, int len, unsigned char* tp);
The first version of the strstreambuf constructor takes no arguments and
constructs an empty strstreambuf object in dynamic mode. Space will be
allocated automatically to accommodate the characters that are put into the
strstreambuf object. This space will be allocated using the operator new and
deallocated using the operator delete. The characters that are already stored
by the strstreambuf object may have to be copied when new space is allocated.
If you know you are going to insert many characters into an strstreambuf
object, you can give the I/O Stream Library an estimate of the size of the
object before you create it by calling strstreambuf::setbuf().
The second version of the strstreambuf constructor takes one argument and
constructs an empty strstreambuf object in dynamic mode. The initial size of
the stream buffer will be at least bufsize bytes.
The third version of the strstreambuf constructor takes two arguments and
creates an empty strstreambuf object in dynamic mode. alloc is a pointer to the
function that is used to allocate space. alloc is passed a long value that
equals the number of bytes that it is supposed to allocate. If the value of
alloc is 0, the operator new is used to allocate space. free is a pointer to
the function that is used to free space. free is passed an argument that is a
pointer to the array of bytes that alloc allocated. If free has a value of 0,
the operator delete is used to free space.
The fourth, fifth, and sixth versions of the strstreambuf constructor take
three arguments and construct a strstreambuf object with a stream buffer that
begins at the position pointed to by sp. The nature of the stream buffer
depends on the value of len:
o If len is positive, the len bytes following the position pointed to by sp
make up the stream buffer.
o If len equals 0, sp points to the beginning of a null-terminated string, and
the bytes of that string, excluding the terminating null character, will make
up the stream buffer.
o If len is negative, the stream buffer has an indefinite length. The get
pointer of the stream buffer is initialized to sp, and the put pointer is
initialized to tp.
Regardless of the value of len, if the value of tp is 0, the get area will
include the entire stream buffer, and insertions will cause errors.
ΓòÉΓòÉΓòÉ 4.10.2.2. Destructor for strstreambuf ΓòÉΓòÉΓòÉ
Class: strstreambuf
~strstreambuf();
If freeze() has not been called for the strstreambuf object, and a stream
buffer is associated with the strstreambuf object, the strstreambuf destructor
frees the space allocated by the strstreambuf constructor. The effect of the
destructor depends on the constructor used to create the strstreambuf object:
o If you created the strstreambuf object using the constructor that takes two
pointers to functions as arguments (see Constructors for strstreambuf for
more details), the destructor frees the space allocated by the destructor by
calling the function pointed to by the second argument to the constructor.
o If you created the strstreambuf object using any of the other constructors,
the destructor calls the delete operator to free the space allocated by the
constructor.
ΓòÉΓòÉΓòÉ 4.10.2.3. doallocate - Allocate Space for a Stream Buffer ΓòÉΓòÉΓòÉ
Class: strstreambuf
virtual int doallocate();
doallocate() attempts to allocate space for a stream buffer. If you created the
strstreambuf object using the constructor that takes two pointers to functions
as arguments (see Constructors for strstreambuf for more details), doallocate()
allocates space for the stream buffer by calling the function pointed to by the
first argument to the constructor. Otherwise, doallocate() calls the operator
new to allocate space for the stream buffer.
ΓòÉΓòÉΓòÉ 4.10.2.4. freeze - Control Deletion of Stream Buffer ΓòÉΓòÉΓòÉ
Class: strstreambuf
void freeze(int n=1);
freeze() controls whether the array that makes up a stream buffer can be
deleted automatically. If n has a nonzero value, the array is not deleted
automatically. If n equals 0, the array is deleted automatically when more
space is needed or when the strstreambuf object is deleted. If you call
freeze() with a nonzero argument for a strstreambuf object that was allocated
in dynamic mode, any attempts to put characters in the stream buffer may result
in errors. Therefore, you should avoid insertions to such stream buffers
because the results are unpredictable. However, if you have a "frozen" stream
buffer and you call freeze() with an argument equal to 0, you can put
characters in the stream buffer again.
Only space that is acquired through dynamic allocation is ever freed.
ΓòÉΓòÉΓòÉ 4.10.2.5. overflow - Clear Put Area ΓòÉΓòÉΓòÉ
Class: strstreambuf
virtual int overflow(int c);
overflow() causes the ultimate consumer to consume the characters in the put
area and calls setp() to establish a new put area. The argument c is stored in
the new put area if c is not equal to EOF.
ΓòÉΓòÉΓòÉ 4.10.2.6. str - Return Pointer to Beginning of Stream Buffer and Freeze strstreambuf Object ΓòÉΓòÉΓòÉ
Class: strstreambuf
char* str();
str() returns a pointer to the first character in the stream buffer and calls
freeze() with a nonzero argument. Any attempts to put characters in the stream
buffer may result in errors. If the strstreambuf object was created with an
explicit array (that is, the strstreambuf constructor with three arguments was
used), str() returns a pointer to that array. If the strstreambuf object was
created in dynamic mode and nothing is stored in the array, str() may return 0.
ΓòÉΓòÉΓòÉ 4.10.2.7. seekoff - Reposition Get or Put Pointer in Memory Array ΓòÉΓòÉΓòÉ
Class: strstreambuf
virtual streampos seekoff(
streamoff so, ios::seek_dir dir, int mode);
seekoff() repositions the get or put pointer in the array of bytes in memory
that serves as the ultimate producer or the ultimate consumer. For a text mode
file, seekoff() returns the actual physical file position, because carriage
return characters and end-of-file characters are discarded on input. Thus,
there may not be a one-to-one correspondence between the characters in a stream
and those in its external representation. For further details, see "Low-Level
I/O" in the IBM C/C++ Tools C Library Reference.
If you constructed the strstreambuf in dynamic mode (see Constructors for
strstreambuf), the results of seekoff() are unpredictable. Therefore, do not
use seekoff() with an strstreambuf object that you created in dynamic mode.
If you did not construct the strstreambuf object in dynamic mode, seekoff()
attempts to reposition the get pointer or the put pointer, depending on the
value of mode. If ios::in is set in mode, seekoff() repositions the get
pointer. If ios::out is set in mode, seekoff() repositions the put pointer. If
both ios::in and ios::out are set, seekoff() repositions both pointers.
seekoff() attempts to reposition the affected pointer to the value of dir + so.
dir can have the following values:
o ios::beg: the beginning of the array in memory
o ios::cur: the current position in the array in memory
o ios::end: the end of the array in memory.
If the value of dir + so is equal to or greater than the end of the array, the
value is not valid and seekoff() returns EOF. Otherwise, seekoff() sets the
affected pointer to this value and returns this value.
The following example shows some of the settings of dir and so that can result
in a value that is not valid:
#include <string.h>
#include <strstrea.h>
char *DATA = "Hello";
#define MODE ios::in
void main()
{
streampos pos;
strstream temp (DATA, (int)strlen(DATA)+1, ios::in);
strstreambuf *ss = temp.rdbuf();
//
// invalid: so = 0, dir = ios::end
streamoff offset = 0;
pos= ss->seekoff(offset, ios::end, MODE);
if (pos == streampos(EOF)) {
cout << "seekoff returned EOF" << endl;
cout << "offset equals " << offset << endl;
cout << "position equals " << ios::end << endl;
}
//
// invalid: so = strlen(DATA)+1, dir = ios::beg
offset = strlen(DATA)+1;
pos= ss->seekoff(offset, ios::beg, MODE);
if (pos == streampos(EOF)) {
cout << "seekoff returned EOF" << endl;
cout << "offset equals " << offset << endl;
cout << "position equals " << ios::beg << endl;
}
//
// valid: so = -1, dir = ios::end
offset = -1;
pos= ss->seekoff(offset, ios::end, MODE);
if (pos == streampos(EOF)) {
cout << "seekoff returned EOF" << endl;
cout << "offset equals " << offset << endl;
cout << "position equals " << ios::end << endl;
}
//
// invalid: so = 1, dir = ios::cur
offset = 1;
pos= ss->seekoff(offset, ios::cur, MODE);
if (pos == streampos(EOF)) {
cout << "seekoff returned EOF" << endl;
cout << "offset equals " << offset << endl;
cout << "position equals " << ios::cur << endl;
}
}
The attempts to position the get pointer to the end of the array or beyond the
end of the array are not valid. seekoff() returns EOF in these cases. The
following is the expected output of this example:
seekoff returned EOF
offset equals 0
position equals 2
seekoff returned EOF
offset equals 6
position equals 0
seekoff returned EOF
offset equals 1
position equals 1
ΓòÉΓòÉΓòÉ 4.10.2.8. setbuf - Set Minimum Stream Buffer Size ΓòÉΓòÉΓòÉ
Class: strstreambuf
virtual streambuf* setbuf(0, int bufsize);
setbuf() records bufsize. The next time that the strstreambuf object
dynamically allocates a stream buffer, the stream buffer is at least bufsize
bytes long.
Note: If you call setbuf() for an strstreambuf object, you must call it with
the first argument equal to 0.
ΓòÉΓòÉΓòÉ 4.10.2.9. underflow - Fill Get Area ΓòÉΓòÉΓòÉ
Class: strstreambuf
virtual int underflow();
If the get area is not empty, underflow() returns the first character in the
get area. If the get area is empty, underflow() creates a new get area that is
not empty and returns the first character. If no more characters are available
in the ultimate producer, underflow() returns EOF and leaves the get area
empty.
ΓòÉΓòÉΓòÉ 4.11. strstream, istrstream, and ostrstream Classes ΓòÉΓòÉΓòÉ
This chapter describes istrstream, ostrsteam, and strstream, the classes that
specialize istream, ostream, and iostream (respectively) to use strstreambuf
objects for stream buffers. These classes are called the array stream buffer
classes because their stream buffers are arrays of bytes in memory. You can use
these classes to perform input and output with strings in memory.
This chapter also describes strstreambase, the class from which the array
stream buffer classes are derived.
The following topics are described in this chapter:
o Declarations for array stream buffer classes in strstrea.h
o Public members of strstreambase
o Public members of strstream
o Public members of istrstream
o Public members of ostrstream
ΓòÉΓòÉΓòÉ 4.11.1. Declarations for strstream, istrstream and ostrstream in strstrea.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses istrstream,
ostrsteam, or strstream:
#include <strstrea.h>
The following is an excerpt from the strstrea.h header file that shows the
relevant declarations for the members of the istrstream, ostrsteam, and
strstream classes:
class strstreambase : public virtual ios {
public:
strstreambuf* rdbuf();
};
class istrstream : public strstreambase, public istream
{
public:
istrstream(char* str);
istrstream(signed char* str);
istrstream(unsigned char* str);
istrstream(char* str, int size );
istrstream(signed char* str, int size);
istrstream(unsigned char* str, int size);
istrstream(const char* str);
istrstream(const signed char* str);
istrstream(const unsigned char* str);
istrstream(const char* str, int size );
istrstream(const signed char* str, int size);
istrstream(const unsigned char* str, int size);
~istrstream();
};
class ostrstream : public strstreambase, public ostream {
public:
ostrstream(char* str, int size,
int=ios::out);
ostrstream(signed char* str,
int size, int=ios::out);
ostrstream(unsigned char* str,
int size, int=ios::out);
ostrstream();
~ostrstream();
char* str();
int pcount();
};
class strstream : public strstreambase, public iostream
{
public:
strstream();
strstream(char* str, int size, int mode);
strstream(signed char* str, int size,
int mode);
strstream(unsigned char* str, int size,
int mode);
~strstream();
char* str();
};
ΓòÉΓòÉΓòÉ 4.11.2. Public Members of strstreambase ΓòÉΓòÉΓòÉ
Note: The strstreambase class is an internal class that provides common
functions for the classes that are derived from it. Do not use the
strstreambase class directly. The following description is provided so that you
can use the function as part of istrstream, ostrsteam, and strstream objects.
ΓòÉΓòÉΓòÉ 4.11.2.1. rdbuf - Return Pointer to Associated Stream Buffer ΓòÉΓòÉΓòÉ
Class: ostrsteam
strstreambuf* rdbuf();
rdbuf() returns a pointer to the stream buffer that the strstreambase object is
attached to.
ΓòÉΓòÉΓòÉ 4.11.3. Public Members of strstream ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructor for strstream
o Destructor for strstream
o str - return pointer to stream buffer array
An example of using the strstream class is also provided.
ΓòÉΓòÉΓòÉ 4.11.3.1. Constructor for strstream ΓòÉΓòÉΓòÉ
Class: strstream
strstream();
strstream(char* cp, int len, int mode);
strstream(signed char* cp, int len, int mode);
strstream(unsigned char* cp, int len, int mode);
There are two versions of the strstream constructor. The version that takes no
arguments specifies that space is allocated dynamically for the stream buffer
that is attached to the strstream object.
The version of the strstream constructor that takes three arguments specifies
that characters should be extracted and inserted into the array of bytes that
starts at the position pointed to by cp with a length of len bytes. If ios::ate
or ios::app is set in mode, cp points to a null-terminated string and
insertions begin at the null character. Otherwise, insertions begin at the
position pointed to by cp. You can use the istream::seekg() function to
reposition the get pointer anywhere in this array.
ΓòÉΓòÉΓòÉ 4.11.3.2. Destructor for strstream ΓòÉΓòÉΓòÉ
Class: ostrsteam
~strstream();
The strstream destructor frees the space allocated by the strstream
constructor.
ΓòÉΓòÉΓòÉ 4.11.3.3. str - Return Pointer to Stream Buffer Array ΓòÉΓòÉΓòÉ
Class: ostrsteam
char* str();
str() returns a pointer to the stream buffer attached to the strstream and
calls freeze() with a nonzero value to prevent the stream buffer from being
deleted. If the stream buffer was constructed with an explicit array, the value
returned is a pointer to that array. If the stream buffer was constructed in
dynamic mode, cp points to the dynamically allocated area.
Until you call str(), deleting the dynamically allocated stream buffer is the
responsibility of the strstream object. After str() has been called, the
calling application has responsibility for the dynamically allocated stream
buffer.
Note: If your application calls str() without calling freeze() with a nonzero
argument (to unfreeze the strstream), or without explicitly deleting the array
of characters returned by the call to str(), the array of characters will not
be deallocated by the strstream when it gets destroyed. This situation is a
potential source of a memory leak.
ΓòÉΓòÉΓòÉ 4.11.3.4. Example of Using the strstream Class ΓòÉΓòÉΓòÉ
Class: ostrsteam
The following example shows how you can use the strstream class. An strstream
object s is created, and a line of data is written into it. This data is sent
to cout using str(). str() calls freeze() with a nonzero argument and "freezes"
the stream buffer attached to s. Therefore, the next step is to "thaw" the
stream buffer by calling freeze() with an argument equal to 0. Once this has
been done, the program continues by writing each character in s to cout using
get().
#include <strstrea.h>
void main()
{
strstream s;
char c;
s << "A line of data is written to the strstream.";
//
// Get access to the stream buffer via str().
// The call to str() freezes the stream buffer.
cout << "The string is: " << s.str() << endl;
//
// Now thaw it so that we can proceed.
s.rdbuf()->freeze(0);
cout << "The string is: ";
while (s)
{
c = s.get();
cout << c;
}
cout << endl;
}
The example produces the following output:
The string is: A line of data is written to the strstream.
The string is: A line of data is written to the strstream.
ΓòÉΓòÉΓòÉ 4.11.4. Public Members of istrstream ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructors for istrstream
o Destructor for istrstream
ΓòÉΓòÉΓòÉ 4.11.4.1. Constructors for istrstream ΓòÉΓòÉΓòÉ
Class: istrstream
istrstream(char* cp);
istrstream(signed char* cp);
istrstream(unsigned char* cp);
istrstream(const char* cp);
istrstream(const signed char* cp);
istrstream(const unsigned char* cp);
istrstream(char* cp, int len);
istrstream(signed char* cp, int len);
istrstream(unsigned char* cp, int len);
istrstream(const char* cp, int len);
istrstream(const signed char* cp, int len);
istrstream(const unsigned char* cp, int len);
The versions of the istrstream constructor that take one argument specify that
characters should be extracted from the null-terminated string that is pointed
to by cp. You can use the istream::seekg() function to reposition the get
pointer in this string.
The versions of the istrstream constructor that take two arguments specify that
characters should be extracted from the array of bytes that starts at the
position pointed to by cp and has a length of len bytes. You can use
istream::seekg() to reposition the get pointer anywhere in this array.
ΓòÉΓòÉΓòÉ 4.11.4.2. istrstream Destructor ΓòÉΓòÉΓòÉ
Class: ostrsteam
~istrstream();
The istrstream destructor frees space that was allocated by the istrstream
constructor.
ΓòÉΓòÉΓòÉ 4.11.5. Public Members of ostrstream ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructors for ostrstream
o Destructor for ostrstream
o str - return pointer to stream buffer array
o pcount - return number of characters in stream buffer
ΓòÉΓòÉΓòÉ 4.11.5.1. Constructors for ostrstream ΓòÉΓòÉΓòÉ
Class: ostrsteam
ostrstream();
ostrstream(char* cp, int len, int mode = ios::out);
ostrstream(signed char* cp, int len, int mode = ios::out);
ostrstream(unsigned char* cp, int len, int mode = ios::out);
The version of the ostrsteam constructor that takes no arguments specifies that
space is allocated dynamically for the stream buffer that is attached to the
ostrsteam object.
The versions of the ostrsteam constructor that take three arguments specify
that the stream buffer that is attached to the ostrsteam object consists of an
array that starts at the position pointed to by cp with a length of len bytes.
If ios::ate or ios::app is set in mode, cp points to a null-terminated string
and insertions begin at the null character. Otherwise, insertions begin at the
position pointed to by cp. You can use the ostream::seekp() function to
reposition the put pointer.
ΓòÉΓòÉΓòÉ 4.11.5.2. Destructor for ostrstream ΓòÉΓòÉΓòÉ
Class: ostrsteam
~ostrstream();
The ostrsteam destructor frees space allocated by the ostrsteam constructor.
The destructor also writes a null byte to the stream buffer to terminate the
stream.
ΓòÉΓòÉΓòÉ 4.11.5.3. str - Return Pointer to Stream Buffer Array ΓòÉΓòÉΓòÉ
Class: ostrsteam
char* str();
str() returns a pointer to the stream buffer attached to the ostrsteam and
calls freeze() with a nonzero value to prevent the stream buffer from being
deleted. If the stream buffer was constructed with an explicit array, the value
returned is a pointer to that array. If the stream buffer was constructed in
dynamic mode, cp points to the dynamically allocated area.
Until you call str(), deleting the dynamically allocated stream buffer is the
responsibility of the ostrsteam object. After str() has been called, the
calling application has responsibility for the dynamically allocated stream
buffer.
ΓòÉΓòÉΓòÉ 4.11.5.4. pcount - Return Number of Characters in Stream Buffer ΓòÉΓòÉΓòÉ
Class: ostrsteam
int pcount();
pcount() returns the number of bytes that have been stored in the stream
buffer. pcount() is mainly useful when binary data has been stored and the
stream buffer attached to the ostrsteam object is not a null-terminated string.
pcount() returns the total number of bytes, not just the number of bytes up to
the first null character.
ΓòÉΓòÉΓòÉ 4.12. stdiobuf and stdiostream Classes ΓòÉΓòÉΓòÉ
This chapter describes the stdiobuf class and stdiostream, the class that uses
stdiobuf objects as stream buffers. Operations on an stdiobuf are mirrored on
the associated FILE structure (defined in the C header file stdio.h).
Note: The classes described in this chapter are meant to be used when you have
to mix C code with C++ code. If you are writing new C++ code, use filebuf
fstream, ifstream, and ofstream instead of stdiobuf and stdiostream.
The following topics are described in this chapter:
o Declarations for stdiobuf and stdiostream in stdiostr.h
o Public members of stdiobuf
o Public members of stdiostream
ΓòÉΓòÉΓòÉ 4.12.1. Declarations for stdiobuf and stdiostream in stdiostr.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses the stdiobuf
class:
#include <stdiostr.h>
The following is an excerpt from the stdiostr.h header file that shows the
relevant declarations for the members of stdiobuf:
class stdiobuf : public streambuf {
public:
stdiobuf(FILE* f);
virtual ~stdiobuf();
virtual int overflow(int=EOF);
virtual int underflow();
virtual int sync() ;
virtual streampos
seekoff(streamoff,ios::seek_dir,int);
virtual int pbackfail(int c);
FILE* stdiofile();
};
class stdiostream : public ios {
public:
stdiostream(FILE*);
~stdiostream();
stdiobuf* rdbuf();
};
ΓòÉΓòÉΓòÉ 4.12.2. Public Members of stdiobuf ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructor for stdiobuf
o Destructor for stdiobuf
o stdiofile - return associated FILE
ΓòÉΓòÉΓòÉ 4.12.2.1. Constructor for stdiobuf ΓòÉΓòÉΓòÉ
Class: stdiobuf
stdiobuf(FILE* f);
The stdiobuf constructor creates an stdiobuf object that is associated with the
FILE pointed to by f. Changes that are made to the stream buffer in an stdiobuf
object are also made to the associated FILE pointed to by f.
Note: If ios::stdio is set in the format state of an ostream object, a call to
osfx() flushes stdout and stderr.
ΓòÉΓòÉΓòÉ 4.12.2.2. Destructor for stdiobuf ΓòÉΓòÉΓòÉ
Class: stdiobuf
~stdiobuf();
The stdiobuf destructor frees space allocated by the stdiobuf constructor and
flushes the file that this stdiobuf object is associated with.
ΓòÉΓòÉΓòÉ 4.12.2.3. stdiofile - Return Associated FILE ΓòÉΓòÉΓòÉ
Class: stdiobuf
FILE* stdiofile();
stdiofile() returns a pointer to the FILE object that the stdiobuf object is
associated with.
ΓòÉΓòÉΓòÉ 4.12.3. Public Members of stdiostream ΓòÉΓòÉΓòÉ
The following member functions are described:
o Constructor for stdiostream
o rdbuf - return pointer to stream buffer
An example of using stdiostream is also provided.
ΓòÉΓòÉΓòÉ 4.12.3.1. Constructor for stdiostream ΓòÉΓòÉΓòÉ
Class: stdiostream
stdiostream(FILE* file);
The stdiostream constructor creates a stdiostream object that is attached to
the FILE pointed to by file.
ΓòÉΓòÉΓòÉ 4.12.3.2. rdbuf - Return Pointer to Stream Buffer ΓòÉΓòÉΓòÉ
Class: stdiostream
stdiobuf* rdbuf();
rdbuf() returns a pointer to the stdiobuf object that is attached to the
stdiostream object.
ΓòÉΓòÉΓòÉ 4.12.3.3. Example of How to Use stdiostream ΓòÉΓòÉΓòÉ
The following example shows how you can use the stdiostream class. Two files
are opened using fopen(). The pointers to the FILE structures are then used to
create stdiostream objects. Finally, the contents of one of these stdiostream
objects are copied into the other stdiostream object.
#include <stdiostr.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
FILE *in = fopen("in.dat", "r");
FILE *out = fopen("out.dat", "w");
int c;
if (in == NULL)
{
cerr << "Cannot open file 'in.dat' for reading."
<< endl;
exit(1);
}
if (out == NULL)
{
cerr << "Cannot open file 'out.dat' for writing."
<< endl;
exit(1);
}
//
// Create a stdiostream object attached to "f"
//
stdiostream sin(in);
stdiostream sout(out);
cout << "The data contained in the file is: " << endl;
//
// Now read data from "sin" and copy it to
// "cout" and "sout"
//
while ((c = sin.rdbuf()->sbumpc()) != EOF)
{
cout << char(c);
sout.rdbuf()->sputc(c);
}
cout << endl;
}
If you run this example with an input file containing the following:
input input input input
The following output is produced:
The data contained in the file is:
input input input input
ΓòÉΓòÉΓòÉ 4.13. Manipulators ΓòÉΓòÉΓòÉ
This chapter describes the parameterized manipulators provided by the I/O
Stream Library and the facilities you can use to declare your own manipulators.
The following topics are described in this chapter:
o Introduction to manipulators
o Declarations for parameterized manipulators in iomanip.h
o Simple manipulators and parameterized manipulators
o Creating simple manipulators for your own types
o Creating parameterized manipulators for your own types
o Parameterized manipulators for the format state
ΓòÉΓòÉΓòÉ 4.13.1. Introduction to Manipulators ΓòÉΓòÉΓòÉ
Manipulators provide a convenient way of changing the characteristics of an
input or output stream, using the same syntax that is used to insert or extract
values. Manipulators allow you to embed a function call in an expression that
contains a series of insertions or extractions. Manipulators usually provide
shortcuts for sequences of iostream library operations. See Simple Manipulators
and Parameterized Manipulators for a description of the two kinds of
manipulators.
The iomanip.h header file contains a definition for a macro IOMANIPdeclare().
IOMANIPdeclare() takes a type name as an argument and creates a series of
classes that can be used to define manipulators for a given kind of stream.
Calling the macro IOMANIPdeclare() with a type as an argument creates a series
of classes that let you define manipulators for your own classes. You will get
a syntax error if you call IOMANIPdeclare() with the same argument more than
once in a file.
ΓòÉΓòÉΓòÉ 4.13.2. Declarations for Parameterized Manipulators in iomanip.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses members of the
parameterized manipulator classes:
#include <iomanip.h>
The following is an excerpt from the iomanip.h header file that shows the
relevant declarations for the members of the parameterized manipulator classes.
This header file supplies macro definitions that you can use to define new
parameterized manipulators.
#include <generic.h>
#include <iostream.h>
#define SMANIP(T)name2(smanip_,T)
#define SAPP(T)name2(sapply_,T)
#define IMANIP(T)name2(imanip_,T)
#define OMANIP(T)name2(omanip_,T)
#define IOMANIP(T)name2(iomanip_,T)
#define IAPP(T)name2(iapply_,T)
#define OAPP(T)name2(oapply_,T)
#define IOAPP(T)name2(ioapply_,T)
#define IOMANIPdeclare(T)
class SMANIP(T) {
ios& (*fct)(ios&,T);
T arg ;
public:
SMANIP(T)(ios& (*f)(ios&, T), T a);
friend istream& operator>>(istream& i,const SMANIP(T)& m);
friend ostream& operator<<(ostream& o, const SMANIP(T)& m);
};
class SAPP(T) {
ios& (*fct)(ios&, T);
public:
SAPP(T)(ios& (*f)(ios&,T));
SMANIP(T) operator()(T a);
};
class IMANIP(T) {
istream& (*fct)(istream&,T);
T arg;
public:
IMANIP(T)(istream& (*f)(istream&, T), T a );
friend istream& operator>>(istream& s, const IMANIP(T)& m);
};
class IAPP(T) {
istream& (*fct)(istream&, T);
public:
IAPP(T)(istream& (*f)(istream&,T));
IMANIP(T) operator()(T a);
};
class OMANIP(T) {
ostream& (*fct)(ostream&,T);
T arg;
public:
OMANIP(T)(ostream& (*f)(ostream&, T), T a );
friend ostream& operator<<(ostream& s, const OMANIP(T)& m);
};
class OAPP(T) {
ostream& (*fct)(ostream&, T);
public:
OAPP(T)(ostream& (*f)(ostream&,T));
OMANIP(T) operator()(T a);
};
class IOMANIP(T) {
iostream& (*fct)(iostream&,T);
T arg ;
public:
IOMANIP(T)(iostream& (*f)(iostream&, T), T a );
friend istream& operator>>(iostream& s,
const IOMANIP(T)& m);
friend ostream& operator<<(iostream& s,
const IOMANIP(T)& m);
};
class IOAPP(T) {
iostream& (*fct)(iostream&, T);
public:
IOAPP(T)(iostream& (*f)(iostream&,T));
IOMANIP(T) operator()(T a);
};
IOMANIPdeclare(int);
IOMANIPdeclare(long);
SMANIP(int) setbase(int b);
SMANIP(long) resetiosflags(long b);
SMANIP(long) setiosflags(long b);
SMANIP(int) setfill(int f);
SMANIP(int) setprecision(int p);
SMANIP(int) setw(int w);
Note:
1. The following classes are defined after the macro IOMANIPdeclare(T)
expands:
o SMANIP(T)
o SAPP(T)
o IMANIP(T)
o IAPP(T)
o OMANIP(T)
o OAPP(T)
o IOMANIP(T)
o IOAPP(T)
2. These classes could have been implemented as template classes with the
argument T rather than as macro expansions.
3. The macro IOMANIPdeclare(T) is defined on a single, continued line in the
iomanip.h header file. The continuation delimiters have been omitted from
the above excerpt to make it easier to read.
ΓòÉΓòÉΓòÉ 4.13.3. Simple Manipulators and Parameterized Manipulators ΓòÉΓòÉΓòÉ
There are two kinds of manipulators:
o Simple manipulators do not take any arguments. The following classes have
built-in simple manipulators:
- ios
- istream
- ostream.
o Parameterized manipulators require one or more arguments. setfill is an
example of a parameterized manipulator. You can create your own parameterized
manipulators and your own simple manipulators.
The following example shows the uses of both simple and parameterized
manipulators.
#include <iostream.h>
#include <iomanip.h>
ostream& SimpleGap (ostream& os)
{ return os << "____"; }
ostream& ParmGap(ostream& os, int n)
{
for (int i=n;i;i--) os << '.';
return os;
}
OMANIP(int) ParmGap(int n) { return OMANIP(int)(ParmGap,n);}
void main()
{
cout << "Here is a" << SimpleGap << "and some text" << endl
<< "Here is a" << ParmGap(10) << "of ten dots" << endl;
}
The simple manipulator SimpleGap allows you to write a fixed-length string of
underscores to an ostream object. ParmGap allows you to write a variable-length
string of dots to an ostream object. The length of the string of dots is
specified as the argument to ParmGap. This program produces the following
output:
Here is a____and some text
Here is a..........of ten dots
ΓòÉΓòÉΓòÉ 4.13.4. Creating Simple Manipulators for Your Own Types ΓòÉΓòÉΓòÉ
The I/O Stream Library gives you the facilities to create simple manipulators
for your own types. Simple manipulators that manipulate istream objects are
accepted by the following input operators:
istream istream::operator>> (istream&, istream& (*f) (istream&));
istream istream::operator>> (istream&, ios&(*f) (ios&));
Simple manipulators that manipulate ostream objects are accepted by the
following output operators:
ostream ostream::operator<< (ostream&, ostream&(*f) (ostream&));
ostream ostream::operator<< (ostream&, ios&(*f) (ios&));
The definition of a simple manipulator depends on the type of object that it is
supposed to modify. The following table shows sample function definitions to
modify istream, ostream, and ios objects.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Class of object Γöé Sample function definition Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé istream Γöé "istream &fi(istream&){ /*...*/ }" Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ostream Γöé "ostream &fo(ostream&){ /*...*/ }" Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ios Γöé "ios &fios(ios&){ /*...*/ }" Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
For example, if you want to define a simple manipulator tab that inserts a tab
character into an ostream object, the definition would look like this:
ostream (ostream& os){ return os << '\t'; }
Thus defined, the tab manipulator could be used like this:
cout << "The value is" << tab << "10" << endl;
ΓòÉΓòÉΓòÉ 4.13.5. Creating Parameterized Manipulators for Your Own Types ΓòÉΓòÉΓòÉ
The I/O Stream Library gives you the facilities to create parameterized
manipulators for your own types. Follow these steps to create a parameterized
manipulator that takes an argument of a particular type tp:
1. Call the macro IOMANIPdeclare(tp). Note that tp must be a single
identifier. For example, if you want tp to be a reference to a long double
value, use typedef to make a single identifier to replace the two
identifiers that make up the type label long double:
typedef long double& LONGREF
2. Determine the class of your manipulator. If you want to define the
manipulator as shown in Example of Defining an APP Parameterized
Manipulator, choose a class that has APP in its name (an APP class, also
known as an applicator). If you want to define the manipulator as shown in
Example of Defining a MANIP Parameterized Manipulator, choose a class that
has MANIP in its name (a MANIP class). Once you have determined whether to
use an APP class or a MANIP class, the particular class that you choose
depends on the type of object that the manipulator is going to manipulate.
The following table shows the class of objects to be modified, and the
corresponding manipulator classes.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Class to be modified Γöé Manipulator class Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé istream Γöé "IMANIP(tp)" or "IAPP(tp)" Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ostream Γöé "OMANIP(tp)" or "OAPP(tp)" Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé iostream Γöé "IOMANIP(tp)" or "IOAPP(tp)" Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé The ios part of istream objects Γöé "SMANIP(tp)" or "SAPP(tp)" Γöé
Γöé or ostream objects Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
3. Define a function f that takes an object of the class tp as an argument.
The definition of this function depends on the class you chose in step 2,
and is shown in the following table:
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Class chosen Γöé Sample definition Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé "IMANIP(tp)" or Γöé "istream &f(istream&, tp){/ *... */ Γöé
Γöé "IAPP(tp)" Γöé }" Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé "OMANIP(tp)" or Γöé "ostream &f(ostream&, tp){/* ... */ Γöé
Γöé "OAPP(tp)" Γöé }" Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé "IOMANIP(tp)" or Γöé "iostream &f(iostream&, tp){/* ... */ Γöé
Γöé "IOAPP(tp)" Γöé }" Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé "SMANIP(tp)" or Γöé "ios &f(ios&, tp){/* ... */ }" Γöé
Γöé "SAPP(tp)" Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
4. If you chose one of the APP classes in step 2, define the manipulator as
shown in Example of Defining an APP Parameterized Manipulator If you chose
one of the MANIP classes in step 2, define the manipulator as shown in
Example of Defining a MANIP Parameterized Manipulator. These two methods
produce equivalent manipulators.
Note: Parameterized manipulators defined with IOMANIP or IOAPP are not
associative. See Examples of Nonassociative Parameterized Manipulators for
more details.
ΓòÉΓòÉΓòÉ 4.13.5.1. Example of Defining an APP Parameterized Manipulator ΓòÉΓòÉΓòÉ
In the following example, the macro IOMANIPdeclare is called with the
user-defined class my_class as an argument. One of the classes that is
produced, OAPP(my_class), is used to define the manipulator pre_print.
#include
<iomanip.h>
// declare class
class my_class {
public:
char * s1;
const char c;
unsigned short ctr;
my_class(char *theme, const char suffix,
unsigned short times):
s1(theme), c(suffix), ctr(times) {}
};
// print a character an indicated number of times
// followed by a string
ostream& produce_prefix(ostream& o, my_class mc) {
for (register i=mc.ctr; i; --i) o << mc.c ;
o << mc.s1;
return o;
}
IOMANIPdeclare(my_class);
// define a manipulator for the class my_class
OAPP(my_class) pre_print=produce_prefix;
void main()
{
my_class obj("Hello",'-',10);
cout << pre_print(obj) << endl;
}
This program produces the following output:
----------Hello
ΓòÉΓòÉΓòÉ 4.13.5.2. Example of Defining a MANIP Parameterized Manipulator ΓòÉΓòÉΓòÉ
In the following example, the macro IOMANIPdeclare is called with the
user-defined class my_class as an argument. One of the classes that is
produced, OMANIP(my_class), is used to define the manipulator pre_print().
#include <iostream.h>
#include <iomanip.h>
class my_class {
public:
char * s1;
const char c;
unsigned short ctr;
my_class(char *theme, const char suffix,
unsigned short times):
s1(theme), c(suffix), ctr(times) {};
};
// print a character an indicated number of times
// followed by a string
ostream& produce_prefix(ostream& o, my_class mc) {
for (register int i=mc.ctr; i; --i) o << mc.c ;
o << mc.s1;
return o;
}
IOMANIPdeclare(my_class);
// define a manipulator for the class my_class
OMANIP(my_class) pre_print(my_class mc) {
return OMANIP(my_class) (produce_prefix,mc);
}
void main()
{
my_class obj("Hello",'-',10);
cout << pre_print(obj) << "\0" << endl;
}
This example produces the same output as the previous example.
ΓòÉΓòÉΓòÉ 4.13.5.3. Examples of Nonassociative Parameterized Manipulators ΓòÉΓòÉΓòÉ
The following example demonstrates that parameterized manipulators defined with
IOMANIP or IOAPP are not associative. The parameterized manipulator mysetw() is
defined with IOMANIP. mysetw() can be applied once in any statement, but if it
is applied more than once, it causes a compile-time error. You can avoid such
an error by putting each application of mysetw into a separate statement.
#include <iomanip.h>
iostream& f(iostream & io, int i) {
io.width(i);
return io;
}
IOMANIP (int) mysetw(int i) {
return IOMANIP(int) (f,i);
}
iostream_withassign ioswa;
void main() {
ioswa = cout ;
int i1 = 8, i2 = 14;
//
// The following statement does not cause a compile-time
// error.
//
ioswa << mysetw(3) << i1 << endl ;
//
// The following statement causes a compile-time error
// because the manipulator mysetw is applied twice.
//
ioswa << mysetw(3) << i1 <<mysetw(5) << i2 << endl;
//
// The following statements are equivalent to the previous
// statement, but they do not cause a compile-time error.
//
ioswa << mysetw(3) << i1 ;
ioswa << mysetw(5) << i2 << endl;
}
ΓòÉΓòÉΓòÉ 4.13.6. Parameterized Manipulators for the Format State ΓòÉΓòÉΓòÉ
The iomanip.h header file also contains calls to the IOMANIPdeclare() macro for
types int and long. These calls create classes that are used to create the
parameterized manipulators that control the format state of ios objects.
The call to IOMANIPdeclare(int) creates classes with names that are expanded
from the following macros:
o SMANIP(int)
o SAPP(int)
o IMANIP(int)
o IAPP(int)
o OMANIP(int)
o OAPP(int)
o IOMANIP(int)
o IOAPP(int).
All of these macros expand to names that include the string "int". Similarly,
IOMANIPdeclare(long) creates eight classes whose names include the string
"long".
The following manipulators are declared using the classes created by the calls
to IOMANIPdeclare(int) and IOMANIPdeclare(long).
Note: All of the parameterized manipulators described below are defined for
both istream and ostream objects. In the following descriptions, os is a
reference to an ostream object and is is a reference to an istream object.
The following manipulators are described:
o resetiosflags - clear format flags
o setbase - set conversion base
o setfill - set fill character
o setiosflags - set format flags
o setprecision - set precision
o setw - set field width
ΓòÉΓòÉΓòÉ 4.13.6.1. resetiosflags - Clear Format Flags ΓòÉΓòÉΓòÉ
Manipulators
SMANIP(long) resetiosflags(long flags);
resetiosflags() clears the format flags specified in flags. It can appear in an
input stream:
is >> resetiosflags(flags);
In this case, resetiosflags() calls is.setf(0,flags).
resetiosflags() can also appear in an output stream:
os << resetiosflags(flags);
In this case, resetiosflags calls os.setf(0,flags).
ΓòÉΓòÉΓòÉ 4.13.6.2. setbase - Set Conversion Base ΓòÉΓòÉΓòÉ
Manipulators
SMANIP(int) setbase(int base);
setbase() sets the conversion base to be equal to the value of the argument
base. If base equals 10, the conversion base is set to 10. If base equals 8,
the conversion base is set to 8. If base equals 16, the conversion base is set
to 16. Otherwise, the conversion base is set to 0. If the conversion base is 0,
output is treated the same as if the base were 10, but input is interpreted
according to the C++ lexical conventions. This means that input values that
begin with "0" are interpreted as octal values, and values that begin with "0x"
or "0X" are interpreted as hexadecimal values.
ΓòÉΓòÉΓòÉ 4.13.6.3. setfill - Set Fill Character ΓòÉΓòÉΓòÉ
Manipulators
SMANIP(int) setfill(int fill);
setfill() sets the fill character, ios::x_fill, to fill. The fill character is
the character that appears in values that need to be padded to fill the field
width. setfill() can appear in either an input stream or an output stream:
is >> setfill(fill);
os << setfill(fill);
setfill() performs the same task as the function fill().
ΓòÉΓòÉΓòÉ 4.13.6.4. setiosflags - Set Format Flags ΓòÉΓòÉΓòÉ
Manipulators
SMANIP(long) setiosflags(long flags);
setiosflags() sets the format flags specified in flags. setiosflags() can
appear in an input stream:
is >> setiosflags(flags);
If it appears in an input stream, setiosflags() calls is.setf.(flags)
If it appears in an output stream, setiosflags() calls os.setf(flags):
os << setiosflags(flags);
ΓòÉΓòÉΓòÉ 4.13.6.5. setprecision - Set Precision ΓòÉΓòÉΓòÉ
Manipulators
SMANIP(int) setprecision(int prec);
setprecision() sets the precision format state variable, ios::x_prec, to the
value of prec. The value of prec must be greater than zero. If the value of
prec is negative, the precision format state variable is set to 6.
setprecision() can appear in either an input stream or an output stream:
is >> setprecision(prec);
os << setprecision(prec);
ΓòÉΓòÉΓòÉ 4.13.6.6. setw - Set Field Width ΓòÉΓòÉΓòÉ
Manipulators
SMANIP(int) setw(int width);
setw() sets the width format state variable, ios::x_width, to the value of
width.
setw() can appear in either an input stream or an output stream:
is >> setw(width);
os << setw(width);
ΓòÉΓòÉΓòÉ 5. The Task Library ΓòÉΓòÉΓòÉ
Introduction to the Task Library
Introduces the Task Library and lists the runtime error messages it
generates.
Task Handling Classes
Describes object, sched, task, and timer, the task handling classes. These
classes give you the facilities to create and manage tasks.
Queue Management Classes
Describes qhead and qtail the queue management classes. These classes let you
implement a wide range of message-passing and data-buffering schemes.
Interrupt_handler Class
Describes Interrupt_handler, the class that allows your tasks to handle
external events in the form of signals from the operating system.
Simulation Classes
Describes histogrm, randint, urand, and erand, the simulation classes. These
classes provide utilities for writing program simulations and gathering
statistics about them.
ΓòÉΓòÉΓòÉ 5.1. Introduction to the Task Library ΓòÉΓòÉΓòÉ
This chapter introduces the classes that make up the Task Library. This library
provides you with facilities to write programs with routines that appear to run
in parallel. These routines, or tasks, can communicate with each other and
start new tasks, but they do not actually run concurrently. The Task Library
lets you simulate concurrent execution and gives you the facilities to write
simulations.
Extended Task Library Examples contains examples of how you might use the Task
Library to implement a parallel algorithm and event-driven simulations.
Note: The Task Library is also referred to as the C++ Coroutine Library in
some non-IBM documentation.
ΓòÉΓòÉΓòÉ 5.1.1. What Are Tasks? ΓòÉΓòÉΓòÉ
Each task described in the context of the Task Library is an instance of a
class that you derive from the class task. The constructor for the task class
is declared protected, so you do not create instances of the class task, only
instances of the classes that you derive from task.
Tasks are said to be nonpreemptive and lightweight. They are nonpreemptive
because only a single task is executing at any one time, and that task
continues to execute until it suspends itself or is terminated. Tasks are
lightweight because less time and space are required to create a task than to
create a true OS/2 process.
Tasks are more similar to OS/2 threads than to OS/2 processes.
Each task object has a pointer associated with it called thistask. thistask is
a pointer to the task that is executing. For example, if you use thistask in
the main() function, you are using a pointer to the main() task, the task whose
code appears in the main() function.
Note: Tasks are commonly used in program simulations. They are not meant to be
replacements for multitasking facilities provided by OS/2 such as OS/2
processes and threads. For further information see Using the Task Library with
OS/2.
ΓòÉΓòÉΓòÉ 5.1.2. What Do Tasks Do? ΓòÉΓòÉΓòÉ
Here are some of the things that tasks can do:
o Communicate with other tasks using the facilities provided by the classes
qhead and qtail. See Queue Management Classes for more details on the qhead
and qtail classes.
o Create new tasks. These tasks are called child tasks, and the task that
creates them is called the parent task.
o Wait for external events. The Interrupt_handler class allows tasks to wait
for external events in the form of signals from the operating system. See
Interrupt_handler Class for more details on the Interrupt_handler class.
o Consume simulated time. The concept of simulated time is implemented by the
timer class.
ΓòÉΓòÉΓòÉ 5.1.3. The Task Library Class Hierarchy ΓòÉΓòÉΓòÉ
The Task Library has the following class hierarchy:
o randint: each object of this class provides an independent sequence of
pseudo-random numbers. It is the base class for the following classes:
- urand
- erand
o object is the base class for the following classes:
- Interrupt_handler
- qtail
- qhead
- sched
o sched is itself the base class for the following classes:
- timer
- task
o task is itself the base class for the internal class Interrupt_alerter
The classes task and sched are used strictly as base classes. The constructors
for both of these classes are declared protected. When you use the Task
Library, you create objects of classes derived from these two classes rather
than creating objects of these classes directly.
Derivation Relationships in the Task Library shows the relationships between
the classes in the task library. In the figure, two classes are connected by an
arrow if the class at the pointed end of the arrow is derived from the class at
the other end of the arrow. object and randint are the two base classes in the
class hierarchy of the task library. histogram is a stand-alone class (that is,
it is neither a base class nor a derived class), but it is commonly used in
conjunction with randint.
object
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿΓöéΓöéΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÿΓööΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
Interrupt_ qtail qhead sched
handler Γöé Γöé
ΓöîΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇΓöÇΓöÇΓöÉ
timer task
Γöé
Γöé
Interrupt_
alerter
histogram randint
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
urand erand
Derivation Relationships in the Task Library
ΓòÉΓòÉΓòÉ 5.1.4. Using the Task Library with OS/2 ΓòÉΓòÉΓòÉ
The Task Library was originally coded to run in a UNIX** operating system
environment. Compromises were made in porting the library to OS/2 because of
architectural differences between operating systems. Use the following
guidelines to ensure that your programs' use of the Task Library is appropriate
and reliable.
ΓòÉΓòÉΓòÉ 5.1.4.1. Linking to the Task Library ΓòÉΓòÉΓòÉ
You must specify the TASK.LIB library when compiling or linking programs that
use the Task Library. There is no multitasking version of the library. You
should not use this library in a multitasking program.
No dynamically linkable version of this library is provided.
ΓòÉΓòÉΓòÉ 5.1.4.2. Compiler Options for Programs that Use the Task Library ΓòÉΓòÉΓòÉ
You must compile any modules that use the Task Library with the following
options to ensure that the correct stack tracebacks are generated for the Task
Library:
/Op- Disable all stack pointer optimization
/O- Disable optimization (Note: this also sets /Os-)
/Gh- Disable profiler hook (This is the default. See Tasks and the Execution
Trace Analyzer for further details.)
ΓòÉΓòÉΓòÉ 5.1.4.3. Tasks and Threads ΓòÉΓòÉΓòÉ
All tasks run in the user process address space and therefore do not benefit
from OS/2's interprocess memory protection. In addition, because threads are
preemptive and tasks are not, threads may be an attractive alternative to tasks
for many OS/2 processes.
The Task Library should never be used in a multithreaded environment, because
it is a single task simulating a multithreaded environment. Unpredictable
results will occur if you use the Task Library in a true multithreaded
environment. See "Creating Multithread Programs" in the IBM C/C++ Tools:
Programming Guide for details on multithreaded programs.
ΓòÉΓòÉΓòÉ 5.1.4.4. Tasks and the Execution Trace Analyzer ΓòÉΓòÉΓòÉ
Do not attempt to use the execution trace analyzer with programs that make use
of the Task Library. Your programs may compile successfully when you specify
the /gh compiler option, but the results will be unpredictable and your program
may fail without warning.
ΓòÉΓòÉΓòÉ 5.1.4.5. Other Restrictions ΓòÉΓòÉΓòÉ
Tasks are simulated on OS/2 by using the heap for all tasks. Because of
differences in the way the Task Library and the operating system access the
stack, you should follow the guidelines below:
1. You can register an exception handler for a task with OS/2, either through
a call to DosSetExceptionHandler or through #pragma handler(). However, you
should not register an exception in one task and use it in another task.
2. Do not call longjmp from one task to another.
ΓòÉΓòÉΓòÉ 5.1.4.6. The /noe Option and the Task Library ΓòÉΓòÉΓòÉ
If you experience problems linking your programs that use the Task Library with
dde4sbs.lib, use the /noe option.
ΓòÉΓòÉΓòÉ 5.1.5. Task Library Error Messages ΓòÉΓòÉΓòÉ
The following list shows the errors that can be generated by member functions
of the classes that make up the Task Library. The first line in each entry
shows the name of the error and the text of the error message that is produced.
For some errors, additional information may be provided to help you determine
the cause of the error. This information is not included here. The second line
explains the error.
Note: You should always use the error name macros, rather than using error
numbers directly. Error numbers may change in subsequent releases of the
compiler, or may vary between different compilers. For example, IBM C Set ++
for AIX*/6000 uses error numbers starting at 1, while IBM C/C++ Tools for OS/2
uses error numbers starting at 7001.
Error Name and Message Explanation
E_OLINK object::delete(): has chain
Attempt to delete an object that remembers a task.
E_ONEXT object::delete(): on chain
Attempt to delete an object that is still on some chain.
E_GETEMPTY qhead::get(): empty
Attempt to get from an empty queue that has mode E_MODE.
E_PUTOBJ qtail::put(): object on another queue
Attempt to put an object that is already on another queue.
E_PUTFULL qtail::put(): full
Attempt to put to a full queue that has mode E_MODE.
E_BACKOBJ qhead::putback(): object on another queue
Attempt to put back an object that is already on another queue.
E_BACKFULL qhead::putback(): full
Attempt to put back to a full queue that has mode E_MODE.
E_SETCLOCK sched::setclock(): clock!=0
Clock was nonzero when setclock() was called.
E_CLOCKIDLE sched::schedule(): clock_task not idle
The clock_task was not IDLE when setclock() was called.
E_RESTERM sched::schedule: terminated
Attempt to resume a task object with state equal to TERMINATED.
E_RESRUN sched::schedule: running
Attempt to resume a task object with state equal to RUNNING.
E_NEGTIME sched::schedule: clock<0
Negative argument to delay().
E_RESOBJ sched::schedule: task or timer on another queue
Attempt to resume a task or timer object that is already on some queue.
E_HISTO histogram::histogram: bad arguments
Bad arguments for the histogram constructor.
E_STACK task::restore(): stack overflow
Task runtime stack overflow.
E_STORE new: free store exhausted
No more free store is available; the call to new() failed.
E_TASKMODE task::task(): bad mode
Mode argument not permitted for the task constructor.
E_TASKDEL task::~task(): not terminated
Attempt to delete a non-TERMINATED task object.
E_TASKPRE task::preempt(): not running
Attempt to preempt a non-RUNNING task.
E_TIMERDEL timer::~timer(): not terminated
Attempt to delete a non-TERMINATED timer object.
E_SCHTIME schedule: bad time
Scheduler run chain is corrupted; the time of the task at the beginning of
the run chain is not valid.
E_SCHOBJ sched object used directly (not as base)
sched object used directly instead of as a base class.
E_QDEL queue::~queue(): not empty
Attempt to delete a nonempty queue.
E_RESULT task::result(): thistask->result()
A task object attempted to obtain its own result().
E_WAIT task::wait(): wait for self
A task object called wait() with a pointer to itself as the argument.
E_FUNCS FrameLayout:: FrameLayout(): function start
Internal error; cannot determine the call frame layout.
E_FRAMES FrameLayout:: FrameLayout(): frame size
Internal error; cannot determine frame size.
E_REGMASK task::fudge_return(): unexpected register mask
Internal error; unexpected register mask.
E_FUDGE_SIZE task::fudge_return(): frame too big
Internal error; the frame size returned by fudge_return is too big.
E_NO_HNDLR sigFunc - no handler for signal
No handler for the generated signal.
E_BADSIG illegal signal number
Attempt to use a signal number that is out of range.
E_LOSTHNDLR Interrupt_handler:: ~Interrupt_handler(): signal handler not on
chain
Attempt to call the destructor for a signal handler that has already been
destroyed.
E_RETURN task returns without calling sched::resultis(int)
Unrecoverable error caused by an attempt to exit a task by a means other than
calling resultis().
E_BADMODE Illegal mode passed to qhead::qhead(), qtail::qtail(),
qhead::setmode() or qtail::setmode()
Unrecoverable error caused by an attempt to set a mode that is not valid for
a queue.
E_QZERO Attempt to set the maximum size of a queue to a value less than or
equal to 0
Unrecoverable error caused by an attempt to set maximum queue size to a value
less than or equal to 0.
E_URAND urand::urand(int, int) bad arguments
Attempt to pass arguments that are not valid to urand::urand().
ΓòÉΓòÉΓòÉ 5.2. Task Handling Classes ΓòÉΓòÉΓòÉ
This chapter describes the task handling classes: task, object, sched, and
timer. You can use these classes to create and manage tasks.
The fact that the Task Library has a class called object can cause some
confusion. In this book, object (in normal typeface) refers to the C++ concept
of an instance of a class, while object (in special typeface) refers to the
class in the Task Library. In the rest of this book, an object of a given
class, such as MyClass, is referred to as a MyClass object. For the sake of
simplicity, an object of class object is called an object rather than an object
object.
Similarly, task (in normal typeface) refers to the concept of a lightweight,
nonpreemptive process that can be used to create program simulations, while
task (in special typeface) refers to the class in the Task Library.
The following topics are described in this chapter:
o Deriving classes from the task class
o Shared and dedicated tasks
o Declarations of task handling classes in task.h
o Public members of object
o Public members of sched
o Members of task
o Public members of timer
ΓòÉΓòÉΓòÉ 5.2.1. Object States ΓòÉΓòÉΓòÉ
The object class is designed to be used as a base class. Objects of all of the
classes that are derived from the object class (sched, timer, task, and any
classes that you derive from these classes) can be in one of the two following
states:
o If a task object has to wait for an object, the object that is waited for has
a state of pending. If a task object performs a blocking operation (that is,
an operation that may cause the task object to give up control of the
processor while it waits for some event to take place) on a pending object,
it will wait until the state of the object changes to ready.
o An object that does not need to be waited for is ready.
You can determine the state of an object by calling the object class member
function pending(). pending() returns a nonzero value if the state of an object
is pending and returns 0 if the state of an object is ready.
Any class that is derived from the class object that may be waited for must
have rules for when it is pending or ready (that is, it must define the virtual
function pending()). Each class derived from the class object can have, at
most, one definition for pending().
The following list contains some examples of pending objects:
o A qhead object that is associated with an empty queue is pending. If a task
calls qhead::get() for this object, that task must wait until some other task
calls qtail::put() to put something in the queue. See Queue Management
Classes for a description of queues.
o A qtail object that is associated with a full queue is pending. If a task
calls qtail::put() for this object, that task must wait until another task
calls qhead::get() to remove something from the queue.
o A task object that does not have a state equal to TERMINATED is pending. If
another task object calls sched::result() for this task object, it must wait
until the state of this task object changes to TERMINATED. Once the state of
the task object has changed to TERMINATED, the task object is no longer
pending.
ΓòÉΓòÉΓòÉ 5.2.2. Task States ΓòÉΓòÉΓòÉ
A task can be in one of the three following states:
o RUNNING: the task is running or it will be scheduled to run.
o IDLE: the task is waiting (possibly for a pending object). Each task object
in the IDLE state has certain conditions that will change its state to
RUNNING.
o TERMINATED: the task is complete. It cannot return to the RUNNING state, but
you can retrieve its result.
ΓòÉΓòÉΓòÉ 5.2.3. Deriving Classes from the task Class ΓòÉΓòÉΓòÉ
The task constructor is declared protected. This means that you cannot create
objects of the class task itself. You must derive a class from task and create
objects of this class. This section describes some of the things that you
should keep in mind when you derive such a class.
The following topics are discussed:
o Parent and child tasks
o Only a single level of derivation is allowed from the task class
o Constructors for classes derived from task cannot be inline
o Using the task constructor
o The default stack size
o Tasks must explicitly call destructors for objects they create
ΓòÉΓòÉΓòÉ 5.2.3.1. Parent and Child Tasks ΓòÉΓòÉΓòÉ
If a task is created by another task, then the created task is called a child
task and the creating task is called a parent task. If the parent creates the
child using dynamic allocation (that is, using the operator new), the child is
created dynamically. Otherwise, the child is created on the local stack of the
parent.
ΓòÉΓòÉΓòÉ 5.2.3.2. Only a Single Level of Derivation Is Allowed ΓòÉΓòÉΓòÉ
Only one level of derivation is allowed from the class task. C/C++ Tools will
not produce an error message if you attempt to derive a class from a class that
is derived from task, but the behavior of the class will be unpredictable. For
example, the following declaration of d_task2 is not valid:
class d_task1 : public task { /* valid declaration */ };
class d_task2 : public d_task1 { /* unpredictable results */ };
A class can be derived from a set of classes that includes the class task, but
the derived class cannot be used as the base class for any other classes.
ΓòÉΓòÉΓòÉ 5.2.3.3. Constructors for Classes Derived from task Cannot Be Inline ΓòÉΓòÉΓòÉ
You should not define as inline the constructor for a class derived from the
class task. You will not get a compile-time error if you attempt to do this,
but the results will be unpredictable. For example:
class d_task : public task {
public:
d_task() { /* inline constructor - results unpredictable */ }
// .
// .
// .
};
ΓòÉΓòÉΓòÉ 5.2.3.4. Using the task Constructor ΓòÉΓòÉΓòÉ
Consider a class Addint that is derived from the class task. The body of the
constructor for the Addint class constitutes the code that will be executed by
tasks of the Addint class. Suppose that a task of the Addint class adds two
numbers together. The definition for Addint could look something like this:
#include <task.h>
#include <iostream.h>
class Addint : public task
{
public:
Addint(int, int);
};
The constructor for the class Addint looks like this:
Addint::Addint(int a, int b)
{
resultis(a+b);
}
A task object of the class Addint could be created and used like this:
void main(){
Addint ai(3,4);
cout << "The sum is: " << ai.result() << endl;
thistask->resultis(0);
}
This program produces the following output:
The sum is: 7
ΓòÉΓòÉΓòÉ 5.2.3.5. The Default Stack Size ΓòÉΓòÉΓòÉ
The default maximum stack size (in words) for tasks is defined as SIZE in the
task.h header file. If you do not specify a maximum stack size when you call
the task constructor, the maximum stack size will be set to this value. If you
are creating a task that will need to put a large amount of data on the stack,
you may need to use a maximum stack size that is bigger than the default.
In the following example, the class BigStack is derived from the class task.
The BigStack constructor specifies that the maximum stack size for objects of
BigStack is bigger than SIZE:
#include <task.h>
#define BIGSIZE SIZE + 256
class BigStack : public task {
public:
BigStack();
};
//
// request a stack that has a size bigger than the default
BigStack::BigStack() : task("Big",DEDICATED,BIGSIZE)
{
resultis(1);
}
void main() {
BigStack bs;
thistask->resultis(0);
}
ΓòÉΓòÉΓòÉ 5.2.3.6. Tasks Must Explicitly Call Destructors for Objects They Create ΓòÉΓòÉΓòÉ
Usually, the destructors for all of the objects that were created on the stack
within a block are automatically called when that block is exited. When a task
calls task::resultis() however, it does not return, and the destructors for
objects that were created by that task are not called automatically. Thus,
before a task calls task::resultis(), it should call the destructors for all of
the objects that have destructors and were created by the task on its stack.
In the following example, the dedicated task mtask creates an object r1 on its
local stack. The constructor for mtask must explicitly call the destructor for
the object r1 to remove it from the run chain.
class Resource
{
public:
Resource(); // get resource
~Resource(); // give up resource
};
// ...
class MyTask : public task {
public:
MyTask();
};
MyTask::MyTask() {
Resource r1;
// ...
r1.Resource::~Resource();
resultis(0);
}
void main() {
MyTask mtask;
// ...
}
ΓòÉΓòÉΓòÉ 5.2.4. Shared and Dedicated Tasks ΓòÉΓòÉΓòÉ
When a task creates another task, it can create it as a shared task or as a
dedicated task. You specify whether a task is shared or dedicated in the second
argument to the protected constructor of the class task. See Constructor for
task for a description of the task class constructor.
Each dedicated task has its own stack that is dynamically allocated when the
task is created. A shared task, on the other hand, shares the memory space for
its stack with its parent.
The following topics are described in this section:
o Advantages of dedicated tasks
o Advantages of shared tasks
o Shared child tasks should be dynamically allocated
o Passing arguments to shared child tasks
ΓòÉΓòÉΓòÉ 5.2.4.1. Advantages of Dedicated Tasks ΓòÉΓòÉΓòÉ
The advantage of using dedicated tasks is that it takes less time to switch
between dedicated tasks than it takes to switch between shared tasks. Suppose
that there are two tasks, task1 and task2, that share the same stack, and
suppose that you want to switch from task1 to task2. Space must be allocated
and the contents of the shared stack (that is, the contents of the stack of
task1) must be copied into this space. This space is called the dynamic save
area of task1. task2 then copies the contents of its stack (currently saved in
its dynamic save area) into the shared stack. If you want to switch back to
task1, the contents of the shared stack must be copied into the dynamic save
area of task2, and the contents of the stack of task1 must be copied from the
dynamic save area of task1 into the shared stack.
When you switch between two dedicated tasks, the stacks do not have to be saved
and restored because both tasks have their own separate stack spaces. The
result is that it is faster to switch between dedicated tasks.
ΓòÉΓòÉΓòÉ 5.2.4.2. Advantages of Shared Tasks ΓòÉΓòÉΓòÉ
The advantage of using shared tasks is that you can save some memory. Each time
that a dedicated task is created, a set amount of memory is allocated for its
stack. Even though memory must be allocated for the dynamic save area before
you switch between shared tasks, the system only needs to allocate the memory
that is needed to save the portion of the stack that the shared task is using.
This amount of memory may be considerably less than the set amount of memory
that must be allocated for a dedicated task.
Note: The following two sections describe some restrictions that are placed on
the use of shared tasks. If you do not adhere to these restrictions when you
use shared tasks, the results will be unpredictable. Because these restrictions
do not affect dedicated tasks, you should use dedicated tasks whenever
possible.
ΓòÉΓòÉΓòÉ 5.2.4.3. Shared Child Tasks Should Be Dynamically Allocated ΓòÉΓòÉΓòÉ
If a parent task creates a child that is a shared task, the parent should
dynamically allocate the child task. The following example shows what can
happen when child tasks are not dynamically allocated. In the following
program, the child tasks are dynamically allocated if the macro WRONG is not
defined, and they are not dynamically allocated if WRONG is defined.
#include <task.h>
#include <iostream.h>
class Semaphore: public object {
int signal;
public:
Semaphore(int s) : signal(s) {}
int pending() { return signal <= 0; }
void p();
void v();
};
void Semaphore::p(){
while (1)
{
if (--signal >= 0)
return;
signal++;
thistask->sleep(this);
}
}
void Semaphore::v(){
if (signal++ == 0)
alert();
}
class Child : public task {
public:
Child(char *name, Semaphore &);
};
Child::Child(char *name, Semaphore &s) : task("Child", SHARED){
cout << "Child " << name <<" entered." << endl;
s.p();
cout << "Child " << name <<" after p()." << endl;
resultis(0);
}
class Parent : public task {
public:
Parent(Semaphore &);
};
Parent::Parent(Semaphore &s) : task("Parent", SHARED){
#ifdef WRONG
Child c1("c1",s);
Child c2("c2",s);
#else
Child &c1 = *new Child("c1",s);
Child &c2 = *new Child("c2",s);
#endif
cout << "Parent task after creating c1 and c2." << endl;
c1.result();
c2.result();
cout << "Parent task after waiting "
<< "for c1 and c2 to terminate." << endl;
resultis(0);
}
void main(){
#ifdef WRONG
Semaphore s(0);
Parent p1(s);
#else
Semaphore &s = *new Semaphore(0);
Parent &p1 = *new Parent(s);
#endif
cout << "Main task after creating parent task." << endl;
s.v();
s.v();
cout << "Main task after signalling semaphores." << endl;
p1.result();
cout << "Main task after parent task has terminated."
<< endl;
thistask->resultis(0);
}
If WRONG is not defined, the following objects are dynamically allocated:
o c1 and c2, the Child objects that are created in the Parent constructor.
o s, the Semaphore object that is created in main().
o p1, the Parent object that is created in main().
Because these are the only child tasks in the program, all of the child tasks
are dynamically allocated. The program produces the following output if WRONG
is not defined:
Child c1 entered.
Main task after creating parent task.
Main task after signalling semaphores.
Child c2 entered.
Child c2 after p().
Child c1 after p().
Parent task after creating c1 and c2.
Parent task after waiting for c1 and c2 to terminate.
Main task after parent task has terminated.
However, if WRONG is defined, none of c1, c2, s, and p1 is dynamically
allocated. If you include the following statement:
#define WRONG
after the include statement for iostream.h, the program fails. The following
output is produced:
Child c1 entered.
Main task after creating parent task.
Main task after signalling semaphores.
SYS1808:
The process has stopped. The software diagnostic
code (exception code) is 0005.
ΓòÉΓòÉΓòÉ 5.2.4.4. Passing Arguments to Shared Child Tasks ΓòÉΓòÉΓòÉ
If you want to pass a reference or a pointer to an object from a parent task to
a shared child task, you should ensure that the object that you are passing is
either dynamically allocated or declared in global scope.
An argument that is either a reference or a pointer to an object that is
created on the local stack of the parent task will not be passed properly. When
a shared child task is created, its stack uses the same space as the local
stack of the parent task. If you pass the child a pointer to a location in the
parent's stack, this pointer will not be valid in the scope of the child task
because it now points to a location occupied by the child's stack. Note that
the parent and child tasks are sharing the same stack space, and thus the
current contents of the stack space depend on which task has control of the
stack. In the following example, q1 is not a valid argument to pass to the
child task, but q2 and q3 are valid arguments:
#include <task.h>
qtail q3; // argument with global scope
class Parent : public task {
public:
Parent();
};
class Child : public task {
public:
Child(qtail*);
};
Child::Child(qtail* qt) : task("Child",SHARED)
{
qt->print(0);
resultis(0);
}
Parent::Parent() {
qtail q1; // object declared on local
// stack of parent
//
Child *c1 = new Child(&q1); // incorrect - argument was
// created on local stack
// of parent task
//
qtail *q2 = new qtail; // dynamically allocated
// object
//
Child *c2 = new Child(q2); // correct - argument
// dynamically allocated
//
Child *c3 = new Child(&q3); // correct - argument
// declared in global scope
resultis(0);
};
void main() {
Parent pp;
thistask->resultis(0);
}
ΓòÉΓòÉΓòÉ 5.2.5. Declarations for the Task Handling Classes in task.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses the task
handling classes:
#include <task.h>
The following is an excerpt from the task.h header file that show the relevant
declarations for the members of the task handling classes.
typedef int (*PFIO) (int,object*);
typedef void (*PFV) ();
typedef void SIG_FUNC_TYP(int);
typedef void (*SIG_PF)(int);
#define SIZE 1024
#define thistask (object::this_task())
#define run_chain (sched::get_run_chain());
#define task_chain (task::get_task_chain())
extern _hwm;
class object{
friend class sched;
friend class task;
private:
static sched* runchain;
public:
enum objtype { OBJECT, TIMER, TASK, QHEAD,
QTAIL, INTHANDLER };
object* o_next;
object();
virtual ~object();
virtual objtype o_type();
void remember(task*);
void forget(task*);
void alert();
virtual int pending();
virtual void print(int, int =0);
static int task_error(int, object*);
int task_error(int);
static task* this_task();
static PFIO error_fct;
};
class sched : public object {
friend class timer;
friend class task;
friend class object;
friend void _print_error(int n);
friend SIG_FUNC_TYP sigFunc;
public:
enum statetype { IDLE, RUNNING, TERMINATED };
static void setclock(long);
static long get_clock();
static sched* get_run_chain();
static int get_exit_status();
static void set_exit_status( int i );
sched* get_priority_sched();
static task* clock_task;
long rdtime();
statetype rdstate();
int pending();
int keep_waiting();
int dont_wait();
void cancel(int);
int result();
virtual void setwho(object* t);
void print(int, int =0);
static PFV exit_fct;
};
class timer : public sched {
void resume();
public:
timer(long);
~timer();
void reset(long);
object::objtype o_type();
void setwho(object*);
void print(int, int =0);
};
class task : public sched {
friend class sched;
private:
int* t_framep;
int* t_basep;
object* t_alert;
protected:
task(char* name=0, modetype mode=DEFAULT_MODE,
int stacksize=SIZE);:
public:
enum modetype { DEDICATED, SHARED };
~task();
object::objtype o_type();
task* t_next;
char* t_name;
static task* get_task_chain();
int waitvec(object**);
int waitlist(object* ...);
void wait(object* ob);
void delay(long);
long preempt();
void sleep(object* t =0);
void resultis(int);
void cancel(int);
void setwho(object* t);
void print(int, int =0);
object* who_alerted_me();
};
inline void setclock(long i);
void _print_error(int);
typedef int (*PFIO)(int,object*);
typedef void (*PFV)();
typedef void SIG_FUNC_TYP(int);
typedef void (*SIG_PF)(int);
#define SIZE 1024
#define thistask (object::this_task())
#define run_chain (sched::get_run_chain())
#define task_chain (task::get_task_chain())
extern _hwm;
class object
{
friend class sched;
friend class task;
private:
static task* thxstxsk;
public:
enum objtype { OBJECT, TIMER, TASK, QHEAD,
QTAIL, INTHANDLER };
object* o_next;
object();
virtual ~object();
virtual objtype o_type();
void remember(task*);
void forget(task*);
void alert();
virtual int pending();
virtual void print(int, int =0);
static int task_error(int, object*);
int task_error(int);
static task* this_task();
static PFIO error_fct;
};
class sched : public object {
friend class timer;
friend class task;
friend class object;
friend void _print_error(int n);
friend SIG_FUNC_TYP sigFunc;
public:
enum statetype { IDLE=1, RUNNING=2, TERMINATED=4 };
static void setclock(long);
static long get_clock();
static sched* get_run_chain();
static int get_exit_status();
static void set_exit_status( int i );
sched* get_priority_sched();
static task* clock_task;
long rdtime();
statetype rdstate();
int pending();
int keep_waiting();
int dont_wait();
void cancel(int);
int result();
virtual void setwho(object* t);
void print(int, int =0);
static PFV exit_fct;
};
class timer : public sched {
void resume();
public:
timer(long);
~timer();
void reset(long);
object::objtype o_type();
void setwho(object*);
void print(int, int =0);
};
class task : public sched {
friend class sched;
private:
int* t_framep;
int* t_basep;
object* t_alert;
protected:
task(char* name=0, modetype mode=DEFAULT_MODE,
int stacksize=SIZE);
public:
enum modetype { DEDICATED, SHARED };
~task();
object::objtype o_type();
task* t_next;
char* t_name;
static task* get_task_chain();
int waitvec(object**);
int waitlist(object* ...);
void wait(object* ob);
void delay(long);
long preempt();
void sleep(object* t =0);
void resultis(int);
void cancel(int);
void setwho(object* t);
void print(int, int =0);
object* who_alerted_me();
};
inline void setclock(long i) { sched::setclock(i); }
void _print_error(int);
ΓòÉΓòÉΓòÉ 5.2.6. Public Members of object ΓòÉΓòÉΓòÉ
Each object of the class object has a list of tasks called a remember chain.
Tasks that are on the remember chain have a state of IDLE. These tasks will
have their state changed from IDLE to RUNNING and be moved to the run chain
when the state of the object changes from pending to ready.
For every object of the task, timer, qhead, and qtail classes, a call to
object::alert() is automatically made when the state of the object changes from
pending to ready. If you derive a class from object, you must ensure that
object::alert() is explicitly called by objects of that class for the tasks
that are on their remember chains.
Each object also has a pointer to a list of other objects. This pointer is used
to chain together objects that are placed on a queue and task objects on the
run chain of the sched object.
Note: The following descriptions assume that the functions are called as part
of an object called obj.
The following functions are described:
o Constructor for object
o alert - change state of tasks
o error_fct - user-defined error-handling function
o forget - remove task from remember chain
o o_type - return class object type
o pending - return object state
o print - print contents of object
o remember - add task to remember chain
o task_error - error-handling
o this_task - return pointer to current task
ΓòÉΓòÉΓòÉ 5.2.6.1. Constructor for object ΓòÉΓòÉΓòÉ
Class: object
object();
The object() constructor constructs an object that is not in any list of
objects.
ΓòÉΓòÉΓòÉ 5.2.6.2. alert - Change State of Tasks ΓòÉΓòÉΓòÉ
Class: object
void alert();
alert() changes the state of all of the tasks on the remember chain for obj
from IDLE to RUNNING.
ΓòÉΓòÉΓòÉ 5.2.6.3. error_fct - User-Defined Error-Handling Function ΓòÉΓòÉΓòÉ
Class: object
typedef int (*PFIO) (int, object*);
static PFIO error_fct;
When an error occurs, task_error() calls the function pointed to by error_fct
with two arguments: the error number, and a pointer to the object that caused
the error. To assign the address of a function to error_fct, use an expression
similar to the following:
error_fct = e_function;
where e_function is a user-defined error-handling function that has the
following format:
int e_function(int errno, object* obj);
The first argument, errno, is the error number, and obj is either 0 or a
pointer to the object that called task_error(). If error_fct is set to point to
such a function, task_error() calls this function with the error number and a
pointer to the object as arguments. The pointer to the object is equal to 0 if
task_error() was not called by an object. If the user-defined error function
does not return 0, task_error calls exit() with an argument equal to errno. If
the user-defined error function returns 0, task_error() retries the operation
that caused the error.
ΓòÉΓòÉΓòÉ 5.2.6.4. forget - Remove Task from Remember Chain ΓòÉΓòÉΓòÉ
Class: object
void forget(task* tsk);
forget() removes the task object pointed to by tsk from the remember chain for
obj.
ΓòÉΓòÉΓòÉ 5.2.6.5. o_type - Return Class Object Type ΓòÉΓòÉΓòÉ
Class: object
virtual objtype o_type();
o_type() returns the class type of obj, namely object::OBJECT.
ΓòÉΓòÉΓòÉ 5.2.6.6. pending - Return Object State ΓòÉΓòÉΓòÉ
Class: object
virtual int pending();
pending() is a virtual function that is meant to return 0 if obj is ready and a
nonzero value if obj is pending. The default definition of pending() always
returns 1. If you want to define a class that is derived from object, and if
you want to be able to wait for objects of that class, you must explicitly
define pending() for that class.
ΓòÉΓòÉΓòÉ 5.2.6.7. print - Print Contents of Object ΓòÉΓòÉΓòÉ
Class: object
virtual void print(int x, int y=0);
print() prints information about obj on standard output. object::print() is
called by the print() member functions of the classes derived from object.
The argument x specifies the amount of information to be printed. The argument
y is used internally by the Task Library. Its default value is 0. print()
prints the type of the object if x equals 0. If x equals VERBOSE, print()
prints the type of the object along with the value of the this pointer and the
list of tasks on the remember chain for this object.
ΓòÉΓòÉΓòÉ 5.2.6.8. remember - Add Task to Remember Chain ΓòÉΓòÉΓòÉ
Class: object
void remember(task* tk);
remember() adds the task pointed to by tk to the remember chain for obj. Tasks
that are on the remember chain will be alerted when the state of obj becomes
ready.
ΓòÉΓòÉΓòÉ 5.2.6.9. task_error - Error-Handling ΓòÉΓòÉΓòÉ
Class: object
static int task_error(int errno, object* op);
int task_error(int errno);
task_error() is called by the task system when a runtime error occurs. errno is
the error number. op is a pointer to the object that called task_error(). If
the member error_fct points to a function, task_error() calls that function
with errno and op as arguments Otherwise, print_error() is called with the
argument errno. print_error() prints an error message on stderr and terminates
the program.
The nonstatic, single-argument form of task_error() is obsolete, but it is kept
for compatibility with the AT&T** C++ Language System Release 1.2 Task Library.
The runtime errors are listed in Task Library Error Messages. These errors can
be divided into two groups:
o Recoverable: the condition that caused the error should be corrected by the
program in the function pointed to by error_fct. error_fct should return 0,
and thus the function that caused the error can be tried again.
o Unrecoverable: the condition that caused the error cannot be corrected by the
program. The function that you define for error_fct must not return 0 for
unrecoverable errors. If this function does return 0 for unrecoverable
errors, the results will be unpredictable.
The following runtime errors are recoverable:
E_BACKOBJ E_FUNCS
E_BACKFULL E_GETEMPTY
E_FRAMES E_PUTOBJ
E_FUDGE_SIZE E_PUTFULL
The following runtime errors are unrecoverable:
E_BADMODE E_QDEL
E_BADSIG E_QZERO
E_CLOCKIDLE E_REGMASK
E_HISTO E_RESOBJ
E_LOSTHNDLR E_RESRUN
E_NEGTIME E_RESTERM
E_NO_HNDLR E_RESULT
E_OLINK E_RETURN
E_ONEXT E_SCHOBJ
ΓòÉΓòÉΓòÉ 5.2.6.10. this_task - Return Pointer to Current Task ΓòÉΓòÉΓòÉ
Class: object
static task* this_task();
#define thistask object::this_task()
this_task() returns a pointer to the task that is currently running.
The macro form, thistask, is kept for compatibility with the AT&T** C++
Language System Release 1.2 Task Library.
ΓòÉΓòÉΓòÉ 5.2.7. Public Members of sched ΓòÉΓòÉΓòÉ
The constructor for the sched class is declared protected, and thus you cannot
create your own objects of the class sched. The sched class is important for
the Task Library because it:
o Provides common functions for task and timer, the classes that are derived
from sched.
o Provides functions for measuring simulated time.
o Implements the scheduler, the construct of the Task Library that determines
the task that is supposed to run next.
The sched class includes a static data member called runchain. This is a list
of all the tasks that are ready to run.
Note: The following descriptions assume that the functions are called as part
of schd, an object of a class derived from sched.
The following functions are described:
o cancel - change state to TERMINATED
o clock_task - system clock task variable
o dont_wait - return number of objects waiting for external events
o exit_fct - user defined exit function
o get_clock - return value of the task system clock
o get_exit_status - return exit status of task program
o get_priority_sched - return pointer to interrupt_alerter
o get_run_chain - return pointer to run chain
o keep_waiting - keep scheduler waiting
o pending - return state
o print - print the contents of sched object
o rdstate - return the state of sched object
o rdtime - return clock time
o result - return result of sched object
o setclock - initialize the system clock
o setwho - record alerting object
o set_exit_status - set exit status of task
ΓòÉΓòÉΓòÉ 5.2.7.1. cancel - Change State to TERMINATED ΓòÉΓòÉΓòÉ
Class: sched
void cancel(int ret_val);
cancel() changes the state of schd to TERMINATED without invoking the scheduler
and sets the result of schd to ret_val. Because the scheduler is not invoked, a
task object should not call cancel() on itself.
ΓòÉΓòÉΓòÉ 5.2.7.2. clock_task - System Clock Task Variable ΓòÉΓòÉΓòÉ
Class: sched
static task* clock_task;
clock_task is a pointer to the task that is scheduled each time the system
clock advances, before any other tasks. The state of the task pointed to by
clock_task must be IDLE when it is scheduled. The task that is pointed to by
clock_task can ensure that it will have a state of IDLE by calling
task::sleep() on itself.
ΓòÉΓòÉΓòÉ 5.2.7.3. dont_wait - Return Number of Objects Waiting for External Events ΓòÉΓòÉΓòÉ
Class: sched
int dont_wait();
dont_wait() returns the number of times that keep_waiting() has been called,
minus the number of times that dont_wait() has been called (excluding the
current call). The return value should equal the number of objects that were
waiting for external events before the current call.
ΓòÉΓòÉΓòÉ 5.2.7.4. exit_fct - User Defined Exit Function ΓòÉΓòÉΓòÉ
Class: sched
typedef void (*PFV) ();
static PFV exit_fct;
exit_fct is a pointer to a user-defined exit function that has the following
format:
void e_function();
If exit_fct is set to point to such a function, the task system scheduler will
call it before the program exits. To assign the address of a function to
exit_fct, use an expression similar to the following:
exit_fct = e_function;
where e_function is a user-defined exit function with a return type of void and
no arguments.
ΓòÉΓòÉΓòÉ 5.2.7.5. get_clock - Return Value of the Task System Clock ΓòÉΓòÉΓòÉ
Class: sched
static long get_clock();
get_clock() returns the value of the task system clock.
ΓòÉΓòÉΓòÉ 5.2.7.6. get_exit_status - Return Exit Status of Task Program ΓòÉΓòÉΓòÉ
Class: sched
static int get_exit_status();
get_exit_status() returns the exit status of the task program. When a task
program terminates normally (task_error() is not called), the program will call
exit() with the argument i, where i is the value of the argument in the last
call of set_exit_status().
ΓòÉΓòÉΓòÉ 5.2.7.7. get_priority_sched - Return Pointer to interrupt_alerter ΓòÉΓòÉΓòÉ
Class: sched
sched* get_priority_sched();
get_priority_sched() returns a pointer to the system task interrupt_alerter if
the following two conditions are true:
o A signal occurred that an Interrupt_handler object was waiting for.
o The Interrupt_handler object has not been scheduled yet.
get_priority_sched() returns 0 otherwise.
ΓòÉΓòÉΓòÉ 5.2.7.8. get_run_chain - Return Pointer to Run Chain ΓòÉΓòÉΓòÉ
Class: sched
#define run_chain (sched::get_run_chain())
private:
static sched* runchain;
public:
static sched* get_run_chain();
get_run_chain() returns a pointer to the static sched member runchain. runchain
is a linked list of task and timer objects that are ready to run. The macro
definition run_chain is obsolete, but it is included for compatibility with the
AT&T** C++ Language System Release 1.2.
ΓòÉΓòÉΓòÉ 5.2.7.9. keep_waiting - Keep Scheduler Waiting ΓòÉΓòÉΓòÉ
Class: sched
int keep_waiting();
keep_waiting() returns the number of times keep_waiting() has been called (not
counting the current call) minus the number of times that dont_wait() has been
called. keep_waiting() is meant to be called when an object that will wait for
an external event is created. For example, the Interrupt_handler constructor
calls keep_waiting() when it creates an Interrupt_handler object. dont_wait()
should be called when such an object is deleted.
keep_waiting() prevents the scheduler from exiting when there are no tasks that
can run. In such a situation, an external event could change the state of a
task from IDLE, and then the scheduler would have to act.
ΓòÉΓòÉΓòÉ 5.2.7.10. pending - Return State ΓòÉΓòÉΓòÉ
Class: sched
int pending();
pending() returns 0 if the state of schd equals TERMINATED. Otherwise,
pending() returns a nonzero value.
ΓòÉΓòÉΓòÉ 5.2.7.11. print - Print the Contents of sched Object ΓòÉΓòÉΓòÉ
Class: sched
void print(int x, int y=0);
print() prints information about schd on standard output. For more details on
print(), see the description of task::print() in print - Print Task
Information.
ΓòÉΓòÉΓòÉ 5.2.7.12. rdstate - Return the State of sched Object ΓòÉΓòÉΓòÉ
Class: sched
statetype rdstate();
rdstate() returns the state of schd. The state can be RUNNING, IDLE, or
TERMINATED.
ΓòÉΓòÉΓòÉ 5.2.7.13. rdtime - Return Clock Time ΓòÉΓòÉΓòÉ
Class: sched
long rdtime();
rdtime() returns the clock time at which schd is supposed to run. If the state
of the task for which rdtime() is called is either TERMINATED or IDLE, the
value returned by rdtime() is undefined. If rdtime() is called for a timer
task, rdtime() returns the time at which the timer task will terminate.
rdtime() is meant to be used in conjunction with the function task::delay() to
determine when a task will stop delaying.
ΓòÉΓòÉΓòÉ 5.2.7.14. result - Return Result of sched Object ΓòÉΓòÉΓòÉ
Class: sched
int result();
result() returns the result of schd. If the state of schd is not TERMINATED,
the calling task will be suspended to wait for schd to terminate. A task that
calls result() for itself will cause an E_RESULT runtime error.
ΓòÉΓòÉΓòÉ 5.2.7.15. setclock - Initialize the System Clock ΓòÉΓòÉΓòÉ
Class: sched
static void setclock(long init_time);
setclock() is a static function that initializes the system clock to the time
init_time. You will get an E_SETCLOCK runtime error if you call setclock() more
than once in a program.
ΓòÉΓòÉΓòÉ 5.2.7.16. setwho - Record Alerting Object ΓòÉΓòÉΓòÉ
Class: sched
virtual void setwho(object* alt_obj);
setwho() is a virtual function that is defined for task and timer objects.
alt_obj is meant to be a pointer to the object that caused schd to be alerted.
ΓòÉΓòÉΓòÉ 5.2.7.17. set_exit_status - Set Exit Status of Task ΓòÉΓòÉΓòÉ
Class: sched
static void set_exit_status(int i);
set_exit_status() sets the exit status of the task program. When a task program
terminates normally (task_error() is not called), the program calls exit() with
the argument i.
ΓòÉΓòÉΓòÉ 5.2.8. Members of task ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of a task object called tsk.
The following functions are described:
o Constructor for task
o cancel - change state to TERMINATED
o delay - suspend task
o get_task_chain - return first task in list
o _hwm - high water mark variable
o o_type - return class object type
o preempt - make running task idle
o print - print task information
o resultis - set return value
o setwho - record alerting object
o sleep - suspend task unconditionally
o wait - suspend task
o waitlist - suspend task, wait for list of objects
o waitvec - suspend task, wait for vector of objects
o who_alerted_me - return object that put task back on run chain
ΓòÉΓòÉΓòÉ 5.2.8.1. Constructor for task ΓòÉΓòÉΓòÉ
Class: task
task(char* name = 0, modetype mode = DEFAULT_MODE,
int stacksize = SIZE);
The task constructor is declared protected. You cannot call the task
constructor to create a task object directly, but you can use the task
constructor to create objects of the classes that you derive from task.
The first argument of the task constructor specifies the name of the task. The
default value for name is 0. mode specifies whether the task is SHARED or
DEDICATED. The default value for mode is DEFAULT_MODE. stacksize specifies the
size of the stack for the task. The default value for stacksize is SIZE. The
default values DEFAULT_MODE and SIZE are defined in task.h.
Notes
1. At the end of every constructor of a task object, including the main()
function in any program that uses the task library, a call to resultis()
should appear, unless you want the constructor to execute infinitely.
2. The results of ending a task abnormally using the standard C library
function exit() are undefined. Unpredictable results will occur.
ΓòÉΓòÉΓòÉ 5.2.8.2. cancel - Change State to TERMINATED ΓòÉΓòÉΓòÉ
Class: task
void cancel(int ret_val);
cancel() changes the state of tsk to TERMINATED and sets the return value of
tsk to ret_val. cancel() does not invoke the scheduler.
ΓòÉΓòÉΓòÉ 5.2.8.3. delay - Suspend Task ΓòÉΓòÉΓòÉ
Class: task
void delay(long interval);
delay() suspends tsk for the time specified by interval. A task that calls
delay() has a state of RUNNING, and the call to delay() does not change the
state of the task. If the current time on the task system clock is t{0}, tsk
resumes at time t{0} + interval. A call to delay() causes the clock to advance.
delay() is usually called by a task on itself. If such a task has a state of
IDLE, a call to delay() results in an E_CLOCKIDLE runtime error.
ΓòÉΓòÉΓòÉ 5.2.8.4. get_task_chain - Return First Task in List ΓòÉΓòÉΓòÉ
Class: task
static task* get_task_chain();
#define task_chain (task::get_task_chain())
get_task_chain() returns a pointer to the first task object in the list of task
objects. Each task object is linked together by the member t_next.
The macro task_chain() is included for compatibility with the AT&T** C++
Language System Release 1.2.
ΓòÉΓòÉΓòÉ 5.2.8.5. _hwm - High Water Mark Variable ΓòÉΓòÉΓòÉ
Class: task
extern _hwm;
The external variable _hwm is the high water mark variable for the stack
associated with a task. If it is initially set to a nonzero value, _hwm causes
the task system to record the maximum size of the stack. _hwm also affects what
is printed by task::print() with an argument of STACK. If _hwm is initially set
to a nonzero value, a call to task::print() with an argument of STACK will
print out high water mark information. This information is meant for debugging.
Note that gathering this information could reduce the performance of your
application, and thus you should only give _hwm an initial nonzero value when
you are debugging.
You can set _hwm in the main() function, but if you want the value of _hwm to
be nonzero for the main() task and the interrupt_alerter task you must set the
value of _hwm in the constructor of a static object. The following example
shows how you might set the value of _hwm to accomplish this:
extern _hwm;
class hwm_init {
public:
hwm_init() { _hwm=1 };
};
static hwm_init hwmi;
// ...
#include <task.h>
Note: The interrupt_alerter task runs before the main() task. Thus, if you set
the value of _hwm in the main() function, no high water mark information will
be recorded for either the main() task or the interrupt_alerter task.
ΓòÉΓòÉΓòÉ 5.2.8.6. o_type - Return Class Object Type ΓòÉΓòÉΓòÉ
Class: task
object::objtype o_type();
o_type() returns the class object type (object::objtype) of tsk, namely
object::TASK.
ΓòÉΓòÉΓòÉ 5.2.8.7. preempt - Make Running Task Idle ΓòÉΓòÉΓòÉ
Class: task
long preempt();
preempt() changes the state of tsk from RUNNING to IDLE. preempt() returns the
number of time units left in the delay for tsk. preempt() produces an E_TASKPRE
runtime error if tsk has state equal to IDLE or TERMINATED.
ΓòÉΓòÉΓòÉ 5.2.8.8. print - Print Task Information ΓòÉΓòÉΓòÉ
Class: task
void print(int x, int y =0);
print() prints information about tsk on standard output. The argument x
specifies the amount of information to be printed. The argument y is used
internally by the Task Library. Its default value is 0.
If x equals 0, the following information is printed:
o The type of the object, namely task
o The task state (RUNNING, IDLE, or TERMINATED)
o The value of the this pointer
If x equals CHAIN, the information listed above is printed, along with the same
information for every task in the chain attached to tsk.
If x equals VERBOSE, the information that is printed when x equals 0 is
printed, along with the following information:
o The mode of the task (DEDICATED or SHARED)
o t_alert, a pointer to the object that alerted tsk
o t_next, a pointer to the next task object in the chain
o The value returned by result() for this task
o The value of the this pointer for the sched and object objects associated
with this task
o The list of tasks on the remember chain for this task
If x equals STACK and the state of tsk is either RUNNING or IDLE, all of the
information that is printed when x equals 0 is printed in addition to the
information listed below:
o The maximum size of the stack for this task
o The current size of the stack
o The size of _hwm (if _hwm is initially set to a nonzero value)
o t_basep, the address of the base of the stack when the state of the task is
RUNNING
o t_framep, the frame pointer for the task when its state is IDLE
o The current address of the top of the stack
o The maximum address for the top of the stack
If x equals STACK and the state of tsk is TERMINATED, all of the information
that is printed when x equals 0 is printed in addition to the information
listed below:
o The status of the stack, namely deleted
o The size and address of _hwm (if _hwm is initially set to a nonzero value)
ΓòÉΓòÉΓòÉ 5.2.8.9. resultis - Set Return Value ΓòÉΓòÉΓòÉ
Class: task
void resultis(int res);
resultis() sets the return value of tsk to res and sets the state of tsk to
TERMINATED. The result() member function of the class sched returns the value
of this result. An object of a class derived from task object cannot return a
value using the usual function return mechanism. A call to resultis() should
appear at the end of every constructor for every class that is derived from
task.
ΓòÉΓòÉΓòÉ 5.2.8.10. setwho - Record Alerting Object ΓòÉΓòÉΓòÉ
Class: task
void setwho(object* alt_obj);
setwho() is a virtual function that is defined for task and timer objects.
alt_obj is a pointer to the object that caused the scheduler to be alerted.
setwho() records the object pointed to by alt_obj as the one that caused the
state of tsk to change from IDLE to RUNNING. alt_obj points to an object that
had a change of state from pending to ready that caused tsk to be put back in
the run chain. who_alerted_me() returns this pointer.
ΓòÉΓòÉΓòÉ 5.2.8.11. sleep - Suspend Task Unconditionally ΓòÉΓòÉΓòÉ
Class: task
void sleep(object* ob=0);
sleep() changes the state of tsk to IDLE. If ob points to a pending object, tsk
will be put back on the run chain when the state of ob changes to ready. If ob
points to a ready object, or if no argument is supplied, tsk will never be put
back on the run chain; the event that would cause tsk to be resumed is
unspecified. In this case, tsk can only be eliminated by a call to cancel().
Only objects of the predefined classes automatically alert the tasks that are
waiting for them. Objects of classes that you define must explicitly call
object::alert() when their state changes from pending to ready.
See Object States for a general description of the object states.
ΓòÉΓòÉΓòÉ 5.2.8.12. wait - Suspend Task ΓòÉΓòÉΓòÉ
Class: task
void wait(object* ob);
If the state of the object pointed to by ob is pending, wait() changes the
state of tsk to IDLE until the object is ready. If the state of the object
pointed to by ob is ready, the state of tsk remains unchanged. If wait() is
called with an argument equal to 0, tsk will never be put back on the run
chain, and tsk can only be eliminated by a call to cancel(). If the argument of
wait() is a pointer to tsk, wait() produces an E_WAIT runtime error.
Unlike sleep(), wait() checks the state of its argument before it changes the
state of tsk. Suppose obr is a pointer to a ready object. tsk.wait(obr) does
not change the state of tsk, but tsk.sleep(obr) does change the state of tsk.
Note: A task should only call wait() on itself.
ΓòÉΓòÉΓòÉ 5.2.8.13. waitlist - Suspend Task, Wait for List of Objects ΓòÉΓòÉΓòÉ
Class: task
int waitlist(object* ob1...);
waitlist() takes as arguments a list of pointers to objects. The last element
in this list must be equal to 0. The result of waitlist() depends on the state
of the objects pointed to by the arguments:
o If all of the arguments point to objects that have a state of pending,
waitlist() changes the state of tsk to IDLE. As soon as the state of one of
the objects pointed to by the arguments becomes ready, the state of tsk is
changed back to RUNNING and waitlist() returns the position of this argument
in the list. For example, if the object pointed to by the third argument is
the first one to become ready, waitlist() has a return value of 2 (because
the first argument is at position 0).
o If any argument obi ( i = 1 . . . n) in the list of arguments is ready (that
is, the function obi->pending() returns 0), the state of tsk is not changed
and waitlist() returns the position of obi in the argument list. Other
arguments in the list may also point to objects that are ready, but
waitlist() only returns the position of the first one.
ΓòÉΓòÉΓòÉ 5.2.8.14. waitvec - Suspend Task, Wait for Vector of Objects ΓòÉΓòÉΓòÉ
Class: task
int waitvec(object** objvec);
waitvec() is the same as waitlist() except that its argument objvec is a
pointer to a vector that holds a list of object pointers. The last pointer in
this vector must be equal to 0.
ΓòÉΓòÉΓòÉ 5.2.8.15. who_alerted_me - Return Object that Put Task Back on Run Chain ΓòÉΓòÉΓòÉ
Class: task
object* who_alerted_me();
who_alerted_me() returns a pointer to the object whose state change from
pending to ready caused tsk to change state from IDLE to RUNNING.
ΓòÉΓòÉΓòÉ 5.2.9. Public Members of timer ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of a timer object called tm.
The following functions are defined:
o Constructor for timer
o o_type - return class object type
o print - print contents of timer object
o reset - reset the delay of the timer object
o setwho - record alerting object
An example of using the timer class is also provided.
ΓòÉΓòÉΓòÉ 5.2.9.1. Constructor for timer ΓòÉΓòÉΓòÉ
Class: timer
timer(long wait_time);
timer() constructs a timer object and inserts it on the scheduler's run chain.
wait_time is the number of time units that tm, the newly created timer object,
runs.
timer objects are inserted into the run chain based on the value of wait_time
when they were created. The scheduler resets the current time to the wait_time
of the task object at the front of the run chain.
ΓòÉΓòÉΓòÉ 5.2.9.2. o_type - Return Class Object Type ΓòÉΓòÉΓòÉ
Class: timer
object::objtype o_type();
o_type() returns the class object type (object::objtype) of tm, namely
object::TIMER.
ΓòÉΓòÉΓòÉ 5.2.9.3. print - Print Contents of timer Object ΓòÉΓòÉΓòÉ
Class: timer
void print(int x, int y);
print() prints information about tm. The argument x specifies the amount of
information to be printed. The argument y is used internally by the Task
Library. Its default value is 0.
If x equals 0, print() displays the following information on standard output:
o The type of the object, namely timer
o The amount of time that tm has to wait
o The offset from the current setting of the task system clock
If x equals VERBOSE, print() displays the information listed above, along with
the following information:
o The value of the this pointer in the sched object
o The value of the this pointer in the object
o The list of remembered task objects
ΓòÉΓòÉΓòÉ 5.2.9.4. reset - Reset the Delay of the timer Object ΓòÉΓòÉΓòÉ
Class: timer
void reset(long wait_time);
reset() resets the time units that tm has to wait to wait_time. A timer object
can be reset even if its state equals TERMINATED.
ΓòÉΓòÉΓòÉ 5.2.9.5. setwho - Record Alerting Object ΓòÉΓòÉΓòÉ
Class: timer
void setwho(object* alt_obj);
In the timer object, setwho() is defined to do nothing.
ΓòÉΓòÉΓòÉ 5.2.9.6. Example of Using the timer Class ΓòÉΓòÉΓòÉ
Class: timer
The following example shows the different ways that you can use the timer class
and advance the clock:
#include <task.h>
#include <iostream.h>
class ct : public task {
int cnt ;
public:
ct();
};
ct::ct():cnt(0) {
while(++cnt) {sleep(); }
}
void main() {
timer *t;
object *ov[2];
//
ct ct1;
sched::clock_task = &ct1;
//
// Advance the task system clock 50 times
// by 50 time units each time. Use various
// different ways for clock advancement.
//
for (register i=0; i<10; ++i) {
thistask->delay(50);
}
for (i=0; i<10; ++i) {
t= new timer (50);
thistask->wait(t);
}
t->print(0);
for (i=0; i<10; ++i) {
t= new timer (50);
thistask->sleep(t);
}
t->print(0);
for (i=0; i<10; ++i) {
t= new timer (50);
thistask->waitlist(t,0);
}
t->print(VERBOSE);
for (i=0; i<10; ++i) {
t= new timer (50);
ov[0]=t;
ov[1]=0;
thistask->waitvec(ov);
}
t->print(0);
thistask->resultis(0);
}
This program produces output similar to the following:
timer 1000 == clock+0
timer 1500 == clock+0
timer 1500 == clock+0
timer 2000 == clock+0
sched: this=b1190
object: this=b1190
No tasks remembered
timer 2500 == clock+0
ΓòÉΓòÉΓòÉ 5.3. Queue Management Classes ΓòÉΓòÉΓòÉ
This chapter describes the queue management classes qhead and qtail. You can
use these classes to implement a wide range of message-passing and
data-buffering schemes. Both classes are derived from the class object.
The following topics are described in this chapter:
o What is a queue?
o Queue attributes
o Cutting and splicing queues
o Restrictions on putting objects in queues
o Declarations for the Queue Management Classes in task.h
o Public members of qhead
o Public members of qtail
ΓòÉΓòÉΓòÉ 5.3.1. What Is a Queue? ΓòÉΓòÉΓòÉ
A queue is a data structure with an associated list of objects that are
extracted from the queue in first-in, first-out order. No public functions deal
with queues directly; you manage a queue using the qhead and qtail objects that
are associated with each queue. You create a queue by creating either a qhead
object or a qtail object.
If you create a qhead object, you can obtain the qtail object that is
associated with that qhead object by calling qhead::tail(). Similarly, if you
create a qtail object, you can obtain the qhead object that is associated with
that qtail object by calling qtail::head().
Once a queue is established, you use qtail::put() to add objects to it and
qhead::get() to remove objects from it.
Because both qhead and qtail are derived from the class object, they both have
definitions for when they are ready and when they are pending. qhead objects
are ready when the queue is not empty and pending when the queue is empty.
qtail objects are ready when the queue is not full and pending when the queue
is full.
ΓòÉΓòÉΓòÉ 5.3.2. Queue Attributes ΓòÉΓòÉΓòÉ
Queues have three attributes that control the operation of the queue:
o mode: controls what happens when a qhead or qtail object is pending. The mode
attribute can have different settings for the qhead and qtail objects that
make up a queue.
o maximum size: controls the maximum number of objects that can be in the
queue.
o count: records the number of objects that are in the queue.
ΓòÉΓòÉΓòÉ 5.3.2.1. Mode Attribute ΓòÉΓòÉΓòÉ
The mode controls what happens when a qhead or qtail object is pending. The
qhead and qtail objects that are attached to the same queue do not necessarily
have the same mode. The mode can have the following values:
o WMODE (wait mode): a task that calls qhead::get() on an empty queue is
suspended until the queue is no longer empty. A task that calls qtail::put()
on a full queue is suspended until the queue is no longer full.
o EMODE (error mode): calling qhead::get() for an empty queue or qtail::put()
for a full queue causes a runtime error.
o ZMODE (zero mode): a call to qtail::put() for a full queue or a call to
qhead::get() for an empty queue returns 0. Otherwise, qtail::put() and
qhead::get() return 1.
ΓòÉΓòÉΓòÉ 5.3.2.2. Maximum Size Attribute ΓòÉΓòÉΓòÉ
The maximum size is set to 10 000 by default. A queue can hold up to 10 000
pointers to objects, but it does not preallocate space. You can use either
qhead::setmax() or qtail::setmax() to reset the maximum queue size. You can use
use either qhead::rdmax() or qtail::rdmax() to get the current setting of the
maximum size attribute.
ΓòÉΓòÉΓòÉ 5.3.2.3. Count Attribute ΓòÉΓòÉΓòÉ
The count is the number of objects in the queue. You can use qhead::rdcount()
to get the current value of the count attribute.
ΓòÉΓòÉΓòÉ 5.3.3. Cutting and Splicing Queues ΓòÉΓòÉΓòÉ
You can split a queue into two pieces using the member functions qhead::cut()
and qtail::cut(). See cut - Split Queue for more details on qhead::cut(). You
can join these two pieces together again into a single queue using the member
functions qhead::splice() and qtail::splice().
You can use cutting and splicing to insert a filter into a data stream. A
filter is a task that takes input from one queue, performs some kind of
transformation on it, and puts the transformed data on another queue. If you
want to insert a filter into an existing queue, you can use cut() to split the
queue in two pieces. Then the filter can get input from the head of one queue
and put output to the tail of the other queue. When the filter has finished its
processing, you can use splice() to make the two pieces into a single queue
again.
Note: Because you do not deal directly with queues, but rather with qhead and
qtail objects, you never use the name of a queue in your code. In this chapter,
queues are given names so that they can be discussed conveniently. These names
would not appear in any actual code.
A queue called oldqueue is attached to the qtail object qt. oldqueue is split,
and qt is now attached to a new queue called newqueue. Finally, oldqueue and
newqueue are reunited with a call to qtail::splice(). The operations
illustrated in Cutting and Splicing a qtail Object could be accomplished by
code that looks like this:
qtail *qt = new qtail;
qhead *qh = qt->head();
qtail *qtp = qt->cut();
qhead *qhp = qt->head();
qtp->splice(qhp);
The following figure illustrates what happens to a qtail object when it is cut
and spliced.
before qt->cut();
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
qh Γöé Γöé qt
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ oldqueue Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
after qt->cut();
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
qh Γöé Γöé qtp qhp Γöé Γöé qt
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ oldqueue Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ newqueue Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Γöé Γöé Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
after qtp->splice(qhp);
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
qh Γöé Γöé qt
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ oldqueue Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Cutting and Splicing a qtail Object
Cutting and Splicing a qhead Object illustrates what happens to a qhead object
when it is cut and spliced. A queue called oldqueue is attached to the qhead
object qh. oldqueue is split, and qh is now attached to a new queue called
newqueue. Finally, oldqueue and newqueue are reunited with a call to
qhead::splice(). The operations illustrated in Cutting and Splicing a qhead
Object could be accomplished by code that looks like this:
qhead *qh = new qhead;
qtail *qt = qh->tail();
qhead *qhp = qh->cut();
qtail *qtp = qh->tail();
qhp->splice(qtp);
before qh->cut();
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
qh Γöé Γöé qt
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ oldqueue Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
after qh->cut();
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
qh Γöé Γöé qtp qhp Γöé Γöé qt
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ newqueue Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ oldqueue Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Γöé Γöé Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
after qhp->splice(qtp);
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
qh Γöé Γöé qt
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ oldqueue Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Cutting and Splicing a qhead Object
ΓòÉΓòÉΓòÉ 5.3.3.1. Example of Cutting and Splicing a Queue ΓòÉΓòÉΓòÉ
The following example shows how you can use cutting and splicing to insert a
filter into a data stream. This example includes the following classes:
o Producer: creates a series of random numbers and puts them into the tail of a
queue.
o Consumer: gets numbers from the head of a queue and prints them.
o Filter: gets numbers from the head of a queue, sorts them, and puts them into
the tail of a queue.
In the main() function of this example, the following operations are performed:
o The Producer object p1 and the Consumer object c1 are created with the same
queue (called oldqueue in this discussion). Thus, c1 prints the numbers
produced by p1.
o oldqueue is cut to produce a new queue (called newqueue in this discussion).
Producer object p2 is created with oldqueue as its argument, and Consumer
object c2 is created with newqueue as its argument. In between p2 and c2,
Filter object f is created with oldqueue and newqueue as arguments. Thus f
takes the numbers produced by p2, sorts them, and sends them to c2 to be
printed.
o oldqueue and newqueue are spliced together to produce a restored oldqueue.
Producer object p3 and Consumer object c3 are created with the same queue,
oldqueue. Thus, c3 prints the numbers produced by p3.
The output produced by this example includes an unsorted list of numbers,
followed by a sorted list of numbers, followed by an unsorted list of numbers.
Note: You must set the language level to "compat" in order to compile this
program successfully. You can use the /Sc switch to do this.
#include <iostream.h>
#include <task.h>
#include <stdlib.h>
const int NumberOfIterations = 10;
class Message : public object {
private:
int value;
public:
Message(int v) : value(v) {}
int getValue() { return value; }
};
class Producer : public task {
public:
Producer(qtail *qt);
};
class Consumer : public task {
public:
Consumer(qhead *qh);
};
class Filter : public task {
static int Comparison(const void *, const void *);
public:
Filter(qhead *qhp, qtail *qtp);
void sortArray(int *arr);
};
Producer::Producer(qtail *qt)
{
urand u(1,100);
for (int lcv=0; lcv < NumberOfIterations; lcv++)
qt->put(new Message(u.draw()));
resultis(0);
}
Consumer::Consumer(qhead *qh)
{
for (int lcv=0; lcv < NumberOfIterations; lcv++)
{
Message *mess = (Message *)qh->get();
cout << "Consumer got "
<< mess->getValue() << endl;
delete mess;
}
resultis(0);
}
Filter::Filter(qhead *qhp, qtail *qtp)
{
int arr[NumberOfIterations];
for (int lcv=0; lcv < NumberOfIterations; lcv++)
{
Message *mess = (Message *)qhp->get();
arr[lcv] = mess->getValue();
delete mess;
}
sortArray(arr);
for (lcv=0; lcv < NumberOfIterations; lcv++)
qtp->put(new Message(arr[lcv]));
resultis(0);
}
int Filter::Comparison(const void *e1, const
void *e2)
{
if (*(int *)e1 < *(int *)e2)
return -1;
if (*(int *)e1 == *(int *)e2)
return 0;
return 1;
}
void Filter::sortArray(int *arr)
{
qsort(arr, NumberOfIterations, sizeof(int),
&Filter::Comparison);
}
void main()
{
qhead *qh = new qhead;
qtail *qt = qh->tail();
Producer p1(qt);
Consumer c1(qh);
cout << "Now insert a filter that will sort the numbers: " << endl;
qhead *qhp = qh->cut();
qtail *qtp = qh->tail();
Producer p2(qt);
Filter f(qhp,qtp);
Consumer c2(qh);
cout << "Now remove the filter: " << endl;
qhp->splice(qtp);
Producer p3(qt);
Consumer c3(qh);
cout << "All done" << endl;
thistask->resultis(0);
}
This program produces output that looks like this:
Consumer got 1
Consumer got 66
Consumer got 31
Consumer got 68
Consumer got 11
Consumer got 52
Consumer got 49
Consumer got 61
Consumer got 37
Consumer got 26
Now insert a filter that will sort the numbers:
Consumer got 1
Consumer got 11
Consumer got 26
Consumer got 31
Consumer got 37
Consumer got 49
Consumer got 52
Consumer got 61
Consumer got 66
Consumer got 68
Now remove the filter:
Consumer got 1
Consumer got 66
Consumer got 31
Consumer got 68
Consumer got 11
Consumer got 52
Consumer got 49
Consumer got 61
Consumer got 37
Consumer got 26
All done
ΓòÉΓòÉΓòÉ 5.3.4. Restrictions on Putting Objects in Queues ΓòÉΓòÉΓòÉ
An object should not be in more than one queue at the same time. An object can
end up in two queues in a subtle fashion. For example, the constructor for the
timer class places the object that it constructs on the run chain, a queue of
task objects that have a state equal to RUNNING.
In the following example, a timer object t1 is created and automatically put on
the run chain queue. t1 is then placed on another queue, q1. Placing t1 on a
second queue causes the program to be suspended:
#include <task.h>
class MyTask : public task {
public:
MyTask();
};
MyTask::MyTask() {
qtail q1;
timer *t1 = new timer(60); // t1 is put on the run
// chain queue by the timer
// constructor
//
q1.put(t1); // t1 is now on 2 queues and
// the program will hang
resultis(0);
}
void main(){
MyTask mt;
thistask->resultis(0);
}
ΓòÉΓòÉΓòÉ 5.3.5. Declarations for the Queue Management Classes in task.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses members of qhead
or qtail classes:
#include <task.h>
The following excerpt from the task.h header file shows member function
declarations for the queue management classes:
enum qmodetype { EMODE, WMODE, ZMODE };
class qhead : public object {
friend class qtail;
public:
qhead(qmodetype = WMODE, int = 10000);
~qhead();
object::objtype o_type();
object* get();
int putback(object*);
int rdcount();
int rdmax();
qmodetype rdmode();
qtail* tail();
qhead* cut();
void splice(qtail*);
void setmode(qmodetype m);
void setmax(int m);
int pending();
void print(int, int =0);
};
class qtail : public object {
friend class qhead;
public:
qtail(qmodetype = WMODE, int = 10000);
~qtail();
object::objtype o_type();
int put(object*);
int rdspace();
int rdmax();
qmodetype rdmode();
qtail* cut();
void splice(qhead*);
qhead* head();
void setmode(qmodetype m);
void setmax(int m);
int pending();
void print(int, int =0);
};
ΓòÉΓòÉΓòÉ 5.3.6. Public Members of qhead ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of a qhead object called qh, unless otherwise noted.
The following functions are described:
o Constructor for qhead
o cut - split queue
o get - extract object from queue
o o_type - return class type
o pending - is queue empty?
o print - print queue contents
o putback - put objects back in queue
o rdcount - return number of objects in queue
o rdmax - return maximum queue size
o rdmode - return mode
o setmode - set mode
o setmax - set maximum queue size
o splice - merge queues
o tail - create qtail object
ΓòÉΓòÉΓòÉ 5.3.6.1. Constructor for qhead ΓòÉΓòÉΓòÉ
Class: qhead
qhead(qmodetype qm= WMODE, int size=10000);
The qhead() constructor takes two optional arguments. The qmodetype, qm, can
have a value of WMODE, EMODE, or ZMODE. WMODE is the default. The argument
size, the maximum number of objects that can be placed in the queue, has a
default value of 10 000.
ΓòÉΓòÉΓòÉ 5.3.6.2. cut - Split Queue ΓòÉΓòÉΓòÉ
Class: qhead
qhead* cut();
cut() splits the queue attached to qh and returns a pointer to a new qhead
object. In this description, this new qhead object is called qhp. qhp is
attached to the original queue. qh now points to a new, empty queue. You must
establish a new qtail for qh. If you want to get objects from the original
queue, you must call qhp.get().
You can use the member function splice() to restore a split queue to its
original configuration.
Cutting and Splicing a qhead Object illustrates the cutting and splicing of a
qhead object.
ΓòÉΓòÉΓòÉ 5.3.6.3. get - Extract Object from Queue ΓòÉΓòÉΓòÉ
Class: qhead
object* get();
If the queue is not empty, get() returns a pointer to the object at the head of
the queue. If the queue is empty, the result depends on the mode:
o WMODE: the task that executes get() is suspended until the queue is no longer
empty.
o EMODE: the E_GETEMPTY runtime error is produced.
o ZMODE: get() returns 0.
ΓòÉΓòÉΓòÉ 5.3.6.4. o_type - Return Class Type ΓòÉΓòÉΓòÉ
Class: qhead
object::objtype o_type();
o_type() returns the class type of qh, namely object::QHEAD.
ΓòÉΓòÉΓòÉ 5.3.6.5. pending - Is Queue Empty? ΓòÉΓòÉΓòÉ
Class: qhead
int pending();
pending() returns a nonzero value if the queue is empty and returns zero
otherwise.
ΓòÉΓòÉΓòÉ 5.3.6.6. print - Print Queue Contents ΓòÉΓòÉΓòÉ
Class: qhead
void print(int detail, int y=0);
print() prints information about the queue attached to qh on stdout. It calls
the print() member function of the object base class. Argument detail specifies
the amount of information to be printed. Argument y is used internally by the
Task Library and defaults to 0.
If detail equals 0, the following information is printed:
o The type of object, namely qhead
o The integer value of the mode of the queue
o The maximum size of the queue
o The value of the count attribute for the queue
o The value of the qtail pointer
If detail equals VERBOSE, the information listed above is printed along with
information about the qtail object that is attached to the queue and
information about all of the tasks that are waiting for qh. The following
values for the qtail object are printed:
o The type of object, namely qtail
o The integer value of the mode of the queue
o The maximum size of the queue
o The number of objects that the queue still has room for
o The value of the qhead pointer
For each task that is waiting for qh, the following information is printed:
o The value of the t_alert pointer, a private pointer to the object that
alerted the task
o The value of the t_next pointer, a pointer to the next task on the chain
o The value of the s_time pointer, a private pointer to the time at which the
task is scheduled to run
o The value of the this pointer for the sched and object this task is derived
from
ΓòÉΓòÉΓòÉ 5.3.6.7. putback - Put Objects Back in Queue ΓòÉΓòÉΓòÉ
Class: qhead
int putback(object* objptr);
putback() puts the object pointed to by objptr back on the head of the queue
attached to qh, allowing qh to operate as a stack. A task that calls putback()
competes for queue space with tasks that call qtail::put(). If the call to
putback() succeeds, putback() returns 1. If the queue is full, a runtime error
occurs if mode equals EMODE or WMODE. 0 is returned if mode equals ZMODE.
ΓòÉΓòÉΓòÉ 5.3.6.8. rdcount - Return Number of Objects in Queue ΓòÉΓòÉΓòÉ
Class: qhead
int rdcount();
rdcount() returns the number of objects in the queue attached to qh.
ΓòÉΓòÉΓòÉ 5.3.6.9. rdmax - Return Maximum Queue Size ΓòÉΓòÉΓòÉ
Class: qhead
int rdmax();
rdmax() returns the maximum size of the queue attached to qh.
ΓòÉΓòÉΓòÉ 5.3.6.10. rdmode - Return Mode ΓòÉΓòÉΓòÉ
Class: qhead
qmodetype rdmode();
rdmode() returns the mode of qh.
ΓòÉΓòÉΓòÉ 5.3.6.11. setmode - Set Mode ΓòÉΓòÉΓòÉ
Class: qhead
void setmode(qmodetype qm);
setmode() resets the mode of qh to qm.
ΓòÉΓòÉΓòÉ 5.3.6.12. setmax - Set Maximum Queue Size ΓòÉΓòÉΓòÉ
Class: qhead
void setmax(int newmax);
setmax() sets the maximum size of the queue attached to qh to newmax. You can
set the maximum size to be less than the current size of the queue. If you do,
you cannot put objects in the queue until the number of objects in the queue is
less than the new maximum size. If newmax is less than or equal to 0, the
E_QZERO runtime error is produced.
ΓòÉΓòÉΓòÉ 5.3.6.13. splice - Merge Queues ΓòÉΓòÉΓòÉ
Class: qhead
void splice(qtail* qt);
splice() reconnects two queues that were split by a call to cut().
qhp->splice(qtp) merges the queue attached to the qhead pointer qhp with the
queue attached to the qtail pointer qtp, where:
o A call qh.cut() was made that returned the qhead pointer qhp. After this
call, qh is attached to a new queue and qhp is attached to the original
queue.
o After the call to cut(), a call qh.tail() was made that returned the qtail
pointer qtp.
In the new queue, the objects that were in the queue attached to qtp precede
the objects that were in the queue attached to qhp. splice() deletes both qhp
and qtp.
If the call to splice() makes an empty queue no longer empty or makes a full
queue no longer full, it will alert all of the tasks that are waiting for
either of these state changes and add these tasks to the scheduler's run chain.
Cutting and Splicing a qhead Object illustrates the cutting and splicing of a
qhead object.
ΓòÉΓòÉΓòÉ 5.3.6.14. tail - Create qtail Object ΓòÉΓòÉΓòÉ
Class: qtail
qtail* tail();
tail() creates a qtail object for the queue attached to qh (if none exists) and
returns a pointer to the new qtail object. If a qtail object already exists for
the queue attached to qh, tail() returns a pointer to that qtail object.
ΓòÉΓòÉΓòÉ 5.3.7. Public Members of qtail ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of a qtail object called qt.
The following functions are described:
o Constructor for qtail
o cut - split queue
o head - create qhead object
o o_type - return class type
o pending - is queue full?
o print - print queue contents
o put - add object to queue
o rdspace - space remaining
o rdmax - return maximum queue size
o rdmode - return mode
o setmode - set mode
o setmax - set maximum queue size
o splice - merge queues
ΓòÉΓòÉΓòÉ 5.3.7.1. Constructor for qtail ΓòÉΓòÉΓòÉ
Class: qtail
qtail(qmodetype qm = WMODE, int size=10000);
The qtail() constructor takes two optional arguments. The qmodetype, qm, can
have a value of WMODE, EMODE, or ZMODE. WMODE is the default. The argument
size, the maximum number of objects that can be placed in the queue, has a
default value of 10 000.
ΓòÉΓòÉΓòÉ 5.3.7.2. cut - Split Queue ΓòÉΓòÉΓòÉ
Class: qtail
qtail* cut();
cut() splits the queue attached to qt and returns a pointer to a new qtail
object, qtp. qtp is attached to the original queue. qt now points to a new,
empty queue. You must establish a new qhead for qt. If you want to put objects
into the original queue, you must call qtp.put().
You can use the member function splice() to restore a split queue to its
original configuration.
Cutting and Splicing a qtail Object illustrates the cutting and splicing of a
qtail object.
ΓòÉΓòÉΓòÉ 5.3.7.3. head - Create qhead Object ΓòÉΓòÉΓòÉ
Class: qtail
qhead* head();
head() creates a qhead object for the queue attached to qt (if none exists) and
returns a pointer to the new qhead object. If a qhead object already exists for
the queue attached to qt, head() returns a pointer to that qhead object.
ΓòÉΓòÉΓòÉ 5.3.7.4. o_type - Return Class Type ΓòÉΓòÉΓòÉ
Class: qtail
object::objtype o_type();
o_type() returns the class type of qt, namely object::QTAIL.
ΓòÉΓòÉΓòÉ 5.3.7.5. pending - Is Queue Full? ΓòÉΓòÉΓòÉ
Class: qtail
int pending();
pending() returns a nonzero value if the queue attached to qt is full and 0
otherwise.
ΓòÉΓòÉΓòÉ 5.3.7.6. print - Print Queue Contents ΓòÉΓòÉΓòÉ
Class: qtail
void print(int detail, int y=0);
print() prints information about the queue attached to qt on stdout. It calls
the print() member function of the object base class. detail specifies the
amount of information to be printed. The second argument, y, is used internally
by the Task Library and has a default value of 0.
If detail equals 0, the following information is printed:
o The type of object, namely qtail
o The integer value of the mode of the queue
o The maximum size of the queue
o The number of objects that the queue still has room for
o The value of the qhead pointer
If detail equals VERBOSE, the information listed above is printed along with
information about the qhead object that is attached to the queue and
information about all of the tasks that are waiting for qt. The following
values for the qhead object are printed:
o The type of object, namely qhead
o The integer value of the mode of the queue
o The maximum size of the queue
o The number of elements in the queue
o The value of the qtail pointer
For each task that is waiting for qt, the following information is printed:
o The value of the t_alert pointer, a private pointer to the object that
alerted the task
o The value of the t_next pointer, a pointer to the next task on the chain
o The value of the s_time pointer, a private pointer to the time at which the
task is scheduled to run
o The value of the this pointer for the sched and object this task is derived
from
ΓòÉΓòÉΓòÉ 5.3.7.7. put - Add Object to Queue ΓòÉΓòÉΓòÉ
Class: qtail
int put(object* obj);
put() adds the object obj to the tail of the queue that is attached to qt.
put() returns 1 if it succeeds. If the queue is full, the result depends on the
mode:
o WMODE: the task that executes put() is suspended until the queue is no longer
full
o EMODE: the E_PUTFAIL runtime error is produced
o ZMODE: put() returns 0
ΓòÉΓòÉΓòÉ 5.3.7.8. rdspace - Space Remaining ΓòÉΓòÉΓòÉ
Class: qtail
int rdspace();
rdspace() returns the number of objects that can be inserted into the queue
attached to qt before it becomes full. The number of objects in a queue can be
greater than the value specified by the maximum size of the queue if one of the
two following conditions is true:
o You call splice() to reunite two pieces of a queue that together contain more
objects than the value specified by the maximum size for the queue.
o You call setmax() with an argument that is less than the number of objects
currently in the queue.
If the number of objects in the queue is greater than the value specified by
the maximum size of the queue, rdspace() returns a negative value. The absolute
value of this value equals the number of objects that are in the queue over and
above the maximum size of the queue.
ΓòÉΓòÉΓòÉ 5.3.7.9. rdmax - Return Maximum Queue Size ΓòÉΓòÉΓòÉ
Class: qtail
int rdmax();
rdmax() returns the maximum size of the queue attached to qt.
ΓòÉΓòÉΓòÉ 5.3.7.10. rdmode - Return Mode ΓòÉΓòÉΓòÉ
Class: qtail
qmodetype rdmode();
rdmode() returns the mode of qt.
ΓòÉΓòÉΓòÉ 5.3.7.11. setmode - Set Mode ΓòÉΓòÉΓòÉ
Class: qtail
void setmode(qmodetype qm);
setmode() sets the mode of qt to qm.
ΓòÉΓòÉΓòÉ 5.3.7.12. setmax - Set Maximum Queue Size ΓòÉΓòÉΓòÉ
Class: qtail
void setmax(int newmax);
setmax() sets the maximum size of the queue attached to qt to newmax. You can
set the maximum size to be less than the current size of the queue. If you do,
you cannot put objects on the queue until the number of objects in the queue is
less than the new maximum size. If newmax is less than or equal to 0, the
E_QZERO runtime error is produced.
ΓòÉΓòÉΓòÉ 5.3.7.13. splice - Merge Queues ΓòÉΓòÉΓòÉ
Class: qtail
void splice(qhead* qh);
splice() reconnects two queues that were split by a call to cut().
qtp->splice(qhp) merges the queue attached to the qtail pointer qtp with the
queue attached to the qhead pointer qhp, where:
o A call qt.cut() was made that returned the qtail pointer qtp. After this
call, qt is attached to a new queue and qtp is attached to the original
queue.
o After the call to cut(), a call qt.head() was made that returned the qhead
pointer qhp.
In the new queue, the objects that were in the queue attached to qtp precede
the objects that were in the queue attached to qhp. splice() deletes both qtp
and qhp.
If the call to splice() makes an empty queue no longer empty or makes a full
queue no longer full, it will alert all of the tasks that are waiting for
either of these state changes and add these tasks to the scheduler's run chain.
Cutting and Splicing a qtail Object illustrates the cutting and splicing of a
qtail object.
ΓòÉΓòÉΓòÉ 5.4. Interrupt_handler Class ΓòÉΓòÉΓòÉ
This chapter describes the Interrupt_handler class. This class allows tasks to
wait for external events in the form of signals from the operating system. The
header file task.h includes the declaration of a related class,
Interrupt_alerter, but this class is not meant to be used directly.
Interrupt_alerter is only documented here to show how it interacts with
Interrupt_handler.
The following topics are described in this chapter:
o Declarations for Interrupt_handler in task.h
o Public members of Interrupt_handler
o Public members of Interrupt_alerter
o Example of using Interrupt_handler
ΓòÉΓòÉΓòÉ 5.4.1. Declarations for Interrupt_handler in task.h ΓòÉΓòÉΓòÉ
You must include the following statement in any file that uses members of the
Interrupt_handler class:
#include <task.h>
The following is an excerpt from task.h that shows the relevant declarations
for the members of Interrupt_handler:
class Interrupt_handler : public object{
friend class Interrupt_alerter;
friend SIG_FUNC_TYP sigFunc;
int id;
int got_interrupt;
Interrupt_handler *old;
virtual void interrupt();
public:
Interrupt_handler(int sig_num);
~Interrupt_handler();
object::objtype o_type();
int pending();
void print(int, int =0);
};
class Interrupt_alerter : public task {
public:
Interrupt_alerter();
~Interrupt_alerter();
};
extern Interrupt_alerter interrupt_alerter;
ΓòÉΓòÉΓòÉ 5.4.2. Public Members of Interrupt_handler ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructor for Interrupt_handler
o Destructor for Interrupt_handler
o interrupt - what to do when an interrupt occurs
o o_type - return class
o pending - did a signal occur
o print - print Interrupt_handler information
ΓòÉΓòÉΓòÉ 5.4.2.1. Constructor for Interrupt_handler ΓòÉΓòÉΓòÉ
Class: Interrupt_handler
Interrupt_handler(int sig);
The Interrupt_handler constructor constructs a new Interrupt_handler object
that is meant to wait for the signal number sig. When the signal with this
signal number occurs, the private virtual function interrupt() is called.
If several tasks are waiting for one Interrupt_handler task, when the interrupt
occurs and that Interrupt_handler is ready, only one of the waiting tasks will
run, and only this task has its state changed to RUNNING. Subsequent interrupts
will allow the other waiting tasks to run, one task per interrupt.
When an interrupt occurs, the current task is suspended and a special, built-in
task, interrupt_alerter, is scheduled. When interrupt() returns, control
resumes at the point where the current task was interrupted. As long as an
Interrupt_handler object exists, the scheduler will not exit when the run chain
becomes empty. It will wait for an interrupt instead. This happens because the
Interrupt_handler constructor calls sched::keep_waiting(). The
Interrupt_handler destructor calls sched::dont_wait().
ΓòÉΓòÉΓòÉ 5.4.2.2. Destructor for Interrupt_handler ΓòÉΓòÉΓòÉ
Class: Interrupt_handler
~Interrupt_handler();
The Interrupt_handler destructor calls sched::dont_wait() to decrement the
count of waiting Interrupt_handler() objects. The destructor also restores the
handler for the signal for which the Interrupt_handler object was created. If
the destructor for an Interrupt_handler has been called previously, the
E_LOSTHNDLR runtime error is produced. Otherwise, the destructor verifies that
it did indeed set up the Interrupt_handler object, and exits.
ΓòÉΓòÉΓòÉ 5.4.2.3. interrupt - What to Do When an Interrupt Occurs ΓòÉΓòÉΓòÉ
Class: Interrupt_handler
virtual void interrupt();
interrupt() is a virtual function that you can define in a class that is
derived from Interrupt_handler to specify the action to be taken when an
interrupt occurs.
ΓòÉΓòÉΓòÉ 5.4.2.4. o_type - Return Class ΓòÉΓòÉΓòÉ
Class: Interrupt_handler
object::objtype o_type();
o_type() is a virtual function that returns the type of the object, namely
object::INTHANDLER.
ΓòÉΓòÉΓòÉ 5.4.2.5. pending - Did a Signal Occur ΓòÉΓòÉΓòÉ
Class: Interrupt_handler
int pending();
pending() returns a nonzero value every time it is called except for the first
time it is called after a signal occurs.
ΓòÉΓòÉΓòÉ 5.4.2.6. print - Print Interrupt_handler Information ΓòÉΓòÉΓòÉ
Class: Interrupt_handler
void print(int detail, int y=0);
print() prints information about the Interrupt_handler object. It calls the
print() member function of the object base class. detail specifies how much
information is printed. The second argument, y, is used internally by the Task
Library and has a default value of 0.
If detail equals 0, the following information is printed:
o The type of object, namely Interrupt_handler.
o The number of the signal that the Interrupt_handler object is waiting for.
o The value of the private member got_interrupt. got_interrupt equals 1 if the
signal that the Interrupt_handler object is waiting for has been raised. It
equals 0 otherwise.
o The value of the private member old. old is a pointer to the previous
Interrupt_handler object for the signal that the current Interrupt_handler
object is waiting for.
If detail equals VERBOSE, the information listed above is printed along with
the following information:
o The objects in the list of previous Interrupt_handler objects for the current
signal
o The value of the this pointer
o The list of remembered tasks
ΓòÉΓòÉΓòÉ 5.4.3. Public Members of Interrupt_alerter ΓòÉΓòÉΓòÉ
Note: Interrupt_alerter is an internal class; do not use it directly. The task
system creates an object of the Interrupt_alerter class when you create an
object of Interrupt_handler.
The following functions are described:
o Constructor for Interrupt_alerter
o Destructor for Interrupt_alerter
ΓòÉΓòÉΓòÉ 5.4.3.1. Constructor for Interrupt_alerter ΓòÉΓòÉΓòÉ
Class: Interrupt_alerter
Interrupt_alerter();
The Interrupt_alerter constructor creates an Interrupt_alerter object. This
constructor is only called once, and this call is in the declaration of the
interrupt_alerter object in task.h. The interrupt_alerter object alerts the
Interrupt_handler objects and any others tasks that have received interrupts
since the Interrupt_alerter constructor last ran. This constructor makes any
tasks that are waiting for those Interrupt_handler objects eligible for
execution.
Note:
1. Interrupt_alerter is a class. interrupt_alerter is a predefined object of
the Interrupt_alerter class.
2. Any program that includes task.h will always have at least two tasks: the
interrupt_alerter task and the main() task.
ΓòÉΓòÉΓòÉ 5.4.3.2. Destructor for Interrupt_alerter ΓòÉΓòÉΓòÉ
Class: Interrupt_alerter
~Interrupt_alerter();
The Interrupt_alerter() destructor cancels the Interrupt_alerter task.
ΓòÉΓòÉΓòÉ 5.4.4. Example of Using Interrupt_handler ΓòÉΓòÉΓòÉ
The following example shows how the Interrupt_handler class can be used. In
this example, the class MyHandler is derived from Interrupt_handler. Two
objects of the MyHandler class are created (h1 and h2), and a signal is raised
for each of them.
#include <iostream.h>
#include <task.h>
#include <signal.h>
class MyHandler : public Interrupt_handler {
private:
int sigNo;
void interrupt();
public:
MyHandler(int sig);
};
void MyHandler::interrupt()
{
cout << "Interrupt " << sigNo << " has occurred." << endl;
}
MyHandler::MyHandler(int sig) : Interrupt_handler(sig), sigNo(sig)
{
cout << "Created an interrupt handler for interrupt "
<< sig << endl;
}
void main()
{
MyHandler h1(SIGUSR1);
MyHandler h2(SIGUSR2);
//
// Raise an interrupt for both MyHandler objects.
//
raise(SIGUSR2);
raise(SIGUSR1);
//
// Explicitly destroy the handlers.
//
h1.Interrupt_handler::~Interrupt_handler();
h2.Interrupt_handler::~Interrupt_handler();
thistask->resultis(0);
}
This program produces the following output:
Created an interrupt handler for interrupt 7
Created an interrupt handler for interrupt 8
Interrupt 8 has occurred.
Interrupt 7 has occurred.
ΓòÉΓòÉΓòÉ 5.5. Simulation Classes ΓòÉΓòÉΓòÉ
This chapter describes the simulation classes: histogrm, randint, urand, and
erand. You can use these classes to create program simulations and gather
statistics on them.
The following topics are described in this chapter:
o Declarations for the Simulation Classes in task.h
o Public members of histogram
o Public members of randint
o Public members of urand
o Public members of erand
ΓòÉΓòÉΓòÉ 5.5.1. Declarations for the Simulation Classes in task.h ΓòÉΓòÉΓòÉ
You must include the following statement in any files that use the simulation
classes:
#include <task.h>
The following is an excerpt from the task.h header file that shows the relevant
declarations for the members of the simulation classes:
struct histogram
{
int l, r;
int binsize;
int nbin;
int* h;
long sum;
long sqsum;
histogram(int=16, int=0, int=16);
void add(int);
void print();
};
class randint
{
long randx;
public:
randint(long s = 0);
void seed(long s);
int draw();
float fdraw();
};
class urand : public randint
{
public:
int low, high;
urand(int l, int h);
int draw();
};
class erand : public randint
public:
{ int mean;
erand(int m);
int draw();
};
ΓòÉΓòÉΓòÉ 5.5.2. Public Members of histogram ΓòÉΓòÉΓòÉ
Note: The following descriptions assume that the functions are called as part
of a histogrm object called hist.
The following functions are described:
o Constructor for histogram
o add - add to a bin
o print - print information about histogram object
An example of using histogrm is also included.
ΓòÉΓòÉΓòÉ 5.5.2.1. Constructor for histogram ΓòÉΓòÉΓòÉ
Class: histogrm
histogram (int nb=16, int left=0, int right=16);
The histogrm constructor creates a histogrm object. A histogram object is a
collection of bins, each of which encompasses a range of numbers. Elements can
be added to these bins, and the range of the bins can be changed as elements
are added to them. The histogrm object has the following data members:
o l: the left end of the range of bins.
o r: the right end of the range of bins.
o binsize: the size of each bin.
o nbin: the number of bins in the histogram.
o h: a pointer to the array of bins. This array is dynamically allocated by the
constructor.
o sum: the sum of the values added to the histogram using the add() member
function. The constructor initializes sum to 0.
o sqsum: the sum of the squares of the values added to the histogram using the
add() member function. The constructor initializes sqsum to 0.
If the nbin member of a histogram object has a value of x, the histogram will
consist of x bins, each covering a range of integers from left to right. The
first argument of the constructor, nb, is the number of bins in the histogram.
If the value of nb is odd, nb is changed to nb + 1. The second argument of the
constructor, left, is the left end of the range of bins. The third argument of
the constructor, right, is the right end of the range of bins. The default
number of bins is 16, the default left end is 0, and the default right end is
16.
If nbin is less than or equal to zero, or if left is greater than or equal to
right, an E_HISTO runtime error is produced. The size of each bin equals the
value binsize=(right-left)/nb. If binsize is not an integer, the number of bins
is equal to the integer value that immediately follows this value, and the
value of right is changed to 1 + nb *binsize.
ΓòÉΓòÉΓòÉ 5.5.2.2. add - Add to a Bin ΓòÉΓòÉΓòÉ
Class: histogrm
void add(int i);
add() adds one to the i th bin of hist. In other words, it performs the
following operations:
h[(i-1)/hist.binsize] = h[(i-1)/hist.binsize] + 1
If i is greater than or equal to hist.l and less than hist .r, hist.l, hist.r,
and hist.binsize are unchanged. However, if i is less than hist.l, these steps
are followed:
1. The value of hist .binsize is doubled.
2. The value (hist .r - hist.nbin*hist.binsize) is calculated. If this value
is less than or equal to i, it becomes the new value of hist.l.
3. If this value is still greater than i, return to step 1 and repeat the
process.
If, on the other hand, i is greater than hist .r, these steps are followed:
1. The value of hist .binsize is doubled.
2. The value (hist .l + hist .nbin*hist .binsize) is calculated. If this value
is greater than i, it becomes the new value of hist .r.
3. If this value is less than or equal to i, return to step 1 and repeat the
process.
ΓòÉΓòÉΓòÉ 5.5.2.3. print - Print Information about histogram Object ΓòÉΓòÉΓòÉ
Class: histogrm
void print();
print() displays on standard output the following information for each bin in
hist that is not empty:
o The range of the bin
o The number of elements in the bin
ΓòÉΓòÉΓòÉ 5.5.2.4. Example of Using histogram Class ΓòÉΓòÉΓòÉ
Class: histogrm
The following program shows how you can use the histogrm class. In this
example, a histogrm object is created with the following characteristics:
o The number of bins is 16
o The size of each bin is 2
o The left end of the range of bins is 0
o The right end of the range of bins is 32
The first call to add() has an argument, 34, that is greater than the right end
of the range of bins. Therefore, the following steps are followed:
o The size of the bins is doubled to 4
o The right end of the range of bins is changed to left + (numbins * binsize) =
64
At this point, the histogram has the following characteristics:
o The number of bins is 16
o The size of each bin is 4
o The left end of the range is 0
o The right end of the range is 64
The arguments for the second and third calls to add() are both within the range
of the bins, so the number and the range of the bins remain unchanged. The
argument of the fourth call to add(), - 4, is less than the left end of the
range of bins, so the following steps are followed:
o The size of the bins is doubled to 8
o The left end of the range of bins is changed to right - (numbins * binsize) =
- 64
Thus, after the fourth call to add(), the histogram has the following
characteristics:
o The number of bins is 16
o The size of each bin is 8
o The left end of the range is -64
o The right end of the range is 64
The following is the code for this example:
#include <task.h>
void main ()
{
int a = 34; // Some integers.
int b = 4;
int c = 9;
int d = -4;
//
// create a histogram
//
histogram h (16,0,32);
//
// add values to the histogram
//
h.add(a);
h.add(b);
h.add(c);
h.add(d);
//
// print the contents of the histogram
//
h.print();
thistask->resultis(0);
}
This program produces the following output:
[-8:0] : 1
[0:8] : 1
[8:16] : 1
[32:40] : 1
ΓòÉΓòÉΓòÉ 5.5.3. Public Members of randint ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructor for randint
o draw - return a random integer
o fdraw - return a random floating-point value
o seed - initialize random number generator
ΓòÉΓòÉΓòÉ 5.5.3.1. randint Constructor ΓòÉΓòÉΓòÉ
Class: randint
randint(long seed=0);
randint() constructs a randint object. seed is used as a seed for the random
number generator. The default value of seed is 0.
ΓòÉΓòÉΓòÉ 5.5.3.2. draw - Return a Random Integer ΓòÉΓòÉΓòÉ
Class: randint
int draw();
draw() returns a random integer value in the range from 0 to UINT_MAX (defined
in limits.h). Integers returned by draw() are uniformly distributed in this
range.
ΓòÉΓòÉΓòÉ 5.5.3.3. fdraw - Return a Random Floating-Point Value ΓòÉΓòÉΓòÉ
Class: randint
float fdraw();
fdraw() returns a random floating-point value in the range from 0 to 1.
Floating-point values returned by fdraw() are uniformly distributed in this
range.
ΓòÉΓòÉΓòÉ 5.5.3.4. seed - Initialize Random Number Generator ΓòÉΓòÉΓòÉ
Class: randint
void seed(long seednum);
seed() reinitializes the random number generator with the seed seednum.
ΓòÉΓòÉΓòÉ 5.5.4. Public Members of urand ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructor for urand
o draw - return a random number from specified range
ΓòÉΓòÉΓòÉ 5.5.4.1. urand Constructor ΓòÉΓòÉΓòÉ
Class: urand
urand(int low, int high);
urand() constructs a urand object. low and high define the lower and upper
bounds for the uniform distribution of the random numbers generated by this
object. If low is greater than high, urand() produces the runtime error
E_URAND.
ΓòÉΓòÉΓòÉ 5.5.4.2. draw - Return a Random Number from Specified Range ΓòÉΓòÉΓòÉ
Class: urand
int draw();
draw() returns a random integer value from the range specified in the call to
the urand constructor. Integer values returned by draw() are uniformly
distributed in this range.
ΓòÉΓòÉΓòÉ 5.5.5. Public Members of erand ΓòÉΓòÉΓòÉ
The following functions are described:
o Constructor for erand
o draw - return a random number from specified range
ΓòÉΓòÉΓòÉ 5.5.5.1. erand Constructor ΓòÉΓòÉΓòÉ
Class: erand
erand(int mean);
erand() constructs an erand object. mean is the mean for the exponential
distribution of the random numbers generated by this object.
ΓòÉΓòÉΓòÉ 5.5.5.2. draw - Return a Random Number from Specified Range ΓòÉΓòÉΓòÉ
Class: erand
int draw();
draw() returns a random integer value. draw() returns values that are
exponentially distributed around the mean value specified in the call to the
erand constructor.
ΓòÉΓòÉΓòÉ 6. Appendixes and Glossary ΓòÉΓòÉΓòÉ
Extended Complex Mathematics Library Examples
Contains examples of how to determine the roots of a complex number, and how
to define your own complex_error function.
Extended Task Library Examples
Contains examples of how to use the Task Library to implement a parallel
algorithm and an event-driven simulation.
ΓòÉΓòÉΓòÉ 6.1. Extended Complex Mathematics Library Examples ΓòÉΓòÉΓòÉ
This appendix contains two examples that show some uses of the Complex
Mathematics Library.
The two examples are:
o Finding the roots of a complex number
o Defining your own complex_error function
ΓòÉΓòÉΓòÉ 6.1.1. Finding the Roots of a Complex Number ΓòÉΓòÉΓòÉ
Note: In the following text, exponents appear in italicized square brackets.
The following example shows how you can use the Complex Mathematics Library to
calculate the roots of a complex number. For every positive integer n, each
complex number z has exactly n distinct nth roots. Suppose that in the complex
plane the angle between the real axis and point z is theta , and the distance
between the origin and the point z is r. Then z has the polar form (r, theta ),
and the n roots of z have the values:
sigma
sigma ┬╖omega
sigma ┬╖omega [2]
sigma ┬╖omega [3]
.
.
.
sigma ┬╖omega [n-1]
where omega is a complex number with the value:
omega = ( cos(2pi /n), sin(2pi /n) )
and sigma is a complex number with the value:
sigma = r[1/n ]( cos(theta /n), sin(theta /n) )
The following code includes the functions get_omega() to calculate the value of
omega , and get_sigma() to calculate the value of sigma . The user is prompted
for the complex value z and the value of n. After the values of omega and
sigma have been calculated, the n roots of z are calculated and printed.
#include <iostream.h>
#include <complex.h>
#include <math.h>
//
// function to calculate the value of omega for a given value
// of n
//
complex get_omega(double n)
{
complex omega = complex(cos((2.0*M_PI)/n), sin((2.0*M_PI)/n));
return omega;
}
//
// function to calculate the value of sigma for a given value of
// n and a given complex value
//
complex get_sigma(complex comp_val, double n)
{
double rn, r, theta;
complex sigma;
r = abs(comp_val);
theta = arg(comp_val);
rn = pow(r,(1.0/n));
sigma = rn * complex(cos(theta/n),sin(theta/n));
return sigma;
}
void main()
{
double n;
complex input, omega, sigma;
//
// prompt the user for a complex number
//
cout << "Please enter a complex number" << endl;
cin >> input;
//
// prompt the user for the value of n
//
cout << "What root would you like of this number?" << endl;
cin >> n;
//
// calculate the value of omega
//
omega = get_omega(n);
cout << "Here is omega " << omega << endl;
//
// calculate the value of sigma
//
sigma = get_sigma(input,n);
cout << "Here is sigma " << sigma << endl;
cout << "Here are the " << n << " roots of " << input << endl;
for (int i = 0; i < n ; i++)
{
cout << sigma*(pow(omega,i)) << endl;
}
}
If you enter the complex value (-7, 24) for z and 2 for n, this program
produces the following output:
Here is omega ( -1, 1.22465e-16)
Here is sigma ( 3, 4)
Here are the 2 roots of ( -7, 24)
( 3, 4)
( -3, -4)
ΓòÉΓòÉΓòÉ 6.1.2. Defining Your Own complex_error Function ΓòÉΓòÉΓòÉ
You can either use the default version of complex_error() described in Errors
Handled by the Complex Mathematics Library, or you can define your own version
of the function. In the following example, complex_error() is redefined:
#include <iostream.h>
#include <complex.h>
#include <float.h>
//
// redefinition of the complex_error function
//
int complex_error(c_exception &c)
{
cout << "================" << endl;
cout << " Exception " << endl;
cout << "type = " << c.type << endl;
cout << "name = " << c.name << endl;
cout << "arg1 = " << c.arg1 << endl;
cout << "arg2 = " << c.arg2 << endl;
cout << "retval = " << c.retval << endl;
cout << "================" << endl;
return 0;
}
void main()
{
complex c1(DBL_MAX,0);
complex result;
result = exp(c1);
cout << "exp(" << c1 << ")= " << result << endl;
}
This example produces the following output:
================
Exception
type = 3
name = exp
arg1 = ( 1.79769e+308, 0)
arg2 = ( 0, 0)
retval = ( infinity, -infinity)
================
exp(( 1.79769e+308, 0)) = ( infinity, -infinity)
If the redefinition of complex_error() in the above code is commented out, the
default definition of complex_error() is used, and the program produces the
following output
exp(( 1.79769e+308, 0)) = ( infinity, -infinity)
ΓòÉΓòÉΓòÉ 6.2. Extended Task Library Examples ΓòÉΓòÉΓòÉ
This appendix contains two examples that show how you can use the Task Library.
The two examples are:
o An example of implementing parallel algorithms
o An example of implementing event-driven simulations
ΓòÉΓòÉΓòÉ 6.2.1. An Example of Implementing Parallel Algorithms ΓòÉΓòÉΓòÉ
Note: In the following text, exponents are shown in italicized square
brackets.
The following example shows how you can use the Task Library to implement
parallel algorithms. In this example, the "fan-in" parallel algorithm is used
in the calculation of the inner product of two vectors. The program creates a
series of objects of the class proc, each of which is identified by a node
number. These proc objects are used to calculate the inner product. The program
also calculates the inner product serially.
The "fan-in" algorithm calculates the inner product of two vectors, A and B. If
A and B are both of size n, their inner product is the sum of the products of
the corresponding elements: A[0]*B[0] + A[1]*B[1] + . . . + A[n]*B[n]. The
algorithm begins with the creation of n nodes numbered 0 to n-1. Each node i
contains the product of the ith elements of the two vectors. Thus, node 0
contains A[0]*B[0]. At the end of the first step, each even-numbered node i
contains A[i]*B[i] + A[i+1]*B[i+1], and the odd-numbered nodes are no longer
used. Thus, node 0 contains A[0]*B[0] + A[1]*B[1] at the end of the first step.
At the end of the second step, each node i (where i == 0 modulo 4) contains the
sum of its previous contents and the contents of node i + 2. Thus, each node i
(where i == 0 modulo 4) contains A[i]*B[i] + A[i+1]*B[i+1] + A[i+2]*B[i+2] +
A[i +3]*B[i+3], and the other nodes are no longer used. In general, at the end
of step s, node i (where i = 0 modulo 2[S]) contains the sum A[i]*B[i] +
A[i+1]*B[i+1] + . . . + A[2[S]-1]*B[2[S]-1]. At the end of the algorithm, node
0 contains the inner product of the two vectors.
#include <task.h>
#include <iostream.h>
#include <math.h>
//
// The size of the two vectors a and b.
// This size also denotes the number
// of processors that will be used
// in the parallel execution.
//
#define VECTOR_SIZE 10000
int power2( int m)
{
//
// compute 2^m
//
int product = 1;
for (register i=1; i<=m; ++i)
product *= 2;
return product;
}
inline double log2( double x)
{
//
// compute the logarithm of x base 2
//
return (log(x)/log(2));
}
//
// receiver() returns the role of the processor with id "node"
// at the step "step".
// It returns true if the particular processor is supposed
// to "receive" the result of another processor.
// It returns false if the particular processor is supposed to
// stop executing and make its result available to another
// processor.
int receiver (int node, int step) {
int numerator, denominator;
if (node == 0) return 1;
else {
numerator = node - power2(step-1);
denominator = power2(step);
if (((float(numerator)/float(denominator)) -
numerator/denominator) <= 1E-6)
return 0;
else
return 1;
}
}
//
// Input data.
//
struct vectors {
int *a, *b;
double ab; // Inner product a*b
vectors();
};
vectors::vectors() {
//
// Initialize vectors a and b with random numbers
// in the interval [1,5]
//
urand rand(1,5);
a = new int [VECTOR_SIZE];
b = new int [VECTOR_SIZE];
for (register i=0; i<VECTOR_SIZE; ++i) {
a[i] = rand.draw();
b[i] = rand.draw();
}
ab = 0;
//
// Calculate the inner product serially
//
for (i=0; i<VECTOR_SIZE; ++i)
ab += a[i]*b[i] ;
}
//
// A processor task
//
class proc : public task {
int my_node ;
public:
proc(int, vectors *, task **);
};
proc::proc(int n, vectors *vptr, task **t):my_node(n) {
int steps = (int) log2 ((double) VECTOR_SIZE) ;
if ((log2((double) VECTOR_SIZE) - steps) >= 1E-6) steps ++;
int s=vptr->a[my_node]*vptr->b[my_node];
//
// multiply Ai*Bi
//
int wait_for;
for( int step=1; step <= steps; ++step) {
if (receiver(my_node, step)) {
wait_for=my_node+power2(step-1);
//
// Special case when
// VECTOR_SIZE is not an
// integral power of 2.
//
if (wait_for >= VECTOR_SIZE)
continue;
s += t[wait_for]->result();
}
else {
break; // terminate
}
}
resultis(s);
}
void main() {
cout << "Initializing the vectors a and b of size: "
<< VECTOR_SIZE
<< " with random numbers in the interval [1,5]... "
<< endl;
vectors v;
cout << "Calculating inner product ..." << endl;
vectors *vptr = &v;
task **processor;
processor = new task *[VECTOR_SIZE] ;
//
// Order of creation of tasks must be from last to first
//
for (register i=VECTOR_SIZE-1; i>=0; --i)
processor[i] = new proc(i,vptr,processor);
int sum;
sum= processor[0]->result();
//
// Wait for result of processor 0.
// display and validate result
//
cout << "This is the inner product of the given vectors\n"
<< "Calculated serially: " << v.ab << endl
<< "Calculated through the fan-in algorithm: "
<< sum << endl;
thistask ->resultis(0);
}
The output created by this program looks like this:
Initializing the vectors a and b of size: 10000 with random numbers
in the interval [1,5]...
Calculating inner product ...
This is the inner product of the given vectors
Calculated serially: 89735
Calculated through the fan-in algorithm: 89735
ΓòÉΓòÉΓòÉ 6.2.2. An Example of Implementing Event-Driven Simulations ΓòÉΓòÉΓòÉ
The following example shows how you can use the Task Library to implement
event-driven simulations. This example simulates a system consisting of two
M/M/1 queues that accept packets, process them, and release them. The two M/M/1
queues have different service rates. In the simulation, the packets are
produced by the producer object input. The M/M/1 queues are represented by
exponential_service_center objects mm1_q1 and mm1_q2. The packets are accepted
at the end of their processing by the consumer object output. output calculates
the throughput of the system (the total number of packets processed divided by
the total time taken to process them). The producer object input, the two M/M/1
queues, and the consumer object output are connected by a series of Task
Library queues.
The following example could easily be modified to model systems that have
exponential service centers in parallel.
Note: The word "queue" is used in two different senses in this section. The
M/M/1 queues that are implemented by the exponential_service_center objects are
meant to simulate the behavior of systems that perform some kind of operation
on a series of customers. The amount of time that each operation takes is
independent of the previous state of the system. The Task Library queues, on
the other hand, are queue data structures. See Queue Management Classes for a
description of the qhead and qtail classes.
This simulation follows the steps illustrated in Structure of the Event-Driven
Simulation Example:
1. The producer object input creates packet objects that it places on the
qtail object packet_q.
2. The exponential_service_center object mm1_q1 takes packet objects from the
qhead object that corresponds with the qtail object packet_q. mm1_q1
"processes" these packet objects and then places them on the qtail object
that corresponds with the qhead object intermediate_result_q.
3. The exponential_service_center object mm1_q2 takes packet objects from the
qhead object intermediate_result_q. mm1_q2 "processes" these packet objects
and then places them on the qtail object that corresponds to the qhead
object result_q.
4. The consumer object output takes packet objects from the qhead object
result_q and calculates throughput statistics.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé input Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé packet_q Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé mm1_q Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé intermediate_result_q Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé mm1_q2 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé result_q Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé output Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Structure of the Event-Driven Simulation Example
#include <task.h>
#include <iostream.h>
#include <time.h>
#include <limits.h>
#define abs(A) (((A)<0.0)? -(A):(A))
static myseed = abs(time(0)+0x74637602) ;
// Request to the system
class packet : public object {
public:
int interval;
long sys_arrival_time;
long sys_departure_time;
};
//
// Task that produces packet arrivals to the system.
//
class producer : public task {
erand *rnd;
public:
producer(int, float, qtail *, task*);
~producer() { delete rnd; }
};
producer::producer(int arrivals, float lambda, qtail *packet_q, task *end) {
packet *pckt;
int interarrival_time, prev_event_time = 0;
float *f = new float(0.0) ;
rnd = new erand(int(1/lambda)); // random number generator.
rnd->seed(myseed++);
for (register i=0; i<arrivals; ++i) {
//
// create packet arrivals
//
pckt = new packet;
interarrival_time=rnd->draw();
*f += interarrival_time;
pckt->interval = interarrival_time;
pckt->sys_arrival_time =
prev_event_time+interarrival_time;
prev_event_time += interarrival_time;
packet_q->put(pckt);
}
//
// Wait for the result analyzer to terminate
//
(void) end->result();
*f = *f/arrivals;
//
// Return achieved input rate
//
*f = 1.0/(*f) ;
resultis((int) f);
}
//
// An M/M/1 queue simulator. This task receives packets
// from a queue and places them into another
// queue after "processing".
//
class exponential_service_center : public task {
erand *rnd;
qtail *local_q_t;
qhead *local_q_h;
public:
exponential_service_center(int, float, qhead*,
qtail*, task *);
~exponential_service_center()
{ delete local_q_t; delete rnd; }
};
exponential_service_center::exponential_service_center (
int arrivals, float mu,
qhead *input, qtail *output, task *end)
{
rnd = new erand(int (1/mu));
rnd -> seed (myseed++);
local_q_t = new qtail;
local_q_h = local_q_t -> head();
int cust=0, service_time, terminated = 0;
register int cur_arrivals = 0; // Arrivals so far
long next_arrival, next_departure;
float *f = new float (0.0);
packet *pckt = (packet *) input->get(), *departing_pckt;
next_arrival = sched::get_clock() + pckt -> interval;
next_departure = LONG_MAX; // "LONG_MAX" is used as a flag
//
// Event loop (Note that every packet generates two events --
// arrival/departure)
//
for (register i=0; i<2*arrivals; ++i) {
if ((next_arrival == LONG_MAX)
&& (next_departure == LONG_MAX)) {
//
// Wait for an arrival of a packet
// at the input queue.
//
pckt = (packet *) input->get();
next_arrival = sched::get_clock()
+ pckt -> interval;
}
//
// Wait for event
//
delay((next_arrival<next_departure)?
(next_arrival - sched::get_clock()):
(next_departure - sched::get_clock()) ) ;
if ( next_arrival < next_departure ) {
//
// Packet arrival
//
cust += 1;
if (cust == 1) {
//
// If there's only one packet in the local
// "departure" queue, schedule its departure
//
service_time = rnd->draw();
*f += service_time;
next_departure = sched::get_clock()
+ service_time;
pckt -> interval = 0 ; // No more inter-arrival time
}
//
// Put packet into a local "departure" queue
//
local_q_t -> put(pckt);
//
// Schedule new arrival if there are
// packets in the input queue
if (++cur_arrivals < arrivals) {
if (input->rdcount() > 0) {
pckt = (packet *) input->get();
next_arrival = sched::get_clock() +
pckt -> interval;
}
else
next_arrival = LONG_MAX;
}
else if (cur_arrivals == arrivals)
next_arrival = LONG_MAX;
}
else {
//
// packet departure
//
cust -= 1;
//
// Remove packet from local "departure"
// queue and put it in the output queue
//
departing_pckt = (packet *) local_q_h->get();
departing_pckt -> sys_departure_time =
sched::get_clock();
output -> put(departing_pckt);
if (cust >0) {
service_time = rnd->draw();
*f += service_time;
next_departure = sched::get_clock()
+ service_time;
departing_pckt = (packet *) local_q_h->get();
departing_pckt -> interval = 0 ;
local_q_h->putback(departing_pckt);
}
else
next_departure = LONG_MAX;
}
}
//
// Wait for termination of result analyzer
//
(void) end->result();
//
// Return achieved output rate (1/service rate)
//
*f = *f/arrivals;
*f = 1/(*f) ;
resultis ((int) f);
}
//
// This task generates the average system throughput and delay
//
class consumer : public task {
public:
float throughput, delay;
consumer(int, qhead *);
};
consumer::consumer(int arrivals, qhead *result_q) {
packet *pckt;
int total_packets=0;
long total_delay=0;
for (register i=0; i<arrivals; ++i) {
pckt=(packet *) result_q->get();
total_packets += 1;
total_delay +=
pckt->sys_departure_time-pckt->sys_arrival_time;
}
throughput = float (total_packets) / sched::get_clock();
delay = float (total_delay) / total_packets ;
resultis (0);
}
void main()
{
sched::setclock(0);
float lambda=0.01; // in packets per msec
float mu1=0.05; // in packets per msec
float mu2=0.07; // in packets per msec
int arrivals=50000;
qtail *packet_q = new qtail;
qhead *intermediate_result_q = new qhead;
qhead *result_q = new qhead;
consumer *output = new consumer(arrivals, result_q);
producer *input = new producer(arrivals, lambda, packet_q, output);
exponential_service_center *mm1_q1 =
new exponential_service_center
(arrivals, mu1, packet_q->qtail::head(),
intermediate_result_q ->qhead::tail(),
output);
exponential_service_center *mm1_q2 =
new exponential_service_center
(arrivals, mu2, intermediate_result_q,
result_q ->qhead::tail(), output);
(void) output->result();
float actual_lambda = *((float *) (input->result()));
float actual_mu1 = *((float *) (mm1_q1->result()));
float actual_mu2 = *((float *) (mm1_q2->result()));
float analytic_throughput = output->throughput;
cout << "Simulation Results :\n"
<< "Average Throughput: " << actual_lambda
<< " packets/msec\n"
<< "Average delay: " << output->delay
<< " msec\n" << endl ;
float analytic_delay =
(1/actual_mu1) / (1.0-actual_lambda/actual_mu1)+
(1/actual_mu2) / (1.0-((actual_lambda<actual_mu1)
? actual_lambda:actual_mu1)/actual_mu2);
cout << "Analytic results : \n"
<< "Average Throughput: " << analytic_throuput
<< " packets/msec\n"
<< "Average delay: " << analytic_delay
<< " msec\n" << endl ;
thistask->resultis(0);
}
The output created by this program looks like this:
Simulation Results:
Average Throughput: 0.00999937 packets/msec
Average delay: 39.7195 msec
Analytic results:
Average Throughput: 0.0099992 packets/msec
Average delay: 39.7881 msec
ΓòÉΓòÉΓòÉ 6.3. Glossary ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.3.1. abstract class ΓòÉΓòÉΓòÉ
abstract class
A class with at least one pure virtual function. It is a C++ class used as a
base class for other classes. The abstract class represents a concept; classes
derived from it represent implementations of the concept. You cannot have a
direct object of an abstract class. (See also base class.)
ΓòÉΓòÉΓòÉ 6.3.2. access ΓòÉΓòÉΓòÉ
access
Determines whether or not a class member is accessible in an expression or
declaration.
ΓòÉΓòÉΓòÉ 6.3.3. access declaration ΓòÉΓòÉΓòÉ
access declaration
Used to restore access to members of a base class.
ΓòÉΓòÉΓòÉ 6.3.4. access resolution ΓòÉΓòÉΓòÉ
access resolution
The process by which the accessibility of a particular class member is
determined.
ΓòÉΓòÉΓòÉ 6.3.5. access specifiers ΓòÉΓòÉΓòÉ
access specifiers
One of the C++ keywords: public, private, and protected.
ΓòÉΓòÉΓòÉ 6.3.6. anonymous union ΓòÉΓòÉΓòÉ
anonymous union
A union without a class name. It must not be followed by a declarator.
ΓòÉΓòÉΓòÉ 6.3.7. argument declaration ΓòÉΓòÉΓòÉ
argument declaration
See parameter declaration.
ΓòÉΓòÉΓòÉ 6.3.8. array ΓòÉΓòÉΓòÉ
array
A variable that contains an ordered group of data objects. All data items (or
elements) in an array have the same data type.
ΓòÉΓòÉΓòÉ 6.3.9. array element ΓòÉΓòÉΓòÉ
array element
A single data item in an array.
ΓòÉΓòÉΓòÉ 6.3.10. base class ΓòÉΓòÉΓòÉ
base class
A class from which other classes are derived. May itself be derived from
another base class. (See also abstract class.)
ΓòÉΓòÉΓòÉ 6.3.11. buffer flush ΓòÉΓòÉΓòÉ
buffer flush
A process that removes the contents of a buffer. After a buffer flush, the
buffer is empty.
ΓòÉΓòÉΓòÉ 6.3.12. case clause ΓòÉΓòÉΓòÉ
case clause
In a switch statement, a case label followed by any number of statements.
ΓòÉΓòÉΓòÉ 6.3.13. case label ΓòÉΓòÉΓòÉ
case label
The word case followed by a constant expression and a colon. When the selector
evaluates the value of the constant expression, the statements following the
case label are processed.
ΓòÉΓòÉΓòÉ 6.3.14. cast expression ΓòÉΓòÉΓòÉ
cast expression
A cast expression explicitly converts its operand to a specified arithmetic,
scalar, or class type.
ΓòÉΓòÉΓòÉ 6.3.15. cast operator ΓòÉΓòÉΓòÉ
cast operator
The cast operator is used for explicit type conversions.
ΓòÉΓòÉΓòÉ 6.3.16. catch block ΓòÉΓòÉΓòÉ
catch block
A block associated with a try block that receives control when an exception
matching its argument is thrown.
ΓòÉΓòÉΓòÉ 6.3.17. class ΓòÉΓòÉΓòÉ
class
A user-defined data type that can contain both data representations (data
members) and functions (member functions).
ΓòÉΓòÉΓòÉ 6.3.18. class key ΓòÉΓòÉΓòÉ
class key
One of the C++ keywords: class, struct and union.
ΓòÉΓòÉΓòÉ 6.3.19. class library ΓòÉΓòÉΓòÉ
class library
A collection of C++ classes.
ΓòÉΓòÉΓòÉ 6.3.20. class member operators ΓòÉΓòÉΓòÉ
class member operators
Used to access class members through class objects or pointers to class
objects. They are ., ->, .*, and ->*.
ΓòÉΓòÉΓòÉ 6.3.21. class template ΓòÉΓòÉΓòÉ
class template
A blueprint describing how a set of related classes can be constructed.
ΓòÉΓòÉΓòÉ 6.3.22. compilation unit ΓòÉΓòÉΓòÉ
compilation unit
A single compiled file and all its associated include files.
ΓòÉΓòÉΓòÉ 6.3.23. complete class name ΓòÉΓòÉΓòÉ
complete class name
The complete qualification of a nested class name including all enclosing class
names.
ΓòÉΓòÉΓòÉ 6.3.24. Complex Mathematics Library ΓòÉΓòÉΓòÉ
Complex Mathematics Library
A class library that provides the facilities to manipulate complex numbers and
perform standard mathematical operations on them.
ΓòÉΓòÉΓòÉ 6.3.25. complex number ΓòÉΓòÉΓòÉ
complex number
A number made up of a real part and an imaginary part. A complex number can be
represented by an ordered pair (a, b), where a is the value of the real part
and b is the value of the imaginary part. The same complex number could also
be represented as a + bi, where i is the square root of -1.
ΓòÉΓòÉΓòÉ 6.3.26. constructor ΓòÉΓòÉΓòÉ
constructor
A class member function with the same name as its class, used to construct
class objects and sometimes to initialize them.
ΓòÉΓòÉΓòÉ 6.3.27. conversion ΓòÉΓòÉΓòÉ
conversion
A change in the type of a value. For example, when you add values having
different data types, the compiler converts both values to the same type before
adding them.
ΓòÉΓòÉΓòÉ 6.3.28. conversion function ΓòÉΓòÉΓòÉ
conversion function
A member function that specifies a conversion from its class type to another
type.
ΓòÉΓòÉΓòÉ 6.3.29. copy constructor ΓòÉΓòÉΓòÉ
copy constructor
A constructor used to make a copy of a class object from another class object
of the same class type.
ΓòÉΓòÉΓòÉ 6.3.30. data abstraction ΓòÉΓòÉΓòÉ
data abstraction
See abstraction (data)
ΓòÉΓòÉΓòÉ 6.3.31. default clause ΓòÉΓòÉΓòÉ
default clause
In a switch statement, the keyword default followed by a colon, and one or more
statements. When the conditions of the specified case labels in the switch
statement do not hold, the default clause is chosen.
ΓòÉΓòÉΓòÉ 6.3.32. default constructor ΓòÉΓòÉΓòÉ
default constructor
A constructor that takes no arguments, or if it takes any arguments, all its
arguments have default values.
ΓòÉΓòÉΓòÉ 6.3.33. default initialization ΓòÉΓòÉΓòÉ
default initialization
The initial value assigned to a data object by the compiler if no initial value
is specified by the programmer.
ΓòÉΓòÉΓòÉ 6.3.34. define statement ΓòÉΓòÉΓòÉ
define statement
A preprocessor statement that causes the preprocessor to replace an identifier
or macro call with specified code.
ΓòÉΓòÉΓòÉ 6.3.35. demangling ΓòÉΓòÉΓòÉ
demangling
The conversion of mangled names back to their original source code names.
During compilation, identifiers such as function and static class member names
are mangled (encoded) with type and scoping information to ensure type-safe
linkage. These mangled names appear in the object file and the final
executable file. Demangling converts these names back to their original names
to make program debugging easier.
ΓòÉΓòÉΓòÉ 6.3.36. delete ΓòÉΓòÉΓòÉ
delete
1) The keyword delete identifies a free store deallocation operator. 2) The
delete operator is used to destroy objects created by new.
ΓòÉΓòÉΓòÉ 6.3.37. derived class ΓòÉΓòÉΓòÉ
derived class
A class that inherits the proper base class become members of a derived class
object. You can add additional data members and member functions to the derived
class. A derived class object can be manipulated as if it is a base class
object. The derived class can override virtual functions of the base class.
ΓòÉΓòÉΓòÉ 6.3.38. destructor ΓòÉΓòÉΓòÉ
destructor
A special member function with the same name as its class preceded by a ~
(tilde). A destructor, which has no arguments and a void return type, "cleans
up" after an object by, for example, freeing any storage that was dynamically
allocated when the object was created.
ΓòÉΓòÉΓòÉ 6.3.39. dynamic binding ΓòÉΓòÉΓòÉ
dynamic binding
Binding that occurs at run-time.
ΓòÉΓòÉΓòÉ 6.3.40. element ΓòÉΓòÉΓòÉ
element
The component of an array, subrange, enumeration, or set.
ΓòÉΓòÉΓòÉ 6.3.41. enumeration constant ΓòÉΓòÉΓòÉ
enumeration constant
An identifier (that has an associated integer value) defined by an enumeration
type. You can use an enumeration constant anywhere an integer constant is
allowed.
ΓòÉΓòÉΓòÉ 6.3.42. enumeration tag ΓòÉΓòÉΓòÉ
enumeration tag
The identifier that names an enumeration data type.
ΓòÉΓòÉΓòÉ 6.3.43. enumeration type ΓòÉΓòÉΓòÉ
enumeration type
In C++, an enumeration type is a distinct data type that is not an integral
type. An enumeration type defines a set of enumeration constants.
ΓòÉΓòÉΓòÉ 6.3.44. enumerator ΓòÉΓòÉΓòÉ
enumerator
An enumeration constant and its associated value.
ΓòÉΓòÉΓòÉ 6.3.45. EOF ΓòÉΓòÉΓòÉ
EOF
End-of-file. A character value used to represent the end of an ASCII file.
Corresponds to the numeric value (-1).
ΓòÉΓòÉΓòÉ 6.3.46. exception ΓòÉΓòÉΓòÉ
exception
Any user, logic, or system error detected by a function that does not itself
deal with the error but passes the error on to a handling routine. Passing this
error is called throwing an exception.
ΓòÉΓòÉΓòÉ 6.3.47. exception handler ΓòÉΓòÉΓòÉ
exception handler
Exception handlers are catch blocks in C++. Catch blocks catch exceptions when
they are thrown from a function enclosed in a try block. Try blocks, catch
blocks and throw expressions are the constructs used to implement formal
exception handling in C++.
ΓòÉΓòÉΓòÉ 6.3.48. exception handling ΓòÉΓòÉΓòÉ
exception handling
A type of error handling that allows control and information to be passed to an
exception handler when an exception occurs.
ΓòÉΓòÉΓòÉ 6.3.49. external data definition ΓòÉΓòÉΓòÉ
external data definition
A definition appearing outside a function. The defined object is accessible to
all functions that follow the definition and are located within the same source
file as the definition.
ΓòÉΓòÉΓòÉ 6.3.50. float constant ΓòÉΓòÉΓòÉ
float constant
A number containing a decimal point, an exponent, or both a decimal point and
an exponent. The exponent contains an e or E, an optional sign (+ or -), and
one or more digits (0 through 9).
ΓòÉΓòÉΓòÉ 6.3.51. free store ΓòÉΓòÉΓòÉ
free store
Dynamically allocates memory. New and delete are used to allocate and
deallocate free store.
ΓòÉΓòÉΓòÉ 6.3.52. friend class ΓòÉΓòÉΓòÉ
friend class
A class in which all the member functions are granted access to the private and
protected members of another class. It is named in the declaration of another
class and uses the keyword friend as a prefix to the class. For example:
class me {
friend class you;
// ...
};
makes all the functions in class you friends of class me.
ΓòÉΓòÉΓòÉ 6.3.53. friend function ΓòÉΓòÉΓòÉ
friend function
A function that is granted access to the private and protected parts of a
class. It is named in the declaration of the class and uses the keyword friend
as a prefix.
ΓòÉΓòÉΓòÉ 6.3.54. function definition ΓòÉΓòÉΓòÉ
function definition
The complete description of a function. A function definition contains an
optional storage class specifier, an optional type specifier, a function
declarator, parameter declarations, and a block statement (the function body).
ΓòÉΓòÉΓòÉ 6.3.55. function template ΓòÉΓòÉΓòÉ
function template
Provides a blueprint describing how a set of related individual functions can
be constructed.
ΓòÉΓòÉΓòÉ 6.3.56. generic class ΓòÉΓòÉΓòÉ
generic class
See class templates.
ΓòÉΓòÉΓòÉ 6.3.57. header file ΓòÉΓòÉΓòÉ
header file
A file that contains declarations used by a group of functions or users.
ΓòÉΓòÉΓòÉ 6.3.58. I/O Stream Library ΓòÉΓòÉΓòÉ
I/O Stream Library
A class library that provides the facilities to deal with many varieties of
input and output.
ΓòÉΓòÉΓòÉ 6.3.59. identifier ΓòÉΓòÉΓòÉ
identifier
A name that refers to a data object. An identifier contains some combination of
letters, digits, and underscores, but its first character cannot be a digit.
ΓòÉΓòÉΓòÉ 6.3.60. include file ΓòÉΓòÉΓòÉ
include file
A text file that contains declarations used by a group of functions, programs,
or users. Also known as a header file.
ΓòÉΓòÉΓòÉ 6.3.61. include statement ΓòÉΓòÉΓòÉ
include statement
A preprocessor statement that causes the preprocessor to replace the statement
with the contents of a specified file.
ΓòÉΓòÉΓòÉ 6.3.62. inheritance ΓòÉΓòÉΓòÉ
inheritance
An object-oriented programming technique that allows you to use existing
classes as bases for creating other classes.
ΓòÉΓòÉΓòÉ 6.3.63. initializer ΓòÉΓòÉΓòÉ
initializer
An expression used to initialize data objects. In C++, there are three types of
initializers: 1) You can use an expression followed by an assignment operator
to initialize fundamental data type objects or class objects that have copy
constructors. 2) You can use an expression enclosed in braces ( {} ) to
initialize aggregates. 3) You can use a parenthesized expression list to
initialize base classes and members using constructors.
ΓòÉΓòÉΓòÉ 6.3.64. inline function ΓòÉΓòÉΓòÉ
inline function
Inlining is a hint to the compiler to perform inline expansion of the body of a
function member. Functions declared and defined simultaneously in a class
definition are inline. You can also explicitly declare a function inline by
using the keyword inline. Both member and nonmember functions can be inlined.
ΓòÉΓòÉΓòÉ 6.3.65. instance ΓòÉΓòÉΓòÉ
instance
An object-oriented programming term synonymous with 'object'. An instance is a
particular instantiation of a data type. It is simply a region of storage that
contains a value or group of values. For example, if a class box is previously
defined, two instances of a class box could be instantiated with the
declaration:
box box1, box2;
ΓòÉΓòÉΓòÉ 6.3.66. instantiate ΓòÉΓòÉΓòÉ
instantiate
To create or generate a particular instance (or object) of a data type. For
example, an instance box1 of class box could be instantiated with the
declaration:
box box1;
ΓòÉΓòÉΓòÉ 6.3.67. integral object ΓòÉΓòÉΓòÉ
integral object
A character object, an object having variations of the type int, or an object
that is a bit field.
ΓòÉΓòÉΓòÉ 6.3.68. internal data definition ΓòÉΓòÉΓòÉ
internal data definition
A description of a variable appearing in a block that directs the system to
allocate storage for that variable and makes that variable accessible to the
current block after its point of declaration.
ΓòÉΓòÉΓòÉ 6.3.69. manipulator ΓòÉΓòÉΓòÉ
manipulator
A value tha can be inserted into streams or extracted from streams to affect or
query the behaviour of the stream.
ΓòÉΓòÉΓòÉ 6.3.70. member ΓòÉΓòÉΓòÉ
member
A data object or function in a structure, union or class. Members can also be
classes, enumerations, bit fields and type names.
ΓòÉΓòÉΓòÉ 6.3.71. member function ΓòÉΓòÉΓòÉ
member function
Operators and functions that are declared as members of a class. A member
function has access to the private and protected data members and member
functions of an object of its class. Member functions are also called methods.
ΓòÉΓòÉΓòÉ 6.3.72. memory leak ΓòÉΓòÉΓòÉ
memory leak
Occurs when dynamic memory that has been allocated to an application is not
freed by the application when the memory is no longer needed.
ΓòÉΓòÉΓòÉ 6.3.73. method ΓòÉΓòÉΓòÉ
method
Method is an object-oriented programming term synonymous with member function.
ΓòÉΓòÉΓòÉ 6.3.74. multiple inheritance ΓòÉΓòÉΓòÉ
multiple inheritance
An object-oriented programming technique implemented in C++ through derivation,
in which the derived class inherits members from more than one base class. See
also inheritance.
ΓòÉΓòÉΓòÉ 6.3.75. nested class ΓòÉΓòÉΓòÉ
nested class
A class defined within the scope of another class.
ΓòÉΓòÉΓòÉ 6.3.76. new ΓòÉΓòÉΓòÉ
new
A keyword identifying a free store allocation operator. The new operator may be
used to create class objects.
ΓòÉΓòÉΓòÉ 6.3.77. object ΓòÉΓòÉΓòÉ
object
A region of storage. An object is created when a variable is defined or new is
invoked. An object is destroyed when it goes out of scope. See also instance.
ΓòÉΓòÉΓòÉ 6.3.78. object-oriented programming ΓòÉΓòÉΓòÉ
object-oriented programming
A programming approach based on the concepts of data abstraction and
inheritance. Unlike procedural programming techniques, object-oriented
programming concentrates not on how something is accomplished but instead on
what data objects comprise the problem and how they are manipulated.
ΓòÉΓòÉΓòÉ 6.3.79. operator function ΓòÉΓòÉΓòÉ
operator function
An overloaded operator that is either a member of a class, or takes at least
one argument that is a class type or a reference to a class type.
ΓòÉΓòÉΓòÉ 6.3.80. overflow ΓòÉΓòÉΓòÉ
overflow
That portion of an operation's result that exceeds the capacity of the intended
unit of storage.
ΓòÉΓòÉΓòÉ 6.3.81. overflow condition ΓòÉΓòÉΓòÉ
overflow condition
A condition that occurs when a portion of the result of an operation exceeds
the capacity of the intended unit of storage.
ΓòÉΓòÉΓòÉ 6.3.82. overloading ΓòÉΓòÉΓòÉ
overloading
Allows you to redefine functions and most standard C++ operators when the
functions and operators are used with class types.
ΓòÉΓòÉΓòÉ 6.3.83. pad ΓòÉΓòÉΓòÉ
pad
To fill unused positions in a field with dummy data, usually zeros, ones, or
blanks.
ΓòÉΓòÉΓòÉ 6.3.84. parameter declaration ΓòÉΓòÉΓòÉ
parameter declaration
A description of a value that a function receives. A parameter declaration
determines the storage class and the data type of the value.
ΓòÉΓòÉΓòÉ 6.3.85. pointer ΓòÉΓòÉΓòÉ
pointer
A variable that holds the address of a data object or function.
ΓòÉΓòÉΓòÉ 6.3.86. pointer to member ΓòÉΓòÉΓòÉ
pointer to member
Used to access the address of non static members of a class.
ΓòÉΓòÉΓòÉ 6.3.87. precedence ΓòÉΓòÉΓòÉ
precedence
The priority system for grouping different types of operators with their
operands.
ΓòÉΓòÉΓòÉ 6.3.88. private ΓòÉΓòÉΓòÉ
private
A private member of a class is only accessible to member functions and friends
of that class.
ΓòÉΓòÉΓòÉ 6.3.89. protected ΓòÉΓòÉΓòÉ
protected
A protected member of a class is accessible to member functions and friends of
that class, or member functions and friends of classes derived from that class.
ΓòÉΓòÉΓòÉ 6.3.90. prototype ΓòÉΓòÉΓòÉ
prototype
See function prototype.
ΓòÉΓòÉΓòÉ 6.3.91. public ΓòÉΓòÉΓòÉ
public
A public member of a class is accessible to all functions.
ΓòÉΓòÉΓòÉ 6.3.92. pure virtual function ΓòÉΓòÉΓòÉ
pure virtual function
A virtual function is declared pure by replacing the function definition with
'=0;'. See also abstract classes.
ΓòÉΓòÉΓòÉ 6.3.93. qualified class name ΓòÉΓòÉΓòÉ
qualified class name
Any class name or class name qualified with one or more :: (scope) operators.
ΓòÉΓòÉΓòÉ 6.3.94. qualified name ΓòÉΓòÉΓòÉ
qualified name
Used to qualify a nonclass type name such as a member by its class name.
ΓòÉΓòÉΓòÉ 6.3.95. qualified type name ΓòÉΓòÉΓòÉ
qualified type name
Used to reduce complex class name syntax by using typedefs to represent
qualified class names,
ΓòÉΓòÉΓòÉ 6.3.96. static ΓòÉΓòÉΓòÉ
static
A keyword used for defining the scope and linkage of variables and functions.
For internal variables, the variable has block scope and retains its value
between function calls. For external values, the variable has file scope and
retains its value within the source file. For class variables, the variable is
shared by all objects of the class and retains its value within the entire
program.
ΓòÉΓòÉΓòÉ 6.3.97. static binding ΓòÉΓòÉΓòÉ
static binding
Binding that occurs at compilation time based on the resolution of overloaded
functions. or more instructions enclosed in braces ({}).
ΓòÉΓòÉΓòÉ 6.3.98. storage class specifier ΓòÉΓòÉΓòÉ
storage class specifier
One of: auto, register, static, or extern.
ΓòÉΓòÉΓòÉ 6.3.99. stream ΓòÉΓòÉΓòÉ
stream
A continuous stream of data elements being transmitted, or intended for
transmission, in character or binary-digit form, using a defined format.
ΓòÉΓòÉΓòÉ 6.3.100. stream buffer ΓòÉΓòÉΓòÉ
stream buffer
A stream buffer is a buffer between the ultimate consumer and the I/O Stream
Library functions that format data. It is implemented in the I/O Stream
Library by the streambuf class and the classes derived from streambuf.
ΓòÉΓòÉΓòÉ 6.3.101. structure ΓòÉΓòÉΓòÉ
structure
A class data type that contains an ordered group of data objects and member
functions. Unlike an array, the data objects within a structure can have varied
data types. A structure can be used in all places a class is used. The initial
projection is public.
ΓòÉΓòÉΓòÉ 6.3.102. structure tag ΓòÉΓòÉΓòÉ
structure tag
The identifier that names a structure data type.
ΓòÉΓòÉΓòÉ 6.3.103. switch expression ΓòÉΓòÉΓòÉ
switch expression
The controlling expression of a switch statement.
ΓòÉΓòÉΓòÉ 6.3.104. switch statement ΓòÉΓòÉΓòÉ
switch statement
A C++ language statement that causes control to be transferred to one of
several statements depending on the value of an expression.
ΓòÉΓòÉΓòÉ 6.3.105. task ΓòÉΓòÉΓòÉ
task
A lightweight, nonpreemptive routine that you can use to simulate the operation
of programs. Only a single task executes at any one time. Less time and space
are required to create a task than a true operating system process.
ΓòÉΓòÉΓòÉ 6.3.106. Task Library ΓòÉΓòÉΓòÉ
Task Library
A class library that provides the facilities to write programs that are made up
of tasks.
ΓòÉΓòÉΓòÉ 6.3.107. template ΓòÉΓòÉΓòÉ
template
A family of classes or functions with variable types.
ΓòÉΓòÉΓòÉ 6.3.108. template class ΓòÉΓòÉΓòÉ
template class
A class instance generated by a class template.
ΓòÉΓòÉΓòÉ 6.3.109. template function ΓòÉΓòÉΓòÉ
template function
A function generated by a function template.
ΓòÉΓòÉΓòÉ 6.3.110. this ΓòÉΓòÉΓòÉ
this
A keyword that identifies a special type of pointer that references in a member
function the class object with which the member function was invoked.
ΓòÉΓòÉΓòÉ 6.3.111. type balancing ΓòÉΓòÉΓòÉ
type balancing
A conversion that makes both operands have the same data type. If the operands
do not have the same size data type, the compiler converts the value of the
operand with the smaller type to a value having the larger type.
ΓòÉΓòÉΓòÉ 6.3.112. type definition ΓòÉΓòÉΓòÉ
type definition
A definition of a data type.
ΓòÉΓòÉΓòÉ 6.3.113. type specifier ΓòÉΓòÉΓòÉ
type specifier
Used to indicate the data type of an object or function being declared.
ΓòÉΓòÉΓòÉ 6.3.114. ultimate consumer ΓòÉΓòÉΓòÉ
ultimate consumer
The target of data in an input and output operation. Can be a file, a device,
or an array of bytes in memory.
ΓòÉΓòÉΓòÉ 6.3.115. ultimate producer ΓòÉΓòÉΓòÉ
ultimate producer
The source of data in an input and output operation. Can be a file, a device,
or an array of bytes in memory.
ΓòÉΓòÉΓòÉ 6.3.116. union ΓòÉΓòÉΓòÉ
union
A variable that can hold any one of several data types, but only one data type
at a time.
ΓòÉΓòÉΓòÉ 6.3.117. union tag ΓòÉΓòÉΓòÉ
union tag
The identifier that names a union data type.
ΓòÉΓòÉΓòÉ 6.3.118. virtual function ΓòÉΓòÉΓòÉ
virtual function
A class function declared with the keyword virtual. The implementation that is
executed when you call a virtual function is determined at run-time based on
the type of the object for which it is called.