- Addressed reviewer comments. Hi revane, tareqsiraj, arielbernal,
http://llvm-reviews.chandlerc.com/D1740 CHANGE SINCE LAST DIFF http://llvm-reviews.chandlerc.com/D1740?vs=4438&id=4517#toc Files: docs/TR1Porting.rst docs/clang-modernize.rst
Index: docs/TR1Porting.rst =================================================================== --- /dev/null +++ docs/TR1Porting.rst @@ -0,0 +1,361 @@ +.. index:: Porting TR1 to C++11 + +==================== +Porting TR1 to C++11 +==================== + +.. contents:: + :local: + :depth: 3 + +.. highlight:: c++ + +Introduction +============ + +The C++ Technical Report 1 (TR1) is a set of extensions to the C++03 Standard +Library. The C++11 standard includes most of the extensions proposed in TR1 [1]_. +This document describes how to port TR1 code to C++11. + +There are various reasons one may want to port code to the latest standard. The +non-exhaustive list includes: + +- The C++11 interface is more mature; the interfaces have more functionality or + are easier to use. +- The C++11 interface takes advantage of new language features: move semantics, + perfect forwarding, ... +- It’s a step in the right direction to support `libc++`_ which doesn’t support + TR1 but provides a complete C++11 implementation. +- Popular TR1 implementations use different conventions which limits + interoperability. Using C++11 will work seamlessly across all C++11-compliant + libraries. + +.. _libc++: http://libcxx.llvm.org/ + +.. rubric:: Footnotes + +.. [1] The specialized math functions haven't been standardized in C++11, see :ref:`ref-cmath-header`. + +TR1 implementations +=================== + +Multiple TR1 implementations are available. They have their own conventions on +how to include TR1 components. The following table lists the vendors and their +respective conventions: + ++------------------------------------+---------------------------------------+ +| Implementation | Header include style | ++====================================+=======================================+ +| GCC / `libstdc++`_ | <tr1/foo> | ++------------------------------------+---------------------------------------+ +| MS Visual Studio (VC++)/Dinkumware | <foo> | ++------------------------------------+---------------------------------------+ +| Boost.TR1 | - <boost/tr1/foo.hpp> *(recommended)* | +| | - <foo> *(alternative)* | ++------------------------------------+---------------------------------------+ + +Aside from the differing header include styles, declarations from each vendor +reside in the namespace ``std::tr1``. + +.. _libstdc++: http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.tr1 + +Conventions +=========== + +The code examples in this document follow the GCC conventions (headers with +``tr1/`` prefix):: + + #include <tr1/memory> + + void f() { + std::tr1::shared_ptr<int> p; + } + + +Transform the inclusion directives +================================== + +Depending on the header include style used by the TR1 implementation it may be +necessary to change the inclusion filename. + +For example with GCC's TR1 implementation:: + + #include <tr1/memory> + +becomes:: + + #include <memory> + + +Note about the demise of ``std::unary_function`` and ``std::binary_function`` +============================================================================= + +In TR1, function objects inherit ``std::unary_function/std::binary_function`` to +provide typedefs for the result type and the argument(s) type(s). This practice +has been deprecated in C++11 in favor of in-class typedefs and the use of the +more generic ``std::function``. This document assumes that the ported code +doesn’t rely on the inheritance of ``std::unary_function/std::binary_function`` +but instead only to the typedefs provided. + + +Differences by header +===================== + +<array> +------- + +The TR1 interface is mostly compatible with C++11 with one exception explained +below. + +.. _ref-array-assign: + +``array::assign()`` renamed to ``array::fill()`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The member method ``assign()`` has been renamed to ``fill()`` in C++11. + +.. code-block:: diff + :emphasize-lines: 6,8 + + -#include <tr1/array> + +#include <array> + + void f() { + - std::tr1::array<int, 3> ary; + - ary.assign(3); + + std::array<int, 3> ary; + + ary.fill(3); + } + +.. _ref-cmath-header: + +<cmath> +------- + +The TR1 extensions in this header are not part of the C++11 standard thus the +special math functions listed below have no C++11 equivalents. + +============== ================ =============== +double float long double +============== ================ =============== +assoc_laguerre assoc_laguerref assoc_laguerrel +assoc_legendre assoc_legendref assoc_legendrel +beta betaf betal +comp_ellint_1 comp_ellint_1f comp_ellint_1l +comp_ellint_2 comp_ellint_2f comp_ellint_2l +comp_ellint_3 comp_ellint_3f comp_ellint_3l +conf_hyperg conf_hypergf conf_hypergl +cyl_bessel_i cyl_bessel_if cyl_bessel_il +cyl_bessel_j cyl_bessel_jf cyl_bessel_jl +cyl_bessel_k cyl_bessel_kf cyl_bessel_kl +cyl_neumann cyl_neumannf cyl_neumannl +ellint_1 ellint_1f ellint_1l +ellint_2 ellint_2f ellint_2l +ellint_3 ellint_3f ellint_3l +expint expintf expintl +hermite hermitef hermitel +hyperg hypergf hypergl +laguerre laguerref laguerrel +legendre legendref legendrel +riemann_zeta riemann_zetaf riemann_zetal +sph_bessel sph_besself sph_bessell +sph_legendre sph_legendref sph_legendrel +sph_neumann sph_neumannf sph_neumannl +============== ================ =============== + +.. _ref-tuple-header: + + +<functional> +------------ + +The TR1 interface is mostly compatible with C++11 with one exception explained +below. + +``std::hash`` specialization for ``std::string`` moved to ``<string>`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In TR1 the ``std::hash`` specialization for ``std::string`` has moved from +``<tr1/functional>`` to ``<string>``. This means that code that relied on +``<tr1/functional>`` to include ``<string>`` should now include ``<string>`` +explicitly. + +.. code-block:: diff + :emphasize-lines: 3 + + -#include <tr1/functional> + +#include <functional> + +#include <string> + + void f() { + - std::tr1::hash<std::string> hasher; + + std::hash<std::string> hasher; + } + + +<memory> +-------- + +The TR1 interface is mostly compatible with C++11 with two exceptions: + +1. shared_ptr + + * If the pointer doesn’t share ownership ``std::unique_ptr`` can be used + instead as it will be more efficient. + * If the pointer is constructed with or assigned from ``auto_ptr`` the + ``auto_ptr`` argument should be wrapped with a call to ``std::move().`` + See :ref:`ref-shared_ptr`. + +2. weak_ptr + + * The comparison operator ``operator<()`` has been replaced by the member + function ``owner_before()``. In associative containers and algorithms that + depends on ``operator<()`` the function object ``std::owner_less`` should + be used as a comparator. See :ref:`ref-weak_ptr`. + +.. _ref-shared_ptr: + +``std::shared_ptr``: construction and assignment from ``std::auto_ptr`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In TR1 ``shared_ptr`` can be constructed or assigned from an lvalue reference to +``std::auto_ptr``:: + + explicit shared_ptr(auto_ptr<Y> &r); + shared_ptr &operator=(auto_ptr<Y> &r); + +In C++11 these special member functions have been changed to take an rvalue +instead:: + + shared_ptr(auto_ptr<Y> &&r); + shared_ptr &operator=(auto_ptr<Y> &&r); + +You now have to call ``std::move()`` explicitly when stealing the ``auto_ptr`` +resource. It makes the intent clearer that the resource is being stolen from the +``auto_ptr``. Taking an rvalue reference also has the advantage to accept +``auto_ptr`` returned by value from a function without the need to have an +lvalue (illustrated in the examples below). + +.. code-block:: diff + :emphasize-lines: 20,29 + + -#include <tr1/memory> + +#include <memory> + #include <set> + + -using std::tr1::shared_ptr; + +using std::shared_ptr; + + // Function that returns a managed object. + std::auto_ptr<int> source(int); + + shared_ptr<int> source_shared(int x) { + - // In TR1 to construct a shared_ptr from an auto_ptr you need a non-const + - // lvalue reference. + - std::auto_ptr<int> A(source(x)); + - return shared_ptr<int>(A); + + // In C++11 to construct a shared_ptr from an auto_ptr you need an rvalue + + // reference. The return type of `source()` can be taken directly. + + return shared_ptr<int>(source(x)); + } + + void f(shared_ptr<int> &shared) { + std::auto_ptr<int> A(source(0)); + + // assign a shared_ptr from an auto_ptr (steals A resource) + - shared = A; + + shared = std::move(A); + } + + +.. _ref-weak_ptr: + +``std::weak_ptr``: use ``std::owner_less`` associative containers and algorithms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In C++11 ``weak_ptr`` dropped the comparison ``operator<()`` used by associative +containers and some algorithms such as ``std::sort()``. The function object +``std::owner_less`` should be specified instead when using these containers or +algorithms. + +.. code-block:: diff + :emphasize-lines: 10 + + -#include <tr1/memory> + +#include <memory> + #include <set> + + -using std::tr1::weak_ptr; + +using std::weak_ptr; + + void f(weak_ptr<int> const &a, weak_ptr<int> const &b) { + - std::set<weak_ptr<int> > ptrs; + + std::set<weak_ptr<int>, std::owner_less<weak_ptr<int>>> ptrs; + + ptrs.insert(a); + ptrs.insert(b); + } + + +<random> +-------- + +.. warning:: + + This section is incomplete. There are many differences and not all of them + have been identified yet. + + The document `N1933 - Improvements to TR1's Facility for Random Number + Generation`_ lists some of the differences and explains the reasons behind + these changes. + +.. _N1933 - Improvements to TR1's Facility for Random Number Generation: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1933.pdf + + +<regex> +-------- + +.. warning:: + + This section is incomplete. GCC TR1's implementation doesn't provide this + feature but others do. + + +<tuple> +------- + +TR1's tuples can be replaced by C++11's ones. + + +<type_traits> +------------- + +Type traits are mostly a drop-in replacement in C++11 except for a few of them +that have been renamed. + +Renamed type traits +~~~~~~~~~~~~~~~~~~~ + +================================= ======================================= +TR1 C++11 +================================= ======================================= +std::tr1::has_nothrow_assign std::is_nothrow_copy_assignable +std::tr1::has_nothrow_constructor std::is_nothrow_default_constructible +std::tr1::has_nothrow_copy std::is_nothrow_copy_constructible +std::tr1::has_trivial_assign std::is_trivially_copy_assignable +std::tr1::has_trivial_constructor std::is_trivially_default_constructible +std::tr1::has_trivial_copy std::is_trivially_copy_constructible +std::tr1::has_trivial_destructor std::is_trivially_destructible +================================= ======================================= + + +<unordered_map> and <unordered_set> +----------------------------------- + +All four TR1's unordered associative containers can be replaced by C++11's ones. + + +<utility> +--------- + +The TR1 version of this header can be replaced by the C++11's one. Index: docs/clang-modernize.rst =================================================================== --- docs/clang-modernize.rst +++ docs/clang-modernize.rst @@ -13,6 +13,7 @@ AddOverrideTransform PassByValueTransform ReplaceAutoPtrTransform + TR1Porting ModernizerUsage cpp11-migrate MigratorUsage @@ -122,3 +123,8 @@ * :doc:`PassByValueTransform` * :doc:`ReplaceAutoPtrTransform` + +Porting TR1 to C++11 +==================== + +* :doc:`TR1Porting`
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
