...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Copyright © 2005, 2008-2016 Rene Rivera
Copyright © 2015 Charly Chevalier
Copyright © 2015 Joel Falcou
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
This library defines a set of compiler, architecture, operating system, library, and other version numbers from the information it can gather of C, C++, Objective C, and Objective C++ predefined macros or those defined in generally available headers. The idea for this library grew out of a proposal to extend the Boost Config library to provide more, and consistent, information than the feature definitions it supports. What follows is an edited version of that brief proposal.
The idea is to define a set of macros to identify compilers and consistently represent their version. This includes:
#if
/#elif
directives, for each of the supported
compilers. All macros would be defined, regardless of the compiler. The
one macro corresponding to the compiler being used would be defined, in
terms of BOOST_VERSION_NUMBER, to carry the exact compiler version. All
other macros would expand to an expression evaluating to false (for instance,
the token 0) to indicate that the corresponding compiler is not present.
The current Predef library is now, both an independent library, and expanded in scope. It includes detection and definition of architectures, compilers, languages, libraries, operating systems, and endianness. The key benefits are:
#ifdef
.
#ifdef
checks.
#include
<boost/predef.h>
so that it's friendly to precompiled header usage.
#include
<boost/predef/os/windows.h>
for single checks.
An important design choice concerns how to represent compiler versions by means
of a single integer number suitable for use in preprocessing directives. Let's
do some calculation. The "basic" signed type for preprocessing constant-expressions
is long in C90 (and C++, as of 2006) and intmax_t in C99. The type long shall
at least be able to represent the number +2 147 483 647
.
This means the most significant digit can only be 0, 1 or 2; and if we want
all decimal digits to be able to vary between 0 and 9, the largest range we
can consider is [0, 999 999 999]
. Distributing evenly, this
means 3 decimal digits for each version number part.
So we can:
It appears relatively safe to go for the first option and set it at 2/2/5. That covers CodeWarrior and others, which are up to and past 10 for the major number. Some compilers use the build number in lieu of the patch one; five digits (which is already reached by VC++ 8) seems a reasonable limit even in this case.
Note | |
---|---|
A 2/2/6 scheme would allow for bigger patch/build numbers at the cost, for instance, of limiting the major version number to 20 (or, with further constraints, to 21). |
It might reassure the reader that this decision is actually encoded in one
place in the code; the definition of BOOST_VERSION_NUMBER
.
Even though the basics of this library are done, there is much work that can be done:
BOOST_WORKAROUND
macro would benefit from a more readable syntax. As would the BOOST_TESTED_AT
detail macro.