<!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>