/**
       * Sends the request to the first allocator, if it cannot fulfill the request
       * then the next Allocator is created and so on
       */
      block allocate(size_t n) noexcept
      {
        if (n == 0) {
          return{};
        }

        block result = allocate_no_grow(n);
        if (result) {
          return result;
        }

        // no node at all there
        if (root_.load() == nullptr) {
          auto firstNode = create_node();
          Node *nullNode = nullptr;
          // test if in the meantime someone else has created a node
          if (!root_.compare_exchange_weak(nullNode, firstNode)) {
            erase_node(firstNode);
          }

          result = allocate_no_grow(n);
          if (result) {
            return result;
          }
        }

        // a new node must be appended
        auto newNode = create_node();
        Node *nullNode = nullptr;
        auto p = root_.load();
        do {
          p = root_;
          while (p->next.load() != nullptr) {
            p = p->next;
          }
        } while (!p->next.compare_exchange_weak(nullNode, newNode));

        result = allocate_no_grow(n);
        return result;
      }