Summary
This article shows how to get started with the Tools.h++ collection and utility classes available in the Irix 6.2 compiler configuration, including the ANSI Class library support via Tools.h++. This is a draft article to be published later in Dev News.
By Kent Sandvik
The C++ development environment in Iris 6.2 includes the Rogue Wave Tools.h++ collection and utility classes. Tools.h++ is a C++ class library that provides a lot of the standard structures needed in common programming exersizes. Examples of such classes are Time classes, String classes, collections, iterators, Time classes, singly- and doubly-linked lists and so on. All together Tools.h++ contains 120 various classes. In addition, Tools.h++ provide interfaces to the draft Standard C++ libraries including ANSI C++ String classes. The Standard Template Library (STL) support in 6.2 compilers are based on Tools.h++ collection classes.
The Tools.h++ classes support persistance, so you could save and
retrieve objects from and to disk, or over a network. This works even
cross-platform, as Tools.h++ has been ported to various platforms
including Windows and MacOS. All Tools.h++ classes are multi-thread
safe. Each class is not derived from a single root class, this means
that it's easy to combine the classes with other C++ classes, using
HAS-A relationships or multiple inheritance.
You should have installed the c++_dev system,
especially
the Rogue Wave related subsystems such as c++_dev.hdr.librw
,
c++_dev.man.librw
, c++_dev.sw.librw
and c++_dev.sw32.librw
.
The RogueWave libraries are called librwtool.a
, so when
you compile code using these libraries, you need to include these using -lrwtool
.
The actual header files are placed inside /usr/include/CC/rw
,
but when you write code you include these using the normal path names,
as in:
#include <rw/rwtime.h> #include <rw/rwdate.h> #include <rw/rstream.h>
Note that various Tools.h++ classes have overrides concerning the C++
streams io libraries, so you need to include the specific rstream.h
header file in order to use these.
Here's a simple example of how to use the RWTime class:
#include <rw/rwtime.h> #include <rw/rwdate.h> #include <rw/rstream.h> void main(void) { RWTime t; // current time RWTime d(RWTime::beginDST(1990, RWZone::local())); cout << "current time: " << RWDate(t) << " " << t << endl; cout << "Start of DST, 1990: " << RWDate(d) << " " << d << endl; }
This example is also explained in the man RWTime entry. You compile this example using: % CC time.c++ -lrwtool -o time_example
The first thing when we explore a framework is to find out what's available in the libraries, what classes are present, how to use these classes and so on. For example, we want to look at existing sample code to get a better feeling what we need from Tools.h++.
Rogue Wave has a class reference available at their web site: http://www.roguewave.com/support/tools/toolsamp.html You could also find examples showing how the libraries map to the ANSI C++ Standard library from http://www.roguewave.com/products/tools/code.html. Finally, the class reference is available from http://www.roguewave.com/products/abbrevcr/tools70cr.abbrev.htm. This document describes all the classes and functions, and has a class hierarchy diagram.
Also, if you know the name of the class you could do a lookup using the man entry; note that many of the man entries have small code snippets showing how to use the actual class.
Each RogueWave class starts with RW
, as in RWCString.
This should eliminate some of the problems with name space collisions.
All classes use the same member function name to make it easier to
learn the framework. For example, the member functions returning the
number of items in various collection classes are always called entries()
.
Most classes are lightweight in that they have low cost initializer and copy constructors. Tools.h++ uses an error model that divides errors up to four different categories:
It also has various assert and pre/postcondition macros that you could use for debugging purposes.
Tools.h++ implements the current standard C++ libraries defined by ANSI and ISO. This is a fairly large collection of classes and functions, such as:
Here's an example how to create a double-linked list with string elements, and how to iterate through these entries.
#include <iostream.h> #include <rw/cstring.h> #include <rw/regexp.h> #include <rw/tvdlist.h> void main(void) { RWTValDlist <RWCString> stringList; RWTValDlistIterator <RWCString> it(stringList); stringList.insert("First"); stringList.insert("Second"); stringList.insert("Third"); stringList.insert("Fourth"); RWCString newString; it.reset(); it.findNext(RWCString("Third")); cout << newString << endl; }
You have to carefully read the man entries for RWTValDlistIterator as
it has certain operator overloaded functions that should be used for
iteration. I used the operator()()
overload that will
traverse along the linked list, until it finds the last one and returns FALSE
in this case. You could insert, remove, find next entries and so on
using this iterator.
Tools.h++ has regular expression classes that could be used for pattern matching. Here's a simple example showing this feature:
#include <rw/regexp.h> #include <rw/cstring.h> #include <rw/rstream.h> void main(void) { RWCString aString("This is a test"); // Create a regular expression that matches any // lower case words starting with 't'. RWCRegexp reg("t[a-z]*"); cout << aString(reg) << endl; // prints out 'test' }
The following example shows how to create a Hash table using specific
so called RWCollection
objects. You could install ints,
strings, Time classes, Date classes, or generic objects into the hash
table:
#include <rw/hashtab.h> #include <rw/cstring.h> #include <rw/collstr.h> #include <rw/rstream.h> void main(void){ RWHashTable table; table.insert(new RWCollectableString("First")); table.insert(new RWCollectableString("Second")); table.insert(new RWCollectableString("Third")); cout << aString(reg) << endl; // prints out 'test' }
Here's an example showing how you could break down strings using the RWCTokenizer
class:
#include <rw/ctoken.h> #include <rw/rstream.h> void main(void) { RWCString aString("This is an example of a string."); RWCTokenizer tokenizer(aString); // Tokenize the string. RWCString item; while(!(item=tokenizer()).isNull()) cout << "Table contains the key: " << key << endl; }
Finally here's an example how to use the persistant storage system using specific RW virtual streams:
#include <rw/collstr.h> #include <rw/ordcltn.h> #include <rw/rstream.h> #include <strstream.h> #include <rw/pstream.h> void main(void) { // Create collectable strings we will stream out later. RWCollectableString stringOut1("First"); RWCollectableString stringOut2("Second"); RWCollectableString stringOut3("Third"); // Create an ordered list. RWOrdered orderedOut; orderedOut.append(&stringOut1); orderedOut.append(&stringOut2); orderedOut.append(&stringOut3); // Create our virtual stream that is attached to a standard ostrstream. ostrstream os; RWpostream post(os); // Fill the posted stream post << orderedIn; // Show the flattened ASCII format cout << os.str() << endl; // Create a virtual stream that is hooked to the ostrstream istrstream is(os.str()); RWpistream pin(is); // Fill the incoming stream RWOrdered orderedIn(3); pin >> orderedIn; cout << "Num entries in: " << orderedIn.entries() << endl; // Restore the objects from the RWCollection set RWCollectableString stringIn1 = *(RWCollectableString*)orderedIn[0]; RWCollectableString stringIn2 = *(RWCollectableString*)orderedIn[1]; RWCollectableString stringIn3 = *(RWCollectableString*)orderedIn[2]; cout << stringIn1 << " " << stringIn2 << " " << stringIn3 << endl; }
RWpostream
will store values in a portable (ASCII format),
that RWpistream
will then read in for restoration of the
objects. Note that this format will work cross-platform, so you could
send this information over the network, or using file storage, for
example.
Rogue Wave has a web site at http://roguewave.com. This site has the latest information about the libraries including sample code, including frequently asked question information and updated README files.
As for using these collection classes instead of STL (Standard Template Libraries), it depends if you want to write STL code, or if there are cases where the Tools.h++ collection classes makes it easier to implement a specific feature. The positive aspect by using STL is that you could move such code to other platforms where the STL libraries are ported.
About the Author
Kent Sandvik works as a Developer Support Engineer for Silicon Graphics, He's worked in this role for over ten years, in various positions inside Apple and SGI including technical lead for the Newton Developer support group, and QuickTime developer support lead.
You could reach him at sandvik@sgi.com
, and his home page
is
at http://reality.sgi.com/sandvik/.
$Date: 1996/06/14 20:29:26 $, $Revision: 1.2 $