<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 04:12:28 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[SERVER-26542] Migrate to std::optional</title>
                <link>https://jira.mongodb.org/browse/SERVER-26542</link>
                <project id="10000" key="SERVER">Core Server</project>
                    <description>&lt;p&gt;Originally this ticket was about using std::optional where possible, and boost::optional elsewhere. The idea of this polyfill was we could avoid including the boost headers in many places if the system provides a std::optional (from std::experimental or similar). After some investigation, the ticket is now about &lt;b&gt;replacing&lt;/b&gt; our use of boost::optional with std::optional entirely.&lt;/p&gt;</description>
                <environment></environment>
        <key id="322313">SERVER-26542</key>
            <summary>Migrate to std::optional</summary>
                <type id="2" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14711&amp;avatarType=issuetype">New Feature</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="10038" iconUrl="https://jira.mongodb.org/images/icons/subtask.gif" description="">Backlog</status>
                    <statusCategory id="2" key="new" colorName="default"/>
                                    <resolution id="-1">Unresolved</resolution>
                                        <assignee username="backlog-server-servicearch">Backlog - Service Architecture</assignee>
                                    <reporter username="andrew.morrow@mongodb.com">Andrew Morrow</reporter>
                        <labels>
                            <label>sa-remove-fv-backlog-22</label>
                    </labels>
                <created>Sun, 9 Oct 2016 20:25:17 +0000</created>
                <updated>Mon, 8 Jan 2024 15:23:02 +0000</updated>
                                                                            <component>Portability</component>
                                        <votes>2</votes>
                                    <watches>14</watches>
                                                                                                                <comments>
                            <comment id="3496055" author="billy.donahue" created="Wed, 18 Nov 2020 17:49:21 +0000"  >&lt;p&gt;There are significantly more significant differences between boost::optional and std::optional than the previously mentioned &lt;tt&gt;get_ptr&lt;/tt&gt; and &lt;tt&gt;boost::none&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;The hardest one is that boost::optional_io.hpp provides an &lt;tt&gt;operator&amp;lt;&amp;lt;&lt;/tt&gt; for &lt;tt&gt;optional&amp;lt;T&amp;gt;&lt;/tt&gt;. This is not sfinae-friendly and will static-assert at you if you try to call it. A boost::optional&amp;lt;T&amp;gt; always appears to be streamable whether T is really streamable or not. This ALREADY screws up detection traits for streamability in frameworks like fmtlib, logv2, StatusWith, or unittest asserts, which all have to handle boost::optional as a special case.&lt;/p&gt;

&lt;p&gt;    &lt;a href=&quot;https://github.com/boostorg/optional/blob/develop/include/boost/optional/optional.hpp#L1594&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/boostorg/optional/blob/develop/include/boost/optional/optional.hpp#L1594&lt;/a&gt;&lt;br/&gt;
In those places we are trying to do a structurally recursive traits check for a property like streamability and they need to each be rewritten to correctly identify and define a convention for std::optional streaming (easiest is to just reuse the boost/optional_io.hpp output format). There&apos;s a generic pluggable-policy-based solution to problems of this type that I think would make an interesting project for reuse across our stringification, logging, and BSON libraries and greatly offload their complexity and redundancy. Kind of a SAX-like descent protocol. Then we can stop reinventing this wheel.&lt;/p&gt;

&lt;p&gt;I&apos;ve prototyped making the custom changes to each of the places where we do structurally recursive visitation for streamability here: &lt;a href=&quot;https://github.com/mongodb/mongo/compare/master...BillyDonahue:boost_optional_io_wean?expand=1&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo/compare/master...BillyDonahue:boost_optional_io_wean?expand=1&lt;/a&gt;&lt;br/&gt;
This gets us completely out of the optional_io.hpp business.&lt;/p&gt;

&lt;p&gt;The most common operations on an optional are has_value() and value(). These would have to be identified and renamed from boost&apos;s is_initialized() and get(), respectively. Here&apos;s a tool to do that.&lt;br/&gt;
&lt;a href=&quot;https://github.com/BillyDonahue/llvm-project/compare/master...BillyDonahue:boost-optional-migration?expand=1&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/BillyDonahue/llvm-project/compare/master...BillyDonahue:boost-optional-migration?expand=1&lt;/a&gt;&lt;br/&gt;
We can also change these to &lt;tt&gt;operator*&lt;/tt&gt; and &lt;tt&gt;operator-&amp;gt;&lt;/tt&gt; and &lt;tt&gt;explicit operator bool&lt;/tt&gt; expressions which would yield code that works in EITHER boost::optional or std::optional.&lt;/p&gt;

