title: Lazy initialization of std::tuple elements
body: <p>I often use <code>std::aligned_storage</code> to specify an uninitialized class member. The typical example is an static_vector, which stores its elements within the structure.</p>
  
  <p>However, I'm not completely sure what I should do when I want a <code>std::tuple</code> to be created <em>step by step</em>, initializing its members in an unspecified order at different points in time.</p>
  
  <p>Would it be legal to create</p>
  
  <pre><code>std::tuple&lt; std::aligned_storage&lt;sizeof(Types),alignof(Types)&gt;::type...&gt;
  </code></pre>
  
  <p>and then reinterpret member reference as a <code>std::tuple&lt;Types...&gt;&amp;</code>?</p>
  
  <p>For example:</p>
  
  <pre><code>#include &lt;bitset&gt;
  #include &lt;memory&gt;
  #include &lt;new&gt;
  #include &lt;tuple&gt;
  #include &lt;utility&gt;
  
  template &lt; class... Ts &gt;
  class uninitialized_tuple {
      public:
          using tuple_type   = typename std::tuple&lt;Ts...&gt;;
          using buffer_type =
              std::tuple&lt;
                  typename std::aligned_storage&lt;sizeof(Ts),alignof(Ts)&gt;::type...
              &gt;;
  
          ~uninitialized_tuple() {
              destruct_helper&lt;std::index_sequence_for&lt;Ts...&gt;&gt;::erase(*this);
          }
  
          tuple_type&amp; as_tuple() {
              reinterpret_cast&lt;tuple_type&amp;&gt;(_storage);
          }
  
          bool valid() const {
              return _is_set.all();
          }
  
          template &lt; size_t index, class... Args &gt;
          void emplace( Args&amp;&amp;... args ) {
              using element_type = typename std::tuple_element&lt;index,tuple_type&gt;::type;
              new (&amp;std::get&lt;index&gt;(_storage)) element_type( std::forward&lt;Args&gt;(args)...);
              _is_set.set(index);
          }
  
          template &lt; size_t index &gt;
          void erase() {
              using element_type = typename std::tuple_element&lt;index,tuple_type&gt;::type;
              if( _is_set[index] ) {
                  std::get&lt;index&gt;(_storage).~element_type();
                  _is_set.reset(index);
              }
          }
  
      private:
          template &lt; class Seq &gt;
          struct destruct_helper {
              static void erase( uninitialized_tuple&amp; ) {}
          };
  
          template &lt; size_t index, size_t... indices &gt;
          struct destruct_helper&lt;std::index_sequence&lt;index,indices...&gt;&gt; {
              static void erase( uninitialized_tuple&amp; value ) {
                  value.erase&lt;index&gt;();
                  destruct_helper&lt;std::index_sequence&lt;indices...&gt;&gt;::erase_one(value);
              }
          };
  
          buffer_type                _storage;
          std::bitset&lt;sizeof...(Ts)&gt; _is_set;
  };
  </code></pre>