From 007286983f4e0b53ddd5782b46ed65db014600d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana=20G=C3=B3mez?= Date: Fri, 27 Jun 2025 22:23:01 +0200 Subject: [PATCH] Implement move semantics --- ArffFiles.hpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 1 + 2 files changed, 51 insertions(+) diff --git a/ArffFiles.hpp b/ArffFiles.hpp index f804dfc..f9b16c0 100644 --- a/ArffFiles.hpp +++ b/ArffFiles.hpp @@ -72,6 +72,45 @@ class ArffFiles { public: ArffFiles() = default; + + // Move constructor + ArffFiles(ArffFiles&& other) noexcept + : lines(std::move(other.lines)) + , numeric_features(std::move(other.numeric_features)) + , attributes(std::move(other.attributes)) + , className(std::move(other.className)) + , classType(std::move(other.classType)) + , states(std::move(other.states)) + , X(std::move(other.X)) + , y(std::move(other.y)) + { + // Other object is left in a valid but unspecified state + } + + // Move assignment operator + ArffFiles& operator=(ArffFiles&& other) noexcept + { + if (this != &other) { + lines = std::move(other.lines); + numeric_features = std::move(other.numeric_features); + attributes = std::move(other.attributes); + className = std::move(other.className); + classType = std::move(other.classType); + states = std::move(other.states); + X = std::move(other.X); + y = std::move(other.y); + } + return *this; + } + + // Copy constructor (explicitly defaulted) + ArffFiles(const ArffFiles& other) = default; + + // Copy assignment operator (explicitly defaulted) + ArffFiles& operator=(const ArffFiles& other) = default; + + // Destructor (explicitly defaulted) + ~ArffFiles() = default; void load(const std::string& fileName, bool classLast = true) { if (fileName.empty()) { @@ -192,6 +231,17 @@ public: const std::vector& getY() const { return y; } const std::map& getNumericAttributes() const { return numeric_features; } const std::vector>& getAttributes() const { return attributes; }; + + // Move-enabled getters for efficient data transfer + // WARNING: These methods move data OUT of the object, leaving it in an empty but valid state + // Use these when you want to transfer ownership of large data structures for performance + std::vector> moveX() noexcept { return std::move(X); } + std::vector moveY() noexcept { return std::move(y); } + std::vector moveLines() noexcept { return std::move(lines); } + std::map> moveStates() noexcept { return std::move(states); } + std::vector> moveAttributes() noexcept { return std::move(attributes); } + std::map moveNumericAttributes() noexcept { return std::move(numeric_features); } + std::vector split(const std::string& text, char delimiter) { std::vector result; diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b84f9..9b34e1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Eliminate redundant memory allocations and enhance memory usage - Enhance error handling with exceptions - Change `getSize` return type to `size_t` for better compatibility with standard library containers +- Implement move semantics for better performance ## [1.1.0] 2024-07-24 String Values in Features