OSDN Git Service

Changed Lazy<T> to take a lambda-function in its constructor. This avoids the need...
authorLoRd_MuldeR <mulder2@gmx.de>
Sat, 4 Nov 2017 20:10:32 +0000 (21:10 +0100)
committerLoRd_MuldeR <mulder2@gmx.de>
Sat, 4 Nov 2017 20:10:32 +0000 (21:10 +0100)
docs/d0/dce/class_m_utils_1_1_lazy.html
docs/d8/d4d/_lazy_8h.html
docs/d8/d4d/_lazy_8h_source.html
docs/da/d44/class_m_utils_1_1_lazy-members.html
include/MUtils/Lazy.h

index e231d5c..e263478 100644 (file)
@@ -65,10 +65,9 @@ $(function() {
 <div class="header">
   <div class="summary">
 <a href="#pub-methods">Public Member Functions</a> &#124;
-<a href="#pro-methods">Protected Member Functions</a> &#124;
 <a href="../../da/d44/class_m_utils_1_1_lazy-members.html">List of all members</a>  </div>
   <div class="headertitle">
-<div class="title">MUtils::Lazy&lt; T &gt; Class Template Reference<span class="mlabels"><span class="mlabel">abstract</span></span></div>  </div>
+<div class="title">MUtils::Lazy&lt; T &gt; Class Template Reference</div>  </div>
 </div><!--header-->
 <div class="contents">
 
@@ -79,23 +78,20 @@ $(function() {
 <table class="memberdecls">
 <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-methods"></a>
 Public Member Functions</h2></td></tr>
+<tr class="memitem:a7dc7baa7d7ac31c644965be2ccc4d8cd"><td class="memItemLeft" align="right" valign="top"><a id="a7dc7baa7d7ac31c644965be2ccc4d8cd"></a>
+&#160;</td><td class="memItemRight" valign="bottom"><b>Lazy</b> (std::function&lt; T *(void)&gt; &amp;&amp;initializer)</td></tr>
+<tr class="separator:a7dc7baa7d7ac31c644965be2ccc4d8cd"><td class="memSeparator" colspan="2">&#160;</td></tr>
 <tr class="memitem:a86cf7d344a38ea09d37d27acd8993f45"><td class="memItemLeft" align="right" valign="top"><a id="a86cf7d344a38ea09d37d27acd8993f45"></a>
 T &amp;&#160;</td><td class="memItemRight" valign="bottom"><b>operator*</b> (void)</td></tr>
 <tr class="separator:a86cf7d344a38ea09d37d27acd8993f45"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pro-methods"></a>
-Protected Member Functions</h2></td></tr>
-<tr class="memitem:a03f52adf0e421b20298f2f7578e3375f"><td class="memItemLeft" align="right" valign="top"><a id="a03f52adf0e421b20298f2f7578e3375f"></a>
-virtual T *&#160;</td><td class="memItemRight" valign="bottom"><b>create</b> ()=0</td></tr>
-<tr class="separator:a03f52adf0e421b20298f2f7578e3375f"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table>
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
 <div class="textblock"><h3>template&lt;typename T&gt;<br />
 class MUtils::Lazy&lt; T &gt;</h3>
 
 <p><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html" title="Lazy initialization template class. ">Lazy</a> initialization template class. </p>
-<p>In order to create your own "lazy" initializer, inherit from the <code><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html" title="Lazy initialization template class. ">Lazy</a>&lt;T&gt;</code> class an implement the <a class="el" href="../../d2/dad/_hash_8h.html#a330b73d6927d6cd95892712f9396f40e" title="Create instance of a hash function. ">create()</a> function. The lazy-initialized value can be obtained from a <code><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html" title="Lazy initialization template class. ">Lazy</a>&lt;T&gt;</code> instance by using the <code>operator*()</code>. Initialization of the value happens when the <code>operator*()</code> is called for the very first time, by invoking the concrete <a class="el" href="../../d2/dad/_hash_8h.html#a330b73d6927d6cd95892712f9396f40e" title="Create instance of a hash function. ">create()</a> function. The return value of <a class="el" href="../../d2/dad/_hash_8h.html#a330b73d6927d6cd95892712f9396f40e" title="Create instance of a hash function. ">create()</a> is then stored internally, so that any subsequent call to the <code>operator*()</code> immediately returns the previously created value.</p>
-<p><b>Note on thread-saftey:</b> This class is thread-safe in the sense that all calls to <code>operator*()</code> on the same <code><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html" title="Lazy initialization template class. ">Lazy</a>&lt;T&gt;</code> instance, regardless from which thread, are guaranteed to return the exactly same value/object. Still, if the value has <em>not</em> been initialized yet <b>and</b> if multiple threads happen to call <code>operator*()</code> at the same time, then the concrete <a class="el" href="../../d2/dad/_hash_8h.html#a330b73d6927d6cd95892712f9396f40e" title="Create instance of a hash function. ">create()</a> function <em>may</em> be invoked more than once (concurrently and by different threads). In that case, all but one return value of <a class="el" href="../../d2/dad/_hash_8h.html#a330b73d6927d6cd95892712f9396f40e" title="Create instance of a hash function. ">create()</a> are discarded, and all threads eventually receive the same value/object. </p>
+<p>The lazy-initialized value of type T can be obtained from a <code><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html" title="Lazy initialization template class. ">Lazy</a>&lt;T&gt;</code> instance by using the <code>operator*()</code>. Initialization of the value happens when the <code>operator*()</code> is called for the very first time, by invoking the <code>initializer</code> lambda-function that was passed to the constructor. The return value of the <code>initializer</code> lambda-function is then stored internally, so that any subsequent call to the <code>operator*()</code> <em>immediately</em> returns the previously created value.</p>
+<p><b>Note on thread-saftey:</b> This class is thread-safe in the sense that all calls to <code>operator*()</code> on the same <code><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html" title="Lazy initialization template class. ">Lazy</a>&lt;T&gt;</code> instance, regardless from which thread, are guaranteed to return the exactly same value/object. Still, if the value has <em>not</em> been initialized yet <b>and</b> if multiple threads happen to call <code>operator*()</code> at the same time, then the <code>initializer</code> lambda-function <em>may</em> be invoked more than once (concurrently and by different threads). In that case, all but one return value of the <code>initializer</code> lambda-function are discarded, and all threads eventually obtain the same value/object. </p>
 </div><hr/>The documentation for this class was generated from the following file:<ul>
 <li>include/MUtils/<a class="el" href="../../d8/d4d/_lazy_8h_source.html">Lazy.h</a></li>
 </ul>
index c567536..194cf96 100644 (file)
@@ -75,8 +75,8 @@ $(function() {
 <a href="#details">More...</a></p>
 <div class="textblock"><code>#include &lt;<a class="el" href="../../d5/d3b/_global_8h_source.html">MUtils/Global.h</a>&gt;</code><br />
 <code>#include &lt;MUtils/Exception.h&gt;</code><br />
-<code>#include &lt;QScopedPointer&gt;</code><br />
 <code>#include &lt;QAtomicPointer&gt;</code><br />
+<code>#include &lt;functional&gt;</code><br />
 </div>
 <p><a href="../../d8/d4d/_lazy_8h_source.html">Go to the source code of this file.</a></p>
 <table class="memberdecls">
index b9bac8d..45a9600 100644 (file)
@@ -67,8 +67,8 @@ $(function() {
 <div class="title">Lazy.h</div>  </div>
 </div><!--header-->
 <div class="contents">
-<a href="../../d8/d4d/_lazy_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">// MuldeR&#39;s Utilities for Qt</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment">// Copyright (C) 2004-2017 LoRd_MuldeR &lt;MuldeR2@GMX.de&gt;</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment">// This library is free software; you can redistribute it and/or</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment">// modify it under the terms of the GNU Lesser General Public</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment">// License as published by the Free Software Foundation; either</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment">// version 2.1 of the License, or (at your option) any later version.</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment">// This library is distributed in the hope that it will be useful,</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment">// but WITHOUT ANY WARRANTY; without even the implied warranty of</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment">// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment">// Lesser General Public License for more details.</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment">// You should have received a copy of the GNU Lesser General Public</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;<span class="comment">// License along with this library; if not, write to the Free Software</span></div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="comment">// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;<span class="comment">// http://www.gnu.org/licenses/lgpl-2.1.txt</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="comment"></span></div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="preprocessor">#pragma once</span></div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;<span class="comment">//MUtils</span></div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;<span class="preprocessor">#include &lt;<a class="code" href="../../d5/d3b/_global_8h.html">MUtils/Global.h</a>&gt;</span></div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;<span class="preprocessor">#include &lt;MUtils/Exception.h&gt;</span></div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;<span class="comment">//Qt</span></div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;<span class="preprocessor">#include &lt;QScopedPointer&gt;</span></div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;<span class="preprocessor">#include &lt;QAtomicPointer&gt;</span></div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;<span class="keyword">namespace </span><a class="code" href="../../d3/da6/namespace_m_utils.html">MUtils</a></div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;{</div><div class="line"><a name="l00046"></a><span class="lineno"><a class="line" href="../../d0/dce/class_m_utils_1_1_lazy.html">   46</a></span>&#160;    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt; <span class="keyword">class </span><a class="code" href="../../d0/dce/class_m_utils_1_1_lazy.html">Lazy</a></div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;    {</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;        T&amp; operator*(<span class="keywordtype">void</span>)</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;        {</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;            <span class="keywordflow">while</span> (!m_data)</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;            {</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;                <span class="keywordflow">if</span> (T *<span class="keyword">const</span> initializer = create())</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;                {</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;                    <span class="keywordflow">if</span> (m_data.testAndSetOrdered(NULL, initializer))</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;                    {</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;                        <span class="keywordflow">return</span> *initializer;</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;                    }</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;                }</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;                {</div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;                    MUTILS_THROW(<span class="stringliteral">&quot;Initializer function returned NULL!&quot;</span>);</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;                }</div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;            }</div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;            <span class="keywordflow">return</span> *m_data;</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;        }</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;    <span class="keyword">protected</span>:</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;        <span class="keyword">virtual</span> T *create() = 0;</div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;</div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;        QAtomicPointer&lt;T&gt; m_data;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;    };</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;}</div><div class="ttc" id="_global_8h_html"><div class="ttname"><a href="../../d5/d3b/_global_8h.html">Global.h</a></div><div class="ttdoc">This file contains miscellaneous functions that are generally useful for Qt-based applications...</div></div>
-<div class="ttc" id="class_m_utils_1_1_lazy_html"><div class="ttname"><a href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy</a></div><div class="ttdoc">Lazy initialization template class. </div><div class="ttdef"><b>Definition:</b> Lazy.h:46</div></div>
+<a href="../../d8/d4d/_lazy_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;<span class="comment">// MuldeR&#39;s Utilities for Qt</span></div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment">// Copyright (C) 2004-2017 LoRd_MuldeR &lt;MuldeR2@GMX.de&gt;</span></div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment">// This library is free software; you can redistribute it and/or</span></div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment">// modify it under the terms of the GNU Lesser General Public</span></div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment">// License as published by the Free Software Foundation; either</span></div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment">// version 2.1 of the License, or (at your option) any later version.</span></div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment">// This library is distributed in the hope that it will be useful,</span></div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment">// but WITHOUT ANY WARRANTY; without even the implied warranty of</span></div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment">// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</span></div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment">// Lesser General Public License for more details.</span></div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment">// You should have received a copy of the GNU Lesser General Public</span></div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;<span class="comment">// License along with this library; if not, write to the Free Software</span></div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="comment">// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA</span></div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;<span class="comment">// http://www.gnu.org/licenses/lgpl-2.1.txt</span></div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="comment"></span></div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="preprocessor">#pragma once</span></div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;<span class="comment">//MUtils</span></div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;<span class="preprocessor">#include &lt;<a class="code" href="../../d5/d3b/_global_8h.html">MUtils/Global.h</a>&gt;</span></div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;<span class="preprocessor">#include &lt;MUtils/Exception.h&gt;</span></div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;<span class="comment">//Qt</span></div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;<span class="preprocessor">#include &lt;QAtomicPointer&gt;</span></div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;<span class="comment">//CRT</span></div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;<span class="preprocessor">#include &lt;functional&gt;</span></div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;<span class="keyword">namespace </span><a class="code" href="../../d3/da6/namespace_m_utils.html">MUtils</a></div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;{</div><div class="line"><a name="l00048"></a><span class="lineno"><a class="line" href="../../d0/dce/class_m_utils_1_1_lazy.html">   48</a></span>&#160;    <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt; <span class="keyword">class </span><a class="code" href="../../d0/dce/class_m_utils_1_1_lazy.html">Lazy</a></div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;    {</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;    <span class="keyword">public</span>:</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;        <a class="code" href="../../d0/dce/class_m_utils_1_1_lazy.html">Lazy</a>(std::function&lt;T*(<span class="keywordtype">void</span>)&gt; &amp;&amp;initializer) : m_initializer(initializer) { }</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;        T&amp; operator*(<span class="keywordtype">void</span>)</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;        {</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;            <span class="keywordflow">while</span> (!m_value)</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;            {</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;                <span class="keywordflow">if</span> (T *<span class="keyword">const</span> value = m_initializer())</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;                {</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;                    <span class="keywordflow">if</span> (!m_value.testAndSetOrdered(NULL, value))</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;                    {</div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;                        <span class="keyword">delete</span> value; <span class="comment">/*too late*/</span></div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;                    }</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;                }</div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;                <span class="keywordflow">else</span></div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;                {</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;                    MUTILS_THROW(<span class="stringliteral">&quot;Initializer returned NULL!&quot;</span>);</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;                }</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;            }</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;            <span class="keywordflow">return</span> *m_value;</div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;        }</div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;    <span class="keyword">private</span>:</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;        QAtomicPointer&lt;T&gt; m_value;</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;        <span class="keyword">const</span> std::function&lt;T*(void)&gt; m_initializer;</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;    };</div><div class="line"><a name="l00076"></a><span class="lineno">   76</span>&#160;}</div><div class="ttc" id="_global_8h_html"><div class="ttname"><a href="../../d5/d3b/_global_8h.html">Global.h</a></div><div class="ttdoc">This file contains miscellaneous functions that are generally useful for Qt-based applications...</div></div>
+<div class="ttc" id="class_m_utils_1_1_lazy_html"><div class="ttname"><a href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy</a></div><div class="ttdoc">Lazy initialization template class. </div><div class="ttdef"><b>Definition:</b> Lazy.h:48</div></div>
 <div class="ttc" id="namespace_m_utils_html"><div class="ttname"><a href="../../d3/da6/namespace_m_utils.html">MUtils</a></div><div class="ttdoc">Global MUtils namespace. </div><div class="ttdef"><b>Definition:</b> CPUFeatures.h:37</div></div>
 </div><!-- fragment --></div><!-- contents -->
 <!-- start footer part -->
index 6f376b7..407b11f 100644 (file)
@@ -70,7 +70,7 @@ $(function() {
 
 <p>This is the complete list of members for <a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy&lt; T &gt;</a>, including all inherited members.</p>
 <table class="directory">
-  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>create</b>()=0 (defined in <a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy&lt; T &gt;</a>)</td><td class="entry"><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy&lt; T &gt;</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">pure virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>Lazy</b>(std::function&lt; T *(void)&gt; &amp;&amp;initializer) (defined in <a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy&lt; T &gt;</a>)</td><td class="entry"><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy&lt; T &gt;</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
   <tr bgcolor="#f0f0f0"><td class="entry"><b>operator*</b>(void) (defined in <a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy&lt; T &gt;</a>)</td><td class="entry"><a class="el" href="../../d0/dce/class_m_utils_1_1_lazy.html">MUtils::Lazy&lt; T &gt;</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
 </table></div><!-- contents -->
 <!-- start footer part -->
index 4c31051..5c2b15f 100644 (file)
 #include <MUtils/Exception.h>
 
 //Qt
-#include <QScopedPointer>
 #include <QAtomicPointer>
 
+//CRT
+#include <functional>
+
 namespace MUtils
 {
        /**
        * \brief Lazy initialization template class
        *
-       * In order to create your own "lazy" initializer, inherit from the `Lazy<T>` class an implement the create() function. The lazy-initialized value can be obtained from a `Lazy<T>` instance by using the `operator*()`. Initialization of the value happens when the `operator*()` is called for the very first time, by invoking the concrete create() function. The return value of create() is then stored internally, so that any subsequent call to the `operator*()` immediately returns the previously created value.
+       * The lazy-initialized value of type T can be obtained from a `Lazy<T>` instance by using the `operator*()`. Initialization of the value happens when the `operator*()` is called for the very first time, by invoking the `initializer` lambda-function that was passed to the constructor. The return value of the `initializer` lambda-function is then stored internally, so that any subsequent call to the `operator*()` *immediately* returns the previously created value.
        *
-       * **Note on thread-saftey:** This class is thread-safe in the sense that all calls to `operator*()` on the same `Lazy<T>` instance, regardless from which thread, are guaranteed to return the exactly same value/object. Still, if the value has *not* been initialized yet **and** if multiple threads happen to call `operator*()` at the same time, then the concrete create() function *may* be invoked more than once (concurrently and by different threads). In that case, all but one return value of create() are discarded, and all threads eventually receive the same value/object.
+       * **Note on thread-saftey:** This class is thread-safe in the sense that all calls to `operator*()` on the same `Lazy<T>` instance, regardless from which thread, are guaranteed to return the exactly same value/object. Still, if the value has *not* been initialized yet **and** if multiple threads happen to call `operator*()` at the same time, then the `initializer` lambda-function *may* be invoked more than once (concurrently and by different threads). In that case, all but one return value of the `initializer` lambda-function are discarded, and all threads eventually obtain the same value/object.
        */
        template<typename T> class Lazy
        {
        public:
+               Lazy(std::function<T*(void)> &&initializer) : m_initializer(initializer) { }
+
                T& operator*(void)
                {
-                       while (!m_data)
+                       while (!m_value)
                        {
-                               if (T *const initializer = create())
+                               if (T *const value = m_initializer())
                                {
-                                       if (!m_data.testAndSetOrdered(NULL, initializer))
+                                       if (!m_value.testAndSetOrdered(NULL, value))
                                        {
-                                               delete initializer;
+                                               delete value; /*too late*/
                                        }
                                }
                                else
                                {
-                                       MUTILS_THROW("Initializer function returned NULL!");
+                                       MUTILS_THROW("Initializer returned NULL!");
                                }
                        }
-                       return *m_data;
+                       return *m_value;
                }
 
-       protected:
-               virtual T *create() = 0;
-
        private:
-               QAtomicPointer<T> m_data;
+               QAtomicPointer<T> m_value;
+               const std::function<T*(void)> m_initializer;
        };
 }