void concatenated_tuple::init() {
  m_type_token = make_type_token();
  for (auto& m : m_data) {
    for (size_t i = 0; i < m->size(); ++i) {
      m_type_token = add_to_type_token(m_type_token, m->type_nr_at(i));
    }
  }
  auto acc_size = [](size_t tmp, const cow_ptr& val) {
    return tmp + val->size();
  };
  m_size = std::accumulate(m_data.begin(), m_data.end(), size_t{0}, acc_size);
}
concatenated_tuple::concatenated_tuple(std::initializer_list<cow_ptr> xs) {
  for (auto& x : xs) {
    if (x) {
      auto dptr = dynamic_cast<const concatenated_tuple*>(x.get());
      if (dptr) {
        auto& vec = dptr->data_;
        data_.insert(data_.end(), vec.begin(), vec.end());
      } else {
        data_.push_back(std::move(x));
      }
    }
  }
  type_token_ = make_type_token();
  for (auto& m : data_) {
    for (size_t i = 0; i < m->size(); ++i) {
      type_token_ = add_to_type_token(type_token_, m->type_nr_at(i));
    }
  }
  auto acc_size = [](size_t tmp, const cow_ptr& val) {
    return tmp + val->size();
  };
  size_ = std::accumulate(data_.begin(), data_.end(), size_t{0}, acc_size);
}
uint32_t empty_type_erased_tuple::type_token() const noexcept {
    return make_type_token();
}