Files
rippled/IntrusiveShared__test_8cpp_source.html
2025-08-19 09:49:50 -07:00

1049 lines
165 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>rippled: IntrusiveShared_test.cpp Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">rippled
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function() { init_codefold(0); });
/* @license-end */
</script>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_120ed4da3e3217b1e7fc0b4f48568e79.html">test</a></li><li class="navelem"><a class="el" href="dir_354330c8aa73f5a2ebe2c490e5cf38ef.html">basics</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle"><div class="title">IntrusiveShared_test.cpp</div></div>
</div><!--header-->
<div class="contents">
<div class="fragment"><div class="line"><a id="l00001" name="l00001"></a><span class="lineno"> 1</span><span class="preprocessor">#include &lt;test/unit_test/SuiteJournal.h&gt;</span></div>
<div class="line"><a id="l00002" name="l00002"></a><span class="lineno"> 2</span> </div>
<div class="line"><a id="l00003" name="l00003"></a><span class="lineno"> 3</span><span class="preprocessor">#include &lt;xrpl/basics/IntrusivePointer.ipp&gt;</span></div>
<div class="line"><a id="l00004" name="l00004"></a><span class="lineno"> 4</span><span class="preprocessor">#include &lt;xrpl/basics/IntrusiveRefCounts.h&gt;</span></div>
<div class="line"><a id="l00005" name="l00005"></a><span class="lineno"> 5</span><span class="preprocessor">#include &lt;xrpl/beast/unit_test.h&gt;</span></div>
<div class="line"><a id="l00006" name="l00006"></a><span class="lineno"> 6</span><span class="preprocessor">#include &lt;xrpl/beast/utility/Journal.h&gt;</span></div>
<div class="line"><a id="l00007" name="l00007"></a><span class="lineno"> 7</span> </div>
<div class="line"><a id="l00008" name="l00008"></a><span class="lineno"> 8</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/array.html">array</a>&gt;</span></div>
<div class="line"><a id="l00009" name="l00009"></a><span class="lineno"> 9</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/atomic.html">atomic</a>&gt;</span></div>
<div class="line"><a id="l00010" name="l00010"></a><span class="lineno"> 10</span><span class="preprocessor">#include &lt;barrier&gt;</span></div>
<div class="line"><a id="l00011" name="l00011"></a><span class="lineno"> 11</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/chrono.html">chrono</a>&gt;</span></div>
<div class="line"><a id="l00012" name="l00012"></a><span class="lineno"> 12</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/condition_variable.html">condition_variable</a>&gt;</span></div>
<div class="line"><a id="l00013" name="l00013"></a><span class="lineno"> 13</span><span class="preprocessor">#include &lt;latch&gt;</span></div>
<div class="line"><a id="l00014" name="l00014"></a><span class="lineno"> 14</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/optional.html">optional</a>&gt;</span></div>
<div class="line"><a id="l00015" name="l00015"></a><span class="lineno"> 15</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/random.html">random</a>&gt;</span></div>
<div class="line"><a id="l00016" name="l00016"></a><span class="lineno"> 16</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/string.html">string</a>&gt;</span></div>
<div class="line"><a id="l00017" name="l00017"></a><span class="lineno"> 17</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/thread.html">thread</a>&gt;</span></div>
<div class="line"><a id="l00018" name="l00018"></a><span class="lineno"> 18</span><span class="preprocessor">#include &lt;<a class="codeRef" href="http://en.cppreference.com/w/cpp/header/variant.html">variant</a>&gt;</span></div>
<div class="line"><a id="l00019" name="l00019"></a><span class="lineno"> 19</span> </div>
<div class="line"><a id="l00020" name="l00020"></a><span class="lineno"> 20</span><span class="keyword">namespace </span><a class="code hl_namespace" href="namespaceripple.html">ripple</a> {</div>
<div class="foldopen" id="foldopen00021" data-start="{" data-end="}">
<div class="line"><a id="l00021" name="l00021"></a><span class="lineno"><a class="line" href="namespaceripple_1_1tests.html"> 21</a></span><span class="keyword">namespace </span>tests {</div>
<div class="line"><a id="l00022" name="l00022"></a><span class="lineno"> 22</span> </div>
<div class="foldopen" id="foldopen00045" data-start="{" data-end="};">
<div class="line"><a id="l00045" name="l00045"></a><span class="lineno"><a class="line" href="structripple_1_1tests_1_1Barrier.html"> 45</a></span><span class="keyword">struct </span><a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a></div>
<div class="line"><a id="l00046" name="l00046"></a><span class="lineno"> 46</span>{</div>
<div class="line"><a id="l00047" name="l00047"></a><span class="lineno"><a class="line" href="structripple_1_1tests_1_1Barrier.html#a023130d72e3cc9fbc1d6640447f3c5a2"> 47</a></span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/mutex.html">std::mutex</a> <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#a023130d72e3cc9fbc1d6640447f3c5a2">mtx</a>;</div>
<div class="line"><a id="l00048" name="l00048"></a><span class="lineno"><a class="line" href="structripple_1_1tests_1_1Barrier.html#abbafe75d92ca1705f9e48d32a34fb825"> 48</a></span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/condition_variable.html">std::condition_variable</a> <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#abbafe75d92ca1705f9e48d32a34fb825">cv</a>;</div>
<div class="line"><a id="l00049" name="l00049"></a><span class="lineno"><a class="line" href="structripple_1_1tests_1_1Barrier.html#a4eb5b73370cd75c8ceef03605f903fa7"> 49</a></span> <span class="keywordtype">int</span> <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#a4eb5b73370cd75c8ceef03605f903fa7">count</a>;</div>
<div class="line"><a id="l00050" name="l00050"></a><span class="lineno"><a class="line" href="structripple_1_1tests_1_1Barrier.html#aab2456bc9b654d4387f4d3ca6abee348"> 50</a></span> <span class="keywordtype">int</span> <span class="keyword">const</span> <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#aab2456bc9b654d4387f4d3ca6abee348">initial</a>;</div>
<div class="line"><a id="l00051" name="l00051"></a><span class="lineno"> 51</span> </div>
<div class="foldopen" id="foldopen00052" data-start="{" data-end="}">
<div class="line"><a id="l00052" name="l00052"></a><span class="lineno"><a class="line" href="structripple_1_1tests_1_1Barrier.html#a9db675aa86b2b103110ae21b991ae6af"> 52</a></span> <a class="code hl_function" href="structripple_1_1tests_1_1Barrier.html#a9db675aa86b2b103110ae21b991ae6af">Barrier</a>(<span class="keywordtype">int</span> n) : <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#a4eb5b73370cd75c8ceef03605f903fa7">count</a>(n), <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#aab2456bc9b654d4387f4d3ca6abee348">initial</a>(n)</div>
<div class="line"><a id="l00053" name="l00053"></a><span class="lineno"> 53</span> {</div>
<div class="line"><a id="l00054" name="l00054"></a><span class="lineno"> 54</span> }</div>
</div>
<div class="line"><a id="l00055" name="l00055"></a><span class="lineno"> 55</span> </div>
<div class="line"><a id="l00056" name="l00056"></a><span class="lineno"> 56</span> <span class="keywordtype">void</span></div>
<div class="foldopen" id="foldopen00057" data-start="{" data-end="}">
<div class="line"><a id="l00057" name="l00057"></a><span class="lineno"><a class="line" href="structripple_1_1tests_1_1Barrier.html#a3024a052f980b05e9585a5f892a4c15a"> 57</a></span> <a class="code hl_function" href="structripple_1_1tests_1_1Barrier.html#a3024a052f980b05e9585a5f892a4c15a">arrive_and_wait</a>()</div>
<div class="line"><a id="l00058" name="l00058"></a><span class="lineno"> 58</span> {</div>
<div class="line"><a id="l00059" name="l00059"></a><span class="lineno"> 59</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/unique_lock.html">std::unique_lock</a> lock(<a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#a023130d72e3cc9fbc1d6640447f3c5a2">mtx</a>);</div>
<div class="line"><a id="l00060" name="l00060"></a><span class="lineno"> 60</span> <span class="keywordflow">if</span> (--<a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#a4eb5b73370cd75c8ceef03605f903fa7">count</a> == 0)</div>
<div class="line"><a id="l00061" name="l00061"></a><span class="lineno"> 61</span> {</div>
<div class="line"><a id="l00062" name="l00062"></a><span class="lineno"> 62</span> <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#a4eb5b73370cd75c8ceef03605f903fa7">count</a> = <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#aab2456bc9b654d4387f4d3ca6abee348">initial</a>;</div>
<div class="line"><a id="l00063" name="l00063"></a><span class="lineno"> 63</span> <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#abbafe75d92ca1705f9e48d32a34fb825">cv</a>.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/thread/condition_variable/notify_all.html">notify_all</a>();</div>
<div class="line"><a id="l00064" name="l00064"></a><span class="lineno"> 64</span> }</div>
<div class="line"><a id="l00065" name="l00065"></a><span class="lineno"> 65</span> <span class="keywordflow">else</span></div>
<div class="line"><a id="l00066" name="l00066"></a><span class="lineno"> 66</span> {</div>
<div class="line"><a id="l00067" name="l00067"></a><span class="lineno"> 67</span> <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#abbafe75d92ca1705f9e48d32a34fb825">cv</a>.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/thread/condition_variable/wait.html">wait</a>(lock, [&amp;] { <span class="keywordflow">return</span> <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#a4eb5b73370cd75c8ceef03605f903fa7">count</a> == <a class="code hl_variable" href="structripple_1_1tests_1_1Barrier.html#aab2456bc9b654d4387f4d3ca6abee348">initial</a>; });</div>
<div class="line"><a id="l00068" name="l00068"></a><span class="lineno"> 68</span> }</div>
<div class="line"><a id="l00069" name="l00069"></a><span class="lineno"> 69</span> }</div>
</div>
<div class="line"><a id="l00070" name="l00070"></a><span class="lineno"> 70</span>};</div>
</div>
<div class="line"><a id="l00071" name="l00071"></a><span class="lineno"> 71</span> </div>
<div class="line"><a id="l00072" name="l00072"></a><span class="lineno"> 72</span><span class="keyword">namespace </span>{</div>
<div class="line"><a id="l00073" name="l00073"></a><span class="lineno"> 73</span><span class="keyword">enum class</span> TrackedState : <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/types/integer.html">std::uint8_t</a> {</div>
<div class="line"><a id="l00074" name="l00074"></a><span class="lineno"> 74</span> uninitialized,</div>
<div class="line"><a id="l00075" name="l00075"></a><span class="lineno"> 75</span> alive,</div>
<div class="line"><a id="l00076" name="l00076"></a><span class="lineno"> 76</span> partiallyDeletedStarted,</div>
<div class="line"><a id="l00077" name="l00077"></a><span class="lineno"> 77</span> partiallyDeleted,</div>
<div class="line"><a id="l00078" name="l00078"></a><span class="lineno"> 78</span> deletedStarted,</div>
<div class="line"><a id="l00079" name="l00079"></a><span class="lineno"> 79</span> deleted</div>
<div class="line"><a id="l00080" name="l00080"></a><span class="lineno"> 80</span>};</div>
<div class="line"><a id="l00081" name="l00081"></a><span class="lineno"> 81</span> </div>
<div class="line"><a id="l00082" name="l00082"></a><span class="lineno"> 82</span><span class="keyword">class </span>TIBase : <span class="keyword">public</span> IntrusiveRefCounts</div>
<div class="line"><a id="l00083" name="l00083"></a><span class="lineno"> 83</span>{</div>
<div class="line"><a id="l00084" name="l00084"></a><span class="lineno"> 84</span><span class="keyword">public</span>:</div>
<div class="line"><a id="l00085" name="l00085"></a><span class="lineno"> 85</span> <span class="keyword">static</span> <span class="keyword">constexpr</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/types/size_t.html">std::size_t</a> maxStates = 128;</div>
<div class="line"><a id="l00086" name="l00086"></a><span class="lineno"> 86</span> <span class="keyword">static</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/array.html">std::array&lt;std::atomic&lt;TrackedState&gt;</a>, maxStates&gt; state;</div>
<div class="line"><a id="l00087" name="l00087"></a><span class="lineno"> 87</span> <span class="keyword">static</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/atomic/atomic.html">std::atomic&lt;int&gt;</a> nextId;</div>
<div class="line"><a id="l00088" name="l00088"></a><span class="lineno"> 88</span> <span class="keyword">static</span> TrackedState</div>
<div class="line"><a id="l00089" name="l00089"></a><span class="lineno"> 89</span> getState(<span class="keywordtype">int</span> <span class="keywordtype">id</span>)</div>
<div class="line"><a id="l00090" name="l00090"></a><span class="lineno"> 90</span> {</div>
<div class="line"><a id="l00091" name="l00091"></a><span class="lineno"> 91</span> assert(<span class="keywordtype">id</span> &lt; state.size());</div>
<div class="line"><a id="l00092" name="l00092"></a><span class="lineno"> 92</span> <span class="keywordflow">return</span> state[id].load(<a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_acquire</a>);</div>
<div class="line"><a id="l00093" name="l00093"></a><span class="lineno"> 93</span> }</div>
<div class="line"><a id="l00094" name="l00094"></a><span class="lineno"> 94</span> <span class="keyword">static</span> <span class="keywordtype">void</span></div>
<div class="line"><a id="l00095" name="l00095"></a><span class="lineno"> 95</span> resetStates(<span class="keywordtype">bool</span> resetCallback)</div>
<div class="line"><a id="l00096" name="l00096"></a><span class="lineno"> 96</span> {</div>
<div class="line"><a id="l00097" name="l00097"></a><span class="lineno"> 97</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; maxStates; ++i)</div>
<div class="line"><a id="l00098" name="l00098"></a><span class="lineno"> 98</span> {</div>
<div class="line"><a id="l00099" name="l00099"></a><span class="lineno"> 99</span> state[i].store(</div>
<div class="line"><a id="l00100" name="l00100"></a><span class="lineno"> 100</span> TrackedState::uninitialized, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_release</a>);</div>
<div class="line"><a id="l00101" name="l00101"></a><span class="lineno"> 101</span> }</div>
<div class="line"><a id="l00102" name="l00102"></a><span class="lineno"> 102</span> nextId.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/atomic/atomic/store.html">store</a>(0, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_release</a>);</div>
<div class="line"><a id="l00103" name="l00103"></a><span class="lineno"> 103</span> <span class="keywordflow">if</span> (resetCallback)</div>
<div class="line"><a id="l00104" name="l00104"></a><span class="lineno"> 104</span> TIBase::tracingCallback_ = [](TrackedState,</div>
<div class="line"><a id="l00105" name="l00105"></a><span class="lineno"> 105</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a>) {};</div>
<div class="line"><a id="l00106" name="l00106"></a><span class="lineno"> 106</span> }</div>
<div class="line"><a id="l00107" name="l00107"></a><span class="lineno"> 107</span> </div>
<div class="line"><a id="l00108" name="l00108"></a><span class="lineno"> 108</span> <span class="keyword">struct </span>ResetStatesGuard</div>
<div class="line"><a id="l00109" name="l00109"></a><span class="lineno"> 109</span> {</div>
<div class="line"><a id="l00110" name="l00110"></a><span class="lineno"> 110</span> <span class="keywordtype">bool</span> resetCallback_{<span class="keyword">false</span>};</div>
<div class="line"><a id="l00111" name="l00111"></a><span class="lineno"> 111</span> </div>
<div class="line"><a id="l00112" name="l00112"></a><span class="lineno"> 112</span> ResetStatesGuard(<span class="keywordtype">bool</span> resetCallback) : resetCallback_{resetCallback}</div>
<div class="line"><a id="l00113" name="l00113"></a><span class="lineno"> 113</span> {</div>
<div class="line"><a id="l00114" name="l00114"></a><span class="lineno"> 114</span> TIBase::resetStates(resetCallback_);</div>
<div class="line"><a id="l00115" name="l00115"></a><span class="lineno"> 115</span> }</div>
<div class="line"><a id="l00116" name="l00116"></a><span class="lineno"> 116</span> ~ResetStatesGuard()</div>
<div class="line"><a id="l00117" name="l00117"></a><span class="lineno"> 117</span> {</div>
<div class="line"><a id="l00118" name="l00118"></a><span class="lineno"> 118</span> TIBase::resetStates(resetCallback_);</div>
<div class="line"><a id="l00119" name="l00119"></a><span class="lineno"> 119</span> }</div>
<div class="line"><a id="l00120" name="l00120"></a><span class="lineno"> 120</span> };</div>
<div class="line"><a id="l00121" name="l00121"></a><span class="lineno"> 121</span> </div>
<div class="line"><a id="l00122" name="l00122"></a><span class="lineno"> 122</span> TIBase() : id_{checkoutID()}</div>
<div class="line"><a id="l00123" name="l00123"></a><span class="lineno"> 123</span> {</div>
<div class="line"><a id="l00124" name="l00124"></a><span class="lineno"> 124</span> assert(state.size() &gt; id_);</div>
<div class="line"><a id="l00125" name="l00125"></a><span class="lineno"> 125</span> state[id_].store(TrackedState::alive, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>);</div>
<div class="line"><a id="l00126" name="l00126"></a><span class="lineno"> 126</span> }</div>
<div class="line"><a id="l00127" name="l00127"></a><span class="lineno"> 127</span> ~TIBase()</div>
<div class="line"><a id="l00128" name="l00128"></a><span class="lineno"> 128</span> {</div>
<div class="line"><a id="l00129" name="l00129"></a><span class="lineno"> 129</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00130" name="l00130"></a><span class="lineno"> 130</span> </div>
<div class="line"><a id="l00131" name="l00131"></a><span class="lineno"> 131</span> assert(state.size() &gt; id_);</div>
<div class="line"><a id="l00132" name="l00132"></a><span class="lineno"> 132</span> tracingCallback_(</div>
<div class="line"><a id="l00133" name="l00133"></a><span class="lineno"> 133</span> state[id_].load(<a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>), deletedStarted);</div>
<div class="line"><a id="l00134" name="l00134"></a><span class="lineno"> 134</span> </div>
<div class="line"><a id="l00135" name="l00135"></a><span class="lineno"> 135</span> assert(state.size() &gt; id_);</div>
<div class="line"><a id="l00136" name="l00136"></a><span class="lineno"> 136</span> <span class="comment">// Use relaxed memory order to try to avoid atomic operations from</span></div>
<div class="line"><a id="l00137" name="l00137"></a><span class="lineno"> 137</span> <span class="comment">// adding additional memory synchronizations that may hide threading</span></div>
<div class="line"><a id="l00138" name="l00138"></a><span class="lineno"> 138</span> <span class="comment">// errors in the underlying shared pointer class.</span></div>
<div class="line"><a id="l00139" name="l00139"></a><span class="lineno"> 139</span> state[id_].store(deletedStarted, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>);</div>
<div class="line"><a id="l00140" name="l00140"></a><span class="lineno"> 140</span> </div>
<div class="line"><a id="l00141" name="l00141"></a><span class="lineno"> 141</span> tracingCallback_(deletedStarted, deleted);</div>
<div class="line"><a id="l00142" name="l00142"></a><span class="lineno"> 142</span> </div>
<div class="line"><a id="l00143" name="l00143"></a><span class="lineno"> 143</span> assert(state.size() &gt; id_);</div>
<div class="line"><a id="l00144" name="l00144"></a><span class="lineno"> 144</span> state[id_].store(TrackedState::deleted, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>);</div>
<div class="line"><a id="l00145" name="l00145"></a><span class="lineno"> 145</span> </div>
<div class="line"><a id="l00146" name="l00146"></a><span class="lineno"> 146</span> tracingCallback_(TrackedState::deleted, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::nullopt</a>);</div>
<div class="line"><a id="l00147" name="l00147"></a><span class="lineno"> 147</span> }</div>
<div class="line"><a id="l00148" name="l00148"></a><span class="lineno"> 148</span> </div>
<div class="line"><a id="l00149" name="l00149"></a><span class="lineno"> 149</span> <span class="keywordtype">void</span></div>
<div class="line"><a id="l00150" name="l00150"></a><span class="lineno"> 150</span> partialDestructor()</div>
<div class="line"><a id="l00151" name="l00151"></a><span class="lineno"> 151</span> {</div>
<div class="line"><a id="l00152" name="l00152"></a><span class="lineno"> 152</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00153" name="l00153"></a><span class="lineno"> 153</span> </div>
<div class="line"><a id="l00154" name="l00154"></a><span class="lineno"> 154</span> assert(state.size() &gt; id_);</div>
<div class="line"><a id="l00155" name="l00155"></a><span class="lineno"> 155</span> tracingCallback_(</div>
<div class="line"><a id="l00156" name="l00156"></a><span class="lineno"> 156</span> state[id_].load(<a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>),</div>
<div class="line"><a id="l00157" name="l00157"></a><span class="lineno"> 157</span> partiallyDeletedStarted);</div>
<div class="line"><a id="l00158" name="l00158"></a><span class="lineno"> 158</span> </div>
<div class="line"><a id="l00159" name="l00159"></a><span class="lineno"> 159</span> assert(state.size() &gt; id_);</div>
<div class="line"><a id="l00160" name="l00160"></a><span class="lineno"> 160</span> state[id_].store(partiallyDeletedStarted, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>);</div>
<div class="line"><a id="l00161" name="l00161"></a><span class="lineno"> 161</span> </div>
<div class="line"><a id="l00162" name="l00162"></a><span class="lineno"> 162</span> tracingCallback_(partiallyDeletedStarted, partiallyDeleted);</div>
<div class="line"><a id="l00163" name="l00163"></a><span class="lineno"> 163</span> </div>
<div class="line"><a id="l00164" name="l00164"></a><span class="lineno"> 164</span> assert(state.size() &gt; id_);</div>
<div class="line"><a id="l00165" name="l00165"></a><span class="lineno"> 165</span> state[id_].store(partiallyDeleted, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>);</div>
<div class="line"><a id="l00166" name="l00166"></a><span class="lineno"> 166</span> </div>
<div class="line"><a id="l00167" name="l00167"></a><span class="lineno"> 167</span> tracingCallback_(partiallyDeleted, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::nullopt</a>);</div>
<div class="line"><a id="l00168" name="l00168"></a><span class="lineno"> 168</span> }</div>
<div class="line"><a id="l00169" name="l00169"></a><span class="lineno"> 169</span> </div>
<div class="line"><a id="l00170" name="l00170"></a><span class="lineno"> 170</span> <span class="keyword">static</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/functional/function.html">std::function</a>&lt;void(TrackedState, <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a>)&gt;</div>
<div class="line"><a id="l00171" name="l00171"></a><span class="lineno"> 171</span> tracingCallback_;</div>
<div class="line"><a id="l00172" name="l00172"></a><span class="lineno"> 172</span> </div>
<div class="line"><a id="l00173" name="l00173"></a><span class="lineno"> 173</span> <span class="keywordtype">int</span> id_;</div>
<div class="line"><a id="l00174" name="l00174"></a><span class="lineno"> 174</span> </div>
<div class="line"><a id="l00175" name="l00175"></a><span class="lineno"> 175</span><span class="keyword">private</span>:</div>
<div class="line"><a id="l00176" name="l00176"></a><span class="lineno"> 176</span> <span class="keyword">static</span> <span class="keywordtype">int</span></div>
<div class="line"><a id="l00177" name="l00177"></a><span class="lineno"> 177</span> checkoutID()</div>
<div class="line"><a id="l00178" name="l00178"></a><span class="lineno"> 178</span> {</div>
<div class="line"><a id="l00179" name="l00179"></a><span class="lineno"> 179</span> <span class="keywordflow">return</span> nextId.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/atomic/atomic/fetch_add.html">fetch_add</a>(1, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_acq_rel</a>);</div>
<div class="line"><a id="l00180" name="l00180"></a><span class="lineno"> 180</span> }</div>
<div class="line"><a id="l00181" name="l00181"></a><span class="lineno"> 181</span>};</div>
<div class="line"><a id="l00182" name="l00182"></a><span class="lineno"> 182</span> </div>
<div class="line"><a id="l00183" name="l00183"></a><span class="lineno"> 183</span><a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/array.html">std::array&lt;std::atomic&lt;TrackedState&gt;</a>, TIBase::maxStates&gt; TIBase::state;</div>
<div class="line"><a id="l00184" name="l00184"></a><span class="lineno"> 184</span><a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/atomic/atomic.html">std::atomic&lt;int&gt;</a> TIBase::nextId{0};</div>
<div class="line"><a id="l00185" name="l00185"></a><span class="lineno"> 185</span> </div>
<div class="line"><a id="l00186" name="l00186"></a><span class="lineno"> 186</span><a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/functional/function.html">std::function</a>&lt;void(TrackedState, <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a>)&gt;</div>
<div class="line"><a id="l00187" name="l00187"></a><span class="lineno"> 187</span> TIBase::tracingCallback_ = [](TrackedState, <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a>) {};</div>
<div class="line"><a id="l00188" name="l00188"></a><span class="lineno"> 188</span> </div>
<div class="line"><a id="l00189" name="l00189"></a><span class="lineno"> 189</span>} <span class="comment">// namespace</span></div>
<div class="line"><a id="l00190" name="l00190"></a><span class="lineno"> 190</span> </div>
<div class="foldopen" id="foldopen00191" data-start="{" data-end="};">
<div class="line"><a id="l00191" name="l00191"></a><span class="lineno"><a class="line" href="classripple_1_1tests_1_1IntrusiveShared__test.html"> 191</a></span><span class="keyword">class </span><a class="code hl_class" href="classripple_1_1tests_1_1IntrusiveShared__test.html">IntrusiveShared_test</a> : <span class="keyword">public</span> <a class="code hl_class" href="classbeast_1_1unit__test_1_1suite.html">beast::unit_test::suite</a></div>
<div class="line"><a id="l00192" name="l00192"></a><span class="lineno"> 192</span>{</div>
<div class="line"><a id="l00193" name="l00193"></a><span class="lineno"> 193</span><span class="keyword">public</span>:</div>
<div class="line"><a id="l00194" name="l00194"></a><span class="lineno"> 194</span> <span class="keywordtype">void</span></div>
<div class="foldopen" id="foldopen00195" data-start="{" data-end="}">
<div class="line"><a id="l00195" name="l00195"></a><span class="lineno"><a class="line" href="classripple_1_1tests_1_1IntrusiveShared__test.html#afd702bb5084b97f82f9dc53124e8316d"> 195</a></span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#afd702bb5084b97f82f9dc53124e8316d">testBasics</a>()</div>
<div class="line"><a id="l00196" name="l00196"></a><span class="lineno"> 196</span> {</div>
<div class="line"><a id="l00197" name="l00197"></a><span class="lineno"> 197</span> <a class="code hl_variable" href="classbeast_1_1unit__test_1_1suite.html#aaa1237d9b85c69d35fe86645cee094b5">testcase</a>(<span class="stringliteral">&quot;Basics&quot;</span>);</div>
<div class="line"><a id="l00198" name="l00198"></a><span class="lineno"> 198</span> </div>
<div class="line"><a id="l00199" name="l00199"></a><span class="lineno"> 199</span> {</div>
<div class="line"><a id="l00200" name="l00200"></a><span class="lineno"> 200</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00201" name="l00201"></a><span class="lineno"> 201</span> </div>
<div class="line"><a id="l00202" name="l00202"></a><span class="lineno"> 202</span> TIBase b;</div>
<div class="line"><a id="l00203" name="l00203"></a><span class="lineno"> 203</span> BEAST_EXPECT(b.use_count() == 1);</div>
<div class="line"><a id="l00204" name="l00204"></a><span class="lineno"> 204</span> b.addWeakRef();</div>
<div class="line"><a id="l00205" name="l00205"></a><span class="lineno"> 205</span> BEAST_EXPECT(b.use_count() == 1);</div>
<div class="line"><a id="l00206" name="l00206"></a><span class="lineno"> 206</span> <span class="keyword">auto</span> s = b.releaseStrongRef();</div>
<div class="line"><a id="l00207" name="l00207"></a><span class="lineno"> 207</span> BEAST_EXPECT(s == <a class="code hl_enumvalue" href="namespaceripple.html#ac34a69f56216ea1e430c09ba049bf0aeaeb6e922eacce325bdb070a71f7ef7894">ReleaseStrongRefAction::partialDestroy</a>);</div>
<div class="line"><a id="l00208" name="l00208"></a><span class="lineno"> 208</span> BEAST_EXPECT(b.use_count() == 0);</div>
<div class="line"><a id="l00209" name="l00209"></a><span class="lineno"> 209</span> TIBase* pb = &amp;b;</div>
<div class="line"><a id="l00210" name="l00210"></a><span class="lineno"> 210</span> <a class="code hl_function" href="namespaceripple.html#a4aaf0c41d96f26147ee484a7b8dee51b">partialDestructorFinished</a>(&amp;pb);</div>
<div class="line"><a id="l00211" name="l00211"></a><span class="lineno"> 211</span> BEAST_EXPECT(!pb);</div>
<div class="line"><a id="l00212" name="l00212"></a><span class="lineno"> 212</span> <span class="keyword">auto</span> w = b.releaseWeakRef();</div>
<div class="line"><a id="l00213" name="l00213"></a><span class="lineno"> 213</span> BEAST_EXPECT(w == <a class="code hl_enumvalue" href="namespaceripple.html#a3b64e12be521bde0f95af971c64faf71afb14982288108e1fbd6207ef55f05027">ReleaseWeakRefAction::destroy</a>);</div>
<div class="line"><a id="l00214" name="l00214"></a><span class="lineno"> 214</span> }</div>
<div class="line"><a id="l00215" name="l00215"></a><span class="lineno"> 215</span> </div>
<div class="line"><a id="l00216" name="l00216"></a><span class="lineno"> 216</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;SharedIntrusive&lt;TIBase&gt;</a>&gt; strong;</div>
<div class="line"><a id="l00217" name="l00217"></a><span class="lineno"> 217</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;WeakIntrusive&lt;TIBase&gt;</a>&gt; weak;</div>
<div class="line"><a id="l00218" name="l00218"></a><span class="lineno"> 218</span> {</div>
<div class="line"><a id="l00219" name="l00219"></a><span class="lineno"> 219</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00220" name="l00220"></a><span class="lineno"> 220</span> </div>
<div class="line"><a id="l00221" name="l00221"></a><span class="lineno"> 221</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00222" name="l00222"></a><span class="lineno"> 222</span> <span class="keyword">auto</span> b = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00223" name="l00223"></a><span class="lineno"> 223</span> <span class="keyword">auto</span> <span class="keywordtype">id</span> = b-&gt;id_;</div>
<div class="line"><a id="l00224" name="l00224"></a><span class="lineno"> 224</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00225" name="l00225"></a><span class="lineno"> 225</span> BEAST_EXPECT(b-&gt;use_count() == 1);</div>
<div class="line"><a id="l00226" name="l00226"></a><span class="lineno"> 226</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; 10; ++i)</div>
<div class="line"><a id="l00227" name="l00227"></a><span class="lineno"> 227</span> {</div>
<div class="line"><a id="l00228" name="l00228"></a><span class="lineno"> 228</span> strong.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/push_back.html">push_back</a>(b);</div>
<div class="line"><a id="l00229" name="l00229"></a><span class="lineno"> 229</span> }</div>
<div class="line"><a id="l00230" name="l00230"></a><span class="lineno"> 230</span> b.reset();</div>
<div class="line"><a id="l00231" name="l00231"></a><span class="lineno"> 231</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00232" name="l00232"></a><span class="lineno"> 232</span> strong.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/resize.html">resize</a>(strong.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/size.html">size</a>() - 1);</div>
<div class="line"><a id="l00233" name="l00233"></a><span class="lineno"> 233</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00234" name="l00234"></a><span class="lineno"> 234</span> strong.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/clear.html">clear</a>();</div>
<div class="line"><a id="l00235" name="l00235"></a><span class="lineno"> 235</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == deleted);</div>
<div class="line"><a id="l00236" name="l00236"></a><span class="lineno"> 236</span> </div>
<div class="line"><a id="l00237" name="l00237"></a><span class="lineno"> 237</span> b = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00238" name="l00238"></a><span class="lineno"> 238</span> <span class="keywordtype">id</span> = b-&gt;id_;</div>
<div class="line"><a id="l00239" name="l00239"></a><span class="lineno"> 239</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00240" name="l00240"></a><span class="lineno"> 240</span> BEAST_EXPECT(b-&gt;use_count() == 1);</div>
<div class="line"><a id="l00241" name="l00241"></a><span class="lineno"> 241</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; 10; ++i)</div>
<div class="line"><a id="l00242" name="l00242"></a><span class="lineno"> 242</span> {</div>
<div class="line"><a id="l00243" name="l00243"></a><span class="lineno"> 243</span> weak.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/push_back.html">push_back</a>(b);</div>
<div class="line"><a id="l00244" name="l00244"></a><span class="lineno"> 244</span> BEAST_EXPECT(b-&gt;use_count() == 1);</div>
<div class="line"><a id="l00245" name="l00245"></a><span class="lineno"> 245</span> }</div>
<div class="line"><a id="l00246" name="l00246"></a><span class="lineno"> 246</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00247" name="l00247"></a><span class="lineno"> 247</span> weak.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/resize.html">resize</a>(weak.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/size.html">size</a>() - 1);</div>
<div class="line"><a id="l00248" name="l00248"></a><span class="lineno"> 248</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00249" name="l00249"></a><span class="lineno"> 249</span> b.reset();</div>
<div class="line"><a id="l00250" name="l00250"></a><span class="lineno"> 250</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == partiallyDeleted);</div>
<div class="line"><a id="l00251" name="l00251"></a><span class="lineno"> 251</span> <span class="keywordflow">while</span> (!weak.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/empty.html">empty</a>())</div>
<div class="line"><a id="l00252" name="l00252"></a><span class="lineno"> 252</span> {</div>
<div class="line"><a id="l00253" name="l00253"></a><span class="lineno"> 253</span> weak.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/resize.html">resize</a>(weak.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/size.html">size</a>() - 1);</div>
<div class="line"><a id="l00254" name="l00254"></a><span class="lineno"> 254</span> <span class="keywordflow">if</span> (weak.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/size.html">size</a>())</div>
<div class="line"><a id="l00255" name="l00255"></a><span class="lineno"> 255</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == partiallyDeleted);</div>
<div class="line"><a id="l00256" name="l00256"></a><span class="lineno"> 256</span> }</div>
<div class="line"><a id="l00257" name="l00257"></a><span class="lineno"> 257</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == deleted);</div>
<div class="line"><a id="l00258" name="l00258"></a><span class="lineno"> 258</span> }</div>
<div class="line"><a id="l00259" name="l00259"></a><span class="lineno"> 259</span> {</div>
<div class="line"><a id="l00260" name="l00260"></a><span class="lineno"> 260</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00261" name="l00261"></a><span class="lineno"> 261</span> </div>
<div class="line"><a id="l00262" name="l00262"></a><span class="lineno"> 262</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00263" name="l00263"></a><span class="lineno"> 263</span> <span class="keyword">auto</span> b = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00264" name="l00264"></a><span class="lineno"> 264</span> <span class="keyword">auto</span> <span class="keywordtype">id</span> = b-&gt;id_;</div>
<div class="line"><a id="l00265" name="l00265"></a><span class="lineno"> 265</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00266" name="l00266"></a><span class="lineno"> 266</span> <a class="code hl_class" href="classripple_1_1WeakIntrusive.html">WeakIntrusive&lt;TIBase&gt;</a> w{b};</div>
<div class="line"><a id="l00267" name="l00267"></a><span class="lineno"> 267</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00268" name="l00268"></a><span class="lineno"> 268</span> <span class="keyword">auto</span> s = w.lock();</div>
<div class="line"><a id="l00269" name="l00269"></a><span class="lineno"> 269</span> BEAST_EXPECT(s &amp;&amp; s-&gt;use_count() == 2);</div>
<div class="line"><a id="l00270" name="l00270"></a><span class="lineno"> 270</span> b.reset();</div>
<div class="line"><a id="l00271" name="l00271"></a><span class="lineno"> 271</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00272" name="l00272"></a><span class="lineno"> 272</span> BEAST_EXPECT(s &amp;&amp; s-&gt;use_count() == 1);</div>
<div class="line"><a id="l00273" name="l00273"></a><span class="lineno"> 273</span> s.reset();</div>
<div class="line"><a id="l00274" name="l00274"></a><span class="lineno"> 274</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == partiallyDeleted);</div>
<div class="line"><a id="l00275" name="l00275"></a><span class="lineno"> 275</span> BEAST_EXPECT(w.expired());</div>
<div class="line"><a id="l00276" name="l00276"></a><span class="lineno"> 276</span> s = w.lock();</div>
<div class="line"><a id="l00277" name="l00277"></a><span class="lineno"> 277</span> <span class="comment">// Cannot convert a weak pointer to a strong pointer if object is</span></div>
<div class="line"><a id="l00278" name="l00278"></a><span class="lineno"> 278</span> <span class="comment">// already partially deleted</span></div>
<div class="line"><a id="l00279" name="l00279"></a><span class="lineno"> 279</span> BEAST_EXPECT(!s);</div>
<div class="line"><a id="l00280" name="l00280"></a><span class="lineno"> 280</span> w.reset();</div>
<div class="line"><a id="l00281" name="l00281"></a><span class="lineno"> 281</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == deleted);</div>
<div class="line"><a id="l00282" name="l00282"></a><span class="lineno"> 282</span> }</div>
<div class="line"><a id="l00283" name="l00283"></a><span class="lineno"> 283</span> {</div>
<div class="line"><a id="l00284" name="l00284"></a><span class="lineno"> 284</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00285" name="l00285"></a><span class="lineno"> 285</span> </div>
<div class="line"><a id="l00286" name="l00286"></a><span class="lineno"> 286</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00287" name="l00287"></a><span class="lineno"> 287</span> <span class="keyword">using </span>swu = <a class="code hl_class" href="classripple_1_1SharedWeakUnion.html">SharedWeakUnion&lt;TIBase&gt;</a>;</div>
<div class="line"><a id="l00288" name="l00288"></a><span class="lineno"> 288</span> swu b = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00289" name="l00289"></a><span class="lineno"> 289</span> BEAST_EXPECT(b.isStrong() &amp;&amp; b.use_count() == 1);</div>
<div class="line"><a id="l00290" name="l00290"></a><span class="lineno"> 290</span> <span class="keyword">auto</span> <span class="keywordtype">id</span> = b.get()-&gt;id_;</div>
<div class="line"><a id="l00291" name="l00291"></a><span class="lineno"> 291</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00292" name="l00292"></a><span class="lineno"> 292</span> swu w = b;</div>
<div class="line"><a id="l00293" name="l00293"></a><span class="lineno"> 293</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00294" name="l00294"></a><span class="lineno"> 294</span> BEAST_EXPECT(w.isStrong() &amp;&amp; b.use_count() == 2);</div>
<div class="line"><a id="l00295" name="l00295"></a><span class="lineno"> 295</span> w.convertToWeak();</div>
<div class="line"><a id="l00296" name="l00296"></a><span class="lineno"> 296</span> BEAST_EXPECT(w.isWeak() &amp;&amp; b.use_count() == 1);</div>
<div class="line"><a id="l00297" name="l00297"></a><span class="lineno"> 297</span> swu s = w;</div>
<div class="line"><a id="l00298" name="l00298"></a><span class="lineno"> 298</span> BEAST_EXPECT(s.isWeak() &amp;&amp; b.use_count() == 1);</div>
<div class="line"><a id="l00299" name="l00299"></a><span class="lineno"> 299</span> s.convertToStrong();</div>
<div class="line"><a id="l00300" name="l00300"></a><span class="lineno"> 300</span> BEAST_EXPECT(s.isStrong() &amp;&amp; b.use_count() == 2);</div>
<div class="line"><a id="l00301" name="l00301"></a><span class="lineno"> 301</span> b.reset();</div>
<div class="line"><a id="l00302" name="l00302"></a><span class="lineno"> 302</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == alive);</div>
<div class="line"><a id="l00303" name="l00303"></a><span class="lineno"> 303</span> BEAST_EXPECT(s.use_count() == 1);</div>
<div class="line"><a id="l00304" name="l00304"></a><span class="lineno"> 304</span> BEAST_EXPECT(!w.expired());</div>
<div class="line"><a id="l00305" name="l00305"></a><span class="lineno"> 305</span> s.reset();</div>
<div class="line"><a id="l00306" name="l00306"></a><span class="lineno"> 306</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == partiallyDeleted);</div>
<div class="line"><a id="l00307" name="l00307"></a><span class="lineno"> 307</span> BEAST_EXPECT(w.expired());</div>
<div class="line"><a id="l00308" name="l00308"></a><span class="lineno"> 308</span> w.convertToStrong();</div>
<div class="line"><a id="l00309" name="l00309"></a><span class="lineno"> 309</span> <span class="comment">// Cannot convert a weak pointer to a strong pointer if object is</span></div>
<div class="line"><a id="l00310" name="l00310"></a><span class="lineno"> 310</span> <span class="comment">// already partially deleted</span></div>
<div class="line"><a id="l00311" name="l00311"></a><span class="lineno"> 311</span> BEAST_EXPECT(w.isWeak());</div>
<div class="line"><a id="l00312" name="l00312"></a><span class="lineno"> 312</span> w.reset();</div>
<div class="line"><a id="l00313" name="l00313"></a><span class="lineno"> 313</span> BEAST_EXPECT(TIBase::getState(<span class="keywordtype">id</span>) == deleted);</div>
<div class="line"><a id="l00314" name="l00314"></a><span class="lineno"> 314</span> }</div>
<div class="line"><a id="l00315" name="l00315"></a><span class="lineno"> 315</span> {</div>
<div class="line"><a id="l00316" name="l00316"></a><span class="lineno"> 316</span> <span class="comment">// Testing SharedWeakUnion assignment operator</span></div>
<div class="line"><a id="l00317" name="l00317"></a><span class="lineno"> 317</span> </div>
<div class="line"><a id="l00318" name="l00318"></a><span class="lineno"> 318</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00319" name="l00319"></a><span class="lineno"> 319</span> </div>
<div class="line"><a id="l00320" name="l00320"></a><span class="lineno"> 320</span> <span class="keyword">auto</span> strong1 = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00321" name="l00321"></a><span class="lineno"> 321</span> <span class="keyword">auto</span> strong2 = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00322" name="l00322"></a><span class="lineno"> 322</span> </div>
<div class="line"><a id="l00323" name="l00323"></a><span class="lineno"> 323</span> <span class="keyword">auto</span> id1 = strong1-&gt;id_;</div>
<div class="line"><a id="l00324" name="l00324"></a><span class="lineno"> 324</span> <span class="keyword">auto</span> id2 = strong2-&gt;id_;</div>
<div class="line"><a id="l00325" name="l00325"></a><span class="lineno"> 325</span> </div>
<div class="line"><a id="l00326" name="l00326"></a><span class="lineno"> 326</span> BEAST_EXPECT(id1 != id2);</div>
<div class="line"><a id="l00327" name="l00327"></a><span class="lineno"> 327</span> </div>
<div class="line"><a id="l00328" name="l00328"></a><span class="lineno"> 328</span> <a class="code hl_class" href="classripple_1_1SharedWeakUnion.html">SharedWeakUnion&lt;TIBase&gt;</a> union1 = strong1;</div>
<div class="line"><a id="l00329" name="l00329"></a><span class="lineno"> 329</span> <a class="code hl_class" href="classripple_1_1SharedWeakUnion.html">SharedWeakUnion&lt;TIBase&gt;</a> union2 = strong2;</div>
<div class="line"><a id="l00330" name="l00330"></a><span class="lineno"> 330</span> </div>
<div class="line"><a id="l00331" name="l00331"></a><span class="lineno"> 331</span> BEAST_EXPECT(union1.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#a5f9b80090815d0a5bd676795ddc9bcc4">isStrong</a>());</div>
<div class="line"><a id="l00332" name="l00332"></a><span class="lineno"> 332</span> BEAST_EXPECT(union2.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#a5f9b80090815d0a5bd676795ddc9bcc4">isStrong</a>());</div>
<div class="line"><a id="l00333" name="l00333"></a><span class="lineno"> 333</span> BEAST_EXPECT(union1.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#aadc1e414a1dbb42a0294cbf9303a2c65">get</a>() == strong1.get());</div>
<div class="line"><a id="l00334" name="l00334"></a><span class="lineno"> 334</span> BEAST_EXPECT(union2.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#aadc1e414a1dbb42a0294cbf9303a2c65">get</a>() == strong2.get());</div>
<div class="line"><a id="l00335" name="l00335"></a><span class="lineno"> 335</span> </div>
<div class="line"><a id="l00336" name="l00336"></a><span class="lineno"> 336</span> <span class="comment">// 1) Normal assignment: explicitly calls SharedWeakUnion assignment</span></div>
<div class="line"><a id="l00337" name="l00337"></a><span class="lineno"> 337</span> union1 = union2;</div>
<div class="line"><a id="l00338" name="l00338"></a><span class="lineno"> 338</span> BEAST_EXPECT(union1.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#a5f9b80090815d0a5bd676795ddc9bcc4">isStrong</a>());</div>
<div class="line"><a id="l00339" name="l00339"></a><span class="lineno"> 339</span> BEAST_EXPECT(union2.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#a5f9b80090815d0a5bd676795ddc9bcc4">isStrong</a>());</div>
<div class="line"><a id="l00340" name="l00340"></a><span class="lineno"> 340</span> BEAST_EXPECT(union1.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#aadc1e414a1dbb42a0294cbf9303a2c65">get</a>() == union2.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#aadc1e414a1dbb42a0294cbf9303a2c65">get</a>());</div>
<div class="line"><a id="l00341" name="l00341"></a><span class="lineno"> 341</span> BEAST_EXPECT(TIBase::getState(id1) == TrackedState::alive);</div>
<div class="line"><a id="l00342" name="l00342"></a><span class="lineno"> 342</span> BEAST_EXPECT(TIBase::getState(id2) == TrackedState::alive);</div>
<div class="line"><a id="l00343" name="l00343"></a><span class="lineno"> 343</span> </div>
<div class="line"><a id="l00344" name="l00344"></a><span class="lineno"> 344</span> <span class="comment">// 2) Test self-assignment</span></div>
<div class="line"><a id="l00345" name="l00345"></a><span class="lineno"> 345</span> BEAST_EXPECT(union1.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#a5f9b80090815d0a5bd676795ddc9bcc4">isStrong</a>());</div>
<div class="line"><a id="l00346" name="l00346"></a><span class="lineno"> 346</span> BEAST_EXPECT(TIBase::getState(id1) == TrackedState::alive);</div>
<div class="line"><a id="l00347" name="l00347"></a><span class="lineno"> 347</span> <span class="keywordtype">int</span> initialRefCount = strong1-&gt;use_count();</div>
<div class="line"><a id="l00348" name="l00348"></a><span class="lineno"> 348</span><span class="preprocessor">#pragma clang diagnostic push</span></div>
<div class="line"><a id="l00349" name="l00349"></a><span class="lineno"> 349</span><span class="preprocessor">#pragma clang diagnostic ignored &quot;-Wself-assign-overloaded&quot;</span></div>
<div class="line"><a id="l00350" name="l00350"></a><span class="lineno"> 350</span> union1 = union1; <span class="comment">// Self-assignment</span></div>
<div class="line"><a id="l00351" name="l00351"></a><span class="lineno"> 351</span><span class="preprocessor">#pragma clang diagnostic pop</span></div>
<div class="line"><a id="l00352" name="l00352"></a><span class="lineno"> 352</span> BEAST_EXPECT(union1.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#a5f9b80090815d0a5bd676795ddc9bcc4">isStrong</a>());</div>
<div class="line"><a id="l00353" name="l00353"></a><span class="lineno"> 353</span> BEAST_EXPECT(TIBase::getState(id1) == TrackedState::alive);</div>
<div class="line"><a id="l00354" name="l00354"></a><span class="lineno"> 354</span> BEAST_EXPECT(strong1-&gt;use_count() == initialRefCount);</div>
<div class="line"><a id="l00355" name="l00355"></a><span class="lineno"> 355</span> </div>
<div class="line"><a id="l00356" name="l00356"></a><span class="lineno"> 356</span> <span class="comment">// 3) Test assignment from null union pointer</span></div>
<div class="line"><a id="l00357" name="l00357"></a><span class="lineno"> 357</span> union1 = <a class="code hl_class" href="classripple_1_1SharedWeakUnion.html">SharedWeakUnion&lt;TIBase&gt;</a>();</div>
<div class="line"><a id="l00358" name="l00358"></a><span class="lineno"> 358</span> BEAST_EXPECT(union1.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#aadc1e414a1dbb42a0294cbf9303a2c65">get</a>() == <span class="keyword">nullptr</span>);</div>
<div class="line"><a id="l00359" name="l00359"></a><span class="lineno"> 359</span> </div>
<div class="line"><a id="l00360" name="l00360"></a><span class="lineno"> 360</span> <span class="comment">// 4) Test assignment to expired union pointer</span></div>
<div class="line"><a id="l00361" name="l00361"></a><span class="lineno"> 361</span> strong2.reset();</div>
<div class="line"><a id="l00362" name="l00362"></a><span class="lineno"> 362</span> union2.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#ab5386228e1dc5f481ffe6412038bd6d8">reset</a>();</div>
<div class="line"><a id="l00363" name="l00363"></a><span class="lineno"> 363</span> union1 = union2;</div>
<div class="line"><a id="l00364" name="l00364"></a><span class="lineno"> 364</span> BEAST_EXPECT(union1.<a class="code hl_function" href="classripple_1_1SharedWeakUnion.html#aadc1e414a1dbb42a0294cbf9303a2c65">get</a>() == <span class="keyword">nullptr</span>);</div>
<div class="line"><a id="l00365" name="l00365"></a><span class="lineno"> 365</span> BEAST_EXPECT(TIBase::getState(id2) == TrackedState::deleted);</div>
<div class="line"><a id="l00366" name="l00366"></a><span class="lineno"> 366</span> }</div>
<div class="line"><a id="l00367" name="l00367"></a><span class="lineno"> 367</span> }</div>
</div>
<div class="line"><a id="l00368" name="l00368"></a><span class="lineno"> 368</span> </div>
<div class="line"><a id="l00369" name="l00369"></a><span class="lineno"> 369</span> <span class="keywordtype">void</span></div>
<div class="foldopen" id="foldopen00370" data-start="{" data-end="}">
<div class="line"><a id="l00370" name="l00370"></a><span class="lineno"><a class="line" href="classripple_1_1tests_1_1IntrusiveShared__test.html#af2a1c944c4a7e84b0909f74dd7ffecf3"> 370</a></span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#af2a1c944c4a7e84b0909f74dd7ffecf3">testPartialDelete</a>()</div>
<div class="line"><a id="l00371" name="l00371"></a><span class="lineno"> 371</span> {</div>
<div class="line"><a id="l00372" name="l00372"></a><span class="lineno"> 372</span> <a class="code hl_variable" href="classbeast_1_1unit__test_1_1suite.html#aaa1237d9b85c69d35fe86645cee094b5">testcase</a>(<span class="stringliteral">&quot;Partial Delete&quot;</span>);</div>
<div class="line"><a id="l00373" name="l00373"></a><span class="lineno"> 373</span> </div>
<div class="line"><a id="l00374" name="l00374"></a><span class="lineno"> 374</span> <span class="comment">// This test creates two threads. One with a strong pointer and one</span></div>
<div class="line"><a id="l00375" name="l00375"></a><span class="lineno"> 375</span> <span class="comment">// with a weak pointer. The strong pointer is reset while the weak</span></div>
<div class="line"><a id="l00376" name="l00376"></a><span class="lineno"> 376</span> <span class="comment">// pointer still holds a reference, triggering a partial delete.</span></div>
<div class="line"><a id="l00377" name="l00377"></a><span class="lineno"> 377</span> <span class="comment">// While the partial delete function runs (a sleep is inserted) the</span></div>
<div class="line"><a id="l00378" name="l00378"></a><span class="lineno"> 378</span> <span class="comment">// weak pointer is reset. The destructor should wait to run until</span></div>
<div class="line"><a id="l00379" name="l00379"></a><span class="lineno"> 379</span> <span class="comment">// after the partial delete function has completed running.</span></div>
<div class="line"><a id="l00380" name="l00380"></a><span class="lineno"> 380</span> </div>
<div class="line"><a id="l00381" name="l00381"></a><span class="lineno"> 381</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00382" name="l00382"></a><span class="lineno"> 382</span> </div>
<div class="line"><a id="l00383" name="l00383"></a><span class="lineno"> 383</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00384" name="l00384"></a><span class="lineno"> 384</span> </div>
<div class="line"><a id="l00385" name="l00385"></a><span class="lineno"> 385</span> <span class="keyword">auto</span> strong = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00386" name="l00386"></a><span class="lineno"> 386</span> <a class="code hl_class" href="classripple_1_1WeakIntrusive.html">WeakIntrusive&lt;TIBase&gt;</a> weak{strong};</div>
<div class="line"><a id="l00387" name="l00387"></a><span class="lineno"> 387</span> <span class="keywordtype">bool</span> destructorRan = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00388" name="l00388"></a><span class="lineno"> 388</span> <span class="keywordtype">bool</span> partialDeleteRan = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00389" name="l00389"></a><span class="lineno"> 389</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/latch.html">std::latch</a> partialDeleteStartedSyncPoint{2};</div>
<div class="line"><a id="l00390" name="l00390"></a><span class="lineno"> 390</span> strong-&gt;tracingCallback_ = [&amp;](TrackedState cur,</div>
<div class="line"><a id="l00391" name="l00391"></a><span class="lineno"> 391</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a> next) {</div>
<div class="line"><a id="l00392" name="l00392"></a><span class="lineno"> 392</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00393" name="l00393"></a><span class="lineno"> 393</span> <span class="keywordflow">if</span> (next == deletedStarted)</div>
<div class="line"><a id="l00394" name="l00394"></a><span class="lineno"> 394</span> {</div>
<div class="line"><a id="l00395" name="l00395"></a><span class="lineno"> 395</span> <span class="comment">// strong goes out of scope while weak is still in scope</span></div>
<div class="line"><a id="l00396" name="l00396"></a><span class="lineno"> 396</span> <span class="comment">// This checks that partialDelete has run to completion</span></div>
<div class="line"><a id="l00397" name="l00397"></a><span class="lineno"> 397</span> <span class="comment">// before the desturctor is called. A sleep is inserted</span></div>
<div class="line"><a id="l00398" name="l00398"></a><span class="lineno"> 398</span> <span class="comment">// inside the partial delete to make sure the destructor is</span></div>
<div class="line"><a id="l00399" name="l00399"></a><span class="lineno"> 399</span> <span class="comment">// given an opportunity to run durring partial delete.</span></div>
<div class="line"><a id="l00400" name="l00400"></a><span class="lineno"> 400</span> BEAST_EXPECT(cur == partiallyDeleted);</div>
<div class="line"><a id="l00401" name="l00401"></a><span class="lineno"> 401</span> }</div>
<div class="line"><a id="l00402" name="l00402"></a><span class="lineno"> 402</span> <span class="keywordflow">if</span> (next == partiallyDeletedStarted)</div>
<div class="line"><a id="l00403" name="l00403"></a><span class="lineno"> 403</span> {</div>
<div class="line"><a id="l00404" name="l00404"></a><span class="lineno"> 404</span> partialDeleteStartedSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00405" name="l00405"></a><span class="lineno"> 405</span> <span class="keyword">using namespace </span>std::chrono_literals;</div>
<div class="line"><a id="l00406" name="l00406"></a><span class="lineno"> 406</span> <span class="comment">// Sleep and let the weak pointer go out of scope,</span></div>
<div class="line"><a id="l00407" name="l00407"></a><span class="lineno"> 407</span> <span class="comment">// potentially triggering a destructor while partial delete</span></div>
<div class="line"><a id="l00408" name="l00408"></a><span class="lineno"> 408</span> <span class="comment">// is running. The test is to make sure that doesn&#39;t happen.</span></div>
<div class="line"><a id="l00409" name="l00409"></a><span class="lineno"> 409</span> <a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/thread/sleep_for.html">std::this_thread::sleep_for</a>(800ms);</div>
<div class="line"><a id="l00410" name="l00410"></a><span class="lineno"> 410</span> }</div>
<div class="line"><a id="l00411" name="l00411"></a><span class="lineno"> 411</span> <span class="keywordflow">if</span> (next == partiallyDeleted)</div>
<div class="line"><a id="l00412" name="l00412"></a><span class="lineno"> 412</span> {</div>
<div class="line"><a id="l00413" name="l00413"></a><span class="lineno"> 413</span> BEAST_EXPECT(!partialDeleteRan &amp;&amp; !destructorRan);</div>
<div class="line"><a id="l00414" name="l00414"></a><span class="lineno"> 414</span> partialDeleteRan = <span class="keyword">true</span>;</div>
<div class="line"><a id="l00415" name="l00415"></a><span class="lineno"> 415</span> }</div>
<div class="line"><a id="l00416" name="l00416"></a><span class="lineno"> 416</span> <span class="keywordflow">if</span> (next == deleted)</div>
<div class="line"><a id="l00417" name="l00417"></a><span class="lineno"> 417</span> {</div>
<div class="line"><a id="l00418" name="l00418"></a><span class="lineno"> 418</span> BEAST_EXPECT(!destructorRan);</div>
<div class="line"><a id="l00419" name="l00419"></a><span class="lineno"> 419</span> destructorRan = <span class="keyword">true</span>;</div>
<div class="line"><a id="l00420" name="l00420"></a><span class="lineno"> 420</span> }</div>
<div class="line"><a id="l00421" name="l00421"></a><span class="lineno"> 421</span> };</div>
<div class="line"><a id="l00422" name="l00422"></a><span class="lineno"> 422</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/thread.html">std::thread</a> t1{[&amp;] {</div>
<div class="line"><a id="l00423" name="l00423"></a><span class="lineno"> 423</span> partialDeleteStartedSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00424" name="l00424"></a><span class="lineno"> 424</span> weak.reset(); <span class="comment">// Trigger a full delete as soon as the partial</span></div>
<div class="line"><a id="l00425" name="l00425"></a><span class="lineno"> 425</span> <span class="comment">// delete starts</span></div>
<div class="line"><a id="l00426" name="l00426"></a><span class="lineno"> 426</span> }};</div>
<div class="line"><a id="l00427" name="l00427"></a><span class="lineno"> 427</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/thread.html">std::thread</a> t2{[&amp;] {</div>
<div class="line"><a id="l00428" name="l00428"></a><span class="lineno"> 428</span> strong.reset(); <span class="comment">// Trigger a partial delete</span></div>
<div class="line"><a id="l00429" name="l00429"></a><span class="lineno"> 429</span> }};</div>
<div class="line"><a id="l00430" name="l00430"></a><span class="lineno"> 430</span> t1.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/thread/thread/join.html">join</a>();</div>
<div class="line"><a id="l00431" name="l00431"></a><span class="lineno"> 431</span> t2.join();</div>
<div class="line"><a id="l00432" name="l00432"></a><span class="lineno"> 432</span> </div>
<div class="line"><a id="l00433" name="l00433"></a><span class="lineno"> 433</span> BEAST_EXPECT(destructorRan &amp;&amp; partialDeleteRan);</div>
<div class="line"><a id="l00434" name="l00434"></a><span class="lineno"> 434</span> }</div>
</div>
<div class="line"><a id="l00435" name="l00435"></a><span class="lineno"> 435</span> </div>
<div class="line"><a id="l00436" name="l00436"></a><span class="lineno"> 436</span> <span class="keywordtype">void</span></div>
<div class="foldopen" id="foldopen00437" data-start="{" data-end="}">
<div class="line"><a id="l00437" name="l00437"></a><span class="lineno"><a class="line" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a8902dcc2f391c0181d18c8cd18cce534"> 437</a></span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a8902dcc2f391c0181d18c8cd18cce534">testDestructor</a>()</div>
<div class="line"><a id="l00438" name="l00438"></a><span class="lineno"> 438</span> {</div>
<div class="line"><a id="l00439" name="l00439"></a><span class="lineno"> 439</span> <a class="code hl_variable" href="classbeast_1_1unit__test_1_1suite.html#aaa1237d9b85c69d35fe86645cee094b5">testcase</a>(<span class="stringliteral">&quot;Destructor&quot;</span>);</div>
<div class="line"><a id="l00440" name="l00440"></a><span class="lineno"> 440</span> </div>
<div class="line"><a id="l00441" name="l00441"></a><span class="lineno"> 441</span> <span class="comment">// This test creates two threads. One with a strong pointer and one</span></div>
<div class="line"><a id="l00442" name="l00442"></a><span class="lineno"> 442</span> <span class="comment">// with a weak pointer. The weak pointer is reset while the strong</span></div>
<div class="line"><a id="l00443" name="l00443"></a><span class="lineno"> 443</span> <span class="comment">// pointer still holds a reference. Then the strong pointer is</span></div>
<div class="line"><a id="l00444" name="l00444"></a><span class="lineno"> 444</span> <span class="comment">// reset. Only the destructor should run. The partial destructor</span></div>
<div class="line"><a id="l00445" name="l00445"></a><span class="lineno"> 445</span> <span class="comment">// should not be called. Since the weak reset runs to completion</span></div>
<div class="line"><a id="l00446" name="l00446"></a><span class="lineno"> 446</span> <span class="comment">// before the strong pointer is reset, threading doesn&#39;t add much to</span></div>
<div class="line"><a id="l00447" name="l00447"></a><span class="lineno"> 447</span> <span class="comment">// this test, but there is no harm in keeping it.</span></div>
<div class="line"><a id="l00448" name="l00448"></a><span class="lineno"> 448</span> </div>
<div class="line"><a id="l00449" name="l00449"></a><span class="lineno"> 449</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00450" name="l00450"></a><span class="lineno"> 450</span> </div>
<div class="line"><a id="l00451" name="l00451"></a><span class="lineno"> 451</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00452" name="l00452"></a><span class="lineno"> 452</span> </div>
<div class="line"><a id="l00453" name="l00453"></a><span class="lineno"> 453</span> <span class="keyword">auto</span> strong = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00454" name="l00454"></a><span class="lineno"> 454</span> <a class="code hl_class" href="classripple_1_1WeakIntrusive.html">WeakIntrusive&lt;TIBase&gt;</a> weak{strong};</div>
<div class="line"><a id="l00455" name="l00455"></a><span class="lineno"> 455</span> <span class="keywordtype">bool</span> destructorRan = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00456" name="l00456"></a><span class="lineno"> 456</span> <span class="keywordtype">bool</span> partialDeleteRan = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00457" name="l00457"></a><span class="lineno"> 457</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/latch.html">std::latch</a> weakResetSyncPoint{2};</div>
<div class="line"><a id="l00458" name="l00458"></a><span class="lineno"> 458</span> strong-&gt;tracingCallback_ = [&amp;](TrackedState cur,</div>
<div class="line"><a id="l00459" name="l00459"></a><span class="lineno"> 459</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a> next) {</div>
<div class="line"><a id="l00460" name="l00460"></a><span class="lineno"> 460</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00461" name="l00461"></a><span class="lineno"> 461</span> <span class="keywordflow">if</span> (next == partiallyDeleted)</div>
<div class="line"><a id="l00462" name="l00462"></a><span class="lineno"> 462</span> {</div>
<div class="line"><a id="l00463" name="l00463"></a><span class="lineno"> 463</span> BEAST_EXPECT(!partialDeleteRan &amp;&amp; !destructorRan);</div>
<div class="line"><a id="l00464" name="l00464"></a><span class="lineno"> 464</span> partialDeleteRan = <span class="keyword">true</span>;</div>
<div class="line"><a id="l00465" name="l00465"></a><span class="lineno"> 465</span> }</div>
<div class="line"><a id="l00466" name="l00466"></a><span class="lineno"> 466</span> <span class="keywordflow">if</span> (next == deleted)</div>
<div class="line"><a id="l00467" name="l00467"></a><span class="lineno"> 467</span> {</div>
<div class="line"><a id="l00468" name="l00468"></a><span class="lineno"> 468</span> BEAST_EXPECT(!destructorRan);</div>
<div class="line"><a id="l00469" name="l00469"></a><span class="lineno"> 469</span> destructorRan = <span class="keyword">true</span>;</div>
<div class="line"><a id="l00470" name="l00470"></a><span class="lineno"> 470</span> }</div>
<div class="line"><a id="l00471" name="l00471"></a><span class="lineno"> 471</span> };</div>
<div class="line"><a id="l00472" name="l00472"></a><span class="lineno"> 472</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/thread.html">std::thread</a> t1{[&amp;] {</div>
<div class="line"><a id="l00473" name="l00473"></a><span class="lineno"> 473</span> weak.reset();</div>
<div class="line"><a id="l00474" name="l00474"></a><span class="lineno"> 474</span> weakResetSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00475" name="l00475"></a><span class="lineno"> 475</span> }};</div>
<div class="line"><a id="l00476" name="l00476"></a><span class="lineno"> 476</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/thread/thread.html">std::thread</a> t2{[&amp;] {</div>
<div class="line"><a id="l00477" name="l00477"></a><span class="lineno"> 477</span> weakResetSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00478" name="l00478"></a><span class="lineno"> 478</span> strong.reset(); <span class="comment">// Trigger a partial delete</span></div>
<div class="line"><a id="l00479" name="l00479"></a><span class="lineno"> 479</span> }};</div>
<div class="line"><a id="l00480" name="l00480"></a><span class="lineno"> 480</span> t1.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/thread/thread/join.html">join</a>();</div>
<div class="line"><a id="l00481" name="l00481"></a><span class="lineno"> 481</span> t2.join();</div>
<div class="line"><a id="l00482" name="l00482"></a><span class="lineno"> 482</span> </div>
<div class="line"><a id="l00483" name="l00483"></a><span class="lineno"> 483</span> BEAST_EXPECT(destructorRan &amp;&amp; !partialDeleteRan);</div>
<div class="line"><a id="l00484" name="l00484"></a><span class="lineno"> 484</span> }</div>
</div>
<div class="line"><a id="l00485" name="l00485"></a><span class="lineno"> 485</span> </div>
<div class="line"><a id="l00486" name="l00486"></a><span class="lineno"> 486</span> <span class="keywordtype">void</span></div>
<div class="foldopen" id="foldopen00487" data-start="{" data-end="}">
<div class="line"><a id="l00487" name="l00487"></a><span class="lineno"><a class="line" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a4c2e8bcf2505eb1e12af38011846d826"> 487</a></span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a4c2e8bcf2505eb1e12af38011846d826">testMultithreadedClearMixedVariant</a>()</div>
<div class="line"><a id="l00488" name="l00488"></a><span class="lineno"> 488</span> {</div>
<div class="line"><a id="l00489" name="l00489"></a><span class="lineno"> 489</span> <a class="code hl_variable" href="classbeast_1_1unit__test_1_1suite.html#aaa1237d9b85c69d35fe86645cee094b5">testcase</a>(<span class="stringliteral">&quot;Multithreaded Clear Mixed Variant&quot;</span>);</div>
<div class="line"><a id="l00490" name="l00490"></a><span class="lineno"> 490</span> </div>
<div class="line"><a id="l00491" name="l00491"></a><span class="lineno"> 491</span> <span class="comment">// This test creates and destroys many strong and weak pointers in a</span></div>
<div class="line"><a id="l00492" name="l00492"></a><span class="lineno"> 492</span> <span class="comment">// loop. There is a random mix of strong and weak pointers stored in</span></div>
<div class="line"><a id="l00493" name="l00493"></a><span class="lineno"> 493</span> <span class="comment">// a vector (held as a variant). Both threads clear all the pointers</span></div>
<div class="line"><a id="l00494" name="l00494"></a><span class="lineno"> 494</span> <span class="comment">// and check that the invariants hold.</span></div>
<div class="line"><a id="l00495" name="l00495"></a><span class="lineno"> 495</span> </div>
<div class="line"><a id="l00496" name="l00496"></a><span class="lineno"> 496</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00497" name="l00497"></a><span class="lineno"> 497</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00498" name="l00498"></a><span class="lineno"> 498</span> </div>
<div class="line"><a id="l00499" name="l00499"></a><span class="lineno"> 499</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/atomic/atomic.html">std::atomic&lt;int&gt;</a> destructionState{0};</div>
<div class="line"><a id="l00500" name="l00500"></a><span class="lineno"> 500</span> <span class="comment">// returns destructorRan and partialDestructorRan (in that order)</span></div>
<div class="line"><a id="l00501" name="l00501"></a><span class="lineno"> 501</span> <span class="keyword">auto</span> getDestructorState = [&amp;]() -&gt; <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/pair.html">std::pair&lt;bool, bool&gt;</a> {</div>
<div class="line"><a id="l00502" name="l00502"></a><span class="lineno"> 502</span> <span class="keywordtype">int</span> s = destructionState.load(<a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>);</div>
<div class="line"><a id="l00503" name="l00503"></a><span class="lineno"> 503</span> <span class="keywordflow">return</span> {(s &amp; 1) != 0, (s &amp; 2) != 0};</div>
<div class="line"><a id="l00504" name="l00504"></a><span class="lineno"> 504</span> };</div>
<div class="line"><a id="l00505" name="l00505"></a><span class="lineno"> 505</span> <span class="keyword">auto</span> setDestructorRan = [&amp;]() -&gt; <span class="keywordtype">void</span> {</div>
<div class="line"><a id="l00506" name="l00506"></a><span class="lineno"> 506</span> destructionState.fetch_or(1, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_acq_rel</a>);</div>
<div class="line"><a id="l00507" name="l00507"></a><span class="lineno"> 507</span> };</div>
<div class="line"><a id="l00508" name="l00508"></a><span class="lineno"> 508</span> <span class="keyword">auto</span> setPartialDeleteRan = [&amp;]() -&gt; <span class="keywordtype">void</span> {</div>
<div class="line"><a id="l00509" name="l00509"></a><span class="lineno"> 509</span> destructionState.fetch_or(2, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_acq_rel</a>);</div>
<div class="line"><a id="l00510" name="l00510"></a><span class="lineno"> 510</span> };</div>
<div class="line"><a id="l00511" name="l00511"></a><span class="lineno"> 511</span> <span class="keyword">auto</span> tracingCallback = [&amp;](TrackedState cur,</div>
<div class="line"><a id="l00512" name="l00512"></a><span class="lineno"> 512</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a> next) {</div>
<div class="line"><a id="l00513" name="l00513"></a><span class="lineno"> 513</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00514" name="l00514"></a><span class="lineno"> 514</span> <span class="keyword">auto</span> [destructorRan, partialDeleteRan] = getDestructorState();</div>
<div class="line"><a id="l00515" name="l00515"></a><span class="lineno"> 515</span> <span class="keywordflow">if</span> (next == partiallyDeleted)</div>
<div class="line"><a id="l00516" name="l00516"></a><span class="lineno"> 516</span> {</div>
<div class="line"><a id="l00517" name="l00517"></a><span class="lineno"> 517</span> BEAST_EXPECT(!partialDeleteRan &amp;&amp; !destructorRan);</div>
<div class="line"><a id="l00518" name="l00518"></a><span class="lineno"> 518</span> setPartialDeleteRan();</div>
<div class="line"><a id="l00519" name="l00519"></a><span class="lineno"> 519</span> }</div>
<div class="line"><a id="l00520" name="l00520"></a><span class="lineno"> 520</span> <span class="keywordflow">if</span> (next == deleted)</div>
<div class="line"><a id="l00521" name="l00521"></a><span class="lineno"> 521</span> {</div>
<div class="line"><a id="l00522" name="l00522"></a><span class="lineno"> 522</span> BEAST_EXPECT(!destructorRan);</div>
<div class="line"><a id="l00523" name="l00523"></a><span class="lineno"> 523</span> setDestructorRan();</div>
<div class="line"><a id="l00524" name="l00524"></a><span class="lineno"> 524</span> }</div>
<div class="line"><a id="l00525" name="l00525"></a><span class="lineno"> 525</span> };</div>
<div class="line"><a id="l00526" name="l00526"></a><span class="lineno"> 526</span> <span class="keyword">auto</span> createVecOfPointers = [&amp;](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; toClone,</div>
<div class="line"><a id="l00527" name="l00527"></a><span class="lineno"> 527</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/numeric/random.html">std::default_random_engine</a>&amp; eng)</div>
<div class="line"><a id="l00528" name="l00528"></a><span class="lineno"> 528</span> -&gt; <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector</a>&lt;</div>
<div class="line"><a id="l00529" name="l00529"></a><span class="lineno"> 529</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/variant.html">std::variant</a>&lt;<a class="code hl_class" href="classripple_1_1SharedIntrusive.html">SharedIntrusive&lt;TIBase&gt;</a>, <a class="code hl_class" href="classripple_1_1WeakIntrusive.html">WeakIntrusive&lt;TIBase&gt;</a>&gt;&gt; {</div>
<div class="line"><a id="l00530" name="l00530"></a><span class="lineno"> 530</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector</a>&lt;</div>
<div class="line"><a id="l00531" name="l00531"></a><span class="lineno"> 531</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/variant.html">std::variant&lt;SharedIntrusive&lt;TIBase&gt;</a>, <a class="code hl_class" href="classripple_1_1WeakIntrusive.html">WeakIntrusive&lt;TIBase&gt;</a>&gt;&gt;</div>
<div class="line"><a id="l00532" name="l00532"></a><span class="lineno"> 532</span> result;</div>
<div class="line"><a id="l00533" name="l00533"></a><span class="lineno"> 533</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution.html">std::uniform_int_distribution&lt;&gt;</a> toCreateDist(4, 64);</div>
<div class="line"><a id="l00534" name="l00534"></a><span class="lineno"> 534</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution.html">std::uniform_int_distribution&lt;&gt;</a> isStrongDist(0, 1);</div>
<div class="line"><a id="l00535" name="l00535"></a><span class="lineno"> 535</span> <span class="keyword">auto</span> numToCreate = toCreateDist(eng);</div>
<div class="line"><a id="l00536" name="l00536"></a><span class="lineno"> 536</span> result.reserve(numToCreate);</div>
<div class="line"><a id="l00537" name="l00537"></a><span class="lineno"> 537</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numToCreate; ++i)</div>
<div class="line"><a id="l00538" name="l00538"></a><span class="lineno"> 538</span> {</div>
<div class="line"><a id="l00539" name="l00539"></a><span class="lineno"> 539</span> <span class="keywordflow">if</span> (isStrongDist(eng))</div>
<div class="line"><a id="l00540" name="l00540"></a><span class="lineno"> 540</span> {</div>
<div class="line"><a id="l00541" name="l00541"></a><span class="lineno"> 541</span> result.push_back(<a class="code hl_class" href="classripple_1_1SharedIntrusive.html">SharedIntrusive&lt;TIBase&gt;</a>(toClone));</div>
<div class="line"><a id="l00542" name="l00542"></a><span class="lineno"> 542</span> }</div>
<div class="line"><a id="l00543" name="l00543"></a><span class="lineno"> 543</span> <span class="keywordflow">else</span></div>
<div class="line"><a id="l00544" name="l00544"></a><span class="lineno"> 544</span> {</div>
<div class="line"><a id="l00545" name="l00545"></a><span class="lineno"> 545</span> result.push_back(<a class="code hl_class" href="classripple_1_1WeakIntrusive.html">WeakIntrusive&lt;TIBase&gt;</a>(toClone));</div>
<div class="line"><a id="l00546" name="l00546"></a><span class="lineno"> 546</span> }</div>
<div class="line"><a id="l00547" name="l00547"></a><span class="lineno"> 547</span> }</div>
<div class="line"><a id="l00548" name="l00548"></a><span class="lineno"> 548</span> <span class="keywordflow">return</span> result;</div>
<div class="line"><a id="l00549" name="l00549"></a><span class="lineno"> 549</span> };</div>
<div class="line"><a id="l00550" name="l00550"></a><span class="lineno"> 550</span> <span class="keyword">constexpr</span> <span class="keywordtype">int</span> loopIters = 2 * 1024;</div>
<div class="line"><a id="l00551" name="l00551"></a><span class="lineno"> 551</span> <span class="keyword">constexpr</span> <span class="keywordtype">int</span> numThreads = 16;</div>
<div class="line"><a id="l00552" name="l00552"></a><span class="lineno"> 552</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;SharedIntrusive&lt;TIBase&gt;</a>&gt; toClone;</div>
<div class="line"><a id="l00553" name="l00553"></a><span class="lineno"> 553</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> loopStartSyncPoint{numThreads};</div>
<div class="line"><a id="l00554" name="l00554"></a><span class="lineno"> 554</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> postCreateToCloneSyncPoint{numThreads};</div>
<div class="line"><a id="l00555" name="l00555"></a><span class="lineno"> 555</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> postCreateVecOfPointersSyncPoint{numThreads};</div>
<div class="line"><a id="l00556" name="l00556"></a><span class="lineno"> 556</span> <span class="keyword">auto</span> engines = [&amp;]() -&gt; <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;std::default_random_engine&gt;</a> {</div>
<div class="line"><a id="l00557" name="l00557"></a><span class="lineno"> 557</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/numeric/random/random_device.html">std::random_device</a> rd;</div>
<div class="line"><a id="l00558" name="l00558"></a><span class="lineno"> 558</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;std::default_random_engine&gt;</a> result;</div>
<div class="line"><a id="l00559" name="l00559"></a><span class="lineno"> 559</span> result.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/reserve.html">reserve</a>(numThreads);</div>
<div class="line"><a id="l00560" name="l00560"></a><span class="lineno"> 560</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numThreads; ++i)</div>
<div class="line"><a id="l00561" name="l00561"></a><span class="lineno"> 561</span> result.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/emplace_back.html">emplace_back</a>(rd());</div>
<div class="line"><a id="l00562" name="l00562"></a><span class="lineno"> 562</span> <span class="keywordflow">return</span> result;</div>
<div class="line"><a id="l00563" name="l00563"></a><span class="lineno"> 563</span> }();</div>
<div class="line"><a id="l00564" name="l00564"></a><span class="lineno"> 564</span> </div>
<div class="line"><a id="l00565" name="l00565"></a><span class="lineno"> 565</span> <span class="comment">// cloneAndDestroy clones the strong pointer into a vector of mixed</span></div>
<div class="line"><a id="l00566" name="l00566"></a><span class="lineno"> 566</span> <span class="comment">// strong and weak pointers and destroys them all at once.</span></div>
<div class="line"><a id="l00567" name="l00567"></a><span class="lineno"> 567</span> <span class="comment">// threadId==0 is special.</span></div>
<div class="line"><a id="l00568" name="l00568"></a><span class="lineno"> 568</span> <span class="keyword">auto</span> cloneAndDestroy = [&amp;](<span class="keywordtype">int</span> threadId) {</div>
<div class="line"><a id="l00569" name="l00569"></a><span class="lineno"> 569</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; loopIters; ++i)</div>
<div class="line"><a id="l00570" name="l00570"></a><span class="lineno"> 570</span> {</div>
<div class="line"><a id="l00571" name="l00571"></a><span class="lineno"> 571</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00572" name="l00572"></a><span class="lineno"> 572</span> loopStartSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00573" name="l00573"></a><span class="lineno"> 573</span> </div>
<div class="line"><a id="l00574" name="l00574"></a><span class="lineno"> 574</span> <span class="comment">// only thread 0 should reset the state</span></div>
<div class="line"><a id="l00575" name="l00575"></a><span class="lineno"> 575</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TIBase::ResetStatesGuard&gt;</a> rsg;</div>
<div class="line"><a id="l00576" name="l00576"></a><span class="lineno"> 576</span> <span class="keywordflow">if</span> (threadId == 0)</div>
<div class="line"><a id="l00577" name="l00577"></a><span class="lineno"> 577</span> {</div>
<div class="line"><a id="l00578" name="l00578"></a><span class="lineno"> 578</span> <span class="comment">// Thread 0 is the genesis thread. It creates the strong</span></div>
<div class="line"><a id="l00579" name="l00579"></a><span class="lineno"> 579</span> <span class="comment">// pointers to be cloned by the other threads. This</span></div>
<div class="line"><a id="l00580" name="l00580"></a><span class="lineno"> 580</span> <span class="comment">// thread will also check that the destructor ran and</span></div>
<div class="line"><a id="l00581" name="l00581"></a><span class="lineno"> 581</span> <span class="comment">// clear the temporary variables.</span></div>
<div class="line"><a id="l00582" name="l00582"></a><span class="lineno"> 582</span> </div>
<div class="line"><a id="l00583" name="l00583"></a><span class="lineno"> 583</span> rsg.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/utility/optional/emplace.html">emplace</a>(<span class="keyword">false</span>);</div>
<div class="line"><a id="l00584" name="l00584"></a><span class="lineno"> 584</span> <span class="keyword">auto</span> [destructorRan, partialDeleteRan] =</div>
<div class="line"><a id="l00585" name="l00585"></a><span class="lineno"> 585</span> getDestructorState();</div>
<div class="line"><a id="l00586" name="l00586"></a><span class="lineno"> 586</span> BEAST_EXPECT(!i || destructorRan);</div>
<div class="line"><a id="l00587" name="l00587"></a><span class="lineno"> 587</span> destructionState.store(0, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_release</a>);</div>
<div class="line"><a id="l00588" name="l00588"></a><span class="lineno"> 588</span> </div>
<div class="line"><a id="l00589" name="l00589"></a><span class="lineno"> 589</span> toClone.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/clear.html">clear</a>();</div>
<div class="line"><a id="l00590" name="l00590"></a><span class="lineno"> 590</span> toClone.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/resize.html">resize</a>(numThreads);</div>
<div class="line"><a id="l00591" name="l00591"></a><span class="lineno"> 591</span> <span class="keyword">auto</span> strong = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00592" name="l00592"></a><span class="lineno"> 592</span> strong-&gt;tracingCallback_ = tracingCallback;</div>
<div class="line"><a id="l00593" name="l00593"></a><span class="lineno"> 593</span> <a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/algorithm/fill.html">std::fill</a>(toClone.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/begin.html">begin</a>(), toClone.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/end.html">end</a>(), strong);</div>
<div class="line"><a id="l00594" name="l00594"></a><span class="lineno"> 594</span> }</div>
<div class="line"><a id="l00595" name="l00595"></a><span class="lineno"> 595</span> </div>
<div class="line"><a id="l00596" name="l00596"></a><span class="lineno"> 596</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00597" name="l00597"></a><span class="lineno"> 597</span> postCreateToCloneSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00598" name="l00598"></a><span class="lineno"> 598</span> </div>
<div class="line"><a id="l00599" name="l00599"></a><span class="lineno"> 599</span> <span class="keyword">auto</span> v =</div>
<div class="line"><a id="l00600" name="l00600"></a><span class="lineno"> 600</span> createVecOfPointers(toClone[threadId], engines[threadId]);</div>
<div class="line"><a id="l00601" name="l00601"></a><span class="lineno"> 601</span> toClone[threadId].reset();</div>
<div class="line"><a id="l00602" name="l00602"></a><span class="lineno"> 602</span> </div>
<div class="line"><a id="l00603" name="l00603"></a><span class="lineno"> 603</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00604" name="l00604"></a><span class="lineno"> 604</span> postCreateVecOfPointersSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00605" name="l00605"></a><span class="lineno"> 605</span> </div>
<div class="line"><a id="l00606" name="l00606"></a><span class="lineno"> 606</span> v.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/clear.html">clear</a>();</div>
<div class="line"><a id="l00607" name="l00607"></a><span class="lineno"> 607</span> }</div>
<div class="line"><a id="l00608" name="l00608"></a><span class="lineno"> 608</span> };</div>
<div class="line"><a id="l00609" name="l00609"></a><span class="lineno"> 609</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;std::thread&gt;</a> threads;</div>
<div class="line"><a id="l00610" name="l00610"></a><span class="lineno"> 610</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numThreads; ++i)</div>
<div class="line"><a id="l00611" name="l00611"></a><span class="lineno"> 611</span> {</div>
<div class="line"><a id="l00612" name="l00612"></a><span class="lineno"> 612</span> threads.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/emplace_back.html">emplace_back</a>(cloneAndDestroy, i);</div>
<div class="line"><a id="l00613" name="l00613"></a><span class="lineno"> 613</span> }</div>
<div class="line"><a id="l00614" name="l00614"></a><span class="lineno"> 614</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numThreads; ++i)</div>
<div class="line"><a id="l00615" name="l00615"></a><span class="lineno"> 615</span> {</div>
<div class="line"><a id="l00616" name="l00616"></a><span class="lineno"> 616</span> threads[i].join();</div>
<div class="line"><a id="l00617" name="l00617"></a><span class="lineno"> 617</span> }</div>
<div class="line"><a id="l00618" name="l00618"></a><span class="lineno"> 618</span> }</div>
</div>
<div class="line"><a id="l00619" name="l00619"></a><span class="lineno"> 619</span> </div>
<div class="line"><a id="l00620" name="l00620"></a><span class="lineno"> 620</span> <span class="keywordtype">void</span></div>
<div class="foldopen" id="foldopen00621" data-start="{" data-end="}">
<div class="line"><a id="l00621" name="l00621"></a><span class="lineno"><a class="line" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a620aec6a6233cb68d20b824029555485"> 621</a></span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a620aec6a6233cb68d20b824029555485">testMultithreadedClearMixedUnion</a>()</div>
<div class="line"><a id="l00622" name="l00622"></a><span class="lineno"> 622</span> {</div>
<div class="line"><a id="l00623" name="l00623"></a><span class="lineno"> 623</span> <a class="code hl_variable" href="classbeast_1_1unit__test_1_1suite.html#aaa1237d9b85c69d35fe86645cee094b5">testcase</a>(<span class="stringliteral">&quot;Multithreaded Clear Mixed Union&quot;</span>);</div>
<div class="line"><a id="l00624" name="l00624"></a><span class="lineno"> 624</span> </div>
<div class="line"><a id="l00625" name="l00625"></a><span class="lineno"> 625</span> <span class="comment">// This test creates and destroys many SharedWeak pointers in a</span></div>
<div class="line"><a id="l00626" name="l00626"></a><span class="lineno"> 626</span> <span class="comment">// loop. All the pointers start as strong and a loop randomly</span></div>
<div class="line"><a id="l00627" name="l00627"></a><span class="lineno"> 627</span> <span class="comment">// convert them between strong and weak pointers. Both threads clear</span></div>
<div class="line"><a id="l00628" name="l00628"></a><span class="lineno"> 628</span> <span class="comment">// all the pointers and check that the invariants hold.</span></div>
<div class="line"><a id="l00629" name="l00629"></a><span class="lineno"> 629</span> <span class="comment">//</span></div>
<div class="line"><a id="l00630" name="l00630"></a><span class="lineno"> 630</span> <span class="comment">// Note: This test also differs from the test above in that the pointers</span></div>
<div class="line"><a id="l00631" name="l00631"></a><span class="lineno"> 631</span> <span class="comment">// randomly change from strong to weak and from weak to strong in a</span></div>
<div class="line"><a id="l00632" name="l00632"></a><span class="lineno"> 632</span> <span class="comment">// loop. This can&#39;t be done in the variant test above because variant is</span></div>
<div class="line"><a id="l00633" name="l00633"></a><span class="lineno"> 633</span> <span class="comment">// not thread safe while the SharedWeakUnion is thread safe.</span></div>
<div class="line"><a id="l00634" name="l00634"></a><span class="lineno"> 634</span> </div>
<div class="line"><a id="l00635" name="l00635"></a><span class="lineno"> 635</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00636" name="l00636"></a><span class="lineno"> 636</span> </div>
<div class="line"><a id="l00637" name="l00637"></a><span class="lineno"> 637</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00638" name="l00638"></a><span class="lineno"> 638</span> </div>
<div class="line"><a id="l00639" name="l00639"></a><span class="lineno"> 639</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/atomic/atomic.html">std::atomic&lt;int&gt;</a> destructionState{0};</div>
<div class="line"><a id="l00640" name="l00640"></a><span class="lineno"> 640</span> <span class="comment">// returns destructorRan and partialDestructorRan (in that order)</span></div>
<div class="line"><a id="l00641" name="l00641"></a><span class="lineno"> 641</span> <span class="keyword">auto</span> getDestructorState = [&amp;]() -&gt; <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/pair.html">std::pair&lt;bool, bool&gt;</a> {</div>
<div class="line"><a id="l00642" name="l00642"></a><span class="lineno"> 642</span> <span class="keywordtype">int</span> s = destructionState.load(<a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>);</div>
<div class="line"><a id="l00643" name="l00643"></a><span class="lineno"> 643</span> <span class="keywordflow">return</span> {(s &amp; 1) != 0, (s &amp; 2) != 0};</div>
<div class="line"><a id="l00644" name="l00644"></a><span class="lineno"> 644</span> };</div>
<div class="line"><a id="l00645" name="l00645"></a><span class="lineno"> 645</span> <span class="keyword">auto</span> setDestructorRan = [&amp;]() -&gt; <span class="keywordtype">void</span> {</div>
<div class="line"><a id="l00646" name="l00646"></a><span class="lineno"> 646</span> destructionState.fetch_or(1, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_acq_rel</a>);</div>
<div class="line"><a id="l00647" name="l00647"></a><span class="lineno"> 647</span> };</div>
<div class="line"><a id="l00648" name="l00648"></a><span class="lineno"> 648</span> <span class="keyword">auto</span> setPartialDeleteRan = [&amp;]() -&gt; <span class="keywordtype">void</span> {</div>
<div class="line"><a id="l00649" name="l00649"></a><span class="lineno"> 649</span> destructionState.fetch_or(2, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_acq_rel</a>);</div>
<div class="line"><a id="l00650" name="l00650"></a><span class="lineno"> 650</span> };</div>
<div class="line"><a id="l00651" name="l00651"></a><span class="lineno"> 651</span> <span class="keyword">auto</span> tracingCallback = [&amp;](TrackedState cur,</div>
<div class="line"><a id="l00652" name="l00652"></a><span class="lineno"> 652</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a> next) {</div>
<div class="line"><a id="l00653" name="l00653"></a><span class="lineno"> 653</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00654" name="l00654"></a><span class="lineno"> 654</span> <span class="keyword">auto</span> [destructorRan, partialDeleteRan] = getDestructorState();</div>
<div class="line"><a id="l00655" name="l00655"></a><span class="lineno"> 655</span> <span class="keywordflow">if</span> (next == partiallyDeleted)</div>
<div class="line"><a id="l00656" name="l00656"></a><span class="lineno"> 656</span> {</div>
<div class="line"><a id="l00657" name="l00657"></a><span class="lineno"> 657</span> BEAST_EXPECT(!partialDeleteRan &amp;&amp; !destructorRan);</div>
<div class="line"><a id="l00658" name="l00658"></a><span class="lineno"> 658</span> setPartialDeleteRan();</div>
<div class="line"><a id="l00659" name="l00659"></a><span class="lineno"> 659</span> }</div>
<div class="line"><a id="l00660" name="l00660"></a><span class="lineno"> 660</span> <span class="keywordflow">if</span> (next == deleted)</div>
<div class="line"><a id="l00661" name="l00661"></a><span class="lineno"> 661</span> {</div>
<div class="line"><a id="l00662" name="l00662"></a><span class="lineno"> 662</span> BEAST_EXPECT(!destructorRan);</div>
<div class="line"><a id="l00663" name="l00663"></a><span class="lineno"> 663</span> setDestructorRan();</div>
<div class="line"><a id="l00664" name="l00664"></a><span class="lineno"> 664</span> }</div>
<div class="line"><a id="l00665" name="l00665"></a><span class="lineno"> 665</span> };</div>
<div class="line"><a id="l00666" name="l00666"></a><span class="lineno"> 666</span> <span class="keyword">auto</span> createVecOfPointers = [&amp;](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; toClone,</div>
<div class="line"><a id="l00667" name="l00667"></a><span class="lineno"> 667</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/numeric/random.html">std::default_random_engine</a>&amp; eng)</div>
<div class="line"><a id="l00668" name="l00668"></a><span class="lineno"> 668</span> -&gt; <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector</a>&lt;<a class="code hl_class" href="classripple_1_1SharedWeakUnion.html">SharedWeakUnion&lt;TIBase&gt;</a>&gt; {</div>
<div class="line"><a id="l00669" name="l00669"></a><span class="lineno"> 669</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;SharedWeakUnion&lt;TIBase&gt;</a>&gt; result;</div>
<div class="line"><a id="l00670" name="l00670"></a><span class="lineno"> 670</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution.html">std::uniform_int_distribution&lt;&gt;</a> toCreateDist(4, 64);</div>
<div class="line"><a id="l00671" name="l00671"></a><span class="lineno"> 671</span> <span class="keyword">auto</span> numToCreate = toCreateDist(eng);</div>
<div class="line"><a id="l00672" name="l00672"></a><span class="lineno"> 672</span> result.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/reserve.html">reserve</a>(numToCreate);</div>
<div class="line"><a id="l00673" name="l00673"></a><span class="lineno"> 673</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numToCreate; ++i)</div>
<div class="line"><a id="l00674" name="l00674"></a><span class="lineno"> 674</span> result.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/push_back.html">push_back</a>(<a class="code hl_class" href="classripple_1_1SharedIntrusive.html">SharedIntrusive&lt;TIBase&gt;</a>(toClone));</div>
<div class="line"><a id="l00675" name="l00675"></a><span class="lineno"> 675</span> <span class="keywordflow">return</span> result;</div>
<div class="line"><a id="l00676" name="l00676"></a><span class="lineno"> 676</span> };</div>
<div class="line"><a id="l00677" name="l00677"></a><span class="lineno"> 677</span> <span class="keyword">constexpr</span> <span class="keywordtype">int</span> loopIters = 2 * 1024;</div>
<div class="line"><a id="l00678" name="l00678"></a><span class="lineno"> 678</span> <span class="keyword">constexpr</span> <span class="keywordtype">int</span> flipPointersLoopIters = 256;</div>
<div class="line"><a id="l00679" name="l00679"></a><span class="lineno"> 679</span> <span class="keyword">constexpr</span> <span class="keywordtype">int</span> numThreads = 16;</div>
<div class="line"><a id="l00680" name="l00680"></a><span class="lineno"> 680</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;SharedIntrusive&lt;TIBase&gt;</a>&gt; toClone;</div>
<div class="line"><a id="l00681" name="l00681"></a><span class="lineno"> 681</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> loopStartSyncPoint{numThreads};</div>
<div class="line"><a id="l00682" name="l00682"></a><span class="lineno"> 682</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> postCreateToCloneSyncPoint{numThreads};</div>
<div class="line"><a id="l00683" name="l00683"></a><span class="lineno"> 683</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> postCreateVecOfPointersSyncPoint{numThreads};</div>
<div class="line"><a id="l00684" name="l00684"></a><span class="lineno"> 684</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> postFlipPointersLoopSyncPoint{numThreads};</div>
<div class="line"><a id="l00685" name="l00685"></a><span class="lineno"> 685</span> <span class="keyword">auto</span> engines = [&amp;]() -&gt; <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;std::default_random_engine&gt;</a> {</div>
<div class="line"><a id="l00686" name="l00686"></a><span class="lineno"> 686</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/numeric/random/random_device.html">std::random_device</a> rd;</div>
<div class="line"><a id="l00687" name="l00687"></a><span class="lineno"> 687</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;std::default_random_engine&gt;</a> result;</div>
<div class="line"><a id="l00688" name="l00688"></a><span class="lineno"> 688</span> result.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/reserve.html">reserve</a>(numThreads);</div>
<div class="line"><a id="l00689" name="l00689"></a><span class="lineno"> 689</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numThreads; ++i)</div>
<div class="line"><a id="l00690" name="l00690"></a><span class="lineno"> 690</span> result.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/emplace_back.html">emplace_back</a>(rd());</div>
<div class="line"><a id="l00691" name="l00691"></a><span class="lineno"> 691</span> <span class="keywordflow">return</span> result;</div>
<div class="line"><a id="l00692" name="l00692"></a><span class="lineno"> 692</span> }();</div>
<div class="line"><a id="l00693" name="l00693"></a><span class="lineno"> 693</span> </div>
<div class="line"><a id="l00694" name="l00694"></a><span class="lineno"> 694</span> <span class="comment">// cloneAndDestroy clones the strong pointer into a vector of</span></div>
<div class="line"><a id="l00695" name="l00695"></a><span class="lineno"> 695</span> <span class="comment">// mixed strong and weak pointers, runs a loop that randomly</span></div>
<div class="line"><a id="l00696" name="l00696"></a><span class="lineno"> 696</span> <span class="comment">// changes strong pointers to weak pointers, and destroys them</span></div>
<div class="line"><a id="l00697" name="l00697"></a><span class="lineno"> 697</span> <span class="comment">// all at once.</span></div>
<div class="line"><a id="l00698" name="l00698"></a><span class="lineno"> 698</span> <span class="keyword">auto</span> cloneAndDestroy = [&amp;](<span class="keywordtype">int</span> threadId) {</div>
<div class="line"><a id="l00699" name="l00699"></a><span class="lineno"> 699</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; loopIters; ++i)</div>
<div class="line"><a id="l00700" name="l00700"></a><span class="lineno"> 700</span> {</div>
<div class="line"><a id="l00701" name="l00701"></a><span class="lineno"> 701</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00702" name="l00702"></a><span class="lineno"> 702</span> loopStartSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00703" name="l00703"></a><span class="lineno"> 703</span> </div>
<div class="line"><a id="l00704" name="l00704"></a><span class="lineno"> 704</span> <span class="comment">// only thread 0 should reset the state</span></div>
<div class="line"><a id="l00705" name="l00705"></a><span class="lineno"> 705</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TIBase::ResetStatesGuard&gt;</a> rsg;</div>
<div class="line"><a id="l00706" name="l00706"></a><span class="lineno"> 706</span> <span class="keywordflow">if</span> (threadId == 0)</div>
<div class="line"><a id="l00707" name="l00707"></a><span class="lineno"> 707</span> {</div>
<div class="line"><a id="l00708" name="l00708"></a><span class="lineno"> 708</span> <span class="comment">// threadId 0 is the genesis thread. It creates the</span></div>
<div class="line"><a id="l00709" name="l00709"></a><span class="lineno"> 709</span> <span class="comment">// strong point to be cloned by the other threads. This</span></div>
<div class="line"><a id="l00710" name="l00710"></a><span class="lineno"> 710</span> <span class="comment">// thread will also check that the destructor ran and</span></div>
<div class="line"><a id="l00711" name="l00711"></a><span class="lineno"> 711</span> <span class="comment">// clear the temporary variables.</span></div>
<div class="line"><a id="l00712" name="l00712"></a><span class="lineno"> 712</span> rsg.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/utility/optional/emplace.html">emplace</a>(<span class="keyword">false</span>);</div>
<div class="line"><a id="l00713" name="l00713"></a><span class="lineno"> 713</span> <span class="keyword">auto</span> [destructorRan, partialDeleteRan] =</div>
<div class="line"><a id="l00714" name="l00714"></a><span class="lineno"> 714</span> getDestructorState();</div>
<div class="line"><a id="l00715" name="l00715"></a><span class="lineno"> 715</span> BEAST_EXPECT(!i || destructorRan);</div>
<div class="line"><a id="l00716" name="l00716"></a><span class="lineno"> 716</span> destructionState.store(0, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_release</a>);</div>
<div class="line"><a id="l00717" name="l00717"></a><span class="lineno"> 717</span> </div>
<div class="line"><a id="l00718" name="l00718"></a><span class="lineno"> 718</span> toClone.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/clear.html">clear</a>();</div>
<div class="line"><a id="l00719" name="l00719"></a><span class="lineno"> 719</span> toClone.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/resize.html">resize</a>(numThreads);</div>
<div class="line"><a id="l00720" name="l00720"></a><span class="lineno"> 720</span> <span class="keyword">auto</span> strong = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00721" name="l00721"></a><span class="lineno"> 721</span> strong-&gt;tracingCallback_ = tracingCallback;</div>
<div class="line"><a id="l00722" name="l00722"></a><span class="lineno"> 722</span> <a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/algorithm/fill.html">std::fill</a>(toClone.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/begin.html">begin</a>(), toClone.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/end.html">end</a>(), strong);</div>
<div class="line"><a id="l00723" name="l00723"></a><span class="lineno"> 723</span> }</div>
<div class="line"><a id="l00724" name="l00724"></a><span class="lineno"> 724</span> </div>
<div class="line"><a id="l00725" name="l00725"></a><span class="lineno"> 725</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00726" name="l00726"></a><span class="lineno"> 726</span> postCreateToCloneSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00727" name="l00727"></a><span class="lineno"> 727</span> </div>
<div class="line"><a id="l00728" name="l00728"></a><span class="lineno"> 728</span> <span class="keyword">auto</span> v =</div>
<div class="line"><a id="l00729" name="l00729"></a><span class="lineno"> 729</span> createVecOfPointers(toClone[threadId], engines[threadId]);</div>
<div class="line"><a id="l00730" name="l00730"></a><span class="lineno"> 730</span> toClone[threadId].reset();</div>
<div class="line"><a id="l00731" name="l00731"></a><span class="lineno"> 731</span> </div>
<div class="line"><a id="l00732" name="l00732"></a><span class="lineno"> 732</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00733" name="l00733"></a><span class="lineno"> 733</span> postCreateVecOfPointersSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00734" name="l00734"></a><span class="lineno"> 734</span> </div>
<div class="line"><a id="l00735" name="l00735"></a><span class="lineno"> 735</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution.html">std::uniform_int_distribution&lt;&gt;</a> isStrongDist(0, 1);</div>
<div class="line"><a id="l00736" name="l00736"></a><span class="lineno"> 736</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> f = 0; f &lt; flipPointersLoopIters; ++f)</div>
<div class="line"><a id="l00737" name="l00737"></a><span class="lineno"> 737</span> {</div>
<div class="line"><a id="l00738" name="l00738"></a><span class="lineno"> 738</span> <span class="keywordflow">for</span> (<span class="keyword">auto</span>&amp; p : v)</div>
<div class="line"><a id="l00739" name="l00739"></a><span class="lineno"> 739</span> {</div>
<div class="line"><a id="l00740" name="l00740"></a><span class="lineno"> 740</span> <span class="keywordflow">if</span> (isStrongDist(engines[threadId]))</div>
<div class="line"><a id="l00741" name="l00741"></a><span class="lineno"> 741</span> {</div>
<div class="line"><a id="l00742" name="l00742"></a><span class="lineno"> 742</span> p.convertToStrong();</div>
<div class="line"><a id="l00743" name="l00743"></a><span class="lineno"> 743</span> }</div>
<div class="line"><a id="l00744" name="l00744"></a><span class="lineno"> 744</span> <span class="keywordflow">else</span></div>
<div class="line"><a id="l00745" name="l00745"></a><span class="lineno"> 745</span> {</div>
<div class="line"><a id="l00746" name="l00746"></a><span class="lineno"> 746</span> p.convertToWeak();</div>
<div class="line"><a id="l00747" name="l00747"></a><span class="lineno"> 747</span> }</div>
<div class="line"><a id="l00748" name="l00748"></a><span class="lineno"> 748</span> }</div>
<div class="line"><a id="l00749" name="l00749"></a><span class="lineno"> 749</span> }</div>
<div class="line"><a id="l00750" name="l00750"></a><span class="lineno"> 750</span> </div>
<div class="line"><a id="l00751" name="l00751"></a><span class="lineno"> 751</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00752" name="l00752"></a><span class="lineno"> 752</span> postFlipPointersLoopSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00753" name="l00753"></a><span class="lineno"> 753</span> </div>
<div class="line"><a id="l00754" name="l00754"></a><span class="lineno"> 754</span> v.clear();</div>
<div class="line"><a id="l00755" name="l00755"></a><span class="lineno"> 755</span> }</div>
<div class="line"><a id="l00756" name="l00756"></a><span class="lineno"> 756</span> };</div>
<div class="line"><a id="l00757" name="l00757"></a><span class="lineno"> 757</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;std::thread&gt;</a> threads;</div>
<div class="line"><a id="l00758" name="l00758"></a><span class="lineno"> 758</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numThreads; ++i)</div>
<div class="line"><a id="l00759" name="l00759"></a><span class="lineno"> 759</span> {</div>
<div class="line"><a id="l00760" name="l00760"></a><span class="lineno"> 760</span> threads.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/emplace_back.html">emplace_back</a>(cloneAndDestroy, i);</div>
<div class="line"><a id="l00761" name="l00761"></a><span class="lineno"> 761</span> }</div>
<div class="line"><a id="l00762" name="l00762"></a><span class="lineno"> 762</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numThreads; ++i)</div>
<div class="line"><a id="l00763" name="l00763"></a><span class="lineno"> 763</span> {</div>
<div class="line"><a id="l00764" name="l00764"></a><span class="lineno"> 764</span> threads[i].join();</div>
<div class="line"><a id="l00765" name="l00765"></a><span class="lineno"> 765</span> }</div>
<div class="line"><a id="l00766" name="l00766"></a><span class="lineno"> 766</span> }</div>
</div>
<div class="line"><a id="l00767" name="l00767"></a><span class="lineno"> 767</span> </div>
<div class="line"><a id="l00768" name="l00768"></a><span class="lineno"> 768</span> <span class="keywordtype">void</span></div>
<div class="foldopen" id="foldopen00769" data-start="{" data-end="}">
<div class="line"><a id="l00769" name="l00769"></a><span class="lineno"><a class="line" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a79add23e5f87fd040165d21c31a9ce9a"> 769</a></span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a79add23e5f87fd040165d21c31a9ce9a">testMultithreadedLockingWeak</a>()</div>
<div class="line"><a id="l00770" name="l00770"></a><span class="lineno"> 770</span> {</div>
<div class="line"><a id="l00771" name="l00771"></a><span class="lineno"> 771</span> <a class="code hl_variable" href="classbeast_1_1unit__test_1_1suite.html#aaa1237d9b85c69d35fe86645cee094b5">testcase</a>(<span class="stringliteral">&quot;Multithreaded Locking Weak&quot;</span>);</div>
<div class="line"><a id="l00772" name="l00772"></a><span class="lineno"> 772</span> </div>
<div class="line"><a id="l00773" name="l00773"></a><span class="lineno"> 773</span> <span class="comment">// This test creates a single shared atomic pointer that multiple thread</span></div>
<div class="line"><a id="l00774" name="l00774"></a><span class="lineno"> 774</span> <span class="comment">// create weak pointers from. The threads then lock the weak pointers.</span></div>
<div class="line"><a id="l00775" name="l00775"></a><span class="lineno"> 775</span> <span class="comment">// Both threads clear all the pointers and check that the invariants</span></div>
<div class="line"><a id="l00776" name="l00776"></a><span class="lineno"> 776</span> <span class="comment">// hold.</span></div>
<div class="line"><a id="l00777" name="l00777"></a><span class="lineno"> 777</span> </div>
<div class="line"><a id="l00778" name="l00778"></a><span class="lineno"> 778</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00779" name="l00779"></a><span class="lineno"> 779</span> </div>
<div class="line"><a id="l00780" name="l00780"></a><span class="lineno"> 780</span> TIBase::ResetStatesGuard rsg{<span class="keyword">true</span>};</div>
<div class="line"><a id="l00781" name="l00781"></a><span class="lineno"> 781</span> </div>
<div class="line"><a id="l00782" name="l00782"></a><span class="lineno"> 782</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/atomic/atomic.html">std::atomic&lt;int&gt;</a> destructionState{0};</div>
<div class="line"><a id="l00783" name="l00783"></a><span class="lineno"> 783</span> <span class="comment">// returns destructorRan and partialDestructorRan (in that order)</span></div>
<div class="line"><a id="l00784" name="l00784"></a><span class="lineno"> 784</span> <span class="keyword">auto</span> getDestructorState = [&amp;]() -&gt; <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/pair.html">std::pair&lt;bool, bool&gt;</a> {</div>
<div class="line"><a id="l00785" name="l00785"></a><span class="lineno"> 785</span> <span class="keywordtype">int</span> s = destructionState.load(<a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_relaxed</a>);</div>
<div class="line"><a id="l00786" name="l00786"></a><span class="lineno"> 786</span> <span class="keywordflow">return</span> {(s &amp; 1) != 0, (s &amp; 2) != 0};</div>
<div class="line"><a id="l00787" name="l00787"></a><span class="lineno"> 787</span> };</div>
<div class="line"><a id="l00788" name="l00788"></a><span class="lineno"> 788</span> <span class="keyword">auto</span> setDestructorRan = [&amp;]() -&gt; <span class="keywordtype">void</span> {</div>
<div class="line"><a id="l00789" name="l00789"></a><span class="lineno"> 789</span> destructionState.fetch_or(1, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_acq_rel</a>);</div>
<div class="line"><a id="l00790" name="l00790"></a><span class="lineno"> 790</span> };</div>
<div class="line"><a id="l00791" name="l00791"></a><span class="lineno"> 791</span> <span class="keyword">auto</span> setPartialDeleteRan = [&amp;]() -&gt; <span class="keywordtype">void</span> {</div>
<div class="line"><a id="l00792" name="l00792"></a><span class="lineno"> 792</span> destructionState.fetch_or(2, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_acq_rel</a>);</div>
<div class="line"><a id="l00793" name="l00793"></a><span class="lineno"> 793</span> };</div>
<div class="line"><a id="l00794" name="l00794"></a><span class="lineno"> 794</span> <span class="keyword">auto</span> tracingCallback = [&amp;](TrackedState cur,</div>
<div class="line"><a id="l00795" name="l00795"></a><span class="lineno"> 795</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TrackedState&gt;</a> next) {</div>
<div class="line"><a id="l00796" name="l00796"></a><span class="lineno"> 796</span> <span class="keyword">using </span>enum TrackedState;</div>
<div class="line"><a id="l00797" name="l00797"></a><span class="lineno"> 797</span> <span class="keyword">auto</span> [destructorRan, partialDeleteRan] = getDestructorState();</div>
<div class="line"><a id="l00798" name="l00798"></a><span class="lineno"> 798</span> <span class="keywordflow">if</span> (next == partiallyDeleted)</div>
<div class="line"><a id="l00799" name="l00799"></a><span class="lineno"> 799</span> {</div>
<div class="line"><a id="l00800" name="l00800"></a><span class="lineno"> 800</span> BEAST_EXPECT(!partialDeleteRan &amp;&amp; !destructorRan);</div>
<div class="line"><a id="l00801" name="l00801"></a><span class="lineno"> 801</span> setPartialDeleteRan();</div>
<div class="line"><a id="l00802" name="l00802"></a><span class="lineno"> 802</span> }</div>
<div class="line"><a id="l00803" name="l00803"></a><span class="lineno"> 803</span> <span class="keywordflow">if</span> (next == deleted)</div>
<div class="line"><a id="l00804" name="l00804"></a><span class="lineno"> 804</span> {</div>
<div class="line"><a id="l00805" name="l00805"></a><span class="lineno"> 805</span> BEAST_EXPECT(!destructorRan);</div>
<div class="line"><a id="l00806" name="l00806"></a><span class="lineno"> 806</span> setDestructorRan();</div>
<div class="line"><a id="l00807" name="l00807"></a><span class="lineno"> 807</span> }</div>
<div class="line"><a id="l00808" name="l00808"></a><span class="lineno"> 808</span> };</div>
<div class="line"><a id="l00809" name="l00809"></a><span class="lineno"> 809</span> </div>
<div class="line"><a id="l00810" name="l00810"></a><span class="lineno"> 810</span> <span class="keyword">constexpr</span> <span class="keywordtype">int</span> loopIters = 2 * 1024;</div>
<div class="line"><a id="l00811" name="l00811"></a><span class="lineno"> 811</span> <span class="keyword">constexpr</span> <span class="keywordtype">int</span> lockWeakLoopIters = 256;</div>
<div class="line"><a id="l00812" name="l00812"></a><span class="lineno"> 812</span> <span class="keyword">constexpr</span> <span class="keywordtype">int</span> numThreads = 16;</div>
<div class="line"><a id="l00813" name="l00813"></a><span class="lineno"> 813</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;SharedIntrusive&lt;TIBase&gt;</a>&gt; toLock;</div>
<div class="line"><a id="l00814" name="l00814"></a><span class="lineno"> 814</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> loopStartSyncPoint{numThreads};</div>
<div class="line"><a id="l00815" name="l00815"></a><span class="lineno"> 815</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> postCreateToLockSyncPoint{numThreads};</div>
<div class="line"><a id="l00816" name="l00816"></a><span class="lineno"> 816</span> <a class="code hl_struct" href="structripple_1_1tests_1_1Barrier.html">Barrier</a> postLockWeakLoopSyncPoint{numThreads};</div>
<div class="line"><a id="l00817" name="l00817"></a><span class="lineno"> 817</span> </div>
<div class="line"><a id="l00818" name="l00818"></a><span class="lineno"> 818</span> <span class="comment">// lockAndDestroy creates weak pointers from the strong pointer</span></div>
<div class="line"><a id="l00819" name="l00819"></a><span class="lineno"> 819</span> <span class="comment">// and runs a loop that locks the weak pointer. At the end of the loop</span></div>
<div class="line"><a id="l00820" name="l00820"></a><span class="lineno"> 820</span> <span class="comment">// all the pointers are destroyed all at once.</span></div>
<div class="line"><a id="l00821" name="l00821"></a><span class="lineno"> 821</span> <span class="keyword">auto</span> lockAndDestroy = [&amp;](<span class="keywordtype">int</span> threadId) {</div>
<div class="line"><a id="l00822" name="l00822"></a><span class="lineno"> 822</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; loopIters; ++i)</div>
<div class="line"><a id="l00823" name="l00823"></a><span class="lineno"> 823</span> {</div>
<div class="line"><a id="l00824" name="l00824"></a><span class="lineno"> 824</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00825" name="l00825"></a><span class="lineno"> 825</span> loopStartSyncPoint.<a class="code hl_function" href="structripple_1_1tests_1_1Barrier.html#a3024a052f980b05e9585a5f892a4c15a">arrive_and_wait</a>();</div>
<div class="line"><a id="l00826" name="l00826"></a><span class="lineno"> 826</span> </div>
<div class="line"><a id="l00827" name="l00827"></a><span class="lineno"> 827</span> <span class="comment">// only thread 0 should reset the state</span></div>
<div class="line"><a id="l00828" name="l00828"></a><span class="lineno"> 828</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/utility/optional.html">std::optional&lt;TIBase::ResetStatesGuard&gt;</a> rsg;</div>
<div class="line"><a id="l00829" name="l00829"></a><span class="lineno"> 829</span> <span class="keywordflow">if</span> (threadId == 0)</div>
<div class="line"><a id="l00830" name="l00830"></a><span class="lineno"> 830</span> {</div>
<div class="line"><a id="l00831" name="l00831"></a><span class="lineno"> 831</span> <span class="comment">// threadId 0 is the genesis thread. It creates the</span></div>
<div class="line"><a id="l00832" name="l00832"></a><span class="lineno"> 832</span> <span class="comment">// strong point to be locked by the other threads. This</span></div>
<div class="line"><a id="l00833" name="l00833"></a><span class="lineno"> 833</span> <span class="comment">// thread will also check that the destructor ran and</span></div>
<div class="line"><a id="l00834" name="l00834"></a><span class="lineno"> 834</span> <span class="comment">// clear the temporary variables.</span></div>
<div class="line"><a id="l00835" name="l00835"></a><span class="lineno"> 835</span> rsg.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/utility/optional/emplace.html">emplace</a>(<span class="keyword">false</span>);</div>
<div class="line"><a id="l00836" name="l00836"></a><span class="lineno"> 836</span> <span class="keyword">auto</span> [destructorRan, partialDeleteRan] =</div>
<div class="line"><a id="l00837" name="l00837"></a><span class="lineno"> 837</span> getDestructorState();</div>
<div class="line"><a id="l00838" name="l00838"></a><span class="lineno"> 838</span> BEAST_EXPECT(!i || destructorRan);</div>
<div class="line"><a id="l00839" name="l00839"></a><span class="lineno"> 839</span> destructionState.store(0, <a class="code hl_variableRef" href="http://en.cppreference.com/w/cpp/types/is_same.html">std::memory_order_release</a>);</div>
<div class="line"><a id="l00840" name="l00840"></a><span class="lineno"> 840</span> </div>
<div class="line"><a id="l00841" name="l00841"></a><span class="lineno"> 841</span> toLock.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/clear.html">clear</a>();</div>
<div class="line"><a id="l00842" name="l00842"></a><span class="lineno"> 842</span> toLock.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/resize.html">resize</a>(numThreads);</div>
<div class="line"><a id="l00843" name="l00843"></a><span class="lineno"> 843</span> <span class="keyword">auto</span> strong = make_SharedIntrusive&lt;TIBase&gt;();</div>
<div class="line"><a id="l00844" name="l00844"></a><span class="lineno"> 844</span> strong-&gt;tracingCallback_ = tracingCallback;</div>
<div class="line"><a id="l00845" name="l00845"></a><span class="lineno"> 845</span> <a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/algorithm/fill.html">std::fill</a>(toLock.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/begin.html">begin</a>(), toLock.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/end.html">end</a>(), strong);</div>
<div class="line"><a id="l00846" name="l00846"></a><span class="lineno"> 846</span> }</div>
<div class="line"><a id="l00847" name="l00847"></a><span class="lineno"> 847</span> </div>
<div class="line"><a id="l00848" name="l00848"></a><span class="lineno"> 848</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00849" name="l00849"></a><span class="lineno"> 849</span> postCreateToLockSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00850" name="l00850"></a><span class="lineno"> 850</span> </div>
<div class="line"><a id="l00851" name="l00851"></a><span class="lineno"> 851</span> <span class="comment">// Multiple threads all create a weak pointer from the same</span></div>
<div class="line"><a id="l00852" name="l00852"></a><span class="lineno"> 852</span> <span class="comment">// strong pointer</span></div>
<div class="line"><a id="l00853" name="l00853"></a><span class="lineno"> 853</span> <a class="code hl_class" href="classripple_1_1WeakIntrusive.html">WeakIntrusive</a> weak{toLock[threadId]};</div>
<div class="line"><a id="l00854" name="l00854"></a><span class="lineno"> 854</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> wi = 0; wi &lt; lockWeakLoopIters; ++wi)</div>
<div class="line"><a id="l00855" name="l00855"></a><span class="lineno"> 855</span> {</div>
<div class="line"><a id="l00856" name="l00856"></a><span class="lineno"> 856</span> BEAST_EXPECT(!weak.expired());</div>
<div class="line"><a id="l00857" name="l00857"></a><span class="lineno"> 857</span> <span class="keyword">auto</span> strong = weak.lock();</div>
<div class="line"><a id="l00858" name="l00858"></a><span class="lineno"> 858</span> BEAST_EXPECT(strong);</div>
<div class="line"><a id="l00859" name="l00859"></a><span class="lineno"> 859</span> }</div>
<div class="line"><a id="l00860" name="l00860"></a><span class="lineno"> 860</span> </div>
<div class="line"><a id="l00861" name="l00861"></a><span class="lineno"> 861</span> <span class="comment">// ------ Sync Point ------</span></div>
<div class="line"><a id="l00862" name="l00862"></a><span class="lineno"> 862</span> postLockWeakLoopSyncPoint.arrive_and_wait();</div>
<div class="line"><a id="l00863" name="l00863"></a><span class="lineno"> 863</span> </div>
<div class="line"><a id="l00864" name="l00864"></a><span class="lineno"> 864</span> toLock[threadId].reset();</div>
<div class="line"><a id="l00865" name="l00865"></a><span class="lineno"> 865</span> }</div>
<div class="line"><a id="l00866" name="l00866"></a><span class="lineno"> 866</span> };</div>
<div class="line"><a id="l00867" name="l00867"></a><span class="lineno"> 867</span> <a class="code hl_classRef" href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector&lt;std::thread&gt;</a> threads;</div>
<div class="line"><a id="l00868" name="l00868"></a><span class="lineno"> 868</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numThreads; ++i)</div>
<div class="line"><a id="l00869" name="l00869"></a><span class="lineno"> 869</span> {</div>
<div class="line"><a id="l00870" name="l00870"></a><span class="lineno"> 870</span> threads.<a class="code hl_functionRef" href="http://en.cppreference.com/w/cpp/container/vector/emplace_back.html">emplace_back</a>(lockAndDestroy, i);</div>
<div class="line"><a id="l00871" name="l00871"></a><span class="lineno"> 871</span> }</div>
<div class="line"><a id="l00872" name="l00872"></a><span class="lineno"> 872</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numThreads; ++i)</div>
<div class="line"><a id="l00873" name="l00873"></a><span class="lineno"> 873</span> {</div>
<div class="line"><a id="l00874" name="l00874"></a><span class="lineno"> 874</span> threads[i].join();</div>
<div class="line"><a id="l00875" name="l00875"></a><span class="lineno"> 875</span> }</div>
<div class="line"><a id="l00876" name="l00876"></a><span class="lineno"> 876</span> }</div>
</div>
<div class="line"><a id="l00877" name="l00877"></a><span class="lineno"> 877</span> </div>
<div class="line"><a id="l00878" name="l00878"></a><span class="lineno"> 878</span> <span class="keywordtype">void</span></div>
<div class="foldopen" id="foldopen00879" data-start="{" data-end="}">
<div class="line"><a id="l00879" name="l00879"></a><span class="lineno"><a class="line" href="classripple_1_1tests_1_1IntrusiveShared__test.html#ac2d35432cbc707b838c0cb11ce6ddd94"> 879</a></span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#ac2d35432cbc707b838c0cb11ce6ddd94">run</a>()<span class="keyword"> override</span></div>
<div class="line"><a id="l00880" name="l00880"></a><span class="lineno"> 880</span><span class="keyword"> </span>{</div>
<div class="line"><a id="l00881" name="l00881"></a><span class="lineno"> 881</span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#afd702bb5084b97f82f9dc53124e8316d">testBasics</a>();</div>
<div class="line"><a id="l00882" name="l00882"></a><span class="lineno"> 882</span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#af2a1c944c4a7e84b0909f74dd7ffecf3">testPartialDelete</a>();</div>
<div class="line"><a id="l00883" name="l00883"></a><span class="lineno"> 883</span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a8902dcc2f391c0181d18c8cd18cce534">testDestructor</a>();</div>
<div class="line"><a id="l00884" name="l00884"></a><span class="lineno"> 884</span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a4c2e8bcf2505eb1e12af38011846d826">testMultithreadedClearMixedVariant</a>();</div>
<div class="line"><a id="l00885" name="l00885"></a><span class="lineno"> 885</span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a620aec6a6233cb68d20b824029555485">testMultithreadedClearMixedUnion</a>();</div>
<div class="line"><a id="l00886" name="l00886"></a><span class="lineno"> 886</span> <a class="code hl_function" href="classripple_1_1tests_1_1IntrusiveShared__test.html#a79add23e5f87fd040165d21c31a9ce9a">testMultithreadedLockingWeak</a>();</div>
<div class="line"><a id="l00887" name="l00887"></a><span class="lineno"> 887</span> }</div>
</div>
<div class="line"><a id="l00888" name="l00888"></a><span class="lineno"> 888</span>}; <span class="comment">// namespace tests</span></div>
</div>
<div class="line"><a id="l00889" name="l00889"></a><span class="lineno"> 889</span> </div>
<div class="line"><a id="l00890" name="l00890"></a><span class="lineno"><a class="line" href="namespaceripple_1_1tests.html#aeec698da3a357cd5ebec1bee1b07d4a0"> 890</a></span>BEAST_DEFINE_TESTSUITE(IntrusiveShared, basics, <a class="code hl_namespace" href="namespaceripple.html">ripple</a>);</div>
<div class="line"><a id="l00891" name="l00891"></a><span class="lineno"> 891</span>} <span class="comment">// namespace tests</span></div>
</div>
<div class="line"><a id="l00892" name="l00892"></a><span class="lineno"> 892</span>} <span class="comment">// namespace ripple</span></div>
<div class="ttc" id="aarray_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/array.html">array</a></div></div>
<div class="ttc" id="aatomic_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/atomic.html">atomic</a></div></div>
<div class="ttc" id="abegin_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/begin.html">std::vector::begin</a></div><div class="ttdeci">T begin(T... args)</div></div>
<div class="ttc" id="achrono_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/chrono.html">chrono</a></div></div>
<div class="ttc" id="aclassbeast_1_1unit__test_1_1suite_html"><div class="ttname"><a href="classbeast_1_1unit__test_1_1suite.html">beast::unit_test::suite</a></div><div class="ttdoc">A testsuite class.</div><div class="ttdef"><b>Definition</b> <a href="suite_8h_source.html#l00054">suite.h:55</a></div></div>
<div class="ttc" id="aclassbeast_1_1unit__test_1_1suite_html_aaa1237d9b85c69d35fe86645cee094b5"><div class="ttname"><a href="classbeast_1_1unit__test_1_1suite.html#aaa1237d9b85c69d35fe86645cee094b5">beast::unit_test::suite::testcase</a></div><div class="ttdeci">testcase_t testcase</div><div class="ttdoc">Memberspace for declaring test cases.</div><div class="ttdef"><b>Definition</b> <a href="suite_8h_source.html#l00155">suite.h:155</a></div></div>
<div class="ttc" id="aclassripple_1_1SharedIntrusive_html"><div class="ttname"><a href="classripple_1_1SharedIntrusive.html">ripple::SharedIntrusive</a></div><div class="ttdoc">A shared intrusive pointer class that supports weak pointers.</div><div class="ttdef"><b>Definition</b> <a href="IntrusivePointer_8h_source.html#l00087">IntrusivePointer.h:88</a></div></div>
<div class="ttc" id="aclassripple_1_1SharedWeakUnion_html"><div class="ttname"><a href="classripple_1_1SharedWeakUnion.html">ripple::SharedWeakUnion</a></div><div class="ttdoc">A combination of a strong and a weak intrusive pointer stored in the space of a single pointer.</div><div class="ttdef"><b>Definition</b> <a href="IntrusivePointer_8h_source.html#l00321">IntrusivePointer.h:322</a></div></div>
<div class="ttc" id="aclassripple_1_1SharedWeakUnion_html_a5f9b80090815d0a5bd676795ddc9bcc4"><div class="ttname"><a href="classripple_1_1SharedWeakUnion.html#a5f9b80090815d0a5bd676795ddc9bcc4">ripple::SharedWeakUnion::isStrong</a></div><div class="ttdeci">bool isStrong() const</div><div class="ttdoc">Return true is this represents a strong pointer.</div></div>
<div class="ttc" id="aclassripple_1_1SharedWeakUnion_html_aadc1e414a1dbb42a0294cbf9303a2c65"><div class="ttname"><a href="classripple_1_1SharedWeakUnion.html#aadc1e414a1dbb42a0294cbf9303a2c65">ripple::SharedWeakUnion::get</a></div><div class="ttdeci">T * get() const</div><div class="ttdoc">If this is a strong pointer, return the raw pointer.</div></div>
<div class="ttc" id="aclassripple_1_1SharedWeakUnion_html_ab5386228e1dc5f481ffe6412038bd6d8"><div class="ttname"><a href="classripple_1_1SharedWeakUnion.html#ab5386228e1dc5f481ffe6412038bd6d8">ripple::SharedWeakUnion::reset</a></div><div class="ttdeci">void reset()</div><div class="ttdoc">Set the pointer to null, decrement the appropriate ref count, and run the appropriate release action.</div></div>
<div class="ttc" id="aclassripple_1_1WeakIntrusive_html"><div class="ttname"><a href="classripple_1_1WeakIntrusive.html">ripple::WeakIntrusive</a></div><div class="ttdoc">A weak intrusive pointer class for the SharedIntrusive pointer class.</div><div class="ttdef"><b>Definition</b> <a href="IntrusivePointer_8h_source.html#l00243">IntrusivePointer.h:244</a></div></div>
<div class="ttc" id="aclassripple_1_1tests_1_1IntrusiveShared__test_html"><div class="ttname"><a href="classripple_1_1tests_1_1IntrusiveShared__test.html">ripple::tests::IntrusiveShared_test</a></div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00191">IntrusiveShared_test.cpp:192</a></div></div>
<div class="ttc" id="aclassripple_1_1tests_1_1IntrusiveShared__test_html_a4c2e8bcf2505eb1e12af38011846d826"><div class="ttname"><a href="classripple_1_1tests_1_1IntrusiveShared__test.html#a4c2e8bcf2505eb1e12af38011846d826">ripple::tests::IntrusiveShared_test::testMultithreadedClearMixedVariant</a></div><div class="ttdeci">void testMultithreadedClearMixedVariant()</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00487">IntrusiveShared_test.cpp:487</a></div></div>
<div class="ttc" id="aclassripple_1_1tests_1_1IntrusiveShared__test_html_a620aec6a6233cb68d20b824029555485"><div class="ttname"><a href="classripple_1_1tests_1_1IntrusiveShared__test.html#a620aec6a6233cb68d20b824029555485">ripple::tests::IntrusiveShared_test::testMultithreadedClearMixedUnion</a></div><div class="ttdeci">void testMultithreadedClearMixedUnion()</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00621">IntrusiveShared_test.cpp:621</a></div></div>
<div class="ttc" id="aclassripple_1_1tests_1_1IntrusiveShared__test_html_a79add23e5f87fd040165d21c31a9ce9a"><div class="ttname"><a href="classripple_1_1tests_1_1IntrusiveShared__test.html#a79add23e5f87fd040165d21c31a9ce9a">ripple::tests::IntrusiveShared_test::testMultithreadedLockingWeak</a></div><div class="ttdeci">void testMultithreadedLockingWeak()</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00769">IntrusiveShared_test.cpp:769</a></div></div>
<div class="ttc" id="aclassripple_1_1tests_1_1IntrusiveShared__test_html_a8902dcc2f391c0181d18c8cd18cce534"><div class="ttname"><a href="classripple_1_1tests_1_1IntrusiveShared__test.html#a8902dcc2f391c0181d18c8cd18cce534">ripple::tests::IntrusiveShared_test::testDestructor</a></div><div class="ttdeci">void testDestructor()</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00437">IntrusiveShared_test.cpp:437</a></div></div>
<div class="ttc" id="aclassripple_1_1tests_1_1IntrusiveShared__test_html_ac2d35432cbc707b838c0cb11ce6ddd94"><div class="ttname"><a href="classripple_1_1tests_1_1IntrusiveShared__test.html#ac2d35432cbc707b838c0cb11ce6ddd94">ripple::tests::IntrusiveShared_test::run</a></div><div class="ttdeci">void run() override</div><div class="ttdoc">Runs the suite.</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00879">IntrusiveShared_test.cpp:879</a></div></div>
<div class="ttc" id="aclassripple_1_1tests_1_1IntrusiveShared__test_html_af2a1c944c4a7e84b0909f74dd7ffecf3"><div class="ttname"><a href="classripple_1_1tests_1_1IntrusiveShared__test.html#af2a1c944c4a7e84b0909f74dd7ffecf3">ripple::tests::IntrusiveShared_test::testPartialDelete</a></div><div class="ttdeci">void testPartialDelete()</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00370">IntrusiveShared_test.cpp:370</a></div></div>
<div class="ttc" id="aclassripple_1_1tests_1_1IntrusiveShared__test_html_afd702bb5084b97f82f9dc53124e8316d"><div class="ttname"><a href="classripple_1_1tests_1_1IntrusiveShared__test.html#afd702bb5084b97f82f9dc53124e8316d">ripple::tests::IntrusiveShared_test::testBasics</a></div><div class="ttdeci">void testBasics()</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00195">IntrusiveShared_test.cpp:195</a></div></div>
<div class="ttc" id="aclear_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/clear.html">std::vector::clear</a></div><div class="ttdeci">T clear(T... args)</div></div>
<div class="ttc" id="acondition_variable_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/condition_variable.html">condition_variable</a></div></div>
<div class="ttc" id="aemplace_back_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/emplace_back.html">std::vector::emplace_back</a></div><div class="ttdeci">T emplace_back(T... args)</div></div>
<div class="ttc" id="aemplace_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/utility/optional/emplace.html">std::optional::emplace</a></div><div class="ttdeci">T emplace(T... args)</div></div>
<div class="ttc" id="aempty_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/empty.html">std::vector::empty</a></div><div class="ttdeci">T empty(T... args)</div></div>
<div class="ttc" id="aend_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/end.html">std::vector::end</a></div><div class="ttdeci">T end(T... args)</div></div>
<div class="ttc" id="afetch_add_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/atomic/atomic/fetch_add.html">std::atomic::fetch_add</a></div><div class="ttdeci">T fetch_add(T... args)</div></div>
<div class="ttc" id="afill_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/algorithm/fill.html">std::fill</a></div><div class="ttdeci">T fill(T... args)</div></div>
<div class="ttc" id="afunction_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/utility/functional/function.html">std::function</a></div></div>
<div class="ttc" id="ainteger_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/types/integer.html">std::uint8_t</a></div></div>
<div class="ttc" id="ais_same_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/types/is_same.html">std::is_same_v</a></div><div class="ttdeci">T is_same_v</div></div>
<div class="ttc" id="ajoin_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/thread/thread/join.html">std::thread::join</a></div><div class="ttdeci">T join(T... args)</div></div>
<div class="ttc" id="alatch_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/thread/latch.html">std::latch</a></div></div>
<div class="ttc" id="amutex_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/thread/mutex.html">std::mutex</a></div></div>
<div class="ttc" id="anamespaceripple_html"><div class="ttname"><a href="namespaceripple.html">ripple</a></div><div class="ttdoc">Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.</div><div class="ttdef"><b>Definition</b> <a href="algorithm_8h_source.html#l00025">algorithm.h:25</a></div></div>
<div class="ttc" id="anamespaceripple_html_a3b64e12be521bde0f95af971c64faf71afb14982288108e1fbd6207ef55f05027"><div class="ttname"><a href="namespaceripple.html#a3b64e12be521bde0f95af971c64faf71afb14982288108e1fbd6207ef55f05027">ripple::ReleaseWeakRefAction::destroy</a></div><div class="ttdeci">@ destroy</div></div>
<div class="ttc" id="anamespaceripple_html_a4aaf0c41d96f26147ee484a7b8dee51b"><div class="ttname"><a href="namespaceripple.html#a4aaf0c41d96f26147ee484a7b8dee51b">ripple::partialDestructorFinished</a></div><div class="ttdeci">void partialDestructorFinished(T **o)</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveRefCounts_8h_source.html#l00479">IntrusiveRefCounts.h:479</a></div></div>
<div class="ttc" id="anamespaceripple_html_ac34a69f56216ea1e430c09ba049bf0aeaeb6e922eacce325bdb070a71f7ef7894"><div class="ttname"><a href="namespaceripple.html#ac34a69f56216ea1e430c09ba049bf0aeaeb6e922eacce325bdb070a71f7ef7894">ripple::ReleaseStrongRefAction::partialDestroy</a></div><div class="ttdeci">@ partialDestroy</div></div>
<div class="ttc" id="anotify_all_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/thread/condition_variable/notify_all.html">std::condition_variable::notify_all</a></div><div class="ttdeci">T notify_all(T... args)</div></div>
<div class="ttc" id="aoptional_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/optional.html">optional</a></div></div>
<div class="ttc" id="apair_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/utility/pair.html">std::pair</a></div></div>
<div class="ttc" id="apush_back_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/push_back.html">std::vector::push_back</a></div><div class="ttdeci">T push_back(T... args)</div></div>
<div class="ttc" id="arandom_device_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/numeric/random/random_device.html">std::random_device</a></div></div>
<div class="ttc" id="arandom_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/random.html">random</a></div></div>
<div class="ttc" id="areserve_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/reserve.html">std::vector::reserve</a></div><div class="ttdeci">T reserve(T... args)</div></div>
<div class="ttc" id="aresize_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/resize.html">std::vector::resize</a></div><div class="ttdeci">T resize(T... args)</div></div>
<div class="ttc" id="asize_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector/size.html">std::vector::size</a></div><div class="ttdeci">T size(T... args)</div></div>
<div class="ttc" id="asize_t_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/types/size_t.html">std::size_t</a></div></div>
<div class="ttc" id="asleep_for_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/thread/sleep_for.html">std::this_thread::sleep_for</a></div><div class="ttdeci">T sleep_for(T... args)</div></div>
<div class="ttc" id="astore_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/atomic/atomic/store.html">std::atomic::store</a></div><div class="ttdeci">T store(T... args)</div></div>
<div class="ttc" id="astring_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/string.html">string</a></div></div>
<div class="ttc" id="astructripple_1_1tests_1_1Barrier_html"><div class="ttname"><a href="structripple_1_1tests_1_1Barrier.html">ripple::tests::Barrier</a></div><div class="ttdoc">Experimentally, we discovered that using std::barrier performs extremely poorly (~1 hour vs ~1 minute...</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00045">IntrusiveShared_test.cpp:46</a></div></div>
<div class="ttc" id="astructripple_1_1tests_1_1Barrier_html_a023130d72e3cc9fbc1d6640447f3c5a2"><div class="ttname"><a href="structripple_1_1tests_1_1Barrier.html#a023130d72e3cc9fbc1d6640447f3c5a2">ripple::tests::Barrier::mtx</a></div><div class="ttdeci">std::mutex mtx</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00047">IntrusiveShared_test.cpp:47</a></div></div>
<div class="ttc" id="astructripple_1_1tests_1_1Barrier_html_a3024a052f980b05e9585a5f892a4c15a"><div class="ttname"><a href="structripple_1_1tests_1_1Barrier.html#a3024a052f980b05e9585a5f892a4c15a">ripple::tests::Barrier::arrive_and_wait</a></div><div class="ttdeci">void arrive_and_wait()</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00057">IntrusiveShared_test.cpp:57</a></div></div>
<div class="ttc" id="astructripple_1_1tests_1_1Barrier_html_a4eb5b73370cd75c8ceef03605f903fa7"><div class="ttname"><a href="structripple_1_1tests_1_1Barrier.html#a4eb5b73370cd75c8ceef03605f903fa7">ripple::tests::Barrier::count</a></div><div class="ttdeci">int count</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00049">IntrusiveShared_test.cpp:49</a></div></div>
<div class="ttc" id="astructripple_1_1tests_1_1Barrier_html_a9db675aa86b2b103110ae21b991ae6af"><div class="ttname"><a href="structripple_1_1tests_1_1Barrier.html#a9db675aa86b2b103110ae21b991ae6af">ripple::tests::Barrier::Barrier</a></div><div class="ttdeci">Barrier(int n)</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00052">IntrusiveShared_test.cpp:52</a></div></div>
<div class="ttc" id="astructripple_1_1tests_1_1Barrier_html_aab2456bc9b654d4387f4d3ca6abee348"><div class="ttname"><a href="structripple_1_1tests_1_1Barrier.html#aab2456bc9b654d4387f4d3ca6abee348">ripple::tests::Barrier::initial</a></div><div class="ttdeci">int const initial</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00050">IntrusiveShared_test.cpp:50</a></div></div>
<div class="ttc" id="astructripple_1_1tests_1_1Barrier_html_abbafe75d92ca1705f9e48d32a34fb825"><div class="ttname"><a href="structripple_1_1tests_1_1Barrier.html#abbafe75d92ca1705f9e48d32a34fb825">ripple::tests::Barrier::cv</a></div><div class="ttdeci">std::condition_variable cv</div><div class="ttdef"><b>Definition</b> <a href="IntrusiveShared__test_8cpp_source.html#l00048">IntrusiveShared_test.cpp:48</a></div></div>
<div class="ttc" id="athread_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/thread.html">thread</a></div></div>
<div class="ttc" id="auniform_int_distribution_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution.html">std::uniform_int_distribution</a></div></div>
<div class="ttc" id="aunique_lock_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/thread/unique_lock.html">std::unique_lock</a></div></div>
<div class="ttc" id="avariant_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/header/variant.html">variant</a></div></div>
<div class="ttc" id="avector_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/container/vector.html">std::vector</a></div></div>
<div class="ttc" id="await_html"><div class="ttname"><a href="http://en.cppreference.com/w/cpp/thread/condition_variable/wait.html">std::condition_variable::wait</a></div><div class="ttdeci">T wait(T... args)</div></div>
</div><!-- fragment --></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8
</small></address>
</body>
</html>