diff --git a/index.htm b/index.htm index 71367b1..4314c81 100644 --- a/index.htm +++ b/index.htm @@ -1,97 +1,125 @@
- - + +![]() |
- Home | -Libraries | -People | -FAQ | -More | -
![]() |
+ Home | +Libraries | +People | +FAQ | +More | +
--Mailing List Discussion Policy. - What's acceptable and what isn't.
-Library Requirements and Guidelines. - Basic standards for those preparing a submission.
-Test Policy and Protocols. How - testing works at Boost.
-Library Submission Process. - How to submit a library to Boost.
-Library Formal Review Process. - Including how to submit a review comment.
-Header Policy. Headers are where a - library contacts its users, so programming practices are particularly - important.
-Implementation Variations. - Sometimes one size fits all, sometimes it doesn't. This page deals with - the trade-offs.
-Library Reuse. Should Boost - libraries use other boost libraries? What about the C++ Standard - Library? It's another trade-off.
+Mailing List Discussion + Policy. What's acceptable and what isn't.
+Library Requirements and + Guidelines. Basic standards for those preparing + a submission.
+Test Policy and Protocols. + How testing works at Boost.
+Library Submission + Process. How to submit a library to Boost.
+Library Formal + Review Process. Including how to submit a review + comment.
+Header Policy. + Headers are where a library contacts its users, so + programming practices are particularly important.
+Implementation Variations. + Sometimes one size fits all, sometimes it doesn't. This + page deals with the trade-offs.
+Library Reuse. + Should Boost libraries use other boost libraries? What + about the C++ Standard Library? It's another trade-off.
-+Compiler Status - Describes what -library works with which compiler.
-Internal Regression Test Suite - Describes the tool for generating the compiler status tables -
Header Dependencies -Describes what -other headers each boost header includes.
+Compiler + Status Describes what library works with + which compiler.
+Internal Regression Test + Suite Describes the tool for generating + the compiler status tables
+Header Dependencies + Describes what other headers each boost header includes.
- -+Error and Exception Handling - describes approaches to errors and exceptions by David Abrahams. - -
Counted Body Techniques by Kevlin - Henney is must reading for those interested in reference counting, a - widely used object management idiom. Originally published in Overload - magazine.
- -Generic Programming - Techniques by David Abrahams - and Jeremy Siekdescribe some of the - techniques used in Boost libraries.
- -Feature Model Diagrams in text and - HTML describes how to represent feature model diagrams in text form.
- -Portability Hints: Borland C++ 5.5.1 - describes Borland C++ portability issues, with suggested workarounds.
- -Portability Hints: Microsoft VC++ 6.0 SP4 - describes Microsoft C++ portability issues, with suggested workarounds.
- +Error and Exception + Handling describes approaches to errors and + exceptions by David + Abrahams.
+Counted Body Techniques + by Kevlin Henney is + must reading for those interested in reference counting, a + widely used object management idiom. Originally + published in Overload + magazine.
+Generic Programming + Techniques by David + Abrahams and Jeremy + Siekdescribe some of the techniques used in Boost + libraries.
+Feature Model + Diagrams in text and HTML describes how to represent + feature model diagrams in text form.
+Portability Hints: Borland C++ + 5.5.1 describes Borland C++ portability issues, with + suggested workarounds.
+Portability Hints: + Microsoft VC++ 6.0 SP4 describes Microsoft C++ + portability issues, with suggested workarounds.
+Coding + Guidelines for Integral Constant Expressions + describes how to work through the maze of compiler related + bugs surrounding this tricky topic.
--The C++ Standard (ISO/IEC 14882) is available online as a PDF file from the - ANSI (American National Standards Institute) - Electronic Standards Store. The price is $US 18.00. The document is - certainly not a tutorial, but is interesting to those who care about the - precise specification of the language and the standard library.
+The C++ Standard (ISO/IEC 14882) is available online as a + PDF file from the ANSI (American + National Standards Institute) Electronic Standards Store. + The price is $US 18.00. The document is certainly not a + tutorial, but is interesting to those who care about the + precise specification of the language and the standard + library.
+ +
+
Revised 12 February, 2001
+Revised 17 April, 2001
- diff --git a/integral_constant_guidelines.htm b/integral_constant_guidelines.htm new file mode 100644 index 0000000..a0e7d49 --- /dev/null +++ b/integral_constant_guidelines.htm @@ -0,0 +1,323 @@ + + + + + + +Integral Constant Expressions are used in many places in C++; +as array bounds, as bit-field lengths, as enumerator +initialisers, and as arguments to non-type template parameters. +However many compilers have problems handling integral constant +expressions; as a result of this, programming using non-type +template parameters in particular can be fraught with difficulty, +often leading to the incorrect assumption that non-type template +parameters are unsupported by a particular compiler. This short +article is designed to provide a set of guidelines and +workarounds that, if followed, will allow integral constant +expressions to be used in a manner portable to all the compilers +currently supported by boost. Although this article is mainly +targeted at boost library authors, it may also be useful for +users who want to understand why boost code is written in a +particular way, or who want to write portable code themselves.
+ +Integral constant expressions are described in section 5.19 of +the standard, and are sometimes referred to as "compile time +constants". An integral constant expression can be one of +the following:
+ +
+
const int my_INTEGRAL_CONSTANT = 3;
struct myclass
+ { static const int value = 0; };
struct myclass
+ { enum{ value = 0 }; };
sizeof
expression, for
+ example:sizeof(foo(a, b, c))
static_cast
, where the
+ target type is an integral or enumerator type, and the
+ argument is either another integral constant expression,
+ or a floating-point literal.INTEGRAL_CONSTANT1 op INTEGRAL_CONSTANT2
+ p
rovided that the operator is not an assignment
+ operator, or comma operator.op INTEGRAL_CONSTANT1
+
provided that the operator is not the increment or
+ decrement operator.+ +
The following guidelines are declared in no particular order (in +other words you need to obey all of them - sorry!), and may also +be incomplete, more guidelines may be added as compilers change +and/or more problems are encountered.
+ +When declaring constants that are class members always +use the macro BOOST_STATIC_CONSTANT.
+ +template <class T> +struct myclass +{ + BOOST_STATIC_CONSTANT(int, value = sizeof(T)); +};+ +
Rationale: not all compilers support inline initialisation of +member constants, others treat member enumerators in strange ways +(they're not always treated as integral constant expressions). +The BOOST_STATIC_CONSTANT macro uses the most appropriate method +for the compiler in question.
+ +Don't declare integral constant expressions whose type +is wider than int.
+ +Rationale: while in theory all integral types are usable in +integral constant expressions, in practice many compilers limit +integral constant expressions to types no wider than int.
+ +Don't use logical operators in integral constant +expressions; use template meta-programming instead.
+ +The header <boost/type_traits/ice.hpp> contains a number +of workaround templates, that fulfil the role of logical +operators, for example instead of:
+ +INTEGRAL_CONSTANT1 | INTEGRAL_CONSTANT2
Use:
+ +::boost::type_traits::ice_or<INTEGRAL_CONSTANT1,INTEGRAL_CONSTANT2>::value
Rationale: A number of compilers (particularly the Borland and +Microsoft compilers), tend to not to recognise integral constant +expressions involving logical operators as genuine integral +constant expressions. The problem generally only shows up when +the integral constant expression is nested deep inside template +code, and is hard to reproduce and diagnose.
+ +Don't use any operators in an integral constant +expression used as a non-type template parameter
+ +Rather than:
+ +typedef myclass<INTEGRAL_CONSTANT1 ==
+INTEGRAL_CONSTANT2> mytypedef;
Use:
+ +typedef myclass< some_symbol> mytypedef;
Where some_symbol
is the symbolic name of a an
+integral constant expression whose value is (INTEGRAL_CONSTANT1
+== INTEGRAL_CONSTANT2).
Rationale: the older EDG based compilers (some of which are +used in the most recent version of that platform's compiler), +don't recognise expressions containing operators as non-type +template parameters, even though such expressions can be used as +integral constant expressions elsewhere.
+ +Always use a fully qualified name to refer to an +integral constant expression.
+ +For example:
+ +typedef
myclass< ::boost::is_integral<some_type>::value> mytypedef;
+
+Rationale: at least one compiler (Borland's), doesn't +recognise the name of a constant as an integral constant +expression unless the name is fully qualified (which is to say it +starts with ::).
+ +Always leave a space after a '<' and before '::'
+ +For example:
+ +typedef
myclass< ::boost::is_integral<some_type>::value> mytypedef;
+ ^
+ ensure there is space here!
+
+Rationale: <: is a legal digraph in it's own right, so <:: +is interpreted as the same as [:.
+ +Don't use local names as integral constant expressions
+ +Example:
+ +template <class T> +struct foobar +{ + BOOST_STATIC_CONSTANT(int, temp = computed_value); + typedef myclass<temp> mytypedef; // error +};+ +
Rationale: At least one compiler (Borland's) doesn't accept +this.
+ +Although it is possible to fix this by using:
+ +template <class T> +struct foobar +{ + BOOST_STATIC_CONSTANT(int, temp = computed_value); + typedef foobar self_type; + typedef myclass<(self_type::temp)> mytypedef; // OK +};+ +
This breaks at least one other compiler (VC6), it is better to +move the integral constant expression computation out into a +separate traits class:
+ +template <class T> +struct foobar_helper +{ + BOOST_STATIC_CONSTANT(int, temp = computed_value); +}; + +template <class T> +struct foobar +{ + typedef myclass< ::foobar_helper<T>::value> mytypedef; // OK +};+ +
Don't use dependent default parameters for non-type +template parameters.
+ +For example:
+ +template <class T, int I = ::boost::is_integral<T>::value> // Error can't deduce value of I in some cases. +struct foobar;+ +
Rationale: this kind of usage fails for Borland C++. Note that +this is only an issue where the default value is dependent upon a +previous template parameter, for example the following is fine:
+ +template <class T, int I = 3> // OK, default value is not dependent +struct foobar;+ +
+ +
The following issues are either unresolved or have fixes that +are compiler specific, and/or break one or more of the coding +guidelines.
+ +Be careful of numeric_limits
+ +There are three issues here:
+ +template <class T> +struct limits_test +{ + BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized); +};+ +
This code fails to compile with VC6 even though no instances
+of the template are ever created; for some bizarre reason ::std::numeric_limits<T>::is_specialized
+
always evaluates to false, irrespective of what the
+template parameter T is. The problem seems to be confined to
+expressions which depend on std::numeric_limts: for example if
+you replace ::std::numeric_limits<T>::is_specialized
+with ::boost::is_arithmetic<T>::value
, then
+everything is fine. The following workaround also works but
+conflicts with the coding guidelines:
template <class T> +struct limits_test +{ + BOOST_STATIC_CONSTANT(bool, check = ::std::numeric_limits<T>::is_specialized); + BOOST_STATIC_ASSERT(check); +};+ +
So it is probably best to resort to something like this:
+ +template <class T> +struct limits_test +{ +#ifdef BOOST_MSVC + BOOST_STATIC_CONSTANT(bool, check = ::std::numeric_limits<T>::is_specialized); + BOOST_STATIC_ASSERT(check); +#else + BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized); +#endif +};+ +
Be careful how you use the sizeof operator
+ +As far as I can tell, all compilers treat sizeof expressions +correctly when the argument is the name of a type (or a template-id), +however problems can occur if:
+ +Don't use boost::is_convertible unless you have to
+ +Since is_convertible is implemented in terms of the sizeof +operator, it consistently gives the wrong value when used with +the Metroworks compiler, and may not compile with the Borland's +compiler (depending upon the template arguments used).
+ +Copyright Dr John Maddock 2001, all rights reserved.
+ ++ +
+ +