# Queue using LL

{% code title="Queue.h" %}
```cpp
#include "Singly LL.h"
#pragma once

template<typename T>class Queue {
    SinglyLL<T> list;
public:
    void enqueue(const T val);
    bool dequeue(T& val);
    bool isEmpty();
    bool isFull();
};

template<typename T>bool Queue<T> :: isEmpty() {
    return list.Empty();
}

template<typename T>bool Queue<T> :: isFull() {
    return false;
}

template<typename T>void Queue<T> :: enqueue(const T val) {
    list.insert(val);
}

template<typename T>bool Queue<T> :: dequeue(T& val) {
    if(isEmpty()) return false;

    list.removeAtHead(val);
    return true;
}
```
{% endcode %}

{% code title="Singly LL.h" %}
```cpp
#include <iostream>
#pragma once
using namespace std;

template<typename T>class Node{
public:
	T data;
	Node* next;
	explicit Node(const T d) : data(d), next(nullptr) {}
};

template<typename T>class SinglyLL{
	Node<T>* head ;
	int elements;
public:
	SinglyLL(): elements(0), head(nullptr) {};

	SinglyLL(const SinglyLL<T>& list);
	
	void insert(const T val);
	
	void insertAtHead(const T val);
	
	bool remove(const T val);
	
	void removeAtHead(T& headData);

    bool Empty() { return elements == 0; }
};

template<typename T>SinglyLL<T> :: SinglyLL(const SinglyLL<T>& list) {
	Node<T>* listHead = list.head;
	Node<T>* newNode = new Node<T>(listHead -> data);
	Node<T>* cur = head = newNode;
	listHead = listHead -> next;

	while (listHead != nullptr) {
		Node<T>* temp = new Node<T>(listHead -> data);
		listHead = listHead -> next;
		cur -> next = temp;
		cur = temp;
	}
}

// Insert At Any Position
template<typename T>void SinglyLL<T> :: insert(const T val) {
	if(elements == 0) {
		Node<T>* newNode = new Node<T>(val);
		head = newNode;
		elements++;
		return;
	}
	
	Node<T>* newNode = new Node<T>(val);
	Node<T>* cur = head;
	
	while (cur -> next != nullptr) {
		cur = cur -> next;
	}
	cur -> next = newNode;
	elements++;
}

// Insert At Head
template<typename T>void SinglyLL<T> :: insertAtHead(const T val) {
	if(elements == 0) {
		Node<T>* newNode = new Node<T>(val);
		head = newNode;
		elements++;
		return;
	}
	
	Node<T>* newNode = new Node<T>(val);
	newNode -> next = head;
	head = newNode;
	elements++;
}

// Remove Head
template<typename T>void SinglyLL<T> :: removeAtHead(T& headData) {
	if(elements == 0) return ;

	if(elements == 1) {
		headData = head -> data;
		delete head;
		elements--;
		return ;
	}

	Node<T>* cur = head;
	headData = cur -> data;
	head = head -> next;
	delete cur;
	elements--;
	return;
}

```
{% endcode %}

```cpp

#include "Queue.h"

int main()
{

    Queue<string> q1;
    q1.enqueue("ABC");
    q1.enqueue("DEF");
    q1.enqueue("GHI");

    cout << "Queue Elements: ";
    while (!q1.isEmpty())
    {
        string temp;
        q1.dequeue(temp);
        cout << temp << " ";
    }
    cout << endl;
}
```
