title: Constexpr: Convert a list of string views into a list of char arrays
body: <p>I came across an interesting constexpr problem that haven't been able to fully crack. The last piece of the puzzle that I'm missing is the following</p>
  <pre class="lang-cpp prettyprint-override"><code>// Given a constexpr array of string views
  constexpr std::array&lt;std::string_view, X&gt; views = ...;
  
  // Convert it to a list of char arrays
  constexpr std::tuple&lt;std::array&lt;char, Xs&gt;...&gt; buffers = ...;
  </code></pre>
  <p>My problem here is finding the right size for each array. How can I extract the sizes of the string_views in <code>views</code> and pass them as template parameters to another function?</p>
  <p>I could just use the same size for every buffer, big enough to hold every argument, but I'm wondering if there is a way of optimizing their sizes since the info is known at compile time.</p>
  <hr />
  <p><strong>Full description of the problem I'm trying to solve.</strong>
  (in case someone can come up with a better approach, also cause I think it's interesting...)</p>
  <p>I want to create a macro that converts a list of arguments into a list of name-value pairs. For instance</p>
  <pre class="lang-cpp prettyprint-override"><code>// Adding types explicitly to show what I want to achieve.
  
  int x;
  float y;
  double z;
  
  using named_values_t = std::tuple&lt;
      std::pair&lt;const char*, int&amp;&gt;,
      std::pair&lt;const char*, float&amp;&gt;,
      std::pair&lt;const char*, double&amp;&gt;&gt;;
  
  named_values_t nv = MY_MACRO(x, y, z);
  </code></pre>
  <p>The <code>const char*</code> adds significant difficulty but it's a requirement for a third-party lib.</p>
  <p>Now I know that can be done with Boost.Preprocessor but I'd like to do it just using the STL and constexpr methods to avoid adding boost just for this. Also I know this would be trivial on a compiler with support for <code>constexpr std::string</code> but I'm using C++17.</p>
  <p>The string processing can be easily done with constexpr functions,</p>
  <pre class="lang-cpp prettyprint-override"><code>// Split &quot;one, two, three&quot; into {&quot;one&quot;, &quot;two&quot;, &quot;three&quot;}.
  template &lt;size_t Count&gt;
  constexpr std::array&lt;std::string_view, Count&gt; split_arguments(std::string_view);
  </code></pre>
  <p>However, I cannot pass these string_views directly as char pointers, since at this point they're just pointers to a bigger array in memory (the complete <code>&quot;one, two, three&quot;</code>). To pass as <code>const char*</code> each element needs to be null-terminated.</p>
  <p>But we can build an <code>std::array</code> for each <code>std::string_view</code> and copy its contents, this way we have a char array for each argument name, that will generate a null-terminated segment of memory for each name.</p>
  <pre class="lang-cpp prettyprint-override"><code>constexpr std::string_view args = &quot;one, two, three&quot;;
  
  constexpr std::array&lt;std::string_view, 3&gt; views = split_arguments&lt;3&gt;(args); // {&quot;one&quot;, &quot;two&quot;, &quot;three&quot;}
  
  constexpr std::tuple&lt;std::array&lt;char, Xs&gt;...&gt; buffers = make_buffers&lt;Xs...&gt;(views);
  </code></pre>
  <p>Here I'm not able to figure out how pass the lengths of the views as template arguments to the next function.</p>
  <p>Working solution here (using bigger fixed-sized buffers): <a href="https://gcc.godbolt.org/z/WKsbvb" rel="nofollow noreferrer">https://gcc.godbolt.org/z/WKsbvb</a></p>
  <p>The fixed-size buffer solution is ok, but it would be great to go that extra step to fit the buffers to their actual size.</p>