From fc5ca10c3c6492d2e1089921e2aa844e8242e099 Mon Sep 17 00:00:00 2001
From: Kushagra9399 <146541055+Kushagra9399@users.noreply.github.com>
Date: Mon, 3 Mar 2025 22:42:31 +0530
Subject: [PATCH 1/4] Update stack.cpp

Here is the updated code for stack.py in c++ implementation. I have checked the array.py and array.cpp and then imported the required modules/ libraries.
---
 .../_backend/cpp/stack/stack.cpp              | 155 ++++++++++++++----
 1 file changed, 127 insertions(+), 28 deletions(-)

diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
index 2ba1bec7a..20cada5b6 100644
--- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
+++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
@@ -1,48 +1,147 @@
 #include <Python.h>
-#include "ArrayStack.hpp"
+#include <vector>
+#include <stdexcept>
+#include "SinglyLinkedList.hpp"
+#include "DynamicOneDimensionalArray.hpp"
 
-static struct PyModuleDef stack_struct = {
+// Forward declarations for types in the module
+extern PyTypeObject ArrayStackType;
+extern PyTypeObject LinkedListStackType;
+
+static struct PyModuleDef stackmodule = {
     PyModuleDef_HEAD_INIT,
     "_stack",
-    0,
+    "Stack Data Structure Module",
     -1,
-    NULL,
+    NULL
 };
 
-PyMODINIT_FUNC PyInit__stack(void) {
-    Py_Initialize();
-    PyObject *stack = PyModule_Create(&stack_struct);
+// Stack base class (Abstract class)
+class Stack {
+public:
+    virtual void push(PyObject* x) = 0;
+    virtual PyObject* pop() = 0;
+    virtual bool is_empty() = 0;
+    virtual PyObject* peek() = 0;
+    virtual Py_ssize_t __len__() = 0;
+    virtual const char* __str__() = 0;
+};
 
-    if (PyType_Ready(&ArrayStackType) < 0) {
-        return NULL;
+// ArrayStack Implementation (Derived class)
+class ArrayStack : public Stack {
+public:
+    std::vector<PyObject*> items; // Dynamic array to store items
+
+    ArrayStack() {}
+
+    ArrayStack(std::vector<PyObject*> initial_items) {
+        items = initial_items;
     }
-    Py_INCREF(&ArrayStackType);
-    PyModule_AddObject(stack, "ArrayStack", reinterpret_cast<PyObject*>(&ArrayStackType));
 
-    if (PyType_Ready(&ArrayType) < 0) {
-        return NULL;
+    void push(PyObject* x) override {
+        items.push_back(x);
     }
-    Py_INCREF(&ArrayType);
-    PyModule_AddObject(stack, "Array", reinterpret_cast<PyObject*>(&ArrayType));
 
-    if (PyType_Ready(&OneDimensionalArrayType) < 0) {
-        return NULL;
+    PyObject* pop() override {
+        if (is_empty()) {
+            throw std::out_of_range("Stack is empty");
+        }
+        PyObject* top_element = items.back();
+        items.pop_back();
+        return top_element;
     }
-    Py_INCREF(&OneDimensionalArrayType);
-    PyModule_AddObject(stack, "OneDimensionalArray", reinterpret_cast<PyObject*>(&OneDimensionalArrayType));
 
-    if (PyType_Ready(&DynamicArrayType) < 0) {
-        return NULL;
+    bool is_empty() override {
+        return items.empty();
     }
-    Py_INCREF(&DynamicArrayType);
-    PyModule_AddObject(stack, "DynamicArray", reinterpret_cast<PyObject*>(&DynamicArrayType));
 
-    if (PyType_Ready(&DynamicOneDimensionalArrayType) < 0) {
-        return NULL;
+    PyObject* peek() override {
+        if (is_empty()) {
+            throw std::out_of_range("Stack is empty");
+        }
+        return items.back();
+    }
+
+    Py_ssize_t __len__() override {
+        return items.size();
+    }
+
+    const char* __str__() override {
+        std::string result = "[";
+        for (size_t i = 0; i < items.size(); ++i) {
+            result += PyUnicode_AsUTF8(PyObject_Str(items[i]));
+            if (i != items.size() - 1) {
+                result += ", ";
+            }
+        }
+        result += "]";
+        return result.c_str();
+    }
+};
+
+// LinkedListStack Implementation (Derived class)
+class LinkedListStack : public Stack {
+public:
+    SinglyLinkedList stack; // Linked list to store the stack elements
+
+    LinkedListStack() {}
+
+    LinkedListStack(std::vector<PyObject*> initial_items) {
+        for (auto& item : initial_items) {
+            push(item);
+        }
+    }
+
+    void push(PyObject* x) override {
+        stack.appendleft(x);
+    }
+
+    PyObject* pop() override {
+        if (is_empty()) {
+            throw std::out_of_range("Stack is empty");
+        }
+        return stack.popleft();
     }
-    Py_INCREF(&DynamicOneDimensionalArrayType);
-    PyModule_AddObject(stack, "DynamicOneDimensionalArray", reinterpret_cast<PyObject*>(&DynamicOneDimensionalArrayType));
 
+    bool is_empty() override {
+        return stack.size() == 0;
+    }
+
+    PyObject* peek() override {
+        return stack.head;
+    }
+
+    Py_ssize_t __len__() override {
+        return stack.size();
+    }
+
+    const char* __str__() override {
+        std::string result = "[";
+        auto node = stack.head;
+        while (node != nullptr) {
+            result += PyUnicode_AsUTF8(PyObject_Str(node->data));
+            if (node->next != nullptr) {
+                result += ", ";
+            }
+            node = node->next;
+        }
+        result += "]";
+        return result.c_str();
+    }
+};
+
+// Python Module Initialization
+PyMODINIT_FUNC PyInit__stack(void) {
+    PyObject *stack_module = PyModule_Create(&stackmodule);
+    if (PyType_Ready(&ArrayStackType) < 0)
+        return NULL;
+    Py_INCREF(&ArrayStackType);
+    PyModule_AddObject(stack_module, "ArrayStack", (PyObject*)&ArrayStackType);
+
+    if (PyType_Ready(&LinkedListStackType) < 0)
+        return NULL;
+    Py_INCREF(&LinkedListStackType);
+    PyModule_AddObject(stack_module, "LinkedListStack", (PyObject*)&LinkedListStackType);
 
-    return stack;
+    return stack_module;
 }

From 5c8214c82bbe6b2d986f0a37b9e0137455f6b924 Mon Sep 17 00:00:00 2001
From: Kushagra9399 <146541055+Kushagra9399@users.noreply.github.com>
Date: Sat, 8 Mar 2025 23:46:28 +0530
Subject: [PATCH 2/4] Update stack.cpp

I have updated this file by add implementation using linkedlist and array.
---
 .../_backend/cpp/stack/stack.cpp              | 317 +++++++++++-------
 1 file changed, 197 insertions(+), 120 deletions(-)

diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
index 20cada5b6..1eeddbdcd 100644
--- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
+++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
@@ -1,147 +1,224 @@
-#include <Python.h>
+#include <iostream>
 #include <vector>
 #include <stdexcept>
-#include "SinglyLinkedList.hpp"
-#include "DynamicOneDimensionalArray.hpp"
-
-// Forward declarations for types in the module
-extern PyTypeObject ArrayStackType;
-extern PyTypeObject LinkedListStackType;
-
-static struct PyModuleDef stackmodule = {
-    PyModuleDef_HEAD_INIT,
-    "_stack",
-    "Stack Data Structure Module",
-    -1,
-    NULL
-};
-
-// Stack base class (Abstract class)
-class Stack {
-public:
-    virtual void push(PyObject* x) = 0;
-    virtual PyObject* pop() = 0;
-    virtual bool is_empty() = 0;
-    virtual PyObject* peek() = 0;
-    virtual Py_ssize_t __len__() = 0;
-    virtual const char* __str__() = 0;
-};
-
-// ArrayStack Implementation (Derived class)
-class ArrayStack : public Stack {
-public:
-    std::vector<PyObject*> items; // Dynamic array to store items
-
-    ArrayStack() {}
-
-    ArrayStack(std::vector<PyObject*> initial_items) {
-        items = initial_items;
-    }
+#include <memory>
+#include <sstream>
+#include <typeinfo>
+
+namespace pydatastructs {
+
+    // DynamicOneDimensionalArray implementation
+    class DynamicOneDimensionalArray {
+    private:
+        std::vector<int> arr;
+        
+    public:
+        void append(int x) {
+            arr.push_back(x);
+        }
 
-    void push(PyObject* x) override {
-        items.push_back(x);
-    }
+        int get_last_filled() const {
+            if (arr.empty()) {
+                throw std::out_of_range("Array is empty");
+            }
+            return arr.back();
+        }
 
-    PyObject* pop() override {
-        if (is_empty()) {
-            throw std::out_of_range("Stack is empty");
+        void delete_last() {
+            if (arr.empty()) {
+                throw std::out_of_range("Array is empty");
+            }
+            arr.pop_back();
         }
-        PyObject* top_element = items.back();
-        items.pop_back();
-        return top_element;
-    }
 
-    bool is_empty() override {
-        return items.empty();
-    }
+        size_t size() const {
+            return arr.size();
+        }
 
-    PyObject* peek() override {
-        if (is_empty()) {
-            throw std::out_of_range("Stack is empty");
+        std::string to_string() const {
+            std::ostringstream oss;
+            for (int val : arr) {
+                oss << val << " ";
+            }
+            return oss.str();
         }
-        return items.back();
-    }
 
-    Py_ssize_t __len__() override {
-        return items.size();
-    }
+        void set_dtype(const std::type_info& type) {
+            // In the context of C++, we typically don't need to worry about dynamic types like in Python.
+        }
+    };
+
+    // SinglyLinkedList Node definition
+    struct Node {
+        int value;
+        std::shared_ptr<Node> next;
+
+        Node(int x) : value(x), next(nullptr) {}
+    };
+
+    // SinglyLinkedList implementation
+    class SinglyLinkedList {
+    private:
+        std::shared_ptr<Node> head;
+        size_t list_size;
+
+    public:
+        SinglyLinkedList() : head(nullptr), list_size(0) {}
+
+        void append_left(int x) {
+            auto new_node = std::make_shared<Node>(x);
+            new_node->next = head;
+            head = new_node;
+            list_size++;
+        }
 
-    const char* __str__() override {
-        std::string result = "[";
-        for (size_t i = 0; i < items.size(); ++i) {
-            result += PyUnicode_AsUTF8(PyObject_Str(items[i]));
-            if (i != items.size() - 1) {
-                result += ", ";
+        int pop_left() {
+            if (head == nullptr) {
+                throw std::out_of_range("List is empty");
             }
+            int value = head->value;
+            head = head->next;
+            list_size--;
+            return value;
         }
-        result += "]";
-        return result.c_str();
-    }
-};
 
-// LinkedListStack Implementation (Derived class)
-class LinkedListStack : public Stack {
-public:
-    SinglyLinkedList stack; // Linked list to store the stack elements
+        int head_value() const {
+            if (head == nullptr) {
+                throw std::out_of_range("List is empty");
+            }
+            return head->value;
+        }
 
-    LinkedListStack() {}
+        size_t size() const {
+            return list_size;
+        }
 
-    LinkedListStack(std::vector<PyObject*> initial_items) {
-        for (auto& item : initial_items) {
-            push(item);
+        std::string to_string() const {
+            std::ostringstream oss;
+            auto current = head;
+            while (current) {
+                oss << current->value << " ";
+                current = current->next;
+            }
+            return oss.str();
         }
-    }
+    };
+}
 
-    void push(PyObject* x) override {
-        stack.appendleft(x);
-    }
 
-    PyObject* pop() override {
-        if (is_empty()) {
-            throw std::out_of_range("Stack is empty");
+namespace pydatastructs {
+    // Forward declaration of the SinglyLinkedList and DynamicOneDimensionalArray
+    class DynamicOneDimensionalArray;
+    class SinglyLinkedList;
+
+    enum class Backend { PYTHON, CPP };
+
+    // Abstract Stack class
+    class Stack {
+    public:
+        virtual ~Stack() {}
+        virtual void push(int x) = 0;
+        virtual int pop() = 0;
+        virtual bool is_empty() const = 0;
+        virtual int peek() const = 0;
+        virtual size_t size() const = 0;
+        virtual std::string to_string() const = 0;
+    };
+
+    // ArrayStack class for stack implementation using dynamic array
+    class ArrayStack : public Stack {
+    private:
+        std::shared_ptr<DynamicOneDimensionalArray> items;
+        
+    public:
+        ArrayStack(std::shared_ptr<DynamicOneDimensionalArray> items) : items(items) {}
+
+        void push(int x) override {
+            items->append(x);
         }
-        return stack.popleft();
-    }
 
-    bool is_empty() override {
-        return stack.size() == 0;
-    }
+        int pop() override {
+            if (is_empty()) {
+                throw std::out_of_range("Stack is empty");
+            }
+            int top_element = items->get_last_filled();
+            items->delete_last();
+            return top_element;
+        }
 
-    PyObject* peek() override {
-        return stack.head;
-    }
+        bool is_empty() const override {
+            return items->size() == 0;
+        }
 
-    Py_ssize_t __len__() override {
-        return stack.size();
-    }
+        int peek() const override {
+            if (is_empty()) {
+                throw std::out_of_range("Stack is empty");
+            }
+            return items->get_last_filled();
+        }
 
-    const char* __str__() override {
-        std::string result = "[";
-        auto node = stack.head;
-        while (node != nullptr) {
-            result += PyUnicode_AsUTF8(PyObject_Str(node->data));
-            if (node->next != nullptr) {
-                result += ", ";
+        size_t size() const override {
+            return items->size();
+        }
+
+        std::string to_string() const override {
+            return items->to_string();
+        }
+    };
+
+    // LinkedListStack class for stack implementation using singly linked list
+    class LinkedListStack : public Stack {
+    private:
+        std::shared_ptr<SinglyLinkedList> stack;
+
+    public:
+        LinkedListStack(std::shared_ptr<SinglyLinkedList> stack) : stack(stack) {}
+
+        void push(int x) override {
+            stack->append_left(x);
+        }
+
+        int pop() override {
+            if (is_empty()) {
+                throw std::out_of_range("Stack is empty");
+            }
+            return stack->pop_left();
+        }
+
+        bool is_empty() const override {
+            return stack->size() == 0;
+        }
+
+        int peek() const override {
+            return stack->head_value();
+        }
+
+        size_t size() const override {
+            return stack->size();
+        }
+
+        std::string to_string() const override {
+            return stack->to_string();
+        }
+    };
+
+    // Stack factory function
+    std::shared_ptr<Stack> create_stack(const std::string& implementation, std::shared_ptr<DynamicOneDimensionalArray> items = nullptr, Backend backend = Backend::CPP) {
+        if (implementation == "array") {
+            if (backend == Backend::CPP) {
+                // Use C++ backend for array stack
+                return std::make_shared<ArrayStack>(items);
+            } else {
+                // Use Python backend or default
+                return std::make_shared<ArrayStack>(items);
+            }
+        } else if (implementation == "linked_list") {
+            if (backend != Backend::PYTHON) {
+                throw std::invalid_argument("Linked list stack requires Python backend.");
             }
-            node = node->next;
+            return std::make_shared<LinkedListStack>(std::make_shared<SinglyLinkedList>());
+        } else {
+            throw std::invalid_argument("Implementation not supported");
         }
-        result += "]";
-        return result.c_str();
     }
-};
-
-// Python Module Initialization
-PyMODINIT_FUNC PyInit__stack(void) {
-    PyObject *stack_module = PyModule_Create(&stackmodule);
-    if (PyType_Ready(&ArrayStackType) < 0)
-        return NULL;
-    Py_INCREF(&ArrayStackType);
-    PyModule_AddObject(stack_module, "ArrayStack", (PyObject*)&ArrayStackType);
-
-    if (PyType_Ready(&LinkedListStackType) < 0)
-        return NULL;
-    Py_INCREF(&LinkedListStackType);
-    PyModule_AddObject(stack_module, "LinkedListStack", (PyObject*)&LinkedListStackType);
-
-    return stack_module;
 }

From 206991710df58c12bb9d2c0bd88af2fc9f283e0b Mon Sep 17 00:00:00 2001
From: Kushagra9399 <146541055+Kushagra9399@users.noreply.github.com>
Date: Sat, 8 Mar 2025 23:51:00 +0530
Subject: [PATCH 3/4] Update stack.cpp

Try solving errors in test cases
---
 .../_backend/cpp/stack/stack.cpp                    | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
index 1eeddbdcd..8a9d0dea9 100644
--- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
+++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
@@ -4,6 +4,19 @@
 #include <memory>
 #include <sstream>
 #include <typeinfo>
+#include <Python.h>
+
+static PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "_stack", /* name of module */
+    nullptr,  /* module documentation */
+    -1,       /* size of per-interpreter state of the module */
+    nullptr   /* methods of the module */
+};
+
+PyMODINIT_FUNC PyInit__stack(void) {
+    return PyModule_Create(&moduledef);
+}
 
 namespace pydatastructs {
 

From 6dedf484ef632c3aa379706527d67c63393b291f Mon Sep 17 00:00:00 2001
From: Kushagra9399 <146541055+Kushagra9399@users.noreply.github.com>
Date: Sat, 29 Mar 2025 15:03:11 +0000
Subject: [PATCH 4/4] Updating ArrayStack.cpp

---
 oryx-build-commands.txt                                         | 2 ++
 .../_backend/cpp/stack/__init__.py                              | 0
 .../miscellaneous_data_structures/_backend/cpp/stack/stack.cpp  | 1 +
 pydatastructs/miscellaneous_data_structures/stack.py            | 2 +-
 4 files changed, 4 insertions(+), 1 deletion(-)
 create mode 100644 oryx-build-commands.txt
 create mode 100644 pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/__init__.py

diff --git a/oryx-build-commands.txt b/oryx-build-commands.txt
new file mode 100644
index 000000000..d647bdf7f
--- /dev/null
+++ b/oryx-build-commands.txt
@@ -0,0 +1,2 @@
+PlatformWithVersion=Python 
+BuildCommands=conda env create --file environment.yml --prefix ./venv --quiet
diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/__init__.py b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
index 8a9d0dea9..613099351 100644
--- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
+++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp
@@ -5,6 +5,7 @@
 #include <sstream>
 #include <typeinfo>
 #include <Python.h>
+#include "ArrayStack.hpp"
 
 static PyModuleDef moduledef = {
     PyModuleDef_HEAD_INIT,
diff --git a/pydatastructs/miscellaneous_data_structures/stack.py b/pydatastructs/miscellaneous_data_structures/stack.py
index 38f72b43f..71efd21af 100644
--- a/pydatastructs/miscellaneous_data_structures/stack.py
+++ b/pydatastructs/miscellaneous_data_structures/stack.py
@@ -1,5 +1,5 @@
 from pydatastructs.linear_data_structures import DynamicOneDimensionalArray, SinglyLinkedList
-from pydatastructs.miscellaneous_data_structures._backend.cpp import _stack
+from pydatastructs.miscellaneous_data_structures._backend.cpp.stack import _stack
 from pydatastructs.utils.misc_util import (
     _check_type, NoneType, Backend,
     raise_if_backend_is_not_python)