<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<title>Experimental shared_ptr for Library Fundamentals TS</title>

<style type="text/css">
  p {text-align:justify}
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  div.inserted { background-color:#A0FFA0; }
  div.deleted { background-color:#FFA0A0; }
</style>
</head><body>
<address style="text-align: left;">
Document number: N4077<br>
Date: 2014-06-20<br>
Author: Jonathan Wakely<br>
Project: Programming Language C++, Library Evolution Working Group<br>
Reply-to: <a href="mailto:cxx@kayari.org">Jonathan Wakely</a>
</address>
<hr>
<h1 style="text-align: center;">Experimental <tt>shared_ptr</tt> for Library Fundamentals TS</h1>
<h2><a name="Introduction"></a>Introduction</h2>
<p>
This paper provides wording to the effect that it creates independent fundamental-ts types in namespace <tt>std::experimental</tt>
for  <tt>shared_ptr</tt>, <tt>weak_ptr</tt>, <tt>owner_less</tt>,
<tt>enable_shared_from_this</tt>, and all relevant functions and hash specializations.
</p>
<h2><a name="Discussion"></a>Discussion</h2>
<p>
Currently, the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4023.html">fundamental-ts</a>
refers to <tt>std::shared_ptr</tt> and <tt>std::weak_ptr</tt> and has applied extensions to those existing C++11 types, which has caused
some significant concerns, which are in described in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4041.html">N4041</a>.
<p/>
As a consequence of discussing this paper ("Guidelines for the contents of Technical Specifications") and 
performing straw polls within LEWG the following direction was requested:
</p>
<blockquote>
<p>
shared_ptr&lt;array> in TS in std::experimental? (shared_ptr&lt;non-array> would also be copied to std::experimental)
</p>
<p>
SF-F-N-A-SA
</p>
<p>
4-9-6-1-0
</p>
</blockquote>
<p>
This proposal attempts to provide wording to realize these effects.
</p>
<p>
Note to the editor:
The intention is simply to create new types (and related functions) in
namespace <tt>std::experimental::fundamentals_v1</tt> with the same behaviour
as was specified for <tt>std::shared_ptr</tt> and <tt>std::weak_ptr</tt>
by the previous draft of the Library Fundamentals TS.
Any other differences introduced by this paper are unintentional and should
be considered editorial, not part of the proposal.
</p>

<h2><a name="Proposed_resolution"></a>Proposed resolution</h2>
<p>
The proposed wording changes refer to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4023.html">N4023</a>.
</p>
<ol>
<li><p>Modify Table 2 &mdash; "Significant features in this technical specification" as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 2 &mdash; Significant features in this technical specification</caption>
<tr>
<th align="center">Doc.<br/>No.</th>
<th align="center">Title</th>
<th align="center">Primary<br/>Section</th>
<th align="center">Macro Name Suffix</th>
<th align="center">Value</th>
<th align="center">Header</th>
</tr>

<tr>
<td colspan="6" align="center">
<tt>&hellip;</tt>
</td>
</tr>

<tr>
<td>
N3920<br/>
</td>
<td>
Extending shared_ptr to Support Arrays
</td>
<td>
<del>2.3 [mods.util.smartptr.shared]</del><br/>
<ins>8.2 [memory.smartptr]</ins>
</td>
<td>
<tt>shared_ptr_arrays</tt>
</td>
<td>
<tt>201402</tt>
</td>
<td>
<tt>&lt;<ins>experimental/</ins>memory&gt;</tt>
</td>
</tr>

<tr>
<td colspan="6" align="center">
<tt>&hellip;</tt>
</td>
</tr>

</table>
</blockquote>
</li>

<li><p>Remove the existing sub-clause 2.2 [mods.util.smartptr.shared] in its entirety:</p>

<p>
<del><b>2.2 Changes to <tt>std::shared_ptr</tt> and <tt>std::weak_ptr</tt> [mods.util.smartptr.shared]</b></del>
</p>
<blockquote>
<p>
<del>-1- Make the following changes in C++14 &sect;20.8.2.2 [&hellip;]</del>
</p>
<p>
<del>[&hellip;]</del>
</p>
<p>
<del>-5- For the purposes of subclause C++14 &sect;20.8.2, [&hellip;]</del>
</p>
</blockquote>

<p>
<del><b>2.2.1 Changes to <tt>std::shared_ptr</tt> constructors [mods.util.smartptr.shared.const]</b></del>
</p>
<blockquote>
<p>
<del>-1- Make the following changes in C++14 &sect;20.8.2.2.1 [&hellip;]</del>
</p>
<p>
<del>[&hellip;]</del>
</p>
<p>
<del>-36- <i>Exception safety:</i> If an exception is thrown, [&hellip;]</del>
</p>
</blockquote>

<p>
<del><b>2.2.2 Changes to <tt>std::shared_ptr</tt> observers [mods.util.smartptr.shared.obs]</b></del>
</p>
<blockquote>
<p>
<del>-1- Make the following changes in C++14 &sect;20.8.2.2.5 [&hellip;]</del>
</p>
<p>
<del>[&hellip;]</del>
</p>
<p>
<del> <i>Remarks:</i> When T is not an array type, [&hellip;]</del>
</p>
</blockquote>

<p>
<del><b>2.2.3 Changes to <tt>std::shared_ptr</tt> casts [mods.util.smartptr.shared.cast]</b></del>
</p>
<blockquote>
<p>
<del>-1- Make the following changes in C++14 &sect;20.8.2.2.9 [&hellip;]</del>
</p>
<p>
<del>[&hellip;]</del>
</p>
<p>
<del>-16- [<i>Note:</i> The seemingly equivalent expression [&hellip;] - <i>end note</i>]</del>
</p>
</blockquote>

<p>
<del><b>2.2.4 Changes to <tt>std::weak_ptr</tt> [mods.util.smartptr.weak]</b></del>
</p>
<blockquote>
<p>
<del>-1- Make the following changes in C++14 &sect;20.8.2.3 [&hellip;]</del>
</p>
<p>
<del>[&hellip;]</del>
</p>
<p>
<del>-6- [<i>Postconditions:</i> <tt>use_count() == r.use_count()</tt>. </del>
</p>
</blockquote>

</li>

<li><p>Change header <tt>&lt;experimental/memory&gt;</tt> synopsis, 8.1 [header.memory.synop], as indicated:</p>

<blockquote>
<pre>
#include &lt;memory&gt;

namespace std {
namespace experimental {
inline namespace fundamentals_v1 {

  // See C++14 &sect;20.7.7, uses_allocator
  template &lt;class T, class Alloc> constexpr bool uses_allocator_v
    = uses_allocator&lt;T, Alloc>::value;
<div class="inserted">
  <i>// 8.2.1 Class template shared_ptr:</i>
  template&lt;class T> class shared_ptr;

  <i>// See C++14 &sect;20.8.2.2.6 <tt>shared_ptr</tt> creation</i>
  template&lt;class T, class... Args> shared_ptr&lt;T> make_shared(Args&amp;&amp;... args);
  template&lt;class T, class A, class... Args>
    shared_ptr&lt;T> allocate_shared(const A&amp; a, Args&amp;&amp;... args);

  <i>// See C++14 &sect;20.8.2.2.7 <tt>shared_ptr</tt> comparison</i>
  template&lt;class T, class U>
    bool operator==(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator!=(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator&lt;(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator>(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator&lt;=(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator>=(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template &lt;class T>
    bool operator==(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator==(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator!=(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator!=(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator&lt;(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator&lt;(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator&lt;=(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator&lt;=(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator>(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator>(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator>=(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator>=(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;

  <i>// See C++14 &sect;20.8.2.2.8 <tt>shared_ptr</tt> specialized algorithms</i>
  template&lt;class T> void swap(shared_ptr&lt;T>&amp; a, shared_ptr&lt;T>&amp; b) noexcept;
</div>
  <i>// 8.2<ins>.1.3</ins>, shared_ptr casts</i><div class="inserted">
  template&lt;class T, class U>
    shared_ptr&lt;T> static_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;
  template&lt;class T, class U>
    shared_ptr&lt;T> dynamic_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;
  template&lt;class T, class U>
    shared_ptr&lt;T> const_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;</div>  template&lt;class T, class U>
    shared_ptr&lt;T> reinterpret_pointer_cast(<ins>const</ins> shared_ptr&lt;U> <del>const</del>&amp; r) noexcept;
<div class="inserted">

  <i>// C++14 &sect;20.8.2.2.10 get_deleter</i>
  template&lt;class D, class T> D* get_deleter(const shared_ptr&lt;T>&amp; p) noexcept;

  <i>// C++14 &sect;20.8.2.2.11 <tt>shared_ptr</tt> I/O</i>
  template&lt;class E, class T, class Y>
    basic_ostream&lt;E, T>&amp; operator&lt;&lt; (basic_ostream&lt;E, T>&amp; os, const shared_ptr&lt;Y>&amp; p);

  <i>// 8.2.2 Class template <tt>weak_ptr</tt></i>
  template&lt;class T> class weak_ptr;

  <i>// C++14 &sect;20.8.2.3.6 <tt>weak_ptr</tt> specialized algorithms</i>
  template&lt;class T> void swap(weak_ptr&lt;T>&amp; a, weak_ptr&lt;T>&amp; b) noexcept;

  <i>// C++14 &sect;20.8.2.4 Class template <tt>owner_less</tt></i>
  template&lt;class T> class owner_less;

  <i>// C++14 &sect;20.8.2.5 Class template <tt>enable_shared_from_this</tt></i>
  template&lt;class T> class enable_shared_from_this;

  <i>// C++14 &sect;20.8.2.6 <tt>shared_ptr</tt> atomic access</i>
  template&lt;class T>
    bool atomic_is_lock_free(const shared_ptr&lt;T>* p);
  template&lt;class T>
    shared_ptr&lt;T> atomic_load(const shared_ptr&lt;T>* p);
  template&lt;class T>
    shared_ptr&lt;T> atomic_load_explicit(const shared_ptr&lt;T>* p, memory_order mo);
  template&lt;class T>
    void atomic_store(shared_ptr&lt;T>* p, shared_ptr&lt;T> r);
  template&lt;class T>
    void atomic_store_explicit(shared_ptr&lt;T>* p, shared_ptr&lt;T> r, memory_order mo);
  template&lt;class T>
    shared_ptr&lt;T> atomic_exchange(shared_ptr&lt;T>* p, shared_ptr&lt;T> r);
  template&lt;class T>
    shared_ptr&lt;T> atomic_exchange_explicit(shared_ptr&lt;T>* p, shared_ptr&lt;T> r,
                                           memory_order mo);
  template&lt;class T>
    bool atomic_compare_exchange_weak(
      shared_ptr&lt;T>* p, shared_ptr&lt;T>* v, shared_ptr&lt;T> w);
  template&lt;class T>
    bool atomic_compare_exchange_strong(
      shared_ptr&lt;T>* p, shared_ptr&lt;T>* v, shared_ptr&lt;T> w);
  template&lt;class T>
    bool atomic_compare_exchange_weak_explicit(
      shared_ptr&lt;T>* p, shared_ptr&lt;T>* v, shared_ptr&lt;T> w,
      memory_order success, memory_order failure);
  template&lt;class T>
    bool atomic_compare_exchange_strong_explicit(
      shared_ptr&lt;T>* p, shared_ptr&lt;T>* v, shared_ptr&lt;T> w,
      memory_order success, memory_order failure);
</div>

} <i>// namespace fundamentals_v1</i>
} <i>// namespace experimental</i>
<ins>
  <i>// C++14 &sect;20.8.2.7 Smart pointer hash support</i>
  template&lt;class T> struct hash&lt;experimental::shared_ptr&lt;T>>;
</ins>
}
</pre>
</blockquote>
</li>

<li><p>Replace section 8.2 [memory.smartptr.shared.cast] as shown:</p>

<p>
<del><b>8.2 <tt>shared_ptr</tt> casts [memory.smartptr.shared.cast] </b> </del>
</p>
<p>
<del>-1- <tt>template&lt;class T, class U> shared_ptr&lt;T> reinterpret_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;</tt></del>
</p>
<blockquote>
<p>
<del>-2- <i>Requires:</i>
The expression <tt>reinterpret_cast&lt;T*>((U*)0)</tt> shall be well formed.</del>
</p>
<p>
<del>-3- <i>Returns:</i>
<tt>shared_ptr&lt;T>(r, reinterpret_cast&lt;typename shared_ptr&lt;T>::element_type*>(r.get()))</tt>.</del>
</p>
</blockquote>

<div class="inserted">
<p>
<b>8.2 Shared-ownership pointers [memory.smartptr] </b>
</p>

<blockquote>
<p>
-1-        The specification of all declarations within this sub-clause [memory.smartptr] and its sub-clauses are the same as the corresponding declarations, as specified in C++14 &sect;20.8.2 [util.smartptr], unless explicitly specified otherwise.
</p>
</blockquote>

<p>
<b>8.2.1 Class template <tt>shared_ptr</tt> [memory.smartptr.shared]</b>
</p>


<pre><code>
namespace std {
namespace experimental {
inline namespace fundamentals_v1 {

  template&lt;class T> class shared_ptr {
  public:
    typedef typename remove_extent&lt;T>::type element_type;
    <i>// 8.2.1.1 <tt>shared_ptr</tt> constructors</i>
    constexpr shared_ptr() noexcept;
    template&lt;class Y> explicit shared_ptr(Y* p);
    template&lt;class Y, class D> shared_ptr(Y* p, D d);
    template&lt;class Y, class D, class A> shared_ptr(Y* p, D d, A a);
    template &lt;class D> shared_ptr(nullptr_t p, D d)
    template &lt;class D, class A> shared_ptr(nullptr_t p, D d, A a);
    template&lt;class Y> shared_ptr(const shared_ptr&lt;Y>&amp; r, element_type* p) noexcept;
    shared_ptr(const shared_ptr&amp; r) noexcept;
    template&lt;class Y> shared_ptr(const shared_ptr&lt;Y>&amp; r) noexcept;
    shared_ptr(shared_ptr&amp;&amp; r) noexcept;
    template&lt;class Y> shared_ptr(shared_ptr&lt;Y>&amp;&amp; r) noexcept;
    template&lt;class Y> explicit shared_ptr(const weak_ptr&lt;Y>&amp; r);
    template&lt;class Y> shared_ptr(auto_ptr&lt;Y>&amp;&amp; r);
    template &lt;class Y, class D> shared_ptr(unique_ptr&lt;Y, D>&amp;&amp; r);
    constexpr shared_ptr(nullptr_t) : shared_ptr() { }

    <i>// C++14 &sect;20.8.2.2.2 [util.smartptr.shared.dest]</i>
    ~shared_ptr();

    <i>// C++14 &sect;20.8.2.2.3 [util.smartptr.shared.assign]</i>
    shared_ptr&amp; operator=(const shared_ptr&amp; r) noexcept;
    template&lt;class Y> shared_ptr&amp; operator=(const shared_ptr&lt;Y>&amp; r) noexcept;
    shared_ptr&amp; operator=(shared_ptr&amp;&amp; r) noexcept;
    template&lt;class Y> shared_ptr&amp; operator=(shared_ptr&lt;Y>&amp;&amp; r) noexcept;
    template&lt;class Y> shared_ptr&amp; operator=(auto_ptr&lt;Y>&amp;&amp; r);
    template &lt;class Y, class D> shared_ptr&amp; operator=(unique_ptr&lt;Y, D>&amp;&amp; r);

    <i>// C++14 &sect;20.8.2.2.4 [util.smartptr.shared.mod]</i>
    void swap(shared_ptr&amp; r) noexcept;
    void reset() noexcept;
    template&lt;class Y> void reset(Y* p);
    template&lt;class Y, class D> void reset(Y* p, D d);
    template&lt;class Y, class D, class A> void reset(Y* p, D d, A a);

    <i>// 8.2.1.2 <tt>shared_ptr</tt> observers</i>
    element_type* get() const noexcept;
    T&amp; operator*() const noexcept;
    T* operator->() const noexcept;
    element_type&amp; operator[](ptrdiff_t i) const noexcept;
    long use_count() const noexcept;
    bool unique() const noexcept;
    explicit operator bool() const noexcept;
    template&lt;class U> bool owner_before(shared_ptr&lt;U> const&amp; b) const;
    template&lt;class U> bool owner_before(weak_ptr&lt;U> const&amp; b) const;
  };

  // See C++14 &sect;20.8.2.2.6 <tt>shared_ptr</tt> creation
  template&lt;class T, class... Args> shared_ptr&lt;T> make_shared(Args&amp;&amp;... args);
  template&lt;class T, class A, class... Args>
    shared_ptr&lt;T> allocate_shared(const A&amp; a, Args&amp;&amp;... args);

  // See C++14 &sect;20.8.2.2.7 <tt>shared_ptr</tt> comparison
  template&lt;class T, class U>
    bool operator==(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator!=(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator&lt;(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator>(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator&lt;=(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template&lt;class T, class U>
    bool operator>=(const shared_ptr&lt;T>&amp; a, const shared_ptr&lt;U>&amp; b) noexcept;
  template &lt;class T>
    bool operator==(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator==(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator!=(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator!=(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator&lt;(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator&lt;(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator&lt;=(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator&lt;=(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator>(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator>(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;
  template &lt;class T>
    bool operator>=(const shared_ptr&lt;T>&amp; a, nullptr_t) noexcept;
  template &lt;class T>
    bool operator>=(nullptr_t, const shared_ptr&lt;T>&amp; b) noexcept;

  <i>// See C++14 &sect;20.8.2.2.8 <tt>shared_ptr</tt> specialized algorithms</i>
  template&lt;class T> void swap(shared_ptr&lt;T>&amp; a, shared_ptr&lt;T>&amp; b) noexcept;

  <i>// 8.2.1.3, shared_ptr casts</i>
  template&lt;class T, class U>
    shared_ptr&lt;T> static_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;
  template&lt;class T, class U>
    shared_ptr&lt;T> dynamic_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;
  template&lt;class T, class U>
    shared_ptr&lt;T> const_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;
  template&lt;class T, class U>
    shared_ptr&lt;T> reinterpret_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;

  <i>// C++14 &sect;20.8.2.2.10 get_deleter</i>
  template&lt;class D, class T> D* get_deleter(const shared_ptr&lt;T>&amp; p) noexcept;

  <i>// C++14 &sect;20.8.2.2.11 <tt>shared_ptr</tt> I/O</i>
  template&lt;class E, class T, class Y>
    basic_ostream&lt;E, T>&amp; operator&lt;&lt; (basic_ostream&lt;E, T>&amp; os, const shared_ptr&lt;Y>&amp; p);

  <i>// C++14 &sect;20.8.2.4 Class template <tt>owner_less</tt></i>
  template&lt;class T> class owner_less;

  <i>// C++14 &sect;20.8.2.5 Class template <tt>enable_shared_from_this</tt></i>
  template&lt;class T> class enable_shared_from_this;

  <i>// C++14 &sect;20.8.2.6 <tt>shared_ptr</tt> atomic access</i>
  template&lt;class T>
    bool atomic_is_lock_free(const shared_ptr&lt;T>* p);
  template&lt;class T>
    shared_ptr&lt;T> atomic_load(const shared_ptr&lt;T>* p);
  template&lt;class T>
    shared_ptr&lt;T> atomic_load_explicit(const shared_ptr&lt;T>* p, memory_order mo);
  template&lt;class T>
    void atomic_store(shared_ptr&lt;T>* p, shared_ptr&lt;T> r);
  template&lt;class T>
    void atomic_store_explicit(shared_ptr&lt;T>* p, shared_ptr&lt;T> r, memory_order mo);
  template&lt;class T>
    shared_ptr&lt;T> atomic_exchange(shared_ptr&lt;T>* p, shared_ptr&lt;T> r);
  template&lt;class T>
    shared_ptr&lt;T> atomic_exchange_explicit(shared_ptr&lt;T>* p, shared_ptr&lt;T> r,
                                           memory_order mo);
  template&lt;class T>
    bool atomic_compare_exchange_weak(
      shared_ptr&lt;T>* p, shared_ptr&lt;T>* v, shared_ptr&lt;T> w);
  template&lt;class T>
    bool atomic_compare_exchange_strong(
      shared_ptr&lt;T>* p, shared_ptr&lt;T>* v, shared_ptr&lt;T> w);
  template&lt;class T>
    bool atomic_compare_exchange_weak_explicit(
      shared_ptr&lt;T>* p, shared_ptr&lt;T>* v, shared_ptr&lt;T> w,
      memory_order success, memory_order failure);
  template&lt;class T>
    bool atomic_compare_exchange_strong_explicit(
      shared_ptr&lt;T>* p, shared_ptr&lt;T>* v, shared_ptr&lt;T> w,
      memory_order success, memory_order failure);

} <i>// namespace fundamentals_v1</i>
} <i>// namespace experimental</i>

  <i>// C++14 &sect;20.8.2.7 Smart pointer hash support</i>
  template&lt;class T> struct hash&lt;experimental::shared_ptr&lt;T>>;

} <i>// namespace std</i></code></pre>

<blockquote>
      <p>-1-
        For the purposes of subclause [memory.smartptr], a pointer type <code>Y*</code> is said to be <i>compatible with</i> a pointer type <code>T*</code> when either <code>Y*</code> is convertible to <code>T*</code> or <code>Y</code> is <code>U[N]</code> and <code>T</code> is <code>U <var>cv</var> []</code>.
      </p>
</blockquote>

<p>
    <b>8.2.1.1 <code>shared_ptr</code> constructors [memory.smartptr.shared.const]</b>
</p>

        <p><tt>template&lt;class Y> explicit shared_ptr(Y* p);</tt></p>

        <blockquote>
        <p>-1-
        <i>Requires:</i> <code>Y</code> shall be a complete type.
        The expression <code>delete[] p</code>, when <code>T</code> is an array type,
        or <code>delete p</code>, when <code>T</code> is not an array type,
        shall be well-formed, shall have well defined behavior, and shall not throw exceptions.
        When <code>T</code> is <code>U[N]</code>, <code>Y(*)[N]</code> shall be convertible to <code>T*</code>;
        when <code>T</code> is <code>U[]</code>, <code>Y(*)[]</code> shall be convertible to <code>T*</code>;
        otherwise, <code>Y*</code> shall be convertible to <code>T*</code>.
        </p>

        <p>-2- <i>Effects:</i> When <code>T</code> is not an array type, constructs a <code>shared_ptr</code> object that <i>owns</i> the pointer <code>p</code>.
        Otherwise, constructs a <code>shared_ptr</code> that <em>owns</em> <code>p</code> and a deleter of an unspecified type that calls <code>delete[] p</code>.

        <p>-3- <i>Postconditions:</i> <code>use_count() == 1 &amp;&amp; get() == p</code>.

        <p>-4- <i>Throws:</i> <code>bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.

        <p>-5- <i>Exception safety:</i> If an exception is thrown, <code>delete p</code> is called when <code>T</code> is not an array type, <code>delete[] p</code> otherwise.
      </blockquote>

        <p>
        <tt>template&lt;class Y, class D> shared_ptr(Y* p, D d);</tt><br>
        <tt>template&lt;class Y, class D, class A> shared_ptr(Y* p, D d, A a);</tt><br>
        <tt>template &lt;class D> shared_ptr(nullptr_t p, D d);</tt><br>
        <tt>template &lt;class D, class A> shared_ptr(nullptr_t p, D d, A a);</tt>
        </p>

        <blockquote>
        <p>-1-
        <i>Requires:</i> <code>D</code> shall be <code>CopyConstructible</code>. The copy constructor and destructor of <code> D</code> shall not throw exceptions. The expression <code>d(p)</code> shall be well formed, shall have well defined behavior, and shall not throw exceptions. <code>A</code> shall be an allocator (C++14 &sect;17.6.3.5 [allocator.requirements]). The copy constructor and destructor of <code>A</code> shall not throw exceptions.
        When <code>T</code> is <code>U[N]</code>, <code>Y(*)[N]</code> shall be convertible to <code>T*</code>;
        when <code>T</code> is <code>U[]</code>, <code>Y(*)[]</code> shall be convertible to <code>T*</code>;
        otherwise, <code>Y*</code> shall be convertible to <code>T*</code>.

        <p>-2- <i>Effects:</i> Constructs a <code>shared_ptr</code> object that <i>owns</i> the object <code>p</code> and the deleter <code>d</code>. The second and fourth constructors shall use a copy of <code>a</code> to allocate memory for internal use.

        <p>-3- <i>Postconditions:</i> <code>use_count() == 1 &amp;&amp; get() == p</code>.

        <p>-4- <i>Throws:</i> <code>bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.

        <p>-5- <i>Exception safety:</i> If an exception is thrown, <code>d(p)</code> is called.
      </blockquote

        <p><tt>template&lt;class Y> shared_ptr(const shared_ptr&lt;Y>&amp; r, element_type* p) noexcept;</tt></p>

        <blockquote>
        <p>-1- <i>Effects:</i> Constructs a <code>shared_ptr</code> instance that stores <code>p</code> and <i>shares ownership</i> with <code>r</code>.

        <p>-2- <i>Postconditions:</i> <code>get() == p &amp;&amp; use_count() == r.use_count()</code>

          <p>-3- [<i>Note:</i> To avoid the possibility of a dangling pointer, the user of this constructor must ensure that <code>p</code> remains valid at least until the ownership group of <code>r</code> is destroyed. -<i>end note</i>]
        </p>

          <p>-4- [<i>Note:</i> This constructor allows creation of an <i>empty</i> <code>shared_ptr</code> instance with a non-null stored pointer. -<i>end note</i>]
        </p>
      </blockquote>

        <p>
        <tt>shared_ptr(const shared_ptr&amp; r) noexcept;</tt><br>
        <tt>template&lt;class Y> shared_ptr(const shared_ptr&lt;Y>&amp; r) noexcept;</tt>
        </p>

        <blockquote><p>-1-
        <i>Requires:</i> The second constructor shall not participate in the overload resolution unless <code>Y*</code> is <i>compatible with</i> <code>T*</code>.

        <p>-2- <i>Effects:</i> If <code>r</code> is <i>empty</i>, constructs an <i>empty</i> <code>shared_ptr</code> object; otherwise, constructs a <code>shared_ptr</code> object that <i>shares ownership</i> with <code>r</code>.

        <p>-3- <i>Postconditions:</i> <code>get() == r.get() &amp;&amp; use_count() == r.use_count()</code>.
      </blockquote>

        <p>
        <tt>shared_ptr(shared_ptr&amp;&amp; r) noexcept;</tt><br>
        <tt>template&lt;class Y> shared_ptr(shared_ptr&lt;Y>&amp;&amp; r) noexcept;</tt>
        </p>

        <blockquote><p>-1-
        <i>Remarks:</i> The second constructor shall not participate in overload resolution unless <code>Y*</code> is <i>compatible with</i> <code>T*</code>.

        <p>-2- <i>Effects:</i> Move-constructs a <code>shared_ptr</code> instance from <code>r</code>.

        <p>-3- <i>Postconditions:</i> <code>*this</code> shall contain the old value of <code>r</code>. <code>r</code> shall be <i>empty</i>. <code>r.get() == 0.</code>
      </blockquote>

        <p><tt>template&lt;class Y> explicit shared_ptr(const weak_ptr&lt;Y>&amp; r);</tt></p>

        <blockquote><p>-1-
        <i>Requires:</i> <code>Y*</code> shall be <i>compatible with</i> <code>T*</code>.

        <p>-2- <i>Effects:</i> Constructs a <code>shared_ptr</code> object that <i>shares ownership</i> with <code>r</code> and stores a copy of the pointer stored in <code>r</code>.

        <p>-3- <i>Postconditions:</i> <code>use_count() == r.use_count()</code>.

        <p>-4- <i>Throws:</i> <code>bad_weak_ptr</code> when <code>r.expired()</code>.

        <p>-5- <i>Exception safety:</i> If an exception is thrown, the constructor has no effect.
      </blockquote>

        <p><tt>template &lt;class Y, class D> shared_ptr(unique_ptr&lt;Y, D>&amp;&amp; r);</tt></p>

        <blockquote><p>-1-
        <i>Requires:</i> <code>Y*</code> shall be <em>compatible with</em> <code>T*</code>.

        <p>-2- <i>Effects:</i> Equivalent to <code>shared_ptr(r.release(), r.get_deleter())</code> when <code>D</code> is not a reference type, otherwise <code>shared_ptr(r.release(), ref(r.get_deleter()))</code>.

        <p>-3- <i>Exception safety:</i> If an exception is thrown, the constructor has no effect.
      </blockquote>

    <p><b>8.2.1.2 <code>shared_ptr</code> observers [memory.smartptr.shared.obs]</b></p>

        <p><tt>element_type* get() const noexcept;</tt></p>

      <blockquote>
        <p>-1- <i>Returns:</i> the stored pointer.
      </blockquote>

        <p><tt>T&amp; operator*() const noexcept;</tt></p>

      <blockquote><p>-1-
        <i>Requires:</i> <code>get() != 0</code>.

        <p>-2- <i>Returns:</i> <code>*get()</code>.

        <p>-3- <i>Notes:</i> When <code>T</code> is an array type or cv-qualified <code>void</code>, it is unspecified whether this member function is declared. If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
      </blockquote>

        <p><tt>T* operator->() const noexcept;</tt></p>

      <blockquote><p>-1-
        <i>Requires:</i> <code>get() != 0</code>.

        <p>-2- <i>Returns:</i> <code>get()</code>.
        <p>-3- <i>Remarks:</i> When <code>T</code> is an array type, it is unspecified whether this member function is declared.
        If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
      </blockquote>

          <p><tt>element_type&amp; operator[](ptrdiff_t i) const noexcept;</tt></p>

      <blockquote><p>-1-
          <i>Requires:</i> <code>get() != 0 &amp;&amp; i &gt;= 0</code>. If <code>T</code> is <code>U[N]</code>, <code>i &lt; N</code>.
          <p>-2- <i>Returns:</i> <code>get()[i]</code>.
          <p>-3- <i>Remarks:</i> When <code>T</code> is not an array type, it is unspecified whether this member function is declared.
          If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
        </blockquote>

    <p><b>8.2.1.3 <code>shared_ptr</code> casts [memory.smartptr.shared.cast]</b></p>

        <p><tt>template&lt;class T, class U> shared_ptr&lt;T> static_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;</tt></p>

      <blockquote><p>-1-
        <i>Requires:</i> The expression <code>static_cast&lt;T*&gt;((U*)0)</code> shall be well formed.

        <p>-2- <i>Returns:</i> <code>shared_ptr&lt;T&gt;(r, static_cast&lt;typename shared_ptr&lt;T&gt;::element_type*&gt;(r.get()))</code>

        <p>
          -3- [<i>Note:</i> The seemingly equivalent expression <code>shared_ptr&lt;T>(static_cast&lt;T*>(r.get()))</code> will eventually result in undefined behavior, attempting to delete the same object twice. -<i>end note</i>]
        </p>
      </blockquote>

        <p><tt>template&lt;class T, class U> shared_ptr&lt;T> dynamic_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;</tt></p>

      <blockquote><p>-1-
        <i>Requires:</i> The expression <code>dynamic_cast&lt;T*&gt;((U*)0)</code> shall be well formed.

        <p>-2- <i>Returns:</i>
          <ul>
            <li>When <code>dynamic_cast&lt;typename shared_ptr&lt;T&gt;::element_type*>(r.get())</code> returns a nonzero value <code>p</code>, <code>shared_ptr&lt;T&gt;(r, p)</code>;</li>

            <li>Otherwise, <code>shared_ptr&lt;T&gt;()</code>.</li>
          </ul>
        

        <p>
          -3- [<i>Note:</i> The seemingly equivalent expression <code>shared_ptr&lt;T>(dynamic_cast&lt;T*>(r.get()))</code> will eventually result in undefined behavior, attempting to delete the same object twice. -<i>end note</i>]
        </p>
      </blockquote>

        <p><tt>template&lt;class T, class U> shared_ptr&lt;T> const_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;</tt></p>

      <blockquote><p>-1-
        <i>Requires:</i> The expression <code>const_cast&lt;T*&gt;((U*)0)</code> shall be well formed.

        <p>-2- <i>Returns:</i> <code>shared_ptr&lt;T&gt;(r, const_cast&lt;typename shared_ptr&lt;T&gt;::element_type*&gt;(r.get()))</code>.

        <p>
          -3- [<i>Note:</i> The seemingly equivalent expression <code>shared_ptr&lt;T>(const_cast&lt;T*>(r.get()))</code> will eventually result in undefined behavior, attempting to delete the same object twice. -<i>end note</i>]
        </p>
      </blockquote>

        <p><tt>template&lt;class T, class U> shared_ptr&lt;T> reinterpret_pointer_cast(const shared_ptr&lt;U>&amp; r) noexcept;</tt></p>

      <blockquote><p>-1-
        <i>Requires:</i> The expression <code>reinterpret_cast&lt;T*>((U*)0)</code> shall be well formed.
        <p>-2- <i>Returns:</i> <code>shared_ptr&lt;T>(r, reinterpret_cast&lt;typename shared_ptr&lt;T>::element_type*>(r.get()))</code>.
      </blockquote>

    <p><b>8.2.2 Class template <tt>weak_ptr</tt> [memory.smartptr.weak]</b></p>

<pre><code>
namespace std {
namespace experimental {
inline namespace fundamentals_v1 {

  template&lt;class T> class weak_ptr {
  public:
    typedef typename remove_extent&lt;T&gt;::type element_type;

    <i>// 8.2.2.1 <tt>weak_ptr</tt> constructors [memory.smartptr.weak.const]</i>
    constexpr weak_ptr() noexcept;
    template&lt;class Y> weak_ptr(shared_ptr&lt;Y> const&amp; r) noexcept;
    weak_ptr(weak_ptr const&amp; r) noexcept;
    template&lt;class Y> weak_ptr(weak_ptr&lt;Y> const&amp; r) noexcept;
    weak_ptr(weak_ptr&amp;&amp; r) noexcept;
    template&lt;class Y> weak_ptr(weak_ptr&lt;Y>&amp;&amp; r) noexcept;

    <i>// C++14 &sect;20.8.2.3.2 [util.smartptr.weak.dest]</i>
    ~weak_ptr();

    <i>// C++14 &sect;20.8.2.3.3 [util.smartptr.weak.assign]</i>
    weak_ptr&amp; operator=(weak_ptr const&amp; r) noexcept;
    template&lt;class Y> weak_ptr&amp; operator=(weak_ptr&lt;Y> const&amp; r) noexcept;
    template&lt;class Y> weak_ptr&amp; operator=(shared_ptr&lt;Y> const&amp; r) noexcept;
    weak_ptr&amp; operator=(weak_ptr&amp;&amp; r) noexcept;
    template&lt;class Y> weak_ptr&amp; operator=(weak_ptr&lt;Y>&amp;&amp; r) noexcept;

    <i>// C++14 &sect;20.8.2.3.4 [util.smartptr.weak.mod]</i>
    void swap(weak_ptr&amp; r) noexcept;
    void reset() noexcept;

    <i>// C++14 &sect;20.8.2.3.5 [util.smartptr.weak.obs]</i>
    long use_count() const noexcept;
    bool expired() const noexcept;
    shared_ptr&lt;T> lock() const noexcept;
    template&lt;class U> bool owner_before(shared_ptr&lt;U> const&amp; b) const;
    template&lt;class U> bool owner_before(weak_ptr&lt;U> const&amp; b) const;
  };

  <i>// C++14 &sect;20.8.2.3.6 <tt>weak_ptr</tt> specialized algorithms</i>
  template&lt;class T> void swap(weak_ptr&lt;T>&amp; a, weak_ptr&lt;T>&amp; b) noexcept;

} // namespace fundamentals_v1
} // namespace experimental
} // namespace std</code></pre>

  
    <p><b>8.2.2.1 <code>weak_ptr</code> constructors [memory.smartptr.weak.const]</b></p>

        <p>
        <tt>weak_ptr(const weak_ptr&amp; r) noexcept;</tt><br>
        <tt>template&lt;class Y> weak_ptr(const weak_ptr&lt;Y>&amp; r) noexcept;</tt><br>
        <tt>template&lt;class Y> weak_ptr(const shared_ptr&lt;Y>&amp; r) noexcept;</tt>
        </p>

      <blockquote>
        <p>-1-
        <i>Requires:</i> The second and third constructors shall not participate in the overload resolution unless <code>Y*</code> is <i>compatible with</i> <code>T*</code>.

        <p>-2- <i>Effects:</i> If <code>r</code> is <i>empty</i>, constructs an <i>empty</i> <code>weak_ptr</code> object; otherwise, constructs a <code>weak_ptr</code> object that <i>shares ownership</i> with <code>r</code> and stores a copy of the pointer stored in <code>r</code>.

        <p>-3- <i>Postconditions:</i> <code>use_count() == r.use_count()</code>.
      </blockquote>

</div>


</li>

</ol>

</body></html>
