Помоги мне создать класс двусвязного списка из моих функций:
struct DL_node { int data; DL_node *prev; DL_node *next; };
void initDL(DL_node* head_DL_node, int data)
{
    // assign data to the head node
    head_DL_node->data = 10;
    // assign prev pointer to the head node
    head_DL_node->prev = NULL;
    // assign next pointer to the head node
    head_DL_node->next = NULL;
}

void insertToEnd(DL_node* head_DL_node, int data)
{
    // create the new node of the doubly linked list
    DL_node* new_node = new DL_node();
    // assign data to the new node
    new_node->data = data;
    // assign next pointer to NULL
    new_node->next = NULL;
    
    // if linked list is empty
    if(head_DL_node == NULL)
    {
        // this is the only node in the list
        new_node->prev = NULL;
    }
    
    DL_node* end_node = head_DL_node;
    
    // travel to the end of the list
    while(end_node->next != NULL)
    {
        end_node = end_node->next;
    }
    
    // assign the new node after the end node
    end_node->next = new_node;
    
    // assign previous of new node to the current end node
    new_node->prev = end_node;
    
}

void printDL(DL_node* head_DL_node)
{
    // print the list
    DL_node* temp_node = head_DL_node;
    while(temp_node != NULL)
    {
        std::cout << temp_node->data << "\t";
        temp_node = temp_node->next;
    }
    
    //if (head_DL_node == nullptr) std::cout << "\nnullptr\n"; else std::cout << "Not empty\n";
}

void printSlice(DL_node* head_DL_node, int l, int r)
{
    DL_node* temp_node = head_DL_node;
    int count = 1;
    
    // Find the starting node
    while (temp_node != NULL && count < l)
    {
        temp_node = temp_node->next;
        count++;
    }
    
    // Print the slice
    while (temp_node != NULL && count <= r)
    {
        std::cout << temp_node->data << "\t";
        temp_node = temp_node->next;
        count++;
    }
    
    std::cout << std::endl;
}

int getValueByIndex(DL_node* head_DL_node, int index)
{
    DL_node* temp_node = head_DL_node;
    int count = 0;
    
    // Find the node at the specified index
    while (temp_node != NULL && count < index)
    {
        temp_node = temp_node->next;
        count++;
    }
    
    if (temp_node != NULL)
    {
        return temp_node->data;
    }
    else
    {
        // Handle the case when the index is out of bounds
        std::cout << "Index out of bounds" << std::endl;
        // Return a default value indicating an error
        return -1;
    }
}

int sizeDL(DL_node* head_DL_node)
{
    int count = 0;
    DL_node* temp_node = head_DL_node;
    
    // Traverse the list and count the elements
    while (temp_node != NULL)
    {
        count++;
        temp_node = temp_node->next;
    }
    
    return count;
}

int main()
{
    // create the head node of the doubly linked list
    DL_node* head_DL_node = new DL_node();
    
    initDL(head_DL_node, 10);
    
    insertToEnd(head_DL_node, 20);
    insertToEnd(head_DL_node, 30);
    insertToEnd(head_DL_node, 40);
    insertToEnd(head_DL_node, 50);
    insertToEnd(head_DL_node, 60);
    
    printDL(head_DL_node);std::cout << "\n";    
    if (head_DL_node == nullptr) std::cout << "\tnullptr\n"; else std::cout << "\tNot empty\n";
    
    return 0;
}