2
0
mirror of https://github.com/boostorg/gil.git synced 2026-01-26 18:42:12 +00:00
Files
gil/develop/doc/html/design/technicalities.html
github-actions[bot] 62e86ae346 deploy: 4115f5b5d3
2026-01-23 01:40:49 +00:00

168 lines
12 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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 name="viewport" content="width=device-width, initial-scale=1" />
<title>Technicalities - Boost.GIL documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/style.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/sphinx_highlight.js"></script>
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/searchtools.js"></script>
<script src="../_static/language_data.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="top" title="Boost.GIL documentation" href="../index.html" />
<link rel="up" title="Design Guide" href="index.html" />
<link rel="next" title="Extending" href="extending.html" />
<link rel="prev" title="Examples" href="examples.html" />
</head>
<body>
<div class="header">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../index.html"><img
alt="C++ Boost" src="../../_static/gil.png" border="0"></a></h3>
</td>
<td >
<h1 align="center"><a href="../index.html"></a></h1>
</td>
<td>
<div id="searchbox" style="display: none">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Search" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</td>
</tr>
</table>
</div>
<hr/>
<div class="content">
<div class="navbar" style="text-align:right;">
<a class="prev" title="Examples" href="examples.html"><img src="../_static/prev.png" alt="prev"/></a>
<a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
<a class="next" title="Extending" href="extending.html"><img src="../_static/next.png" alt="next"/></a>
</div>
<section id="technicalities">
<h1>Technicalities<a class="headerlink" href="#technicalities" title="Link to this heading"></a></h1>
<nav class="contents local" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#creating-a-reference-proxy" id="id1">Creating a reference proxy</a></p></li>
</ul>
</nav>
<section id="creating-a-reference-proxy">
<h2><a class="toc-backref" href="#id1" role="doc-backlink">Creating a reference proxy</a><a class="headerlink" href="#creating-a-reference-proxy" title="Link to this heading"></a></h2>
<p>Sometimes it is necessary to create a proxy class that represents a
reference to a given object. Examples of these are GILs reference to
a planar pixel (<code class="docutils literal notranslate"><span class="pre">planar_pixel_reference</span></code>) and GILs sub-byte channel
references. Writing a reference proxy class can be tricky. One problem
is that the proxy reference is constructed as a temporary object and
returned by value upon dereferencing the iterator:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">rgb_planar_pixel_iterator</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">typedef</span><span class="w"> </span><span class="n">my_reference_proxy</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">reference</span><span class="p">;</span>
<span class="w"> </span><span class="n">reference</span><span class="w"> </span><span class="k">operator</span><span class="o">*</span><span class="p">()</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">reference</span><span class="p">(</span><span class="n">red</span><span class="p">,</span><span class="n">green</span><span class="p">,</span><span class="n">blue</span><span class="p">);</span><span class="w"> </span><span class="p">}</span>
<span class="p">};</span>
</pre></div>
</div>
<p>The problem arises when an iterator is dereferenced directly into a
function that takes a mutable pixel:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">Pixel</span><span class="o">&gt;</span><span class="w"> </span><span class="c1">// Models MutablePixelConcept</span>
<span class="kt">void</span><span class="w"> </span><span class="n">invert_pixel</span><span class="p">(</span><span class="n">Pixel</span><span class="o">&amp;</span><span class="w"> </span><span class="n">p</span><span class="p">);</span>
<span class="n">rgb_planar_pixel_iterator</span><span class="w"> </span><span class="n">myIt</span><span class="p">;</span>
<span class="n">invert_pixel</span><span class="p">(</span><span class="o">*</span><span class="n">myIt</span><span class="p">);</span><span class="w"> </span><span class="c1">// compile error!</span>
</pre></div>
</div>
<p>C++ does not allow for matching a temporary object against a non-constant
reference. The solution is to:</p>
<ul class="simple">
<li><p>Use const qualifier on all members of the reference proxy object:</p></li>
</ul>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">T</span><span class="o">&gt;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">my_reference_proxy</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">my_reference_proxy</span><span class="o">&amp;</span><span class="w"> </span><span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">my_reference_proxy</span><span class="o">&amp;</span><span class="w"> </span><span class="n">p</span><span class="p">)</span><span class="w"> </span><span class="k">const</span><span class="p">;</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">my_reference_proxy</span><span class="o">*</span><span class="w"> </span><span class="k">operator</span><span class="o">-&gt;</span><span class="p">()</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">this</span><span class="p">;</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">...</span>
<span class="p">};</span>
</pre></div>
</div>
<ul class="simple">
<li><p>Use different classes to denote mutable and constant reference
(maybe based on the constness of the template parameter)</p></li>
<li><p>Define the reference type of your iterator with const qualifier:</p></li>
</ul>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">iterator_traits</span><span class="o">&lt;</span><span class="n">rgb_planar_pixel_iterator</span><span class="o">&gt;</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">typedef</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">my_reference_proxy</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">reference</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>A second important issue is providing an overload for <code class="docutils literal notranslate"><span class="pre">swap</span></code> for
your reference class. The default <code class="docutils literal notranslate"><span class="pre">std::swap</span></code> will not work
correctly. You must use a real value type as the temporary. A further
complication is that in some implementations of the STL the <code class="docutils literal notranslate"><span class="pre">swap</span></code>
function is incorrectly called qualified, as <code class="docutils literal notranslate"><span class="pre">std::swap</span></code>. The only
way for these STL algorithms to use your overload is if you define it
in the <code class="docutils literal notranslate"><span class="pre">std</span></code> namespace:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="k">namespace</span><span class="w"> </span><span class="nn">std</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">template</span><span class="w"> </span><span class="o">&lt;</span><span class="k">typename</span><span class="w"> </span><span class="nc">T</span><span class="o">&gt;</span>
<span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">swap</span><span class="p">(</span><span class="n">my_reference_proxy</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&amp;</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">my_reference_proxy</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&amp;</span><span class="w"> </span><span class="n">y</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">my_value</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">tmp</span><span class="o">=</span><span class="n">x</span><span class="p">;</span>
<span class="w"> </span><span class="n">x</span><span class="o">=</span><span class="n">y</span><span class="p">;</span>
<span class="w"> </span><span class="n">y</span><span class="o">=</span><span class="n">tmp</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Lastly, remember that constructors and copy-constructors of proxy
references are always shallow and assignment operators are deep.</p>
<p>We are grateful to Dave Abrahams, Sean Parent and Alex Stepanov for
suggesting the above solution.</p>
</section>
</section>
<div class="navbar" style="text-align:right;">
<a class="prev" title="Examples" href="examples.html"><img src="../_static/prev.png" alt="prev"/></a>
<a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
<a class="next" title="Extending" href="extending.html"><img src="../_static/next.png" alt="next"/></a>
</div>
</div>
<div class="footer" role="contentinfo">
Last updated on 2026-01-23 01:01:39.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 7.2.6.
</div>
</body>
</html>