Hi revane, tareqsiraj, arielbernal, This is a first submission for the TR1 migration document. Some pieces are missings and will come later.
Missing pieces are: - <random> I figured out some changes but there is probably more that I haven't be able to identify. - <regex> Not supported by GCC but by some other implementations. - the C compatibility headers. <complex> has some differences but the others seems to be drop-in replacements. http://llvm-reviews.chandlerc.com/D1740 Files: docs/TR1Porting.rst docs/clang-modernize.rst
Index: docs/TR1Porting.rst =================================================================== --- /dev/null +++ docs/TR1Porting.rst @@ -0,0 +1,548 @@ +.. 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 the new language features (e.g: 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 list 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 different header include style all declarations 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; + } + + +Sparse changes +============== + +This section describes changes that aren’t unique to one header but instead are +spread across severals. + +Include 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> + + +Specialized algorithms and operators +------------------------------------ + +Some TR1 components offer: + +- A template specialization for some algorithms (e.g: ``std::swap()``). +- Overloaded IO operators for stream input/output (e.g: ``operator<<()``). +- Overloaded comparison operators for integration with associative containers or + algorithms (e.g: ``operator<()``). + +These situations aren’t detailed for each class that provides such +functionality. Instead it is assumed that the reader will remove the ``tr1::`` +namespace as necessary. Uses of operators usually do not specify the namespace +and as such no changes is needed with them in general. + + +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 directly on the inheritance of +``std::unary_function/std::binary_function`` but instead only to the typedefs +provided. + +Changes by header +================= + +<array> +------- + +The TR1 interface is mostly compatible with C++11 with one exception explained +below. + +* std::tr1::array + + * :ref:`ref-array-assign` + +The tuple-like access specializations for arrays is a drop-in replacement in +C++11, see :ref:`ref-tuple-header`. + +* | std::tr1::tuple_size (std::array specialization) + | std::tr1::tuple_element (std::array specialization) + +* std::tr1::get (std::array specialization) + + +.. _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. + +* 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> +------------ + +All TR1 extensions to this header are compatible with C++11. + +* | std::tr1::reference_wrapper + | std::tr1::ref + | std::tr1::cref + +* | std::tr1::result_of + +* | std::tr1::mem_fn + +* | std::tr1::is_bind_expression + | std::tr1::is_placeholder + | std::tr1::bind + | std::tr1::placeholders + +* | std::tr1::bad_function_call + | std::tr1::function + + +* | std::tr1::hash + + * :ref:`ref-hash_string_specialization` + + +.. _ref-hash_string_specialization: + +``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. + +In TR1:: + + #include <tr1/functional> + + void f() { + std::tr1::hash<std::string> hasher; + } + +In C++11: + +.. code-block:: c++ + :emphasize-lines: 2 + + + #include <functional> + #include <string> + + void f() { + std::hash<std::string> hasher; + } + + +<memory> +-------- + +The TR1 additions to this header are *mostly compatible* with C++11 with two +exceptions described below. + +* | std:tr1::bad_weak_ptr + +* | std:tr1::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`. + +* | std:tr1::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`. + +* | std::tr1::static_pointer_cast + | std::tr1::dynamic_pointer_cast + | std::tr1::const_pointer_cast + +* | std::tr1::get_deleter + +* | std::tr1::enable_shared_from_this + + +.. _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). + +In TR1: + +.. code-block:: c++ + :emphasize-lines: 12,14,22 + + #include <tr1/memory> + #include <set> + + bool foo(int); + + // Function that returns a managed object. + std::auto_ptr<int> source(int a, int b); + + // In TR1 to construct a shared_ptr from an auto_ptr you need + // a non-const lvalue reference. + std::tr1::shared_ptr<int> source_shared(int a, int b) { + std::auto_ptr<int> A(source(a, b)); + // construct a shared_ptr from an auto_ptr + return std::tr1::shared_ptr<int>(A); + } + + void do_something(std::tr1::shared_ptr<int> &shared, int i) { + std::auto_ptr<int> A(source(i, 0)); + + if (foo(*A)) + // assign a shared_ptr from an auto_ptr (steals A resource) + shared = A; + } + + +In C++11: + +.. code-block:: c++ + :emphasize-lines: 12,20 + + #include <memory> + #include <set> + + bool foo(int); + + // Function that returns a managed object. + std::auto_ptr<int> source(int a, int b); + + // In C++11 to construct a shared_ptr from an auto_ptr you need an rvalue. + std::shared_ptr<int> source_shared(int a, int b) { + // construct a shared_ptr from an auto_ptr value + return std::shared_ptr<int>(source(a, b)); + } + + void do_something(std::shared_ptr<int> &shared, int i) { + std::auto_ptr<int> A(source(i, 0)); // you can also use unique_ptr here + + if (foo(*A)) + // assign a shared_ptr from an auto_ptr (steals A resource) + 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 ``operator<()`` used by associative containers +and some algorithms (i.e: ``std::sort()``). The function object ``owner_less`` +should be specified instead when using these containers or algorithms. + +In TR1: + +.. code-block:: c++ + :emphasize-lines: 5 + + #include <tr1/memory> + #include <set> + + void f(std::tr1::weak_ptr<int> const &a, std::tr1::weak_ptr<int> const &b) { + std::set<std::tr1::weak_ptr<int> > ptrs; + + ptrs.insert(a); + ptrs.insert(b); + } + + +In C++11: + +.. code-block:: c++ + :emphasize-lines: 5 + + #include <memory> + #include <set> + + void f(std::weak_ptr<int> const &a, std::weak_ptr<int> const &b) { + std::set<std::weak_ptr<int>, std::owner_less<std::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> +------- + +C++11 tuple interface is compatible with TR1’s one. It also takes advantages of +the new language features such as variadic templates, perfect-forwarding, +constexpr, etc. + +* | std::tr1::tuple + | std::tr1::ignore + +* | std::tr1::make_tuple + | std::tr1::tie + +* | std::tr1::tuple_size + | std::tr1::tuple_element + +* | std::tr1::get + +<type_traits> +------------- + +Type traits are mostly a drop-in replacement in C++11 except for a few of them +that have been renamed. + +* | std::tr1::integral_constant + | std::tr1::true_type + | std::tr1::false_type + +* | std::tr1::is_void + | std::tr1::is_integral + | std::tr1::is_floating_point + | std::tr1::is_array + | std::tr1::is_pointer + | std::tr1::is_reference + | std::tr1::is_member_object_pointer + | std::tr1::is_member_function_pointer + | std::tr1::is_enum + | std::tr1::is_union + | std::tr1::is_class + | std::tr1::is_function + +* | std::tr1::is_arithmetic + | std::tr1::is_fundamental + | std::tr1::is_object + | std::tr1::is_scalar + | std::tr1::is_compound + | std::tr1::is_member_pointer + +* | std::tr1::is_const + | std::tr1::is_volatile + | std::tr1::is_pod + | std::tr1::is_empty + | std::tr1::is_polymorphic + | std::tr1::is_abstract + | std::tr1::has_virtual_destructor + | std::tr1::is_signed + | std::tr1::is_unsigned + | std::tr1::alignment_of + | std::tr1::rank + | std::tr1::extent + +* | std::tr1::is_same + | std::tr1::is_base_of + | std::tr1::is_convertible + +* | std::tr1::remove_const + | std::tr1::remove_volatile + | std::tr1::remove_cv + | std::tr1::add_const + | std::tr1::add_volatile + | std::tr1::add_cv + +* | std::tr1::remove_reference + | std::tr1::add_reference + +* | std::tr1::remove_pointer + | std::tr1::add_pointer + +* | std::tr1::aligned_storage + + +Renamed type traits +------------------- + +Some type traits have changed name in C++11, see the following table: + +================================= ======================================= +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> +----------------------------------- + +C++11 unordered associative containers can be used as a drop-in replacement of +TR1's ones. + +* | std::tr1::unordered_map + | std::tr1::unordered_multimap + +* | std::tr1::unordered_set + | std::tr1::unordered_multiset + + +<utility> +--------- + +The additions in this header provide tuple-like access to pairs, see +:ref:`ref-tuple-header`. No differences between TR1 and C++11. + +* std::tr1::tuple_size *(std::pair specialization)* +* std::tr1::tuple_element *(std::pair specialization)* +* std::tr1::get *(std::pair specialization)* 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
