Skip to content

BSL and STL

Oleg Subbotin edited this page Mar 12, 2018 · 9 revisions

BSL and STL

BSL's STL Compatibility and Interoperability

The bsl package group provides containers (and other facilities) that parallel many of those in the Standard Template Library (STL), providing a C++03-compatible interface except for the allocator semantics (which follow the scoped allocator model instead).

The 'bsl' package group provides implementations (in namespace bsl rather than std) for:

  • bitset
  • deque
  • list
  • map
  • unordered_map
  • unordered_set
  • set
  • stack
  • string
  • (i|o)stringstream
  • vector

Using these implementations is simple: for a given STL header <xyz>, just include <bsl_xyz.h> instead.

For example:

    #include <bsl_map.h>
    #include <bsl_string.h>
    #include <bslma_testallocator.h>
    #include <iostream>
    
    int main(int argc, char **argv)
    {
        typedef bsl::map<bsl::string, int> TStringCounts;
    
        // Create a test allocator to track how much memory our bsl::map and
        // bsl::string request when processing the given arguments.  Longer
        // arguments are expected to show a higher allocation count, since
        // bsl::string uses the *short-string optimization*, storing shorter
        // strings directly in the object's footprint to avoid unnecessary
        // allocations.  Note that bsl::map uses a pool internally, so the
        // resulting allocation count won't have a linear relationship with
        // the number of arguments.
        BloombergLP::bslma::TestAllocator testAlloc("supplied", 1);
    
        // Both the map and the contained bsl::string keys will allocate from the
        // supplied test allocator.
        TStringCounts argCounts(&testAlloc);
    
        for (int i = 1; i < argc; ++i) {
            argCounts[argv[i]]++;
        }
    
        for (TStringCounts::const_iterator i = argCounts.begin();
                     i != argCounts.end();
                     ++i) {
            std::cout << "Argument '"
                      << i->first
                      << "' occurs "
                      << i->second
                      << " time"
                      << (i->second>1?"s":"")
                      << std::endl;
        }
    
        return 0;
    }

You can also mix-and-match bsl containers with std containers, sometimes referred to as "Dual STL" mode:

    #include <bsl_map.h>
    #include <string>
    #include <bslma_testallocator.h>
    #include <iostream>
    
    int main(int argc, char **argv)
    {
        // Note that the keys are of type 'std::string', not 'bsl::string' - so
        // the map will not pass its allocator down to the string objects.
        typedef bsl::map<std::string, int> TStringCounts;
    
        // Create a test allocator to track how much memory our bsl::map requests
        // when processing the given arguments. Note that bsl::map uses a pool
        // internally, so the resulting allocation count won't have a linear
        // relationship with the number of arguments.
        BloombergLP::bslma::TestAllocator testAlloc("supplied", 1);
    
        // Only the map nodes will be allocated using the supplied test allocator.
        // Any internal allocations the std::string keys need to make will be made
        // from the platform STL's default allocator, and won't be reflected in the
        // 'testAlloc' statistics.
        TStringCounts argCounts(&testAlloc);
    
        for (int i = 1; i < argc; ++i) {
            argCounts[argv[i]]++;
        }
    
        for (TStringCounts::const_iterator i = argCounts.begin();
                     i != argCounts.end();
                     ++i) {
            std::cout << "Argument '"
                      << i->first
                      << "' occurs "
                      << i->second
                      << " time"
                      << (i->second>1?"s":"")
                      << std::endl;
        }
    
        return 0;
    }

Headers are also provided which "import" std components that aren't provided in BSL into namespace bsl. For example, one could

    #include <bsl_iostream.h>

and then refer to bsl::cout and bsl::endl, even though the bsl library doesn't implement iostreams.

BSL as an STL Replacement

We also support a legacy build mode where the bsl components are included via STL header names. If you define BSL_OVERRIDES_STD on your compilation command lines (in Unix, usually -DBSL_OVERRIDES_STD) and put the bsl+stdhdrs directory in front of your other include paths (in Unix, by putting -I(bde-location)/groups/bsl/bsl+stdhdrs early on your compilation command lines) then code which does the following:

    #include <vector>

    int main()
    {
        std::vector<int> v;
        // ...

is actually using bsl::vector.

This can be a good way to test whether you see performance gains for existing code with BDE's container and allocator implementations with minimal code changes, but it's not recommended for large projects, since you'll encounter problems with any pre-built libraries which expect std:: types to refer to the platform's built-in STL implementations.

This mode was mainly used here at Bloomberg to facilitate the adoption of bsl in existing Bloomberg C++ code bases.

The original standard library remains available via namespace native_std.

Questions, Comments, and Feedback

If you have questions, comments, suggestions for improvement or any other inquiries regarding BDE or this wiki, feel free to open an issue in the issue tracker.


Creative Commons License  BDE Wiki by Bloomberg Finance L.P. is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.