<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title></title>
  <style type="text/css">
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
</head>
<body>
<p>Hi Hugo,</p>
<p>The helpers currently follow the same naming scheme as we have for other VLC-functions, though we could just as well put them inside a new namespace instead of using the <code>vlc_</code> prefix.</p>
<p>On 2018-07-12 15:20, Hugo Beauzée-Luyssen wrote:</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> Those are coming from my medialibrary branch, but since I plan on using
 them elsewhere at some point, might as well make them VLC wide
 Those helpers won't accept void* so they can't directly wrap a malloc
 call, but we could have additional wrapper that perform the
 reinterpret_cast for the caller.
 ---
  include/vlc_common.h | 55 ++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 55 insertions(+)

 diff --git a/include/vlc_common.h b/include/vlc_common.h
 index c88503c1a5..606f5fedf7 100644
 --- a/include/vlc_common.h
 +++ b/include/vlc_common.h
 @@ -1170,6 +1170,61 @@ static inline char *xstrdup (const char *str)
      return ptr;
  }

 +/******************************************************************************
 + * C++ memory management helpers
 + ******************************************************************************/
 +
 +#ifdef __cplusplus</code></pre>
</blockquote>
<p>Helpers are always nice, but one immediate reaction to the patch is that these four, as a consequence will force modules written in <code>C++</code> to be compiled as at least <code>C++11</code>, something we formerly did not demand.</p>
<p>This could be circumvented by introducing <code>#if __cplusplus >= 201103</code> so that we do not force an error diagnostic down someones throat who are for whatever stuck with an older compiler. One could argue that we should simply say <em>“hey, you need at least c++11 to compile a vlc module written in c++”</em>, though I don’t think we should make such unnecessary requirement.</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> +
 +#include <memory>
 +</code></pre>
</blockquote>
<p>An anonymous namespace would in my opinion be neater than declaring each of these entities as individually <code>static</code>.</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> +// Wraps a C pointer to be released with free.
 +// ex: vlc_wrap_cptr( var_GetString( "foo" ) );
 +template <typename T>
 +static inline std::unique_ptr<T, void (*)(void*)> vlc_wrap_cptr( T* ptr ) noexcept
 +{
 +    return std::unique_ptr<T, decltype( &free )>( ptr, &free );
 +}
 +
 +// Wraps a C array to be released with free.
 +// This is necessary to allow the operator[] to be used
 +template <typename T>
 +static inline std::unique_ptr<T[], void (*)(void*)> vlc_wrap_carray( T* ptr ) noexcept
 +{
 +    return std::unique_ptr<T[], decltype( &free )>( ptr, &free );
 +}
 +
 +// Wraps a pointer with a custom releaser
 +// ex: auto ptr = vlc_wrap_cptr( input_item, &input_item_Release );
 +template <typename T, typename Releaser>
 +static inline auto vlc_wrap_cptr( T* ptr, Releaser&& r )
 +    noexcept( noexcept( std::unique_ptr<T,
 +                        typename std::decay<decltype( r )>::type> {
 +                            ptr, std::forward<Releaser>( r )
 +                        } ) )
 +    -> std::unique_ptr<T, typename std::decay<decltype( r )>::type>
 +{
 +    return std::unique_ptr<T, typename std::decay<decltype( r )>::type>{
 +                ptr, std::forward<Releaser>( r )
 +    };
 +}</code></pre>
</blockquote>
<p><code>std::decay</code> lives in <code><type_traits></code>, and <code>std::forward</code> in <code><utility></code>.</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> +// Wraps a C array with a custom releaser
 +template <typename T, typename Releaser>
 +static inline auto vlc_wrap_carray( T* ptr, Releaser&& r )
 +    noexcept( noexcept( std::unique_ptr<T[],
 +                    typename std::decay<decltype( r )>::type> {
 +                        ptr, std::forward<Releaser>( r )
 +                    } ) )
 +    -> std::unique_ptr<T[], typename std::decay<decltype( r )>::type>
 +{
 +    return std::unique_ptr<T[], typename std::decay<decltype( r )>::type>{
 +        ptr, std::forward<Releaser>( r )
 +    };
 +}</code></pre>
</blockquote>
<p>As far as I am aware, both of the above overloads with custom releasers are doing more than they are required in terms of <code>noexcept</code>. If <code>Releaser</code> in <code>std::unique_ptr<class T, class Releaser></code> is not an <em>lvalue-reference</em>, it shall not throw an exception in its <em>move-</em> and/or <em>copy-constructor</em> (which one depends on the reference type of <code>r</code>).</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> +
 +#endif
 +
  /*****************************************************************************
   * libvlc features
   *****************************************************************************/
 -- 
 2.18.0</code></pre>
</blockquote>
</body>
</html>