forked from OSchip/llvm-project
119 lines
3.8 KiB
ReStructuredText
119 lines
3.8 KiB
ReStructuredText
|
=======================
|
||
|
Extended C++03 Support
|
||
|
=======================
|
||
|
|
||
|
.. contents::
|
||
|
:local:
|
||
|
|
||
|
Overview
|
||
|
========
|
||
|
|
||
|
libc++ is an implementation of the C++ standard library targeting C++11 or later.
|
||
|
|
||
|
In C++03, the library implements the C++11 standard using C++11 language extensions provided
|
||
|
by Clang.
|
||
|
|
||
|
This document tracks the C++11 extensions libc++ requires, the C++11 extensions it provides,
|
||
|
and how to write minimal C++11 inside libc++.
|
||
|
|
||
|
Required C++11 Compiler Extensions
|
||
|
==================================
|
||
|
|
||
|
Clang provides a large subset of C++11 in C++03 as an extension. The features
|
||
|
libc++ expects Clang to provide are:
|
||
|
|
||
|
* Variadic templates.
|
||
|
* RValue references and perfect forwarding.
|
||
|
* Alias templates
|
||
|
* defaulted and deleted Functions.
|
||
|
* reference qualified Functions
|
||
|
|
||
|
There are also features that Clang *does not* provide as an extension in C++03
|
||
|
mode. These include:
|
||
|
|
||
|
* ``constexpr`` and ``noexcept``
|
||
|
* ``auto``
|
||
|
* Trailing return types.
|
||
|
* ``>>`` without a space.
|
||
|
|
||
|
|
||
|
Provided C++11 Library Extensions
|
||
|
=================================
|
||
|
|
||
|
.. warning::
|
||
|
The C++11 extensions libc++ provides in C++03 are currently undergoing change. Existing extensions
|
||
|
may be removed in the future. New users are strongly discouraged depending on these extension
|
||
|
in new code.
|
||
|
|
||
|
This section will be updated once the libc++ developer community has further discussed the
|
||
|
future of C++03 with libc++.
|
||
|
|
||
|
|
||
|
Using Minimal C++11 in libc++
|
||
|
=============================
|
||
|
|
||
|
This section is for developers submitting patches to libc++. It describes idioms that should be
|
||
|
used in libc++ code, even in C++03, and the reasons behind them.
|
||
|
|
||
|
|
||
|
Use Alias Templates over Class Templates
|
||
|
----------------------------------------
|
||
|
|
||
|
Alias templates should be used instead of class templates in metaprogramming. Unlike class templates,
|
||
|
Alias templates do not produce a new instantiation every time they are used. This significantly
|
||
|
decreases the amount of memory used by the compiler.
|
||
|
|
||
|
For example, libc++ should not use ``add_const`` internally. Instead it should use an alias template
|
||
|
like
|
||
|
|
||
|
.. code-block:: cpp
|
||
|
|
||
|
template <class _Tp>
|
||
|
using _AddConst = const _Tp;
|
||
|
|
||
|
Use Default Template Parameters for SFINAE
|
||
|
------------------------------------------
|
||
|
|
||
|
There are three places in a function declaration that SFINAE may occur: In the template parameter list,
|
||
|
in the function parameter list, and in the return type. For example:
|
||
|
|
||
|
.. code-block:: cpp
|
||
|
|
||
|
template <class _Tp, class _ = enable_if_t</*...*/ >
|
||
|
void foo(_Tp); // #1
|
||
|
|
||
|
template <class _Tp>
|
||
|
void bar(_Tp, enable_if_t</*...*/>* = nullptr); // # 2
|
||
|
|
||
|
template <class _Tp>
|
||
|
enable_if_t</*...*/> baz(_Tp); // # 3
|
||
|
|
||
|
Using default template parameters for SFINAE (#1) should always be prefered.
|
||
|
|
||
|
Option #2 has two problems. First, users can observe and accidentally pass values to the SFINAE
|
||
|
function argument. Second, the default arguement creates a live variable, which causes debug
|
||
|
information to be emitted containing the text of the SFINAE.
|
||
|
|
||
|
Option #3 can also cause more debug information to be emitted than is needed, because the function
|
||
|
return type will appear in the debug information.
|
||
|
|
||
|
Use ``unique_ptr`` when allocating memory
|
||
|
------------------------------------------
|
||
|
|
||
|
The standard library often needs to allocate memory and then construct a user type in it.
|
||
|
If the users constructor throws, the library needs to deallocate that memory. The idiomatic way to
|
||
|
achieve this is with ``unique_ptr``.
|
||
|
|
||
|
``__builtin_new_allocator`` is an example of this idiom. Example usage would look like:
|
||
|
|
||
|
.. code-block:: cpp
|
||
|
|
||
|
template <class T>
|
||
|
T* __create() {
|
||
|
using _UniquePtr = unique_ptr<void*, __default_new_allocator::__default_new_deleter>;
|
||
|
_UniquePtr __p = __default_new_allocator::__allocate_bytes(sizeof(T), alignof(T));
|
||
|
T* __res = ::new(__p.get()) T();
|
||
|
(void)__p.release();
|
||
|
return __res;
|
||
|
}
|