From 8c34d8e696502cd42560fccc26a489456df6d5b1 Mon Sep 17 00:00:00 2001 From: whaffman Date: Wed, 20 Aug 2025 13:12:22 +0200 Subject: [PATCH] Add initial implementation of Easyfind, Span, and MutantStack classes with tests --- .gitignore | 6 ++ common.mk | 2 +- ex00/Makefile | 2 + ex00/compile_commands.json | 19 ++++++ ex00/inc/easyfind.hpp | 18 +++++ ex00/inc/easyfind.tpp | 3 + ex00/src/main.cpp | 86 ++++++++++++++++++++++++ ex01/Makefile | 2 + ex01/compile_commands.json | 19 ++++++ ex01/inc/Span.hpp | 49 ++++++++++++++ ex01/src/Span.cpp | 100 ++++++++++++++++++++++++++++ ex01/src/main.cpp | 131 +++++++++++++++++++++++++++++++++++++ ex02/Makefile | 2 + ex02/compile_commands.json | 36 ++++++++++ ex02/inc/MutantStack.hpp | 24 +++++++ ex02/inc/MutantStack.tpp | 63 ++++++++++++++++++ ex02/src/main.cpp | 79 ++++++++++++++++++++++ 17 files changed, 640 insertions(+), 1 deletion(-) create mode 100644 ex00/Makefile create mode 100644 ex00/compile_commands.json create mode 100644 ex00/inc/easyfind.hpp create mode 100644 ex00/inc/easyfind.tpp create mode 100644 ex00/src/main.cpp create mode 100644 ex01/Makefile create mode 100644 ex01/compile_commands.json create mode 100644 ex01/inc/Span.hpp create mode 100644 ex01/src/Span.cpp create mode 100644 ex01/src/main.cpp create mode 100644 ex02/Makefile create mode 100644 ex02/compile_commands.json create mode 100644 ex02/inc/MutantStack.hpp create mode 100644 ex02/inc/MutantStack.tpp create mode 100644 ex02/src/main.cpp diff --git a/.gitignore b/.gitignore index e69de29..4a87260 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,6 @@ +*.d +*.o +.cache +Easyfind +Span +MutantStack \ No newline at end of file diff --git a/common.mk b/common.mk index 2e13a39..e1f8179 100644 --- a/common.mk +++ b/common.mk @@ -15,7 +15,7 @@ VPATH = src SRC = $(notdir $(wildcard src/*.cpp)) OBJ = $(SRC:.cpp=.o) CC = c++ -CFLAGS = -Wall -Wextra -Werror -std=c++11 -MMD +CFLAGS = -Wall -Wextra -Werror -std=c++23 -MMD all: $(NAME) diff --git a/ex00/Makefile b/ex00/Makefile new file mode 100644 index 0000000..a963e26 --- /dev/null +++ b/ex00/Makefile @@ -0,0 +1,2 @@ +NAME := Easyfind +include ../common.mk \ No newline at end of file diff --git a/ex00/compile_commands.json b/ex00/compile_commands.json new file mode 100644 index 0000000..f2fc738 --- /dev/null +++ b/ex00/compile_commands.json @@ -0,0 +1,19 @@ +[ + { + "arguments": [ + "/usr/bin/c++", + "-Wall", + "-Wextra", + "-Werror", + "-std=c++23", + "-I./inc", + "-c", + "-o", + "main.o", + "src/main.cpp" + ], + "directory": "/home/willem/projects/CPP08/ex00", + "file": "/home/willem/projects/CPP08/ex00/src/main.cpp", + "output": "/home/willem/projects/CPP08/ex00/main.o" + } +] diff --git a/ex00/inc/easyfind.hpp b/ex00/inc/easyfind.hpp new file mode 100644 index 0000000..65cae78 --- /dev/null +++ b/ex00/inc/easyfind.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +template +int &easyfind(T &container, int value) +{ + typename T::iterator it = std::find(container.begin(), container.end(), value); + if (it != container.end()) + { + return *it; + } + else + { + throw std::out_of_range("Value not found"); + } +} diff --git a/ex00/inc/easyfind.tpp b/ex00/inc/easyfind.tpp new file mode 100644 index 0000000..27190c4 --- /dev/null +++ b/ex00/inc/easyfind.tpp @@ -0,0 +1,3 @@ +#pragma once + +#include "easyfind.hpp" \ No newline at end of file diff --git a/ex00/src/main.cpp b/ex00/src/main.cpp new file mode 100644 index 0000000..1d65b29 --- /dev/null +++ b/ex00/src/main.cpp @@ -0,0 +1,86 @@ +#include "easyfind.hpp" +#include +#include +#include + +int main() +{ + std::vector vec = {1, 2, 3, 4, 5}; + try + { + std::cout << "Testing with vector...\n"; + std::cout << "Vector contents: "; + for (const auto &val : vec) + { + std::cout << val << " "; + } + std::cout << "\n"; + + std::cout << "Searching for value 3...\n"; + int &found = easyfind(vec, 3); + std::cout << "Found: " << found << std::endl; + + std::cout << "Modifying found value...\n"; + found = 10; // Modify the found value + for (const auto &val : vec) + { + std::cout << val << " "; + } + std::cout << "\n"; + } + catch (const std::out_of_range &e) + { + std::cerr << e.what() << std::endl; + } + + try + { + std::cout << "Searching for value 6 (not in vector)...\n"; + int ¬Found = easyfind(vec, 6); + std::cout << "Found: " << notFound << std::endl; + } + catch (const std::out_of_range &e) + { + std::cerr << e.what() << std::endl; + } + + std::cout << "\n\nTesting with deque...\n"; + + std::deque deq = {10, 20, 30, 40, 50}; + try + { + std::cout << "Deque contents: "; + for (const auto &val : deq) + { + std::cout << val << " "; + } + std::cout << "\n"; + std::cout << "Searching for value 30...\n"; + int &foundInDeque = easyfind(deq, 30); + std::cout << "Found: " << foundInDeque << "\n"; + std::cout << "Modifying found value...\n"; + foundInDeque = 100; // Modify the found value + for (const auto &val : deq) + { + std::cout << val << " "; + } + std::cout << "\n"; + } + catch (const std::out_of_range &e) + { + std::cerr << e.what() << std::endl; + } + + try + { + std::cout << "Searching for value 60 (not in deque)...\n"; + int ¬FoundInDeque = easyfind(deq, 60); + std::cout << "Found: " << notFoundInDeque << std::endl; + } + catch (const std::out_of_range &e) + { + std::cerr << e.what() << std::endl; + } + + return 0; +} diff --git a/ex01/Makefile b/ex01/Makefile new file mode 100644 index 0000000..97f9897 --- /dev/null +++ b/ex01/Makefile @@ -0,0 +1,2 @@ +NAME := Span +include ../common.mk \ No newline at end of file diff --git a/ex01/compile_commands.json b/ex01/compile_commands.json new file mode 100644 index 0000000..f14c0b5 --- /dev/null +++ b/ex01/compile_commands.json @@ -0,0 +1,19 @@ +[ + { + "arguments": [ + "/usr/bin/c++", + "-Wall", + "-Wextra", + "-Werror", + "-std=c++23", + "-I./inc", + "-c", + "-o", + "main.o", + "src/main.cpp" + ], + "directory": "/home/willem/projects/CPP08/ex01", + "file": "/home/willem/projects/CPP08/ex01/src/main.cpp", + "output": "/home/willem/projects/CPP08/ex01/main.o" + } +] diff --git a/ex01/inc/Span.hpp b/ex01/inc/Span.hpp new file mode 100644 index 0000000..54434f1 --- /dev/null +++ b/ex01/inc/Span.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include + +class Span +{ + public: + Span() = delete; + Span(unsigned int size); + Span(const Span &other); + Span(Span &&other) noexcept; + Span &operator=(const Span &other); + Span &&operator=(Span &&other) noexcept; + ~Span() noexcept; + + void addNumber(int number); + + unsigned int shortestSpan() const; + unsigned int longestSpan() const; + + template + requires std::same_as, int> + void addRange(Iterator begin, Iterator end) + { + for (Iterator it = begin; it < end; it++) + { + addNumber(*it); + } + } + + class OutOfSpaceException : public std::exception + { + public: + const char *what() const throw(); + }; + + class NoSpanFoundException : public std::exception + { + public: + const char *what() const throw(); + }; + + private: + unsigned int _size; + std::vector _data; +}; diff --git a/ex01/src/Span.cpp b/ex01/src/Span.cpp new file mode 100644 index 0000000..5f9ffe6 --- /dev/null +++ b/ex01/src/Span.cpp @@ -0,0 +1,100 @@ +#include "Span.hpp" + +#include +#include +#include + +Span::Span(unsigned int size) : _size(size), _data() { + _data.reserve(size); +} + +Span::Span(const Span &other) : _size(other._size), _data(other._size) +{ + for (int n : other._data) + { + addNumber(n); + } +} + +Span::Span(Span &&other) noexcept : _size(other._size), _data(std::move(other._data)) +{ + other._size = 0; +} + +Span &Span::operator=(const Span &other) +{ + if (this != &other) + { + _size = other._size; + _data = other._data; + } + return *this; +} + +Span &&Span::operator=(Span &&other) +{ + if (this != &other) + { + _size = other._size; + _data = std::move(other._data); + other._size = 0; + } + return std::move(*this); +} + +Span::~Span() {} + +void Span::addNumber(int number) +{ + if (_data.size() >= _size) + { + throw OutOfSpaceException(); + } + _data.push_back(number); +} + +unsigned int Span::shortestSpan() const +{ + if (_data.size() < 2) + { + throw NoSpanFoundException(); + } + + std::vector sortedData = _data; + std::sort(sortedData.begin(), sortedData.end()); + + unsigned int minSpan = std::numeric_limits::max(); + for (size_t i = 0; i < sortedData.size() - 1; i++) + { + unsigned int span = sortedData[i + 1] - sortedData[i]; + if (span < minSpan) + { + minSpan = span; + } + } + + return minSpan; +} + +unsigned int Span::longestSpan() const +{ + if (_data.size() < 2) + { + throw NoSpanFoundException(); + } + + auto min = std::min_element(_data.begin(), _data.end()); + auto max = std::max_element(_data.begin(), _data.end()); + + return *max - *min; +} + +const char *Span::OutOfSpaceException::what() const throw() +{ + return "No more space to add numbers"; +} + +const char *Span::NoSpanFoundException::what() const throw() +{ + return "No span found, not enough numbers"; +} diff --git a/ex01/src/main.cpp b/ex01/src/main.cpp new file mode 100644 index 0000000..8f9b511 --- /dev/null +++ b/ex01/src/main.cpp @@ -0,0 +1,131 @@ +#include "Span.hpp" + +#include +#include +#include +#include + +#define GUB "\033[1;32;4m" +#define ERROR "\033[1;31m" +#define END "\033[0m" + +std::vector generateRandomVecor(int size) +{ + std::vector vec; + std::srand(static_cast(std::time(nullptr))); + + for (int i = 0; i < size; ++i) + { + vec.push_back(rand()); + } + + return vec; +} + +int main() +{ + std::println(GUB "Testing Span with more numbers then the size of the span..." END); + try + { + std::println("Creating Span with size 5..."); + Span span(5); + std::println("Adding 6 numbers to the span..."); + span.addNumber(1); + span.addNumber(2); + span.addNumber(3); + span.addNumber(4); + span.addNumber(5); + span.addNumber(6); // This should throw an exception + } + catch (const Span::OutOfSpaceException &e) + { + std::println(std::cerr, ERROR "Error: {}" END, e.what()); + } + std::println(); + + std::println(GUB "Testing Span with 0 numbers..." END); + try + { + std::println("Creating Span with size 0..."); + Span span(0); + std::println("Trying to find the shortest span..."); + span.shortestSpan(); // This should throw an exception + } + catch (const Span::NoSpanFoundException &e) + { + std::println(std::cerr, ERROR "Error: {}" END, e.what()); + } + std::println(); + + std::println(GUB "Testing Span with one number..." END); + try + { + std::println("Creating Span with size 1..."); + Span span(1); + std::println("Adding 1 number to the span..."); + span.addNumber(42); + std::println("Trying to find the shortest span..."); + span.shortestSpan(); // This should throw an exception + } + catch (const Span::NoSpanFoundException &e) + { + std::println(std::cerr, ERROR "Error: {}" END, e.what()); + } + std::println(); + + std::println(GUB "Testing Span with two numbers..." END); + try + { + std::println("Creating Span with size 2..."); + Span span(2); + std::println("Adding 2 numbers to the span..."); + span.addNumber(10); + span.addNumber(20); + std::println("Trying to find the shortest span..."); + unsigned int shortest = span.shortestSpan(); + std::println("Shortest span: {}", shortest); + + std::println("Finding the longest span..."); + unsigned int longest = span.longestSpan(); + std::println("Longest span: {}", longest); + } + catch (const Span::NoSpanFoundException &e) + { + std::println(std::cerr, ERROR "Error: {}" END, e.what()); + } + catch (const Span::OutOfSpaceException &e) + { + std::println(std::cerr, ERROR "Error: {}" END, e.what()); + } + std::println(); + + std::println(GUB "Testing Span with a range of random numbers..." END); + + try + { + unsigned int size = 10'000; + std::println("Generating a vector with {} random numbers...", size); + std::vector randomNumbers = generateRandomVecor(size); + std::println("Adding the random numbers to a span of size {}...", size); + Span span(size); + span.addRange(randomNumbers.begin(), randomNumbers.end()); + + std::println("Finding the shortest span..."); + unsigned int shortest = span.shortestSpan(); + std::println("Shortest span: {}", shortest); + + std::println("Finding the longest span..."); + unsigned int longest = span.longestSpan(); + std::println("Longest span: {}", longest); + } + catch (const Span::OutOfSpaceException &e) + { + std::println(std::cerr, ERROR "Error: {}" END, e.what()); + } + catch (const Span::NoSpanFoundException &e) + { + std::println(std::cerr, ERROR "Error: {}" END, e.what()); + } + + return 0; +} diff --git a/ex02/Makefile b/ex02/Makefile new file mode 100644 index 0000000..129a47c --- /dev/null +++ b/ex02/Makefile @@ -0,0 +1,2 @@ +NAME := MutantStack +include ../common.mk \ No newline at end of file diff --git a/ex02/compile_commands.json b/ex02/compile_commands.json new file mode 100644 index 0000000..34ae24a --- /dev/null +++ b/ex02/compile_commands.json @@ -0,0 +1,36 @@ +[ + { + "arguments": [ + "/usr/bin/c++", + "-Wall", + "-Wextra", + "-Werror", + "-std=c++23", + "-I./inc", + "-c", + "-o", + "main.o", + "src/main.cpp" + ], + "directory": "/home/willem/projects/CPP08/ex02", + "file": "/home/willem/projects/CPP08/ex02/src/main.cpp", + "output": "/home/willem/projects/CPP08/ex02/main.o" + }, + { + "arguments": [ + "/usr/bin/c++", + "-Wall", + "-Wextra", + "-Werror", + "-std=c++23", + "-I./inc", + "-c", + "-o", + "MutantStack.o", + "src/MutantStack.cpp" + ], + "directory": "/home/willem/projects/CPP08/ex02", + "file": "/home/willem/projects/CPP08/ex02/src/MutantStack.cpp", + "output": "/home/willem/projects/CPP08/ex02/MutantStack.o" + } +] diff --git a/ex02/inc/MutantStack.hpp b/ex02/inc/MutantStack.hpp new file mode 100644 index 0000000..0647d8d --- /dev/null +++ b/ex02/inc/MutantStack.hpp @@ -0,0 +1,24 @@ +#pragma once +#include + +template +class MutantStack : public std::stack +{ + public: + MutantStack(); + MutantStack(const MutantStack &other); + MutantStack(MutantStack &&other) noexcept; + MutantStack &operator=(const MutantStack &other); + MutantStack &&operator=(MutantStack &&other) noexcept; + ~MutantStack() noexcept; + + typedef typename std::stack::container_type::iterator iterator; + typedef typename std::stack::container_type::const_iterator const_iterator; + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; +}; + +#include "MutantStack.tpp" \ No newline at end of file diff --git a/ex02/inc/MutantStack.tpp b/ex02/inc/MutantStack.tpp new file mode 100644 index 0000000..160ca76 --- /dev/null +++ b/ex02/inc/MutantStack.tpp @@ -0,0 +1,63 @@ +#pragma once + +#include "MutantStack.hpp" + +template +MutantStack::MutantStack() : std::stack() +{} + +template +MutantStack::MutantStack(const MutantStack &other) : std::stack(other) +{} + +template +MutantStack::MutantStack(MutantStack &&other) noexcept : std::stack(std::move(other)) +{} + +template +MutantStack &MutantStack::operator=(const MutantStack &other) +{ + if (this != &other) + { + std::stack::operator=(other); + } + return *this; +} + +template +MutantStack &&MutantStack::operator=(MutantStack &&other) noexcept +{ + if (this != &other) + { + std::stack::operator=(std::move(other)); + } + return std::move(*this); +} + +template +MutantStack::~MutantStack() noexcept +{} + +template +typename MutantStack::iterator MutantStack::begin() +{ + return this->c.begin(); +} + +template +typename MutantStack::iterator MutantStack::end() +{ + return this->c.end(); +} + +template +typename MutantStack::const_iterator MutantStack::begin() const +{ + return this->c.begin(); +} + +template +typename MutantStack::const_iterator MutantStack::end() const +{ + return this->c.end(); +} diff --git a/ex02/src/main.cpp b/ex02/src/main.cpp new file mode 100644 index 0000000..24ce3b1 --- /dev/null +++ b/ex02/src/main.cpp @@ -0,0 +1,79 @@ +#include "MutantStack.hpp" + +#include +#include + +#define INFO "\n\033[1;32;4m" +#define ERROR "\033[1;31m" +#define END "\033[0m" + +int main() +{ + std::println(INFO "Testing MutantStack..." END); + std::println(INFO "Creating a MutantStack of integers..." END); + MutantStack mutantStack; + mutantStack.push(1); + mutantStack.push(2); + mutantStack.push(3); + std::println("MutantStack created with elements: 1, 2, 3"); + std::println("The size of MutantStack is: {}", mutantStack.size()); + std::println("Pop the top element: {}", mutantStack.top()); + mutantStack.pop(); + std::println("The size of MutantStack after pop is: {}", mutantStack.size()); + + std::println(INFO "Testing Copy constructor..." END); + MutantStack copyStack(mutantStack); + std::println("Copy constructor called."); + std::println("The size of the copied MutantStack is: {}", copyStack.size()); + std::println("The elements of the copied MutantStack are: "); + for (MutantStack::iterator it = copyStack.begin(); it != copyStack.end(); ++it) + { + std::println(" - {}", *it); + } + std::println(INFO "Testing the Copy assignment operator..." END); + MutantStack assignStack; + assignStack = copyStack; + std::println("Copy assignment operator called."); + std::println("The size of the assigned MutantStack is: {}", assignStack.size()); + std::println("The elements of the assigned MutantStack are: "); + for (MutantStack::iterator it = assignStack.begin(); it != assignStack.end(); ++it) + { + std::println(" - {}", *it); + } + std::println(INFO "Testing Move constructor..." END); + MutantStack moveStack(std::move(mutantStack)); + std::println("Move constructor called."); + std::println("The size of the moved MutantStack is: {}", moveStack.size()); + std::println("The elements of the moved MutantStack are: "); + for (MutantStack::iterator it = moveStack.begin(); it != moveStack.end(); ++it) + { + std::println(" - {}", *it); + } + + std::println(INFO "Testing Move assignment operator..." END); + MutantStack moveAssignStack; + moveAssignStack = std::move(moveStack); + std::println("Move assignment operator called."); + std::println("The size of the assigned MutantStack is: {}", moveAssignStack.size()); + std::println("The elements of the assigned MutantStack are: "); + for (MutantStack::iterator it = moveAssignStack.begin(); it != moveAssignStack.end(); ++it) + { + std::println(" - {}", *it); + } + + std::println(INFO "Testing MutantStack with const iterators..." END); + MutantStack constStack; + constStack.push(1); + constStack.push(2); + constStack.push(3); + std::println("Const MutantStack created with elements: 1, 2, 3"); + std::println("The size of Const MutantStack is: {}", constStack.size()); + std::println("Pop the top element: {}", constStack.top()); + constStack.pop(); + std::println("The size of Const MutantStack after pop is: {}", constStack.size()); + std::println("The elements of the Const MutantStack are: "); + for (MutantStack::const_iterator it = constStack.begin(); it != constStack.end(); ++it) + { + std::println(" - {}", *it); + } +}