From 54e91c799a32b7e447d64b50b327ba74ec750bd8 Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Mon, 13 Sep 2021 11:12:39 +0200
Subject: [PATCH] WIP: move constructor and assignment operator for Entity

---
 include/caosdb/entity.h | 44 +++++++++++++++++++++++++++++++++++++++++
 include/caosdb/value.h  |  1 -
 test/test_entity.cpp    | 31 ++++++++++++++++++++++++++++-
 3 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h
index fea060d..89bb320 100644
--- a/include/caosdb/entity.h
+++ b/include/caosdb/entity.h
@@ -52,6 +52,7 @@
 #include <random>                                      // for mt19937, rand...
 #include <stdexcept>                                   // for out_of_range
 #include <string>                                      // for string, basic...
+#include <utility>                                     // for move
 #include <vector>                                      // for vector
 
 namespace caosdb::entity {
@@ -611,6 +612,9 @@ private:
  */
 class Entity {
 public:
+  /**
+   * Copy constructor.
+   */
   inline Entity(const Entity &original) : Entity(Copy(*original.wrapped)) {
     this->errors.wrapped->CopyFrom(*original.errors.wrapped);
     this->warnings.wrapped->CopyFrom(*original.warnings.wrapped);
@@ -643,6 +647,37 @@ public:
 
   explicit inline Entity() : Entity(Entity::CreateProtoEntity()){};
 
+  /**
+   * Move constructor.
+   */
+  explicit inline Entity(Entity &&original)
+    : wrapped(std::move(original.wrapped)), value(Value(original.value.wrapped)),
+      data_type(DataType(original.data_type.wrapped)) {
+    // TODO(tf) move other things as well
+    this->properties.wrapped = std::move(original.properties.wrapped);
+    this->parents.wrapped = std::move(original.parents.wrapped);
+    this->errors.wrapped = original.errors.wrapped;
+    this->warnings.wrapped = original.warnings.wrapped;
+    this->infos.wrapped = original.infos.wrapped;
+  };
+
+  /**
+   * Move assignment operator.
+   */
+  auto operator=(Entity &&other) -> Entity & {
+    this->wrapped = std::move(other.wrapped);
+    this->data_type.wrapped = std::move(other.data_type.wrapped);
+    this->value.wrapped = std::move(other.value.wrapped);
+    this->properties.wrapped = std::move(other.properties.wrapped);
+    this->parents.wrapped = std::move(other.parents.wrapped);
+    file_descriptor = std::move(other.file_descriptor);
+    // TODO(tf) add move to messages
+    errors.wrapped->Swap(other.errors.wrapped);
+    warnings.wrapped->Swap(other.warnings.wrapped);
+    infos.wrapped->Swap(other.infos.wrapped);
+    return *this;
+  }
+
   [[nodiscard]] inline auto GetId() const noexcept -> const std::string & { return wrapped->id(); };
   [[nodiscard]] inline auto HasId() const noexcept -> bool { return !wrapped->id().empty(); }
   [[nodiscard]] inline auto GetVersionId() const -> const std::string & {
@@ -758,6 +793,15 @@ public:
     infos.Clear();
   }
 
+  /**
+   * Return true if the other entity is equal to to this entity.
+   *
+   * This method ignores the errors, warnings and info messages.
+   */
+  inline auto operator==(const Entity &other) const noexcept -> bool {
+    return this->wrapped->SerializeAsString() == other.wrapped->SerializeAsString();
+  }
+
 private:
   static inline auto Copy(const ProtoEntity &from) -> ProtoEntity * {
     auto to = from.New();
diff --git a/include/caosdb/value.h b/include/caosdb/value.h
index 6031e75..1a99138 100644
--- a/include/caosdb/value.h
+++ b/include/caosdb/value.h
@@ -136,7 +136,6 @@ public:
   }
   [[nodiscard]] inline auto AsString() const noexcept -> const std::string & {
     return this->wrapped->scalar_value().string_value();
-    ;
   }
 
   [[nodiscard]] inline auto IsDouble() const noexcept -> bool {
diff --git a/test/test_entity.cpp b/test/test_entity.cpp
index df196c1..191e364 100644
--- a/test/test_entity.cpp
+++ b/test/test_entity.cpp
@@ -38,7 +38,7 @@
 #include <memory>                                // for allocator, shared_ptr
 #include <stdexcept>                             // for out_of_range
 #include <string>                                // for operator+, to_string
-
+#include <utility>                               // for move
 namespace caosdb::entity {
 using caosdb::entity::v1alpha1::IdResponse;
 using ProtoEntity = caosdb::entity::v1alpha1::Entity;
@@ -460,4 +460,33 @@ TEST(test_entity, test_add_file) {
   EXPECT_EQ(entity.SetLocalPath(TEST_DATA_DIR + "/test.json"), StatusCode::SUCCESS);
 }
 
+TEST(test_entity, test_move_assign) {
+  Entity entity1;
+  entity1.SetRole(Role::RECORD_TYPE);
+  entity1.SetName("E1");
+  entity1.SetValue("some-string-1");
+  entity1.SetDataType("some-other-string-1");
+
+  Entity entity2;
+  entity1.SetRole(Role::RECORD);
+  entity1.SetName("E2");
+  entity1.SetValue("some-string-2");
+  entity1.SetDataType("some-other-string-2");
+
+  const Entity copy1(entity1); // NOLINT
+  const Entity copy2(entity2); // NOLINT
+
+  EXPECT_EQ(copy1, entity1);
+  EXPECT_EQ(copy2, entity2);
+
+  // Swap
+  Entity tmp;
+  tmp = std::move(entity1);
+  entity1 = std::move(entity2);
+  entity2 = std::move(tmp);
+
+  EXPECT_EQ(copy2, entity1);
+  EXPECT_EQ(copy1, entity2);
+}
+
 } // namespace caosdb::entity
-- 
GitLab