...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
We know that a library like this one will be an eternal work-in-progress. And as such we expect, and look forward to, others contributing corrections and additions to the predefs. With that in mind we need to keep a consistent way of defining the new predefs. Hence all current, and future, predefs follow the same structure and requirements.
All predefs need to follow a set of requirements:
BOOST_VERSION_NUMBER(0,0,0)
.
BOOST_VERSION_NUMBER(0,0,1)
when the predef is detected.
*_AVAILABLE
macros.
And there are some extra guidelines that predef headers should follow:
For general consistency it's suggested that new predef headers follow the structure below, as current predef headers do. First we have the copyright and license statement, followed by the include guard:
/* Copyright Jane Doe YYYY 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) */ #ifndef BOOST_PREDEF_category_tag_H #define BOOST_PREDEF_category_tag_H
Depending on how you are defining the predef you will at minimum have to include
the version_number.h
header. But you might also want to include
the make.h
header for the version number decomposing
utility macros:
#include <boost/predef/version_number.h> #include <boost/predef/make.h>
The Predef library uses Quickbook for documentation and for the individual predefs to appear in the reference section we add in-code documentation followed by the zero-value default definition of the predef macro. We strongly recommend this particular placement of the documentation and default definition because some development environments automatically interpret this and provide in-line help for the macro. In particular this works for the popular Eclipse IDE:
/*` [heading `BOOST_category_tag`] Documentation about what is detected. */ #define BOOST_category_tag BOOST_VERSION_NUMBER(0,0,0)
Next is the detection and definition of the particular predef. The structure
for this is to do a single overall check (condition_a
)
and place further version detection inside this. The first action inside the
overall check is to "#undef
BOOST_category_tag
" which undefines
the zero-value default. The rest is up to the you how to do the checks for
defining the version. But at minimum it must "#define
BOOST_category_tag BOOST_VERSION_NUMBER(0,0,1)
" as the fallback to minimally indicate
that the predef was detected:
#if (condition_a) # undef BOOST_category_tag # if (condition_b) # define BOOST_category_tag BOOST_VERSION_NUMBER(major,minor,patch) # else # define BOOST_category_tag BOOST_VERSION_NUMBER(0,0,1) # endif #endif
We also need to provide the *_AVAILABLE
versions of the predef. And for
convenience we also want to provide a *_NAME
macro:
#if BOOST_category_tag # define BOOST_category_tag_AVAILABLE #endif #define BOOST_catagory_tag_NAME "Name"
The testing of the predef macros is automated to generate checks for all the defined predefs, whether detected or not. To do this we need to declare the predef to the test system. This declaration is empty for regular use. And during the test programs they expand out specially to create informational output:
#include <boost/predef/detail/test.h> BOOST_PREDEF_DECLARE_TEST(BOOST_category_tag,BOOST_category_tag_NAME)
And, of course, we last need to close out the include guard:
#endif
By including:
#include <boost/predef/make.h>
One will get a set of utility macros to decompose common version macros as defined by compilers. For example the EDG compiler uses a simple 3-digit version macro (M,N,P). It can be decomposed and defined as:
#define BOOST_CCOMP_EDG BOOST_PREDEF_MAKE_N_N_N(__EDG_VERSION__)
The decomposition macros are split into three types: decimal decomposition, hexadecimal decomposition, and date decomposition. They follow the format of using "N" for decimal, "F" for hexadecimal, and "Y", "M", "D" for dates.