&lt;p&gt;There are a few uses of &lt;tt&gt;boost::optional&amp;lt;T&amp;amp;&amp;gt;&lt;/tt&gt;, which isn&apos;t supported in std::optional. All uses in our codebase seem to be unnecessary cleverness that can be trivially replaced with &lt;tt&gt;T*&lt;/tt&gt; without change of semantics.&lt;/p&gt;

&lt;p&gt;There are conditional constructors in boost::optional that std::optional doesn&apos;t have. They take a (bool,T&amp;amp;&amp;amp;) kind of signature, constructing an empty optional if the bool is false. These are easily rewritten and there aren&apos;t that many of them. Maybe 10 or 20.&lt;/p&gt;

&lt;p&gt;std::optional is convertible from values that are convertible. boost::optional is not. This could yield sfinae (or similar) ambiguities that must be resolved in a transition.&lt;/p&gt;

&lt;p&gt;Boost::optional has some monadic operations like value_or which std::optional has. Others like map and flat_map are missing from std::optional but we have only a couple of uses that can spell it out with explicit lambdas.&lt;/p&gt;

&lt;p&gt;There&apos;s a difference between boost::optional::value_or and boost::optional::get_value_or, which is deprecated because it returns a reference that&apos;s often dangling. We should scrub our code of get_value_or anyway, but this migration would make the scrub mandatory.&lt;/p&gt;

&lt;p&gt;The get_ptr problem isn&apos;t so bad. All call sites in practice can be replaced with a ternary &lt;tt&gt;(opt?&amp;amp;*opt:nullptr)&lt;/tt&gt;. At most calls of &lt;tt&gt;get_ptr&lt;/tt&gt; (there are not that many), we already tested the opt&apos;s bool value and can just replace &lt;tt&gt;opt.get_ptr()&lt;/tt&gt; with &lt;tt&gt;&amp;amp;*opt&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;More trivial things:&lt;/p&gt;

&lt;p&gt;Obviously we&apos;d have to rewrite the #include lines.&lt;/p&gt;

&lt;p&gt;Replace all the declarations of:&lt;br/&gt;
    boost::optional to std::optional&lt;br/&gt;
    boost::none to std::nullopt&lt;br/&gt;
    boost::none_t to std::nullopt_t&lt;br/&gt;
    boost::in_place to std::in_place&lt;br/&gt;
    boost::in_place_t to std::in_place_t&lt;/p&gt;

&lt;p&gt;IDL would need some minor surgery to make it emit std::optional compatible code. That was pretty easy to do.&lt;/p&gt;
</comment>
                            <comment id="2305720" author="acm" created="Sat, 29 Jun 2019 13:30:01 +0000"  >&lt;p&gt;I propose we remove this from the C++17 epic, retitle it to &quot;Migrate to std::optional&quot;, and take it out of the sprint. The re-titled ticket can live on the backlog until we decide that a sufficient motivation has emerged to make the switch over to &lt;tt&gt;std::optional&lt;/tt&gt;.&lt;/p&gt;</comment>
                            <comment id="2296928" author="jason.carey" created="Tue, 25 Jun 2019 16:56:13 +0000"  >&lt;p&gt;deduction guides (like those on std::optional) might also be nice.&lt;/p&gt;

&lt;p&gt;I think I agree with &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=acm&quot; class=&quot;user-hover&quot; rel=&quot;acm&quot;&gt;acm&lt;/a&gt;.   I&apos;m in the camp of: &quot;using std types is a nice, but this looks like a wide change that delivers relatively little value&quot;.  I&apos;m not too worried that we&apos;re going to run into bad implementations of std::optional (like we have for variant), it&apos;s just a lot of motion for a world that&apos;s basically where we are today.&lt;/p&gt;

