Boost C++ Libraries Home Libraries People FAQ More

Next

Chapter 1. The Cxx Dual Library

Edward Diener

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Table of Contents

Introduction
Terminology
Mods
Basic Functionality
Advanced Functionality
Low-level inclusion
Overriding the default choosing algorithm
Consistency
Using in a library
Use in a header only library
Use in a non-header only library
Support for naming library variants and testing all valid possibilities
Preprocessing errors
Build support
Boost Build
General build support
Header files
Tests
Dual library knowledge and concerns
Design Rationale
History
Acknowledgements
Reference
Header <boost/cxx_dual/impl/array.hpp>
Header <boost/cxx_dual/impl/atomic.hpp>
Header <boost/cxx_dual/impl/bind.hpp>
Header <boost/cxx_dual/impl/chrono.hpp>
Header <boost/cxx_dual/impl/condition_variable.hpp>
Header <boost/cxx_dual/impl/cxx_mods.hpp>
Header <boost/cxx_dual/impl/enable_shared_from_this.hpp>
Header <boost/cxx_dual/impl/function.hpp>
Header <boost/cxx_dual/impl/hash.hpp>
Header <boost/cxx_dual/impl/make_shared.hpp>
Header <boost/cxx_dual/impl/mem_fn.hpp>
Header <boost/cxx_dual/impl/move.hpp>
Header <boost/cxx_dual/impl/mutex.hpp>
Header <boost/cxx_dual/impl/random.hpp>
Header <boost/cxx_dual/impl/ratio.hpp>
Header <boost/cxx_dual/impl/ref.hpp>
Header <boost/cxx_dual/impl/regex.hpp>
Header <boost/cxx_dual/impl/shared_mutex.hpp>
Header <boost/cxx_dual/impl/shared_ptr.hpp>
Header <boost/cxx_dual/impl/system_error.hpp>
Header <boost/cxx_dual/impl/thread.hpp>
Header <boost/cxx_dual/impl/tuple.hpp>
Header <boost/cxx_dual/impl/type_index.hpp>
Header <boost/cxx_dual/impl/type_traits.hpp>
Header <boost/cxx_dual/impl/unordered_map.hpp>
Header <boost/cxx_dual/impl/unordered_multimap.hpp>
Header <boost/cxx_dual/impl/unordered_multiset.hpp>
Header <boost/cxx_dual/impl/unordered_set.hpp>
Header <boost/cxx_dual/impl/weak_ptr.hpp>
Header <boost/cxx_dual/library_name.hpp>
Header <boost/cxx_dual/valid_variants.hpp>
Index

The Cxx Dual library, or CXXD for short, is a macro library which chooses between using a Boost library or its C++ standard equivalent library for a number of different C++ implementations, while allowing the end-user to use the same code to program either choice. An implementation is a Boost library which has a C++ standard library equivalent whose public interfaces are nearly the same in both cases. An 'implementation' is called a 'mod' for short and each of the possible Boost or C++ standard implementations for that mod are called a 'dual library'.

The library does this by:

  • Automatically choosing either the Boost library or the C++ standard library for a particular mod based on compile-time preprocessor macros in Boost Config. If the C++ standard library is available, as indicated by the relevant Boost Config macro, it is chosen, else the Boost library is chosen.
  • Including the correct header file(s) needed for the dual library chosen.
  • Creating a namespace alias for the namespace of the dual library chosen.

All of this is done on a per-mod basis when a header file representing that mod is included by the end-user in his code. Any single mod is completely separated from all other mods, so that the use of each mod is self-contained and does not involve the use of anything else in the CXXD library.

The CXXD library also provides:

  • A macro-based solution for distinguishing between the Boost version and the C++ standard version of a dual library so that specific code for a particular dual library choice may be written in those cases where the public interfaces diverge.
  • A macro-based solution for overriding the default algorithm by which CXXD chooses between the Boost version and the C++ standard version of a dual library.

Basic example using CXXD

Let us say that the end-user wishes to use the C++ regex mod functionality in his code in order to create a regular expression object and use it to find data in a string based on that regular expression.

If the end-user had chosen to use the Boost regex library his code could be:

#include <boost/regex.hpp>

