Boost logo

Boost Users :

From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2019-06-24 22:54:40


On Sun, Jun 16, 2019 at 7:30 AM Zach Laine via Boost-users <
boost-users_at_[hidden]> wrote:
>
> Dear Boost community,
>
> The formal review of JeanHeyd Meneide's out_ptr library starts Sunday,
June 16th
> and ends on Wednesday, June 26th.

Not yet a review, more like initial thoughts and questions.

I've always used shared_ptr to wrap all kinds of "handles" 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't go far enough.

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<unsigned const>, 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:

namespace handle_detail
{
  template <class H, class D>
  struct deleter
  {
    deleter( H h, D d ):
      h_(h),
      d_(d)
    {
    }

    void operator()( H * h )
    {
      assert(!h);
      (void) d_(h_);
    }

    H h_;
    D d_;
  };
}

template <class H,class D>
std::shared_ptr<H const> make_handle( H h, D d )
{
  std::shared_ptr<H> p((H *)0,handle_detail::deleter<H,D>(h,d));
  return std::shared_ptr<H const>(
    p,
    &std::get_deleter<handle_detail::deleter<H,D> >(p)->h_ );
}

Then I write a wrapper function for glCreateShader:

std::shared_ptr<unsigned const> CreateShader( unsigned shaderType )
{
  assert(!glGetError());
  if( unsigned s=glCreateShader(shaderType) )
  {
    if( unsigned err=glGetError_() )
      throw ....;
    return make_handle(s,glDeleteShader);
  }
  else
    throw zero_handle_detected();
}

Which in the end is used like this:

std::shared_ptr<unsigned const> sh = CreateShader(GL_VERTEX_SHADER);

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.

(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.)

Which leads to my questions:

- Is it possible for out_ptr to support returning the shared_ptr instead of
taking it as an argument?

- Is it possible to support non-pointer handle types as well?

- Can error handling be incorporated? I realize there are different
options, but perhaps only two need to be supported: a result<T> of some
sort (such types' interfaces are somewhat standard much like smart pointer
interfaces are) or throw an exception.



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net