diff --git a/.vscode/settings.json b/.vscode/settings.json index 51a1ca9..72e45a9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -51,6 +51,7 @@ "ctime": "cpp", "iomanip": "cpp", "sstream": "cpp", - "*.tpp": "cpp" + "*.tpp": "cpp", + "chrono": "cpp" } } \ No newline at end of file diff --git a/ex02/inc/PmergeMe.hpp b/ex02/inc/PmergeMe.hpp index 89d657b..b96141c 100644 --- a/ex02/inc/PmergeMe.hpp +++ b/ex02/inc/PmergeMe.hpp @@ -5,6 +5,7 @@ #include #include +template class PmergeMe { public: @@ -16,25 +17,20 @@ public: PmergeMe &operator=(const PmergeMe &other); void sort(); - std::string getPrintableVector() const; - std::string getPrintableDeque() const; + std::string getString() const; private: - std::vector _data_vector; - std::deque _data_deque; + Container _data; std::vector _jacobstahl_numbers; - bool less(int a, int b); int _comparisons; + bool less(int a, int b); bool areAllUnique() const; - - template void insert(Container &main, Container &pend, int start_index, int right, int group_size); - - template Container sort(Container &data, int level); }; -std::ostream &operator<<(std::ostream &os, const PmergeMe &obj); +template +std::ostream &operator<<(std::ostream &os, const PmergeMe &obj); #include "PmergeMe.tpp" \ No newline at end of file diff --git a/ex02/inc/PmergeMe.tpp b/ex02/inc/PmergeMe.tpp index 965ef98..d044737 100644 --- a/ex02/inc/PmergeMe.tpp +++ b/ex02/inc/PmergeMe.tpp @@ -1,7 +1,115 @@ +#pragma once + #include "PmergeMe.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +template +std::string getTypeName() { + if (std::is_same_v>) return "std::vector "; + if (std::is_same_v>) return "std::deque "; + return typeid(T).name(); // fallback to mangled name +} + template -Container PmergeMe::sort(Container &data, int level) +PmergeMe::PmergeMe(const int argc, const char **argv) : _comparisons(0) +{ + for (int i = 1; argv[i] != nullptr; ++i) + { + size_t pos; + int value = std::stoi(argv[i], &pos); + if (value < 0) + throw std::invalid_argument("All inputs must be non-negative integers"); + if (pos != std::strlen(argv[i])) + throw std::invalid_argument("Invalid input: not a valid integer"); + + _data.push_back(value); + } + + if (!areAllUnique()) + throw std::invalid_argument("All inputs must be unique integers"); + + if (_data.size() != static_cast(argc) - 1 || _data.empty()) + throw std::invalid_argument("Invalid input detected"); + + _jacobstahl_numbers = Jacobstahl().getUpTo(_data.size()); +} + +template +PmergeMe::PmergeMe(const PmergeMe &other) + : _data(other._data), _jacobstahl_numbers(other._jacobstahl_numbers) +{ +} + +template +PmergeMe::~PmergeMe() {} + +template +PmergeMe &PmergeMe::operator=(const PmergeMe &other) +{ + if (this != &other) + { + _data = other._data; + _jacobstahl_numbers = other._jacobstahl_numbers; + } + return *this; +} + +template +void PmergeMe::sort() +{ + + // high resolution timing + _comparisons = 0; + auto time_start = std::chrono::high_resolution_clock::now(); + _data = sort(_data, 0); + // std::cout << "Total comparisons: " << _comparisons << std::endl; + // std::cout << (std::is_sorted(_data_vector.begin(), _data_vector.end()) ? "Sorted!!!" : "ERROR!!") << std::endl; + auto time_end = std::chrono::high_resolution_clock::now(); + auto time_diff = std::chrono::duration_cast(time_end - time_start).count(); + std::cout << "Time to process a range of " << _data.size() << " elements with " << getTypeName() << ": " << time_diff << " us" << std::endl; +} + +template +std::string PmergeMe::getString() const +{ + std::string result; + for (auto it = _data.begin(); it != _data.end(); ++it) + { + if (it != _data.begin()) + result += ", "; + result += std::to_string(*it); + } + return result; +} + +template +bool PmergeMe::less(int a, int b) +{ + _comparisons++; + return a < b; +} +template +bool PmergeMe::areAllUnique() const +{ + Container temp = _data; // Create a copy + std::sort(temp.begin(), temp.end()); + auto it = std::unique(temp.begin(), temp.end()); + return it == temp.end(); +} + +template +Container PmergeMe::sort(Container &data, int level) { // #1 Create pairs and sort them if (data.size() <= 1) @@ -60,7 +168,7 @@ Container PmergeMe::sort(Container &data, int level) } template -void PmergeMe::insert(Container &main, Container &pend, int to_insert, int right, int group_size) +void PmergeMe::insert(Container &main, Container &pend, int to_insert, int right, int group_size) { if (pend.empty() || to_insert < 0 || to_insert >= static_cast(pend.size())) return; @@ -82,4 +190,12 @@ void PmergeMe::insert(Container &main, Container &pend, int to_insert, int right main.insert(insert_pos, pend.begin() + to_insert * group_size, pend.begin() + (to_insert + 1) * group_size); pend.erase(pend.begin() + to_insert * group_size, pend.begin() + (to_insert + 1) * group_size); -} \ No newline at end of file +} +template +std::ostream &operator<<(std::ostream &os, const PmergeMe &obj) +{ + os << obj.getString(); + + return os; +} + diff --git a/ex02/src/PmergeMe.cpp b/ex02/src/PmergeMe.cpp index d44d6d2..fce1e04 100644 --- a/ex02/src/PmergeMe.cpp +++ b/ex02/src/PmergeMe.cpp @@ -12,123 +12,15 @@ std::ostream &operator<<(std::ostream &os, const std::vector &obj) { - for (std::vector::const_iterator it = obj.begin(); it != obj.end(); ++it) - { - if (it != obj.begin()) - os << " "; - os << *it; - } + for (std::vector::const_iterator it = obj.begin(); it != obj.end(); ++it) + { + if (it != obj.begin()) + os << " "; + os << *it; + } - return os; + return os; } -PmergeMe::PmergeMe(const int argc, const char **argv) : _comparisons(0) -{ - for (int i = 1; argv[i] != nullptr; ++i) - { - size_t pos; - int value = std::stoi(argv[i], &pos); - if (value < 0) - throw std::invalid_argument("All inputs must be non-negative integers"); - if (pos != std::strlen(argv[i])) - throw std::invalid_argument("Invalid input: not a valid integer"); - _data_vector.push_back(value); - _data_deque.push_back(value); - } - if (!areAllUnique()) - throw std::invalid_argument("All inputs must be unique integers"); - - if (_data_vector.size() != static_cast(argc) - 1 - || _data_deque.size() != static_cast(argc) - 1) - throw std::invalid_argument("Invalid input detected"); - - _jacobstahl_numbers = Jacobstahl().getUpTo(_data_vector.size()); -} - -PmergeMe::PmergeMe(const PmergeMe &other) - : _data_vector(other._data_vector), _data_deque(other._data_deque), _jacobstahl_numbers(other._jacobstahl_numbers) -{} - -PmergeMe::~PmergeMe() {} - -PmergeMe &PmergeMe::operator=(const PmergeMe &other) -{ - if (this != &other) - { - _data_vector = other._data_vector; - _data_deque = other._data_deque; - _jacobstahl_numbers = other._jacobstahl_numbers; - } - return *this; -} - -void PmergeMe::sort() -{ - - //high resolution timing - _comparisons = 0; - auto time_start = std::chrono::high_resolution_clock::now(); - _data_vector = sort(_data_vector, 0); - // std::cout << "Total comparisons: " << _comparisons << std::endl; - // std::cout << (std::is_sorted(_data_vector.begin(), _data_vector.end()) ? "Sorted!!!" : "ERROR!!") << std::endl; - auto time_end = std::chrono::high_resolution_clock::now(); - auto time_diff = std::chrono::duration_cast(time_end - time_start).count(); - std::cout << "Time to process a range of " << _data_vector.size() << " elements with std::vector : " << time_diff << " us" << std::endl; - - _comparisons = 0; - auto time_start_deque = std::chrono::high_resolution_clock::now(); - _data_deque = sort(_data_deque, 0); - // std::cout << "Total comparisons: " << _comparisons << std::endl; - // std::cout << (std::is_sorted(_data_deque.begin(), _data_deque.end()) ? "Sorted!!!" : "ERROR!!") << std::endl; - auto time_end_deque = std::chrono::high_resolution_clock::now(); - auto time_diff_deque = std::chrono::duration_cast(time_end_deque - time_start_deque).count(); - std::cout << "Time to process a range of " << _data_deque.size() << " elements with std::deque : " << time_diff_deque << " us" << std::endl; - -} - -std::string PmergeMe::getPrintableVector() const -{ - std::string result; - for (std::vector::const_iterator it = _data_vector.begin(); it != _data_vector.end(); ++it) - { - if (it != _data_vector.begin()) - result += ", "; - result += std::to_string(*it); - } - return result; -} - -std::string PmergeMe::getPrintableDeque() const -{ - std::string result; - for (std::deque::const_iterator it = _data_deque.begin(); it != _data_deque.end(); ++it) - { - if (it != _data_deque.begin()) - result += ", "; - result += std::to_string(*it); - } - return result; -} - -bool PmergeMe::less(int a, int b) -{ - _comparisons++; - return a < b; -} - -bool PmergeMe::areAllUnique() const -{ - std::vector temp = _data_vector; // Create a copy - std::sort(temp.begin(), temp.end()); - auto it = std::unique(temp.begin(), temp.end()); - return it == temp.end(); -} - -std::ostream &operator<<(std::ostream &os, const PmergeMe &obj) -{ - os << "Vector: " << obj.getPrintableVector() << "\n"; - os << "Deque: " << obj.getPrintableDeque(); - return os; -} diff --git a/ex02/src/main.cpp b/ex02/src/main.cpp index b276b28..d8bdfd3 100644 --- a/ex02/src/main.cpp +++ b/ex02/src/main.cpp @@ -1,16 +1,22 @@ #include "Jacobstahl.hpp" #include "PmergeMe.hpp" #include +#include +#include + int main(const int argc, const char **argv) { try { - PmergeMe sorter(argc, argv); - std::cout << "Before sorting:\n" << sorter << std::endl; + PmergeMe > sorter(argc, argv); + std::cout << "Before: " << sorter << std::endl; sorter.sort(); - std::cout << "After sorting:\n" << sorter << std::endl; + PmergeMe > sorter_deque(argc, argv); + sorter_deque.sort(); + std::cout << "After: " << sorter_deque << std::endl; + } catch (const std::invalid_argument &e) {