The Database Managers, Inc.

Contact The Database Managers, Inc.


Use an RSS enabled news reader to read these articles.Use an RSS enabled news reader to read these articles.

STLplus

Review and upgrades
by Curtis Krauskopf

UPDATE: STLplus3 3.40 review and download is available at www.decompile.com/not_invented_here/stlplus3/
 

STLplus is an eclectic collection of STL C++ components. The areas covered in STLplus range from the mundane (trimming strings) to advanced (directed graphs, hash tables and file management). Figure A shows the broad categories covered by the library and the solutions provided in each category.

STLplus is cross-platform compatible.

Figure A
Utilities
  • Debugging Utilities
  • CPU Timer
  • Time Manipulation Functions
Concepts
  • Exceptions Thrown by STLplus
  • Interfaces
Data Persistence
  • Persistence Functions
String Formatting Utilities
  • String Formatting Utilities
  • Printf-like String Formatting
TextIO Subsystem
  • Text I/O Base classes
  • File I/O Derivative
  • String I/O Derivative
  • String Vector I/O Derivative
  • IOStream Derivative
  • Multiple I/O Derivative
Container Classes
  • Smart Pointer
  • Directed Graph
  • Hash Table
  • N-ary Tree
  • 2-Dimensional Matrix
Basic Types
  • Infinite Precision Integers
  • Binary String Arithmetic
Operating System Functions
  • File System Access
  • Subprocess Handler
  • TCP Internet classes
Subsystems
  • Library Manager
  • Error and Message Handler
  • Ini File Manager
  • Command Line Parser
STLplus contains over 12,000 lines of algorithms, STL containers and utility functions in 24 modules. This image is a composite of the STLplus HTML documentation.

Installation

According to Andy Rushton, the creator and maintainer of STLplus, "The reason I keep hammering on about this ease of use is that I've had nightmare scenes with other code libraries which require mind-bogglingly complicated procedures to build and use them (e.g. STLport and the Boost libraries - for all I know these are all superb, but if I can't build them, how am I to find out?). So I want to let you know that STLplus is not like this - it is trivially easy to build." [1]

He's right. STLplus is easy to install and build. Although there isn't a Borland project in the distribution, the STLplus source code includes __BORLAND__ conditionally compiled code. It seems to me that STLplus was, at some time in its past, Borland compiler compatible.

I created a Borland project by converting the Microsoft Visual C++ project. In Borland C++Builder 6, I used the Tools | Visual C++ Project Conversion Utility wizard. Unfortunately, the wizard-generated project gave me many compile-time errors in Borland's stdlib.h in the __MFC_COMPAT__ section. From experience importing other libraries, I've learned that tracking down compile-time errors like

E2316 '_itoa' is not a member of 'std'

can eat hours (or an entire day).

My favorite solution when I encounter a problem like this is to rebuild the entire project from scratch. A quick audit of the files that the wizard placed in the project told me that all of .cpp files in the STLplus ~\source\ folder were used. The conditional defines looked normal: WIN32;_DEBUG;_LIB;_MBCS

Creating a static library project

First, I create an STLplus\IDE\BCB60 folder. The open-source libraries I use follow this same pattern so I don't have to hunt for the project files. Separating the Borland files from the distribution files makes incorporating future upgrades (of either the project code or the compiler I'm using) easier too.

I create a project group with File | New | Other | Project Group (see Figure B).

Figure B
Start creating a static library by first creating a new Project Group. Then choose the Library icon from this new items dialog to create the library.

A static library is added to the project by using File | New | Other | Library. Both the static library and the project group default to my CBuilder6 folder but I don't worry about that now.

Next, I open Windows Explorer and navigate to the STLplus\source folder. Sorting the files by type puts all of the .cpp files together. At that point, it's easy to highlight the .cpp files and drag them over to the Project1.lib in the Project Manager panel.

Then I save the Project Group and static library in the IDE\BCB60 folder I previously created. I use appropriate project and unit names called STLplus.

Compiling this project gives a compile-time error in string_utilities.hpp:

'time_t' cannot start a parameter declaration.

