<div dir="ltr">&gt; Is support for <font face="monospace">std::cout</font> specifically required or would support for <font face="monospace">std::format()</font> and <font face="monospace">std::print()</font> suffice? If <font face="monospace">std::cout</font> support is specifically required, what motivates that requirement?<br><br>Not an author, but it would be very novel and potentially surprising to users to not support std::cout for such a fundamental thing as a reflected name.<div><br></div><div>- Victor</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Apr 28, 2024 at 8:49 AM Tom Honermann via SG16 &lt;<a href="mailto:sg16@lists.isocpp.org">sg16@lists.isocpp.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  

    
  
  <div>
    <p>SG16 reviewed <a href="http://wg21.link/p2996r2" target="_blank">P2996R2
        (Reflection for C++26)</a> during its 2024-04-24 meeting and
      will continue review during the 2024-05-08 SG16 meeting. I am
      working on the meeting summary for the previous meeting now and
      hope to publish it in the next few days. In the meantime, I wanted
      to get some discussion going to help prepare for our next review
      (in ~10 days).</p>
    <p>Daveed&#39;s presentation slides are available <a href="https://docs.google.com/presentation/d/1XYGCTXfnxWyWio8UmLdskl4D4Z7HvKkHHIVmBgT19f8/edit?usp=sharing" target="_blank">here</a>
      for anyone that would like to review them. They appear to have had
      some minor updates since the SG16 review (e.g., slide 10 is new).<br>
    </p>
    <p><a href="https://docs.google.com/presentation/d/1XYGCTXfnxWyWio8UmLdskl4D4Z7HvKkHHIVmBgT19f8/edit#slide=id.g2cf22bb8e94_0_16" target="_blank">Slide
        6</a> lists some requirements for the design. These include:</p>
    <ul>
      <li>Round-tripping must work (e.g., names returned by <font face="monospace">name_of()</font> must be valid input to <font face="monospace">data_member_spec()</font> via <font face="monospace">data_member_options_t::name</font>).</li>
      <li>Output to <font face="monospace">std::cout</font> must work
        reasonably (e.g., <font face="monospace">std::cout &lt;&lt;
          name_of(^int)</font>).</li>
      <li>Some text may not be source-like text (<font face="monospace">std::meta::display_name_of</font>).<br>
      </li>
    </ul>
    <p>I would like to further clarify these requirements. P2996R2
      authors, please answer the following questions.</p>
    <p>Are names returned by <font face="monospace">qualified_name_of()</font>
      required to be round-trippable?</p>
    <p>Is support for <font face="monospace">std::cout</font>
      specifically required or would support for <font face="monospace">std::format()</font>
      and <font face="monospace">std::print()</font> suffice? If <font face="monospace">std::cout</font> support is specifically
      required, what motivates that requirement?<br>
    </p>
    <p>Are all of <font face="monospace">name_of()</font>, <font face="monospace">qualified_name_of()</font>, and <font face="monospace">display_name_of()</font> required to return
      text (perhaps not source-like text, but content that is
      nevertheless text)? In other words, can they be guaranteed to
      provide well-formed text in some encoding?</p>
    <p>During the meeting, we briefly discussed use of an opaque type
      for the return type of <font face="monospace">name_of()</font>
      and friends. I would like to see further exploration of this idea
      prior to our next review. I&#39;m envisioning a type something like
      the following (This particular formulation follows existing
      precedent established by the <font face="monospace">std::filesystem::path</font>
      native format observers, <a href="http://eel.is/c++draft/fs.path.native.obs" target="_blank">[fs.path.native.obs]</a>).<br>
    </p>
    <blockquote>
      <p><font face="monospace">class name {<br>
            std::string_view <i>internal-representation</i>; //
          exposition only.<br>
            name(/* unspecified */);<br>
          public:<br>
            constexpr std::string string()       const; // ordinary
          literal encoding.<br>
            constexpr std::wstring wstring()     const; // wide literal
          encoding.<br>
            constexpr std::u8string u8string()   const; // UTF-8.<br>
            constexpr std::u16string u16string() const; // UTF-16.<br>
            constexpr std::u32string u32string() const; // UTF-32.<br>
          };</font><br>
      </p>
    </blockquote>
    <p>The intent is that the data accessed by the <i>internal-representation</i>
      member has static storage duration; perhaps a string literal. The
      observers would then provide access to the name in the above
      encodings. If I&#39;m not mistaken, this should enable use of these
      names in <font face="monospace">std::basic_string</font> objects
      during constant evaluation (so long as the object&#39;s lifetime is
      appropriately constrained) and run-time while only requiring
      static persistence of the internal representation.<br>
    </p>
    <p>Support for all five of the standard specified encodings is not
      necessarily required. SG16 can provide a recommendation for LEWG.
      The paper should discuss the pros, cons, and implementation costs
      for support of each encoding. Given existing precedent, lack of
      support for any given encoding should be motivated.</p>
    <p>Note that the above type suffices to provide support for printing
      names via <font face="monospace">std::cout</font>, <font face="monospace">std::format()</font>, and <font face="monospace">std::print()</font>. A iostream insertion
      operator and/or a <font face="monospace">std::formatter</font>
      specialization could be defined to enable printing names without
      having to call one of the member functions.<br>
    </p>
    <p>If I understand the intent correctly (it would be helpful to
      clarify this in a revision of the paper), names returned by <font face="monospace">name_of()</font> do not reflect a scope but do
      not necessarily reflect an identifier either. For example,
      something like &quot;<font face="monospace">operator bool</font>&quot; might
      be returned. Tangentially, I think the formatting of names
      accepted by <font face="monospace">data_member_spec()</font>
      needs to be rigorously specified for programs to be portable.</p>
    <p>We will need to make a decision regarding how characters that
      lack representation in the ordinary and wide literal encodings are
      to be handled. We have a few options.</p>
    <ol>
      <li>Don&#39;t provide the above <font face="monospace">string()</font>
        and <font face="monospace">wstring()</font> member functions.<br>
      </li>
      <li>Constrain the above <font face="monospace">string()</font>
        and <font face="monospace">wstring()</font> member functions so
        that they are not callable (e.g., does not participate in
        overload resolution...) if the associated literal encoding is
        unable to represent all characters that might appear in an
        identifier.</li>
      <li>Specify that the above <font face="monospace">string()</font>
        and <font face="monospace">wstring()</font> member functions
        fail constant evaluation or throw an exception (or similar error
        handling) if the name uses a character that is not representable
        in the associated literal encoding.</li>
      <li>Specify a way to encode non-representable characters in the
        names returned by the above <font face="monospace">string()</font>
        and <font face="monospace">wstring()</font> member functions
        and specify that <font face="monospace">data_member_spec()</font>
        accepts such encoded names.<br>
      </li>
    </ol>
    <p>If <font face="monospace">data_member_spec()</font> is modified
      to accept names specified by a class like <font face="monospace">name</font>
      above, then it will be necessary to specify a way to construct an
      object of that type with a name constructed during constant
      evaluation. Assuming the <i>internal-representation</i> format is
      unspecified, this will require means to construct that format in a
      buffer with a lifetime that matches the lifetime of the
      constructed object.<br>
    </p>
    <p>Tom.<br>
    </p>
  </div>

-- <br>
SG16 mailing list<br>
<a href="mailto:SG16@lists.isocpp.org" target="_blank">SG16@lists.isocpp.org</a><br>
<a href="https://lists.isocpp.org/mailman/listinfo.cgi/sg16" rel="noreferrer" target="_blank">https://lists.isocpp.org/mailman/listinfo.cgi/sg16</a><br>
</blockquote></div>

