<div dir="ltr"><div>On Mon, Jun 24, 2019 at 5:55 PM Emil Dotchevski via Boost-users &lt;<a href="mailto:boost-users@lists.boost.org">boost-users@lists.boost.org</a>&gt; wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">On Sun, Jun 16, 2019 at 7:30 AM Zach Laine via Boost-users &lt;<a href="mailto:boost-users@lists.boost.org" target="_blank">boost-users@lists.boost.org</a>&gt; wrote:<br>&gt;<br>&gt; Dear Boost community,<br>&gt;<br>&gt; The formal review of JeanHeyd Meneide&#39;s out_ptr library starts Sunday, June 16th<br>&gt; and ends on Wednesday, June 26th.<br><br>Not yet a review, more like initial thoughts and questions.<br><br>I&#39;ve always used shared_ptr to wrap all kinds of &quot;handles&quot; to objects, including IUnknown and HANDLE on Windows, but even things like OpenGL unsigned int handles. It would be really nice to support such non-pointer handle types, so my initial reaction is that out_ptr doesn&#39;t go far enough.<br><br>To clarify what I mean by non-pointer handle types, consider that it makes sense to keep an OpenGL shader alive by a shared_ptr&lt;unsigned const&gt;, even though the OpenGL handle itself is an unsigned int, not a pointer. To this end I use the following helper function make_handle, which takes a non-pointer handle and a deleter function, and returns a shared_ptr:<br><br>namespace handle_detail<br>{<br>  template &lt;class H, class D&gt;<br>  struct deleter<br>  {<br>    deleter( H h, D d ):<br>      h_(h),<br>      d_(d)<br>    {<br>    }<br><br>    void operator()( H * h )<br>    {<br>      assert(!h);<br>      (void) d_(h_);<br>    }<br><br>    H h_;<br>    D d_;<br>  };<br>}<br><br>template &lt;class H,class D&gt;<br>std::shared_ptr&lt;H const&gt; make_handle( H h, D d )<br>{<br>  std::shared_ptr&lt;H&gt; p((H *)0,handle_detail::deleter&lt;H,D&gt;(h,d));<br>  return std::shared_ptr&lt;H const&gt;(<br>    p,<br>    &amp;std::get_deleter&lt;handle_detail::deleter&lt;H,D&gt; &gt;(p)-&gt;h_ );<br>}<br><br>Then I write a wrapper function for glCreateShader:<br><br>std::shared_ptr&lt;unsigned const&gt; CreateShader( unsigned shaderType )<br>{<br>  assert(!glGetError());<br>  if( unsigned s=glCreateShader(shaderType) )<br>  {<br>    if( unsigned err=glGetError_() )<br>      throw ....;<br>    return make_handle(s,glDeleteShader);<br>  }<br>  else<br>    throw zero_handle_detected();<br>}<br><br>Which in the end is used like this:<br><br>std::shared_ptr&lt;unsigned const&gt; sh = CreateShader(GL_VERTEX_SHADER);<div><br></div><div>As you can see the CreateShader wrapper is verbose and clunky, but easy to use. It would be nice to be able to automate that.<br><br>(By the way, it never crossed my mind to pass the shared_ptr, like it is done in out_ptr, instead of returning it. One problem with passing it as an argument is that it makes it impossible to use in a constructor initializer list.)</div><div><br></div><div>Which leads to my questions:</div><div><br></div><div>- Is it possible for out_ptr to support returning the shared_ptr instead of taking it as an argument?</div><div><br></div><div>- Is it possible to support non-pointer handle types as well?<br></div><div><br></div><div>- Can error handling be incorporated? I realize there are different options, but perhaps only two need to be supported: a result&lt;T&gt; of some sort (such types&#39; interfaces are somewhat standard much like smart pointer interfaces are) or throw an exception.</div></div></blockquote><div><br></div><div>Sorry for the overquoting; I&#39;m adding JenHeyd (the author), so he can easily share the context here.  He was not subscribed to boost-users previously.</div><div><br></div><div>Zach </div></div></div>