Boost C++ Libraries: Ticket #8362: Move ctor or assignment for boost::geometry::model::ring? https://svn.boost.org/trac10/ticket/8362 <p> Hi, I have this clumsy piece of code: </p> <pre class="wiki">if( !vecpt.empty() ) { emplace_back( polygon_type() ); static_cast&lt; std::vector&lt; _TPoint&lt; T &gt; &gt;&amp; &gt;( back().outer() ) = std::move(vecpt); } </pre><p> which actually should be written like this: </p> <pre class="wiki">boost::geometry::convert( polygon_type::ring_type( std::move(vecpt) ), *this ); </pre><p> but unfortunately this kind of conversion does not work. Did I make a mistake in my above statement, or is this not (yet) supported? If the latter, do you plan on adding support for this at some point? Thanks! </p> <blockquote> <p> Volker </p> </blockquote> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/8362 Trac 1.4.3 Barend Gehrels Fri, 05 Apr 2013 21:20:55 GMT owner changed https://svn.boost.org/trac10/ticket/8362#comment:1 https://svn.boost.org/trac10/ticket/8362#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Barend Gehrels</span> to <span class="trac-author">Mateusz Loskot</span> </li> </ul> Ticket Volker Schöch <vschoech@…> Wed, 10 Apr 2013 08:13:32 GMT <link>https://svn.boost.org/trac10/ticket/8362#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8362#comment:2</guid> <description> <p> Some additional information. <strong>*this</strong> is a multi-polygon with the following definition: </p> <pre class="wiki">template&lt;typename T&gt; class _TPolygon : public std::vector&lt; boost::geometry::model::polygon&lt; _TPoint&lt; T &gt;, /*ClockWise*/false, /*Closed*/false &gt; &gt;, boost::equality_comparable&lt; _TPolygon&lt;T&gt;, boost::additive&lt; _TPolygon&lt;T&gt;, _TSize&lt;T&gt; &gt; &gt; { ... } namespace boost { namespace geometry { namespace traits { template&lt;typename T&gt; struct tag&lt; _TPolygon&lt;T&gt; &gt; { typedef multi_polygon_tag type; }; } } } // namespace boost::geometry::traits </pre><p> The polygon definition is based on our <strong>_TPoint&lt;T&gt;</strong> type which is declared for use with boost::geometry as follows: </p> <pre class="wiki">namespace boost { namespace geometry { namespace traits { template &lt;typename T&gt; struct tag&lt; _TPoint&lt;T&gt; &gt; { typedef point_tag type; }; template &lt;typename T&gt; struct coordinate_type&lt; _TPoint&lt;T&gt; &gt; { typedef T type; }; template &lt;typename T&gt; struct coordinate_system&lt; _TPoint&lt;T&gt; &gt; { typedef cs::cartesian type; }; template &lt;typename T&gt; struct dimension&lt; _TPoint&lt;T&gt; &gt; : boost::mpl::int_&lt;2&gt; {}; template &lt;typename T, std::size_t Dimension&gt; struct access&lt; _TPoint&lt;T&gt;, Dimension &gt; { static inline T get(_TPoint&lt;T&gt; const&amp; p) { return p[(EOrientation)Dimension]; } static inline void set(_TPoint&lt;T&gt;&amp; p, T const&amp; value) { p[(EOrientation)Dimension] = value; } }; } } } // namespace boost::geometry::traits </pre><p> Similarly, we have our own <strong>_TRect&lt;T&gt;</strong> type which we plug into boost::geometry: </p> <pre class="wiki">namespace boost { namespace geometry { namespace traits { template &lt;typename T&gt; struct tag&lt; _TRect&lt;T&gt; &gt; { typedef box_tag type; }; template &lt;typename T&gt; struct point_type&lt; _TRect&lt;T&gt; &gt; { typedef _TPoint&lt;T&gt; type; }; template &lt;typename T, std::size_t Dimension&gt; struct indexed_access&lt; _TRect&lt;T&gt;, min_corner, Dimension &gt; { typedef typename geometry::coordinate_type&lt; _TPoint&lt;T&gt; &gt;::type coordinate_type; static inline coordinate_type get(_TRect&lt;T&gt; const&amp; rect) { return geometry::get&lt;Dimension&gt;( rect.TopLeft() ); } static inline void set(_TRect&lt;T&gt;&amp; rect, coordinate_type const&amp; value) { geometry::set&lt;Dimension&gt;( rect.TopLeft(), value ); } }; template &lt;typename T, std::size_t Dimension&gt; struct indexed_access&lt; _TRect&lt;T&gt;, max_corner, Dimension &gt; { typedef typename geometry::coordinate_type&lt; _TPoint&lt;T&gt; &gt;::type coordinate_type; static inline coordinate_type get(_TRect&lt;T&gt; const&amp; rect) { return geometry::get&lt;Dimension&gt;( rect.BottomRight() ); } static inline void set(_TRect&lt;T&gt;&amp; rect, coordinate_type const&amp; value) { geometry::set&lt;Dimension&gt;( rect.BottomRight(), value ); } }; } } } // namespace boost::geometry::traits </pre><p> In our code, these classes are instantiated with template parameter <strong>T</strong> being either <strong>int</strong> or <strong>double</strong>. We have a lot of use for <strong>int</strong>-based geometry calculations. </p> <p> With these geometry types we successfully call many algorithms from boost::geometry, e.g., </p> <pre class="wiki">template&lt;typename T&gt; _TPolygon&lt; T &gt;::_TPolygon(_TRect&lt; T &gt; const&amp; rect) { boost::geometry::convert( rect, *this ); } </pre><p> but the following does not seem to work (as of boost 1.52.0): </p> <pre class="wiki">template&lt;typename T&gt; _TPolygon&lt; T &gt;::_TPolygon(std::vector&lt; _TPoint&lt; T &gt; &gt; vecpt) { // vecpt: // - No need to add end==begin point. // - Orientation is mathematically counter-clockwise (i.e., clockwise with the // origin in the upper left as is the case with screen or slide coordinates). // - No self-intersection allowed! if( !vecpt.empty() ) { boost::geometry::convert( polygon_type::ring_type( std::move(vecpt) ), *this ); } } </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Mateusz Loskot</dc:creator> <pubDate>Mon, 15 Apr 2013 00:26:21 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8362#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8362#comment:3</guid> <description> <p> Barend, </p> <p> The requested move semantic is one issue, but unless I'm missing something, is the ring model supposed to be constructible directly from compatible container of compatible points? The extension constructor in ring takes iterators only, not container. </p> <p> Obviously, this does not compile: </p> <pre class="wiki">#include &lt;vector&gt; #include &lt;boost/geometry.hpp&gt; #include &lt;boost/geometry/geometries/ring.hpp&gt; #include &lt;boost/geometry/geometries/point_xy.hpp&gt; int main() { typedef boost::geometry::model::d2::point_xy&lt;double&gt; point; typedef boost::geometry::model::ring&lt;point&gt; ring; std::vector&lt;point&gt; r1; ring r2; boost::geometry::convert(r1, r2); return 0; } </pre><p> Shall I extend the ring to make it constructible from the container too? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Barend Gehrels</dc:creator> <pubDate>Mon, 15 Apr 2013 06:08:44 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8362#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8362#comment:4</guid> <description> <p> OK for me to add a constructor with a container with its point types. It was not there because vector/deque do not have it neither. </p> <p> Does this solve the whole issue? In the reported problem, std::move seems not necessary in the call to convert... </p> </description> <category>Ticket</category> </item> <item> <author>Volker Schöch <vschoech@…></author> <pubDate>Mon, 15 Apr 2013 08:24:27 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8362#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8362#comment:5</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8362#comment:3" title="Comment 3">mloskot</a>: </p> <blockquote class="citation"> <p> The requested move semantic is one issue, but unless I'm missing something, is the ring model supposed to be constructible directly from compatible container of compatible points? The extension constructor in ring takes iterators only, not container. </p> </blockquote> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8362#comment:4" title="Comment 4">barendgehrels</a>: </p> <blockquote class="citation"> <p> OK for me to add a constructor with a container with its point types. It was not there because vector/deque do not have it neither. </p> </blockquote> <p> Although to me this seems to be a desirable extension, I am not saying that this is the only way to solve the issue. Leaving constructors alone, you could alternatively overload the convert algorithm to support conversion from vector-of-points to (Multi-)Polygon: </p> <pre class="wiki">boost::geometry::convert( std::move(vecpt), *this ); </pre><p> My suggestion to call convert by way of constructing a ring_type first was merely based on my observation that convert already supports conversion from Ring to Polygon. </p> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8362#comment:4" title="Comment 4">barendgehrels</a>: </p> <blockquote class="citation"> <p> Does this solve the whole issue? </p> </blockquote> <p> There are two more niceties I would like to suggest to solve the whole issue: </p> <ol><li>In boost 1.52.0, convert supports Ring to Polygon conversion, but does not support <em>(any Geometry that supports conversion to Polygon)</em> to Multi-Polygon conversion. Is this by design, or is this considered a missing feature? </li></ol><ol start="2"><li>While we are at it, is it intentional that I have to guard the conversion with "!vecpt.empty()"? I don't see a problem with creating a Ring from an empty vector-of-points and convert that to a Polygon that consist of empty vectors. </li></ol><p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8362#comment:4" title="Comment 4">barendgehrels</a>: </p> <blockquote class="citation"> <p> In the reported problem, std::move seems not necessary in the call to convert... </p> </blockquote> <p> Can you explain why you think std::move is unnecessary there? It may in fact be useless if there is any link in the chain of calls that does not support move semantics, but from my perspective I should still put it there to enable move semantics where it is supported. There seems to be consensus that <a class="ext-link" href="http://stackoverflow.com/questions/15387271/can-compiler-generate-stdmove-for-a-last-use-of-lvalue-automatically"><span class="icon">​</span>the compiler must not automatically turn a copy into a move</a>. Thus I think I have to be explicit about my intent to use move semantics. </p> </description> <category>Ticket</category> </item> <item> <author>Volker Schöch <vschoech@…></author> <pubDate>Fri, 14 Nov 2014 16:35:16 GMT</pubDate> <title>version changed https://svn.boost.org/trac10/ticket/8362#comment:6 https://svn.boost.org/trac10/ticket/8362#comment:6 <ul> <li><strong>version</strong> <span class="trac-field-old">Boost 1.52.0</span> → <span class="trac-field-new">Boost 1.57.0</span> </li> </ul> Ticket Volker Schöch <vschoech@…> Fri, 14 Nov 2014 16:39:17 GMT <link>https://svn.boost.org/trac10/ticket/8362#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8362#comment:7</guid> <description> <p> As far as I understand, I still cannot write an expression like this in 1.57.0: </p> <pre class="wiki">boost::geometry::convert( polygon_type::ring_type( tc_move(vecpt) ), *this ); </pre><p> I'm not saying that this is a major problem or anything, just updating the ticket. </p> </description> <category>Ticket</category> </item> <item> <author>vschoech@…</author> <pubDate>Mon, 21 Sep 2015 15:39:37 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8362#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8362#comment:8</guid> <description> <p> This is still true in 1.59.0. </p> </description> <category>Ticket</category> </item> </channel> </rss>