<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/56031>56031</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [libc+] std::basic_string::insert pessimization for custom character types
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          treh
      </td>
    </tr>
</table>

<pre>
    std::basic_string::insert unnecessarily always copies into a `__temp` buffer if `charT` is a custom type.

[The implementation](https://github.com/llvm/llvm-project/blob/c36870c8e79c1690432076c69cb98a879555efa8/libcxx/include/string#L2930-L2949) uses [`__string_is_trivial_iterator`](https://github.com/llvm/llvm-project/blob/c36870c8e79c1690432076c69cb98a879555efa8/libcxx/include/string#L604-L613) to determine if it should copy the input range into a `basic_string __temp` buffer, before calling `__insert_from_safe_copy`.

However, for custom class-type `_CharT`, even a plain `_CharT const*` does not satisfy `__string_is_trivial_iterator`, so nothing is won by creating this buffer.

Shouldn't the definition for `__string_is_trivial_iterator` use something like `is_nothrow_convertible<Tp, _CharT>` instead of `is_arithmetic<Tp>`?

Note: Custom class-type character types **are** allowed in `basic_string`, the [requirements are](https://timsong-cpp.github.io/cppwp/n4861/strings#basic.string-1)

> The class template basic_­string describes objects that can store a sequence consisting of a varying number of arbitrary char-like objects with the first element of the sequence at position zero. Such a sequence is also called a “string” if the type of the char-like objects that it holds is clear from context. In the rest of this Clause, the **type of the char-like objects** held in a basic_­string object is designated by **charT**.

and *char-like* is defined [before](https://timsong-cpp.github.io/cppwp/n4861/strings#general-1) as

> This Clause describes components for manipulating sequences of **any non-array trivial standard-layout type. Such types are called char-like types**, and objects of char-like types are called char-like objects or simply characters.

Note2: This even was a bug from [this]( https://reviews.llvm.org/D98573) to [this](https://reviews.llvm.org/D119633) revision, causing infinite recursion.

Here is a small example to play around with: [main.cpp](https://github.com/llvm/llvm-project/files/8899669/main.cpp.txt)

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNVktv4zYQ_jXyhbChhy1bBx-8TowWWPSyuRsUNbLYUqRKUnG8v74zpOzE2WDTFj0UCByJj3l933yj2jSXrfNNUuzwr-ZOiqPzVupTXJHagfVs1BoEOMetVBfG1ZlfHBNmkOCY1N4wzpIyPR499AM-sHpsW7BMtrQsOm6faFU6PCdG503P_GWARZI-JOlu-l19eeqAyX5Q0IP23Eujk9VDkm867wdH8eQH_DtJ3431QpgeX5R6vv6bD9b8DsLja61Mjf9EUW7WqdjAuhJZWaXLIk_XpSgrUVcbvllXq9UKWr4hA7IWLy_4ILVQYwP4NJUhL77mVZHO8XdZJXnFRodJY7Qh4XjoKN0RH54lV0fpwXJvLG7_P6Iv0-X8a5kVFDsi1QAG2EsNhI70zHVmVA2BeWGeANDD6Jnl-gRvoH3LDPYe5yTfsxpaY4EJrhQdCcWJ5Dm21vRHx1s4khPcucP9F3OG52gDLVzpIRR3bk4kCab2E4XoFJ7WGNSguNSvm5iAdli9HYXVGIRIG0wOWeTaC_sbWKFlZ-hSR_EjVc9Gs_rChAU0gku44aaE7xL4Fgqok3ztQwEbaKWWxN6Q0OeuiVHou4foWsk_QtJ4mKKx5ox101giL2sFSbF_GijYqSbFY-gszB14w0w73cRG9R1alCJeCMeS4vA28N-MR3M7tv-h5NSxXGCEoU2R7VjWfMctxAcUAIWoNSwCcKcasZJUB2wRC3-O0oZ2xtbH6x80hJe9M_o0F8OwmJpDGqL_MJwx0YNebsrsRmiHjA7-FvF9jlvVnYwUj4x0JGTDiKeKe2AxxmSfJ7uHicUNOGFljemZmjoPT3fcI4M1w3oglzlzGD9oAYFc0gUaYIk5e-b2Qi967GusEq3ZWnqLy6F48wDi1e4Z0wolaaV1nkEUOLpFizcn6HwwLjLnO1izYN9G0b0NgwRUIUupy7D82JmPebJJk2o_VX96faDeJtsBzcnPj3GFfFECOqMaR8aFAm4Z9Stl7OHFL9ivOty24KaI8dxeceTsDehAip-6mnjTgQqk4R_hEY9SGIiMPGmEraEGjHfjEAmPd93HdcOm7eCR3AQT2IR4H0kYlem_od4JNLatCqxj3P1IvFtx3tALtX4wOvQACULPtRxGFUXlCq0LrRvbTF9QhvScW8tRkqNeICUxU26bueIXgwId5mckSOxRPqkvJv1a_rAVzRJaVKwr-Ojv3bmPTdzOW-ZoOF9e1cEt3stJTnoSqhBU-sxp4tfjKXIKwSD6RCjYPRYWniWc3YJm4cJYnFyHh2qzWl_H1t3dz69mWVUW4S7tOvqUwPwFIhPUXQeJJlaL0dLu_UgCG3uNuR7LweCF01cJhYFqgt8_1oxYSWpryhdD63EWLZA2_3Lit1IRTIfNpqrKEr8yDleDC__ibwo3a7ZFUxUVn3npFWzRMU3-JP-CftnnX3GIMUIov_PbcLpO23u9n41Wbf9xEtK5MWSxKtMim3VbnjXFuoaygbwo-aaFpi1FWvIiXWZ1sapmitegHKWB8c_kNk_zPC2zZZbn61W6yFZpk4kWcp4um1XGk2UKWBd1A3pmtyEGJJjDTYUK_cqCGeo_qgjA1T4ffWfs1lvoZiHWbQj0L9Gro6g">