&lt;p&gt;In terms of future integration with the language, I&apos;m not aware of anything that&apos;s currently returning an optional in the standard lib.  The only area I see work kicking around is in support for &amp;lt;=&amp;gt; for optional.  But I&apos;d assume that&apos;s something that would make it&apos;s way to boost (with the same semantics) if/when that lands&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;</comment>
                            <comment id="2296469" author="acm" created="Tue, 25 Jun 2019 13:51:53 +0000"  >&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jesse&quot; class=&quot;user-hover&quot; rel=&quot;jesse&quot;&gt;jesse&lt;/a&gt; - To be honest that doesn&apos;t sound that bad since most would be an easy search and replace. If we are going to do it I think we probably wouldn&apos;t even polyfill, just cut straight over to std::optional. I guess the other question is what if anything we gain by switching over. I&apos;d expect &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=redbeard0531&quot; class=&quot;user-hover&quot; rel=&quot;redbeard0531&quot;&gt;redbeard0531&lt;/a&gt;, &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=adam.martin%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;adam.martin@mongodb.com&quot;&gt;adam.martin@mongodb.com&lt;/a&gt; and &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=mira.carey%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;mira.carey@mongodb.com&quot;&gt;mira.carey@mongodb.com&lt;/a&gt; may have opinions. My feeling is that we are getting along just fine with &lt;tt&gt;boost::optional&lt;/tt&gt;. On the other hand if something coming in C++20 makes deeper connection with &lt;tt&gt;std::optional&lt;/tt&gt; we could end up with an annoying impedance mismatch if we were still on &lt;tt&gt;boost::optional&lt;/tt&gt; when we got there.&lt;/p&gt;</comment>
                            <comment id="2295728" author="jesse" created="Mon, 24 Jun 2019 20:54:13 +0000"  >&lt;p&gt;&lt;a href=&quot;https://www.bfilipek.com/2018/05/using-optional.html#migration-from-boostoptional&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Bartek has a list of boost/std::optional differences&lt;/a&gt;, I think these two matter to us:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;boost::optional has get_ptr() but std::optional doesn&apos;t. We use get_ptr in about 39 places which would have to be replaced.&lt;/li&gt;
	&lt;li&gt;A disengaged boost::optional equals boost::none, but a disengaged std::optional equals std::nullopt. We use boost::none in about 1772 places. We&apos;d have to typedef our own stdx::nullopt as either std::nullopt or boost::none depending on which is available.&lt;/li&gt;
&lt;/ul&gt;
</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10012">
                    <name>Related</name>
                                            <outwardlinks description="related to">
                                        <issuelink>
            <issuekey id="2093290">SERVER-68121</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="2097692">SERVER-68246</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </issuelinktype>
                    </issuelinks>
                <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                <customfield id="customfield_10050" key="com.atlassian.jira.toolkit:comments">
                        <customfieldname># Replies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>5.0</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                <customfield id="customfield_12751" key="com.atlassian.jira.plugin.system.customfieldtypes:multiselect">
                        <customfieldname>Assigned Teams</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="25132"><![CDATA[Service Arch]]></customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                            <customfield id="customfield_10011" key="com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons">
                        <customfieldname>Backwards Compatibility</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10038"><![CDATA[Fully Compatible]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                            <customfield id="customfield_10055" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>Date of 1st Reply</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Mon, 24 Jun 2019 20:54:13 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10052" key="com.atlassian.jira.toolkit:dayslastcommented">
                        <customfieldname>Days since reply</customfieldname>
                        <customfieldvalues>
                                        3 years, 12 weeks ago
    
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_18254" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Dependencies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue><![CDATA[]]></customfieldvalue>


                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10057" key="com.atlassian.jira.toolkit:lastusercommented">
                        <customfieldname>Last comment by Customer</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>true</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_10056" key="com.atlassian.jira.toolkit:lastupdaterorcommenter">
                        <customfieldname>Last commenter</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>luke.bonanomi@mongodb.com</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_11151" key="com.atlassian.jira.toolkit:LastCommentDate">
                        <customfieldname>Last public comment date</customfieldname>
                        <customfieldvalues>
                            3 years, 12 weeks ago
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                    <customfield id="customfield_10051" key="com.atlassian.jira.toolkit:participants">
                        <customfieldname>Participants</customfieldname>
                        <customfieldvalues>
                                        <customfieldvalue>jesse@mongodb.com</customfieldvalue>
            <customfieldvalue>andrew.morrow@mongodb.com</customfieldvalue>
            <customfieldvalue>backlog-server-servicearch</customfieldvalue>
            <customfieldvalue>billy.donahue@mongodb.com</customfieldvalue>
            <customfieldvalue>mira.carey@mongodb.com</customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_14254" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Product Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hrjttb:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hr568n:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_23361" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Requested By</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_22870" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Triagers</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_14350" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>serverRank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hsegvb:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                    </customfields>
    </item>
</channel>
</rss>