Doc. no. J16/04-0015=WG21/N1575
Date: 10 February 2004
Project: Programming Language C++
Reply to: Beman Dawes <bdawes@acm.org>
Motivation
Requirements and Objectives
Design Rationale
Granularity of macros
Transition between the TR and future standards
Names
Proposed additions to the TR
Revision History
Because the Library Technical Report (TR) is non-normative, implementers are permitted to ship partial implementations or to not implement the TR at all. At least one vendor has already begun shipping a partial implementation.
Users wishing to write portable programs that use TR components must therefore determine which TR components are actually available.
For example, several Boost libraries already use a component availability macro (BOOST_HAS_HASH) to determine if a non-standard hash map is available. If present, they use hash maps to speed execution, but otherwise rely on std::map.
Similarly, users of the TR may wish to code something like this:
# include <climits> # ifdef __TR19768_UNORDERED__ # include <unordered_map> # else # include <map> # endif
(For brevity, the example above ignores namespace and other naming issues.)
Such usage is portable if the header and component macro are specified as part of the Library TR. If not specified by the TR, then users are forced to develop their own configuration mechanisms to determine TR component availability. This would be a burden for users wishing to write portable code.
A second use case might occur when user code requires TR components, and wishes to issue an explicit error message when they are not present:
# include <climits> # ifndef __TR19768_UNORDERED__ # error Standard Library Technical Report 19768 <unordered_map> header required # endif
Note: This proposal does not deal with the question of how users request
that std::tr1
components be made available by an implementation. That is an
orthogonal issue, and is already dealt with in the TR working paper.
To provide a useful level of functionality to users without unduly burdening implementers, a design needs to consider the following as at least objectives if not downright requirements:
Much of the design is driven by the Requirements and Objectives.
The <limits> header is chosen as the location of the macros since it best meets requirements (2), (5). Requirement (5) implies the macros are defined in existing headers, so a new header can't be used.
The proposed granularity is based on intuition rather than any hard-and-fast rule. If the granularity is too fine, implementations will diverge through honest confusion, and the names will be hard to remember. If the granularity is too coarse, there will be a mismatch between what components some implementers will wish to actually deliver and what components the macros identify.
Pete Becker expressed concern over the fine granularity of the macros in c++std-lib-12274. Discussion followed.
Given that implementers are already shipping partial implementations of the TR, I continue to propose macros with some granularity. I'm not adverse to reducing the granularity somewhat, but I feel it greatly benefits users to have some granularity. Three options are provided so that LWG members have a choice of granularity.
Several LWG members expressed concern over the transition between the TR and future standards.
Notes have been added to the proposal to make it clear to users that in
the transition from the TR to future standards, the TR components will not
remain in namespace std::tr1
and the configuration macros will
disappear.
Choose one of the following options:
After [tr.intro.namespaces] add:
[Note: Should any components specified by this technical report become part of a future version of the C++ standard, they will be placed in a namespace other than
std::tr1
. --end note]
After [tr.intro] add:
If and only if all of the components specified by this technical report are supplied by the implementation, the header <climits> shall define the macro __TR19768__. No other header supplied by the implementation shall cause macro __TR19768__ to be defined.
[Note: The macro __TR19768__ will not be defined by future versions of the C++ Standard Library. Future versions of the C++ Standard can be identified by the value of the predefined macro
__cplusplus
. --end note]
After [tr.intro.namespaces] add:
[Note: Should any components specified by this technical report become part of a future version of the C++ standard, they will be placed in a namespace other than
std::tr1
. --end note]
After [tr.intro] add:
If and only if all of the components specified by this technical report are supplied by the implementation, the header <climits> shall define the macro __TR19768__. If and only if a header supplies all of the components specified in this technical report for that header, it shall define macro __TR19768__. No other header supplied by the implementation shall cause macro __TR19768__ to be defined.
[Note: The macro __TR19768__ will not be defined by future versions of the C++ Standard Library. Future versions of the C++ Standard can be identified by the value of the predefined macro
__cplusplus
. --end note]
After [tr.intro.namespaces] add:
[Note: Should any components specified by this technical report become part of a future version of the C++ standard, they will be placed in a namespace other than
std::tr1
. --end note]
After [tr.intro] add:
The availability of components described in this technical report are reported by the presence of the macros described in the Component Availability Macros Table. Each macro shall be defined if and only if the entire component it identifies is available. Each macro definition shall appear in the <climits> header and in all other headers specified by this technical report as containing any part of the component that it identifies. No other header supplied by the implementation shall cause any of these macros to be defined.
[Note: These macros will not be defined by future versions of the C++ Standard Library. Future versions of the C++ Standard can be identified by the value of the predefined macro
__cplusplus
. --end note]Component Availability Macros Table
Macro Component __TR19768__
All. [note - not defined unless all TR19768 components are available. - end note] __TR19768_UTILITY__
Reference wrappers ([tr.util.refwrp.synopsis]) __TR19768_MEMORY__
Smart Pointers ([tr.util.smartptr]) __TR19768_FUNCTIONAL__
Function objects and higher-order programming. ([tr.func]) __TR19768_TYPE_TRAITS__
Metaprogramming and type traits ([tr.meta]) __TR19768_RANDOM__
Random number generation ([tr.rand]) __TR19768_MATH__
Mathematical special functions ([tr.num.sf]) __TR19768_TUPLE__
Tuple types ([tr.tuple]) __TR19768_UNORDERED__
Unordered associative containers ([tr.hash]) [note - also defined in <functional>. - end note] __TR19768_REGEX__
Regular expressions ([tr.re]) __TR19768_ARRAY__
Fixed size array wrapper ([TBD]) __TR19768_ITERATOR__
Iterator concepts, facades, and adaptors ([TBD]) __TR19768_C99__
C99 library ([TBD])
N1558 - Initial version
N1575 - Revision 1
© Copyright Beman Dawes, 2003.
Revised 11 February, 2004