For the Borland compiler, time_t is defined in the <time.h> header. I added the code highlighted in Figure C near

Figure C
STLplus needs to include the time.h header file to define the time_t symbol.
the top of the string_utilities.hpp file, after the last #include.

Encouraged by my initial compilation success, I press forward and encounter a new compile-time error:

digraph.tpp(244): E2293 ) expected

This tells us a couple things. STLplus uses .tpp files for template header files. I've never seen that extension used in a C++ project but I like that idea and I might use it in my own projects. Previous experience with E2293 tells me that the error is actually earlier on the line – in this case it’s an undefined PARAMETER_TYPENAME symbol. Grepping for PARAMETER_TYPENAME shows that it's conditionally defined in os_fixes.hpp.

Definitions for PARAMETER_TYPENAME are provided for GNU C++ and Microsoft Visual Studio but not for Borland C++. I added the code in Listing A to os_fixes.hpp on line 216 (before the 'problems with missing functions' comment).

Listing A
#if __BORLANDC__ >= 0x0560 
#define TYPEDEF_TYPENAME typename 
#define PARAMETER_TYPENAME typename 
#define TEMPLATE_TYPENAME typename 
#endif
Add this code to os_fixes.hpp

The next compile-time error complains that the library is too large. After some experimenting, I found that setting the library page size to 0x0080 fixed that problem. To change the library size:

  • Open the Project Options for the STLplus library by using the shortcut key Alt+F7.
  • Choose the TLIB tab
  • Change the Page Size from 0x0010 (the default) to 0x0080

The next build is successful. Wow -- only two source files and one default in the compiler had to be changed. That's not too bad for a library with over 12,000 lines.

Warnings

Most of the compile-time warnings complain about initialized data in the header that prevents precompilation from working. A warning in inf.cpp complains that a throw type is different than the type promised in the function declaration. In inf.cpp (line 1423), change the exception from persistent_dump_failed to persistent_restore_failed.

While you're there, change the error message on that line too. The distribution says inf::dump but the error message should be inf::restore.

The next build successfully creates the STLplus.lib file with only warnings about creating pre-compiled headers.

Hash table example

Listing B shows an example hash table. I purposely kept the hashing algorithm simple to force hash table collisions. The comment says that it’s the world’s worst hashing algorithm but that’s not true. The worst hashing algorithm would return random numbers for the same string.

Listing B
#include <iostream>
#pragma hdrstop
#include <hash.hpp>

using std::string; // to make 
using std::cout;   // this listing
using std::endl;   // narrower

// World's worst hashing algorithm
struct hash_string {  
    unsigned operator()    
    (const string & s) const    
    { return 5; }
};

int main(int argc, char* argv[]) {  
    hash<string, string, hash_string> symbols;  
    
    symbols["alpha"] = "a";  
    symbols["bravo"] = "b";  
    
    cout << "alpha = ";  
    cout << symbols["alpha"] << endl;  
    cout << "bravo = ";  
    cout << symbols["bravo"] << endl;  
    
    if (symbols.present("charlie"))     
        cout << "found charlie" << endl;  
    else     
        cout << "charlie not found" << endl;  
        
    symbols["charlie"] = "c";  
    
    if (symbols.present("charlie"))       
        cout << "found charlie" << endl;  
    else     
        cout << "charlie not found" << endl;  
        
    return 0;
}

// Expected output:
// alpha = a
// bravo = b
// charlie not found
// found charlie
Hash Table Example

Compiling this example uncovered a compile-time problem in hash.tpp: make_pair was undefined. To fix this problem, I inserted std:: in front of make_pair on line 499:

return std::make_pair(hash<K....

Pros and cons

The library's code is very well organized. For example, all of the operating system specific code is in the os_fixes.hpp file. Users can choose to include stlplus.hpp (which defines everything) or they can include specific .hpp files, such as hash.hpp as shown in Listing B.

The code is well written with copious helpful comments.

Some developers will dislike the CVS files that are included in the distribution because they might interfere with the developer's revision control system. A bigger problem is that there are no unit tests and there are no examples (other than the snippets and few examples provided in the documentation).

The documentation is comprehensive and it's written in HTML. Every module has an introduction, a colorized C++ header, and details about using the public methods. The cross-reference is poor and the documentation for at least one module (library_manager) is unfinished.

A library this large needs excellent documentation. The main problem with the documentation is that it tries to be a reference manual and a user manual simultaneously. The documentation fails as a user manual because detailed examples are not provided and it fails as a reference manual because summaries and cross-references of the module's functionality are not provided in all cases.

The size and scope of the library is large but the Borland linker is smart enough to include only the portions that are really needed. I have not experienced significant code bloat from using the File System Access and String Formatting modules.

The os_fixes.hpp disables some Borland-specific warnings that I consider to be important. Lines 45-70 in os_fixes.hpp very clearly document which warnings are disabled. This is really a case of comment-creep because some of the warnings don't need to be disabled anymore. The W8022 and W8060 warnings (virtual function in a base class is overridden and possible incorrect assignment respectively) are not problems in the STLplus code anymore. The other two warnings (W8008 for condition always true and W8066 for unreachable code) only appear when compiling the .cpp files. Because the header files are unaffected, I've chosen to comment-out the pragmas that disable all four of those warnings.

My experience with STLplus is that I focus on three or four of the modules and use the others when I have a special need. STLplus is very similar to a Swiss Army knife in that you use two or three of the blades almost all the time and use the other blades on rare occasions for special purposes.

License

STLplus uses one of the most generous licenses I've seen. To quote Andy Rushton, "I don't subscribe to the idealism of some open-source advocates who claim that open-source software should only be available to other open-source developers. I want this library to be used by anyone and everyone, well except intellectual property thieves and litigious idiots. There are therefore no restrictions saying you have to make your products open source as well because I don't believe in that. If you wish to use this library in an open source project, great. If you wish to use it in a closed-source commercial product, equally great." [2]

I wish more open-source developers were as open-minded about the free distribution of source code.

VCL overlap

STLplus does not provide any GUI interfaces, database connections or interfaces with user or system events. The overlap with VCL is mostly limited to filename and path name manipulation functions. The STLplus TextIO module provides powerful text, file and string files that rival the LoadFromFile and LoadFromStream methods in the TStrings class. The STLplus persistent methods and string manipulation functions duplicate some functionality in the VCL classes too. However, overall there is very little functionality overlap between STLplus and VCL.

Availability

STLplus is available at http://sourceforge.net/projects/stlplus

Borland project files, the Borland-specific changes to STLplus and three example programs using STLplus version 2.5 are available at the STLplus BCB Patches Download page.

Conclusion

STLplus is a large library of C++ functions, algorithms and STL containers. The only commonality between the modules is the use of the Standard Template Library as the basis of the building blocks. The modules have such a broad range of functionality that at least one module will be useful to most developers, even on small projects.

Recommendation

Get STLplus and the STLplus Borland-specific patches. The STLplus code is well-written and it provides many examples of creating STL containers and using STL templates. Even though the library is enormous, the Borland C++ Builder linker removes the unused code so your executable will not bloat from using one mundane function. The specialized header files (such as hash.hpp) keep the compile-times down as well. Most coders will use one or two of the modules but having the other, more esoteric, modules available can result in having the right tool at the right time.

References

  1. "Building and Using the STLplus Library
    STLplus documentation:
    ~\docs\building.html
  2. "License Agreement
    STLplus documentation:
    ~\docs\license.html

Contact Curtis at

Curtis Krauskopf is a software engineer and the president of The Database Managers (www.decompile.com). He has been writing code professionally for over 25 years. His prior projects include multiple web e-commerce applications, decompilers for the DataFlex language, aircraft simulators, an automated Y2K conversion program for over 3,000,000 compiled DataFlex programs, and inventory control projects. Curtis has spoken at many domestic and international DataFlex developer conferences and has been published in FlexLines Online, JavaPro Magazine, C/C++ Users Journal and C++ Builder Developer's Journal.


Popular C++ topics at The Database Managers:

Services | Programming | Contact Us | Recent Updates
Send feedback to: