Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Using the predefs

To use the automatically defined predefs one needs to only include the single top-level header:

#include <boost/predef.h>

This defines all the version macros known to the library. For each macro it will be defined to either a zero valued expression for when the particular item is not detected, and to a positive value if it is detected. The predef macros fall onto five categories each with macros of a particular prefix:

[Note] Note

The detected definitions are for the configuration one is targeting during the compile. In particular in a cross-compile this means the target system, and not the host system.

One uses the individual definitions to compare against specific versions by comparing against the BOOST_VERSION_NUMBER macro. For example, to make a choice based on the version of the GCC C++ compiler one would:

#include <boost/predef.h>
#include <iostream>

int main()
{
  if (BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4,0,0))
    std::cout << "GCC compiler is at least version 4.0.0" << std::endl;
  else
    std::cout << "GCC compiler is at older than version 4.0.0, or not a GCC compiler" << std::endl;
  return 0;
}

As you might notice above the else clause also covers the case where the particular compiler is not detected. But one can make the test also test for the detection. All predef definitions are defined as a zero (0) expression when not detected. Hence one could use the detection with a natural single condition. For example:

#include <boost/predef.h>
#include <iostream>

int main()
{
  if (BOOST_COMP_GNUC)
    std::cout << "This is GNU GCC!" << std::endl;
  else
    std::cout << "Not GNU GCC." << std::endl;
  return 0;
}

And since the predef's are preprocessor definitions the same is possible from the preprocessor:

#include <boost/predef.h>
#include <iostream>

#if BOOST_COMP_GNUC
  #if BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4,0,0)
    const char * the_compiler = "GNU GCC, of at least version 4."
  #else
    const char * the_compiler = "GNU GCC, less than version 4."
  #endif
#else
  const char * the_compiler = "Not GNU GCC."
#endif

int main()
{
  std::cout << the_compiler << std::endl;
  return 0;
}

In addition, for each version macro defined there is an *_AVAILABLE macro defined only when the particular aspect is detected. I.e. a definition equivalent to:

#if BOOST_PREDEF_ABC
  #define BOOST_PREDEF_ABC_AVAILABLE
#endif

Also for each aspect there is a macro defined with a descriptive name of what the detection is.

The *_EMULATED macros

Predef definitions are guaranteed to be uniquely detected within one category. But there are contexts under which multiple underlying detections are possible. The well known example of this is detection of GCC and MSVC compilers which are commonly emulated by other compilers by defining the same base macros. To account for this detection headers are allowed to define *_EMULATED predefs when this situation is detected. The emulated predefs will be set to the version number of the detection instead of the regular predef macro for that detection. For example MSVC will set BOOST_COMP_MSVC_EMULATED but not set BOOST_COM_MSVC, and it will also set BOOST_COMP_MSVC_AVAILABLE.

Using the BOOST_VERSION_NUMBER macro

All the predefs are defined to be a use of the BOOST_VERSION_NUMBER macro. The macro takes individual major, minor, and patch value expressions:

#define BOOST_VERSION_NUMBER( major, minor, patch ) ...

The arguments are:

  1. Major version number, as a constant value expression in the range [0,99].
  2. Minor version number, as a constant value expression in the range [0,99].
  3. Patch-level version number, as a constant value expression in the range [0,99999].

The ranges for each are "enforced" by the use of a modulo ("%"), i.e. truncation, as opposed to a clamp. And hence this means that the limits are enforced only enough to keep from having out-of-range problems. But not enough to prevent other kinds of problems. Like exceeding the range and getting false detections, or non-detections. It is up to the individual predefs to ensure correct usage beyond the range guarantee.

The values for the arguments can be any preprocessor valid constant value expression. Only constant value arithmetic is used in the definition of the BOOST_VERSION_NUMBER macro and in any of the other predef macros. This means that any allowed base is possible, i.e. binary, octal, decimal, and hexadecimal. For example:

#define MY_APPLICATION_VERSION_NUMBER BOOST_VERSION_NUMBER(2,0xA,015)

Is equivalent to:

#define MY_APPLICATION_VERSION_NUMBER BOOST_VERSION_NUMBER(2,10,13)

PrevUpHomeNext