FAQ

This is a listing of each FAQ entry so far. Click on a FAQ to see the answer. If you wish to search, you may use the search option from the menu above. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Back to Top

FAQ: 1

How do I get started using the STLSoft libraries?

Simply download the latest distribution, extract the library header files to a directory that is on the include path for your C++ project(s), and #include the files that you wish to use.

In terms of using the types and symbols provided in the library, you will need to be cognnisant of the stlsoft namespace. Apart from those few compilers that do not support the namespace concept sufficiently, all components of the STLSoft main project (as opposed to the other projects: ATLSTLCOMSTLMFCSTLWinSTLXMLSTL ) libraries reside in the stlsoft namespace. Hence, to use these types you should qualify them with stlsoft::, or you can use the qualifications macros (stlsoft_ns_qualstlsoft_ns_using) defined within stlsoft.h.


Back to Top

FAQ: 2

Can I switch to stlsoft from stlport?

STLSoft is not a replacement for the standard library. It is an extension of the concepts of STL into different technology areas, currently including ATLCOMMFCUNIX and Win32. (There are others, but they’re not mature.) It does, as well, have stuff that’s general, such as frame-stringfixed-2 & 3 d arraysstring-tokeniser, etc. etc., but it’s fair to say that the main thrust is to apply STL to other things.

A couple of good examples are WinSTL‘s findfile_sequence, and COMSTL‘s simple_enum_sequence. The first wraps the Win32 FindFile API into an STL-like sequence that provides Input Iterators (also does Forward ones, but they’re less efficient). The second is a policy-based gizmo for wrapping arbitrary COM enumerators into STL-like sequences providing Input or Forward (policy-based) Iterators.

There’s also one last part that’s salient to this. As you may know, the implementation behind the standard libraries provided by many of the compiler vendors are quite different. In particular, VC 5, 6, and 7 all do nasty things. STLSoft provides a set of classes – in stlsoft_iterator.h – such as iterator_baseconst_reverse_bidirectional_iterator_basepointer_iterator that handles all that evil filth (check out that file, if you don’t know just how evil!) for you, so you can write your sequences confident that you’ll compile with BorlandDMC++IntelGCCMSVCMetrowerks, etc. etc.

 


Back to Top

FAQ: 3

Why is it that so many of the components don’t seem to actually do anything?

Because they don’t! Well that’s not quite fair. Actually, many of them do their useful work at compile time. For example, the true_typedef component’s code is optimised out completely by all our supported compilers. However, true-typedefs have their use in the compiling stage, since they prevent inter-typedef corruption, and help to disambiguate overloaded function calls.

Of course, many of the components do have significant runtime behaviour. For example, the integer_to_string conversion functions convert integers to string-form at runtime; the fixed and frame array classes are fully-functional containers. On the whole, however, the library attempts to perform as much work as possible at compile time, and to have as little “overhead” (size, speed) as is feasible. The catchphrase is “Robust, Lightweight, Cross-platform, Template Software”, after all.

 


Back to Top

FAQ: 4

Why do you support so many compilers? Why do you support some really old versions of compilers?

These are actually two separate issues. The STLSoft libraries support a diverse range of compiler vendors (and will include more in the future: see News) simply because the development community uses this diverse range, and one of the main raisons d’etre of STLSoft is to be independent of compilers (along with independence from platforms, threading models, character encodings, etc).

The reason the libraries support older versions of compilers is again partly because they are still in use, and also (and other providers of public-domain sources will no doubt agree) because providing compatibility against older versions of known compilers makes it a great deal easier to provide compatibility for any additional compilers by ensuring that any untenable assumptions (e.g. sizeof(int) == sizeof(void*)) are teased out early on.


Back to Top

FAQ: 5

What can I do if my compiler is not supported?

There are three options:
1. You can contact us (see contacts page) and discuss the situation. If the compiler is one which is available to us, we will probably do the adaptation required.

2. From release 1.6.1 onwards you can define the _STLSOFT_FORCE_UNKNOWN_COMPILER pre-processor symbol, which results in the __STLSOFT_COMPILER_IS_UNKNOWN symbol being defined, and the file stlsoft_cccap_unknown.h to be included. This file assumes a reasonable set of modern compiler capabilities (e.g. partial template specialisation, support for the veneer concept), but does not assume any proprietary extensions (e.g. native-sized integers such as __int8).

3. From release 1.6.1 onwards you can define the _STLSOFT_FORCE_CUSTOM_COMPILER pre-processor symbol, which results in the __STLSOFT_COMPILER_IS_CUSTOM symbol being defined. You must then also define __STLSOFT_CF_CUSTOM_COMPILER_INCLUDE_NAME as the name of your include file (e.g. #define __STLSOFT_CF_CUSTOM_COMPILER_INCLUDE_NAME <stlsoft_cccap_my_compiler.h>, which must contain the symbols defining the compiler capabilities (see the file stlsoft_cccap_unknown.h for possible definitions).


Back to Top

FAQ: 6

What headers does stlsoft.h depend on, and how can I suspend them?

stlsoft.h is the root header for the STLSoft libraries. It includes only stddef.h and stdlib.h. If you wish to prevent it from including those files, you can do so by specifying the pre-processor symbol _STLSOFT_NO_STD_INCLUDES. When you do this, the types ss_char_w_tss_size_t and ss_ptrdiff_t are no longer defined from wchar_tsize_t and ptrdiff_t but are defined from scratch within stlsoft.h itself.


Back to Top

FAQ: 7

I have used the Boost libraries, and like the fact that they exist in a separate boost directory. Can I do the same with STLSoft?

Yes and no. You can, of course, put the STLSoft headers in a separate directory. Indeed, that is what we strongly recommend. However, that specific directory will have to be in your system/project include paths list. The boost model differs in that a boost directory is created under a known include directory, and all refernces – both in your code and within the boost headers – stipulates the relative path, e.g. #include <boost/array.hpp>. The advantages with this second model are that the include paths do not need to be altered, but the code can still reside in a separate location, and that the file names do not have to be of a unique naming convention. The disadvantage is that all references must explicitly stipulate the relative path.

The STLSoft libraries do not currently support the second model, but this is planned for the next release. It will be tailorable, such that you can select by means of a preprocessor which model you wish to use, thereby providing the best of both worlds.


Back to Top

FAQ: 8

There are a lot of strange looking symbols in the code, like ss_typename_param_k, that I don’t understand. What’s going on?

Since there is, regrettably, a range in the support for “standard C++” throughout the supported compilers, some of these concepts have had to be abstracted. A good example of this is the typename keyword. This keyword has two uses, as a parameter class specifier in template parameter lists, and as a type qulifier within template definitions. A few compilers do not support the former use (requiring the keyword class instead), so that the abstraction ss_typename_param_k is used, which is defined as typename where supported, or class otherwise. A significant number do not support the latter use, so the abstraction ss_typename_type_k is used, which is defined as typename where supported, or defined as nothing.

This technique is only used where it must be. Where support is ubiquitous for a keyword, such as inline, then no abstraction is made, and the keyword is used “in the raw.


Back to Top

FAQ: 9

Why are the macros stlsoft_num_elements(), stlsoft_static_assert(), stlsoft_throw_0() etc. not simply called the much easier to type num_elements(), static_assert(), throw_0()?

Because macros (can only) exist in the global namespace, and are a notorious source of namespace pollution and library incompatibility. Obviously, when writing code one can put types within namespace (as the various elements of the STLSoft, WinSTL, XMLSTL, COMSTL etc libraries are in the stlsoftwinstlxmlstl and comstl namespaces.), but no such mechanism is available for macros. Hence, it is wise to be as unambiguous as possible, hence the stlsoft_ prefix.


Back to Top

FAQ: 10

How do I disable the STLSoft namespace?

You can define: #define _STLSOFT_NO_NAMESPACES or remove just stlsoft (and leave the sub-projects’ namespaces intact).


Back to Top

FAQ: 11

How do I write code that works correctly whether or not I choose to use [the default] or disable [via _STLSOFT_NO_NAMESPACES] the stlsoft namespace?

You can make use of the stlsoft_ns_qual() and stlsoft_ns_using() macros. stlsoft_ns_qual() may be used in the place of a namespace qualification. Where you might have written

typedef stlsoft::auto_buffer<char, . . .> buffer_t;

you would write

typedef stlsoft_ns_qual(auto_buffer)<char, . . .> buffer_t;

so that your code will now successfully compile when used with compilers that support namespaces and those that do not


Back to Top

FAQ: 12

How do I build STLSoft? I can’t find the C++ files!

The short answer is: you don’t. Since STLSoft is 100% header-only, there is no building to be done. You include the source in your code as needed, and the compiler will incorporate only those elements as are needed by the code that you’ve written.

Having said that, there are a variety of test programs and – as of version 1.7.1 – sample programs. Naturally these need to be built as you would any other program, and this is largely your responsibility. However, there will be project files for many popular compilers/IDDEs to make that easy. A forthcoming release (hopefully 1.7.2) will also include build scripts in various scripting languages, so it can all be made ridiculously straightforward.


Back to Top

FAQ: 13

My compiler doesn’t support namespaces, what do I do?

If your compiler does not support namespaces, then all the STLSoft constructs will be declared in the global namespace, and to use them you can simply omit the namespace qualifications. Of course, there are a couple of conflicts that may occur. For example, both MFCSTL and WinSTL have resource_string types. (Note: as of 1.6.3, the WinSTL template resource_string<> was correctly renamed to basic_template_string<>, so this is no longer a true example, but it is still instructive.)

If you plan to never use another compiler then that’s the easiest route to go. However, if you want your code to be portable, then you should use the namespace qualification macros, e.g. comstl_ns_qual()winstl_ns_using(). These macros resolve to the appropriate namespace prefix on compilers that support namespaces, and to the plain declarations on those that do not. Some examples will help:

In a source file you may have the following include and using declaration:

#include <winstl_processheap_allocator.h>
 
using winstl::processheap_allocator;
 
int main()
{
    typedef processheap_allocator<char>  char_ator_t;
...

or you might use explicit qualification in your code

 
#include <winstl_processheap_allocator.h>
 
int main()
{
    typedef winstl::processheap_allocator<char>  char_ator_t;
...

On a compiler that does not support namespaces, there will be no winstl namespace. You could then end up with code such as:

#include <winstl_processheap_allocator.h>
 
#ifndef _WINSTL_NO_NAMESPACE 
// This will be defined by the STLSoft headers on compilers not supporting 
// namespaces, but may also be defined by you yourself

using winstl::processheap_allocator;

#endif // !_WINSTL_NO_NAMESPACE
 
int main()
{
    typedef processheap_allocator<char>  char_ator_t;

or

#include <winstl_processheap_allocator.h>
 
int main()
{
  #ifndef _WINSTL_NO_NAMESPACE
    typedef winstl::processheap_allocator<char>  char_ator_t;
  #else
    typedef processheap_allocator<char>            char_ator_t;
  #endif // !_WINSTL_NO_NAMESPACE

But this is tedious and error-prone, not to mention ugly! The answer is to use either the “_using” (for using declarations) or “_qual” (for explicit qualification) macros, as in:

#include <winstl_processheap_allocator.h>
 
  winstl_ns_using(processheap_allocator)
 
int main()
{
    typedef processheap_allocator<char>  char_ator_t;

or

#include <winstl_processheap_allocator.h>
 
int main()
{
    typedef winstl_ns_qual(processheap_allocator)<char>   char_ator_t;

which keeps your code as nice and neat as possible. As I said earlier, this is to be used when portability is a concern. If you don’t care about portability, then you are perfectly free to either use or omit the namespace tokens as appropriate.

As with the general ethos of STLSoft, the mechanisms are provided to enable your preference, and the choice remains, as it should, squarely with you.


Back to Top

FAQ: 14

Can I use STLSoft with C instead of just C++?

At the moment, STLSoft header files will issue an #error if not compiled as C++. There are plans to make some of the types and macros available to C, which would help out on a couple of projects that are using STLSoft. Also, almost all of the components could not work as C-files. This includes all the templates and classes. For certain compilers, e.g. Visual C++, that provide inlinemechanisms for C (__inline for VC++) many of the free functions would be useful.

This is all pretty low priority at the moment, but will likely be included in 1.7.1 or shortly thereafter


Back to Top

FAQ: 15

I like [insert template here]. How can I help it see place in the next standard?

Thanks! As for the standards process, I guess you’d have to contact the standards body, and put in a proposal. That would be cool. 🙂


Back to Top

FAQ: 16

When will you make a tutorial or does one already exist for STLSoft?

I’m hoping my helpful STLSoft friend Greg Peet will do that [GP: =(], once he’s done with the FAQ (for which thanks are due). My problem is that there is only one of me, and that other activities often have to take precedence; such is the life of the open-sourceror. Nevertheless, I am aware that the libraries are not immediately/transparently accessible, and a tutorial would be very helpful.


Back to Top

FAQ: 17

Does STLSoft incorporate exception-handling?

Yes and no. Basically the components in STLSoft work with or without exception-handling, according to your needs. I do not believe in prescribing the use of exceptions on users of my libraries, since there are times when use of exceptions is impossible (certain compilers, environments) or unacceptable (performance reasons). Conversely, exceptions are an important part of the language and well used in many circumstances, all of which must be supported.

So the components are written to work with/without exceptions. A couple of examples may help to make this clear:

        1. stlsoft::auto_buffer<> works with exceptions in that failure to allocate the block from the parameterising allocator will result in the throwing of the allocator’s exception type (std::bad_alloc, one would hope) and the concomitant failure to construct the instance of the auto_buffer. It also works without exceptions in that failure to allocate the block from the parameterising allocator will result in the size() method returning 0, and the begin() method returning the same value as the end() method. Thus you can use exception-handling (trycatch), or an error handler. Of course, if you do not provide exception/error handling and allocation fails, then your program will crash, but that’s got nothing to do with the auto_buffer; that’s just sloppy programming.

 

      1. winstl::basic_resource_string<> veneer template is parameterised a string type and an exception policy type. When the loading of a given (string) resource into an instance of a parameterisation of basic_resource_string<> fails, the exception policy type is given the opportunity to throw an exception – by calling its function call operator – after which the string instance is assigned from the empty string. Thus, if the exception policy type throws an exception, then the string instance is not constructed, and your code will need to handle the exception. If the exception policy type does nothing (in which case you might want to use the stlsoft::null_exception function object, provided for this purpose), then you end up with a correctly constructed empty instance. In either case, your code is consistent (though you will need to gracefully handle the empty string in the latter case), and it is up to you, the programmer, as to what paradigm of error-handling is appropriate to your needs.

Back to Top

FAQ: 18

Do the macros stlsoft_assert, stlsoft_message_assert, etc expand only with DEBUG defined?

Not necessarily. They are defined in terms of assert() (from <assert.h> / <cassert>) or, for Visual C++ and Intel C++, _ASSERTE() (from <crtdbg.h>), and will therefore be expanded or not by whatever criteria your compiler does with those assertion macros. Having given that long caveat-like explanation, the short answer will be yes in most cases.


Back to Top

FAQ: 19

What’s the difference between __STLSOFT_NO_NAMESPACE and __STLSOFT_NO_NAMESPACES?

#define _STLSOFT_NO_NAMESPACE places all things in the stlsoft namespace into the global namespace.

#define _STLSOFT_NO_NAMESPACES places all things in the stlsoft and all sub-project namespaces into the global namespace.


Back to Top

FAQ: 20

Does stlsoft_static_assert() expand at all times?

Since it is a compile-time thing, in theory it does expand at all times, and because it merely declares a typedef to an array (the static-assert mechanism) within a

do{}while(0);

it will all be optimised out. Alas, not all compiler implementations conform to theory. The offender here is Borland, where both versions 5.5(1) and 5.6 are unable to optimise out the empty loop, so the static assertion is expanded as a runtime assertion (stlsoft_assert()), which is obviously not the most desirable situation.


Back to Top

FAQ: 21

What’s your plans on a stlsoft_static_message_assert()?

I have not done this because:

      1. static assertions are very very rare, so the effort involved to come up with a similar system to (or the discomfort in plagiarising) that of Andrei Alexandrescu was not deemed worth it.
      2. static assertions are, by their very nature, compile-time, and one therefore has the source at hand when the assertion fires (i.e. when the compiler balks), so it is trivially simple to see what condition has been violated by the contents of the line that has caused the compile error.
      3. The stuff that Alexandrescu does requires (IIRC) a lot more template capabilities than the full spectrum of the STLSoft supported compilers. Given (1) and (2), therefore, it doesn’t seem worth the effort.

Only a limited set of invariants are appropriate for static assertions. Remember that only things that the compiler knows can be subject to a static assertion. Examples are sizes of types, member ordering, etc. Axiomatically, anything remotely runtime cannot be subject to static assertion.


Back to Top

FAQ: 22

I want to write portable code that will run on *NIX and Win32. Should I just use WIN32_LEAN_AND_MEAN to conditionally include the correct headers?

That’s wrong. WIN32_LEAN_AND_MEAN is a user-definable symbol that is by-no-means guaranteed to be there. Check for WIN32 and/or _WIN32: For example

#if defined(WIN32) || defined(_WIN32)
    // Win32-specific code here
#else
   // Other (*NIX)-specfic code here
#endif /* platform */

Back to Top

FAQ: 23

I am getting internal compiler errors using Visual C++ 5 & 6 from STLSoft classes, why?

For these two compilers we’ve learned that with STLSoft, and many other template components, much of the crashing is caused by the “Enable minimal Rebuild” option (/Gm). If you turn this off, many of the Internal Compiler Errors go away.