void SomeFunction()
    {
    boost::regex re("A regular expression etc.");
    bool result(boost::regex_match("Some string...",re));
    // etc.
    }

If the end-user had chosen to use the C++ standard library his code could be:

#include <regex>

void SomeFunction()
    {
    std:regex re("A regular expression etc.");
    bool result(std::regex_match("Some string...",re));
    // etc.
    }

However the end-user's goal is that if the C++ standard library regex implementation is available he wants to use that, otherwise he wants to use the Boost regex implementation. Most importantly he wants to use the exact same code to achieve his goals no matter which implementation he uses. To do that he uses CXXD. Using CXXD we use the regex mod and we could code:

#include <boost/cxx_dual/regex.hpp>

void SomeFunction()
    {
    cxxd_regex_ns::regex re("A regular expression etc.");
    bool result(cxxd_regex_ns::regex_match("Some string...",re));
    // etc.
    }

The header file representing the regex mod is included. This includes whatever header files are needed by the regex library chosen. Afterwards regex namespace alias is used to program with whichever regex dual library is chosen.

This is all one has to do to use the CXXD library in its most basic mode. Despite the fact that CXXD is a macro library, and many programmers are distrustful and afraid to use macros, the vast majority of actual user code when using CXXD does not use CXXD macros at all.

CXXD mods

There are currently 28 different mods in CXXD and each mod has its own header file to be included in order to use that mod in your code, and each has its own namespace alias to be used.

This basic use of CXXD is very simple, yet it provides the ability to program using any of the 28 different mods supported in a way such that the choice of which dual library is actually used for a particular mod is automatically made by CXXD.

Who the library is for

The CXXD library is for any programmer who wants to let CXXD decide whether to use the C++ standard library or the Boost library version of a mod at compile time, and who wants to write a single set of code for either library.

On a more practical basis the CXXD library is for:

  1. Programmers writing code not using C++11 syntax who still want to target some C++11 libraries if the code is compiled in C++11 mode.
  2. Programmers writing code using C++11 syntax who still want the option of targeting some Boost libraries if the equivalent C++11 library does not exist for a given implementation.

Current CXXD alternatives

Popular alternative choices in programmers's code are:

  • Use the Boost library of a mod since it is always available.
  • Use the C++ standard library of a mod for code written using C++11, and fail to compile if the library is not available.
  • Write separate code using the C++ standard library of a mod if it is available, otherwise using the Boost of a mod.

The first choice is easily the most popular since Boost library developers, and those involved using any one of the approximately current 130+ Boost libraries, assume that a Boost distribution is always available for the programmer to use. What are the possible negatives in the first choice ?

  • Some programmers, programming groups, businesses and large corporation employing programmers, do not like the idea of having to rely on the Boost distribution as a whole while feeling it is fine to rely on certain individual Boost libraries. This is not a reflection on Boost libraries themselves but more a reflection of the current monolithic structure of the Boost distribution.
  • Many programmers would like to use the C++ standard libraries when available with their compiler implementation rather than have a dependency in their code on the equivalent Boost library.
  • Programmers may be already using a C++ standard library in their code and do not want to have to therefore use the Boost library equivalent for a particular library interface.

The second choice, always using the C++ standard equivalent library, will occur less often because of its most obvious negative; if the C++ standard library is not available for a particular compiler implementation and C++ standard compiler level, the code will fail to compile. If however you write a library for a particular level of the C++ standard, such as C++11, and assume a strong implementation of that standard is needed by certain compilers which can compile your code, this is often your most viable choice.

The third choice, supporting both the Boost version of a library and the equivalent C++ standard version of that library, is obviously programmable but entails a much greater amount of work. Each usage of a mod will entail writing code that supports both libraries and this will require a great deal of extra code. Furthermore your code will be filled with uses of preprocessor #if statements to delineate which usage of a mod would be available at any given time.

All these choices are understandable. The CXXD library offers another choice and the purpose of the library is to provide that other choice to programmers who see it as a viable one.

CXXD basic mode

Using CXXD in its basic mode has been briefly illustrated above. There are more areas of basic mode that will be explored, though those areas are more rarely used. But before I go on to explore those areas, and to list the mods supported by CXXD, I want to give some terminology that will be used in this documentation in the next section.

Last revised: October 29, 2016 at 15:55:46 GMT


Next