Eric Fiselier | d011bdc | 2019-06-11 22:53:49 +0000 | [diff] [blame] | 1 | ======================= |
| 2 | Extended C++03 Support |
| 3 | ======================= |
| 4 | |
| 5 | .. contents:: |
| 6 | :local: |
| 7 | |
| 8 | Overview |
| 9 | ======== |
| 10 | |
| 11 | libc++ is an implementation of the C++ standard library targeting C++11 or later. |
| 12 | |
| 13 | In C++03, the library implements the C++11 standard using C++11 language extensions provided |
| 14 | by Clang. |
| 15 | |
| 16 | This document tracks the C++11 extensions libc++ requires, the C++11 extensions it provides, |
| 17 | and how to write minimal C++11 inside libc++. |
| 18 | |
| 19 | Required C++11 Compiler Extensions |
| 20 | ================================== |
| 21 | |
| 22 | Clang provides a large subset of C++11 in C++03 as an extension. The features |
| 23 | libc++ expects Clang to provide are: |
| 24 | |
| 25 | * Variadic templates. |
| 26 | * RValue references and perfect forwarding. |
| 27 | * Alias templates |
| 28 | * defaulted and deleted Functions. |
| 29 | * reference qualified Functions |
| 30 | |
| 31 | There are also features that Clang *does not* provide as an extension in C++03 |
| 32 | mode. These include: |
| 33 | |
| 34 | * ``constexpr`` and ``noexcept`` |
| 35 | * ``auto`` |
| 36 | * Trailing return types. |
| 37 | * ``>>`` without a space. |
| 38 | |
| 39 | |
| 40 | Provided C++11 Library Extensions |
| 41 | ================================= |
| 42 | |
| 43 | .. warning:: |
| 44 | The C++11 extensions libc++ provides in C++03 are currently undergoing change. Existing extensions |
| 45 | may be removed in the future. New users are strongly discouraged depending on these extension |
| 46 | in new code. |
| 47 | |
| 48 | This section will be updated once the libc++ developer community has further discussed the |
| 49 | future of C++03 with libc++. |
| 50 | |
| 51 | |
| 52 | Using Minimal C++11 in libc++ |
| 53 | ============================= |
| 54 | |
| 55 | This section is for developers submitting patches to libc++. It describes idioms that should be |
| 56 | used in libc++ code, even in C++03, and the reasons behind them. |
| 57 | |
| 58 | |
| 59 | Use Alias Templates over Class Templates |
| 60 | ---------------------------------------- |
| 61 | |
| 62 | Alias templates should be used instead of class templates in metaprogramming. Unlike class templates, |
| 63 | Alias templates do not produce a new instantiation every time they are used. This significantly |
| 64 | decreases the amount of memory used by the compiler. |
| 65 | |
| 66 | For example, libc++ should not use ``add_const`` internally. Instead it should use an alias template |
| 67 | like |
| 68 | |
| 69 | .. code-block:: cpp |
| 70 | |
| 71 | template <class _Tp> |
| 72 | using _AddConst = const _Tp; |
| 73 | |
| 74 | Use Default Template Parameters for SFINAE |
| 75 | ------------------------------------------ |
| 76 | |
| 77 | There are three places in a function declaration that SFINAE may occur: In the template parameter list, |
| 78 | in the function parameter list, and in the return type. For example: |
| 79 | |
| 80 | .. code-block:: cpp |
| 81 | |
| 82 | template <class _Tp, class _ = enable_if_t</*...*/ > |
| 83 | void foo(_Tp); // #1 |
| 84 | |
| 85 | template <class _Tp> |
| 86 | void bar(_Tp, enable_if_t</*...*/>* = nullptr); // # 2 |
| 87 | |
| 88 | template <class _Tp> |
| 89 | enable_if_t</*...*/> baz(_Tp); // # 3 |
| 90 | |
| 91 | Using default template parameters for SFINAE (#1) should always be prefered. |
| 92 | |
| 93 | Option #2 has two problems. First, users can observe and accidentally pass values to the SFINAE |
| 94 | function argument. Second, the default arguement creates a live variable, which causes debug |
| 95 | information to be emitted containing the text of the SFINAE. |
| 96 | |
| 97 | Option #3 can also cause more debug information to be emitted than is needed, because the function |
| 98 | return type will appear in the debug information. |
| 99 | |
| 100 | Use ``unique_ptr`` when allocating memory |
| 101 | ------------------------------------------ |
| 102 | |
| 103 | The standard library often needs to allocate memory and then construct a user type in it. |
| 104 | If the users constructor throws, the library needs to deallocate that memory. The idiomatic way to |
| 105 | achieve this is with ``unique_ptr``. |
| 106 | |
| 107 | ``__builtin_new_allocator`` is an example of this idiom. Example usage would look like: |
| 108 | |
| 109 | .. code-block:: cpp |
| 110 | |
| 111 | template <class T> |
| 112 | T* __create() { |
| 113 | using _UniquePtr = unique_ptr<void*, __default_new_allocator::__default_new_deleter>; |
| 114 | _UniquePtr __p = __default_new_allocator::__allocate_bytes(sizeof(T), alignof(T)); |
| 115 | T* __res = ::new(__p.get()) T(); |
| 116 | (void)__p.release(); |
| 117 | return __res; |
| 118 | } |