Skip to content
Snippets Groups Projects

F move entity

Merged Timm Fitschen requested to merge f-move-entity into dev

Files

+ 148
24
@@ -51,8 +51,8 @@
#include <random> // for mt19937, rand...
#include <stdexcept> // for out_of_range
#include <string> // for string, basic...
#include <vector> // for vector
#include <utility> // for move
#include <vector> // for vector
namespace caosdb::entity {
using boost::filesystem::exists;
@@ -187,6 +187,32 @@ public:
return result.append(std::string("]\n"));
}
/**
* Return true if the underlying Protobuf messages have the same
* serialization.
*/
inline auto operator==(const RepeatedPtrFieldWrapper<T, P> &other) const noexcept -> bool {
if (this->wrapped != nullptr && other.wrapped != nullptr && this->size() == other.size()) {
for (int i = 0; i < this->size(); i++) {
if (this->wrapped->Get(i).SerializeAsString() !=
other.wrapped->Get(i).SerializeAsString()) {
return false;
}
}
return true;
}
// last chance for "true": both nullptr?
return this->wrapped == other.wrapped;
}
/**
* Return true if the underlying Protobuf messages have a different
* serialization.
*/
inline auto operator!=(const RepeatedPtrFieldWrapper<T, P> &other) const noexcept -> bool {
return !(*this == other);
}
protected:
RepeatedPtrFieldWrapper() : ProtoMessageWrapper<RepeatedPtrField<P>>(){};
explicit inline RepeatedPtrFieldWrapper(RepeatedPtrField<P> *wrapped)
@@ -337,15 +363,13 @@ private:
*/
class Messages : public RepeatedPtrFieldWrapper<Message, ProtoMessage> {
public:
~Messages();
friend class Entity;
// TODO(fspreck) Same here.
// friend class Parent;
// friend class Property;
private:
inline Messages() : RepeatedPtrFieldWrapper(){};
inline Messages() : RepeatedPtrFieldWrapper<Message, ProtoMessage>(){};
};
/**
@@ -359,6 +383,37 @@ class Parent : public ScalarProtoMessageWrapper<ProtoParent> {
public:
explicit inline Parent(ProtoParent *wrapped) : ScalarProtoMessageWrapper<ProtoParent>(wrapped){};
Parent() : ScalarProtoMessageWrapper<ProtoParent>(){};
~Parent() = default;
/**
* Copy constructor.
*/
inline Parent(const Parent &other)
: Parent(ProtoMessageWrapper<ProtoParent>::CopyProtoMessage(other.wrapped)) {}
/**
* Move constructor.
*/
inline Parent(Parent &&other) : Parent(other.wrapped) { other.wrapped = nullptr; }
/**
* Copy assignment operator.
*/
inline auto operator=(const Parent &other) -> Parent & {
if (this != &other) {
this->wrapped->CopyFrom(*other.wrapped);
}
return *this;
}
/**
* Move assignment operator.
*/
inline auto operator=(Parent &&other) -> Parent & {
this->wrapped = other.wrapped;
other.wrapped = nullptr;
return *this;
}
/**
* Return the id of the parent entity.
@@ -426,14 +481,13 @@ private:
*/
class Parents : public RepeatedPtrFieldWrapper<Parent, ProtoParent> {
public:
~Parents() = default;
friend class Entity;
private:
inline Parents() : RepeatedPtrFieldWrapper(){};
inline Parents() : RepeatedPtrFieldWrapper<Parent, ProtoParent>(){};
explicit inline Parents(
::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Parent> *wrapped)
: RepeatedPtrFieldWrapper(wrapped){};
: RepeatedPtrFieldWrapper<Parent, ProtoParent>(wrapped){};
};
/**
@@ -456,13 +510,10 @@ public:
/**
* Move constructor.
*/
inline Property(Property &&other) : Property() {
inline Property(Property &&other) : Property(other.wrapped) {
CAOSDB_LOG_TRACE(logger_name) << "Property::Property(Property &&) "
<< "- Move constructor";
this->wrapped = std::move(other.wrapped);
this->value.wrapped = this->wrapped->mutable_value();
this->data_type.wrapped = this->wrapped->mutable_data_type();
other.wrapped = nullptr;
other.data_type.wrapped = nullptr;
other.value.wrapped = nullptr;
}
@@ -477,6 +528,8 @@ public:
: ScalarProtoMessageWrapper<ProtoProperty>(), value(static_cast<ProtoValue *>(nullptr)),
data_type(static_cast<ProtoDataType *>(nullptr)){};
~Property() = default;
/**
* Return the id of this property
*/
@@ -563,8 +616,12 @@ public:
CAOSDB_LOG_TRACE(logger_name) << "Property::operator=(const Property &) "
<< "- Copy assignment operator";
this->wrapped->CopyFrom(*other.wrapped);
this->value = Value(this->wrapped->mutable_value());
this->data_type = DataType(this->wrapped->mutable_data_type());
this->value.wrapped = (this->wrapped->has_value() ? this->wrapped->mutable_value()
: static_cast<ProtoValue *>(nullptr));
this->data_type.wrapped =
(this->wrapped->has_data_type() ? this->wrapped->mutable_data_type()
: static_cast<ProtoDataType *>(nullptr));
return *this;
}
@@ -574,7 +631,8 @@ public:
auto operator=(Property &&other) -> Property & {
CAOSDB_LOG_TRACE(logger_name) << "Property::operator=(Property &&) "
<< "- Move assignment operator";
this->wrapped = std::move(other.wrapped);
this->wrapped = other.wrapped;
other.wrapped = nullptr;
this->value = std::move(other.value);
this->data_type = std::move(other.data_type);
return *this;
@@ -606,7 +664,6 @@ private:
*/
class Properties : public RepeatedPtrFieldWrapper<Property, ProtoProperty> {
public:
~Properties() = default;
friend class Entity;
private:
@@ -624,17 +681,23 @@ private:
* Overview of the Constructors:
*
* <li> Entity() - Calls Entity(ProtoEntity *) with a fresh ProtoEntity
* <li> Entity(Entity) - Copy constructor, calls Entity(ProtoEntity *) after copying wrapped
* ProtoEntity of the original, then also copies all Messages. <li> Entity(ProtoEntity *) - The
* workhorse of the constructors. Initializes everything and does not call other Entity
* constructors. <li> Entity(EntityResponse *) - Constructor which is used by the Transaction class
* to create an Entity from the server's response, calls Entity(ProtoEntity). <li> Entity(IdResponse
* *) - Constructor which is used by the Transaction class to create an Entity from the servers's
* response. calls Entity(), then moves the data to the wrapped ProtoEntity.
*
* <li> Entity(const Entity&) - Copy constructor, calls Entity(ProtoEntity *) after
* copying wrapped ProtoEntity of the original, then also copies all Messages.
* <li> Entity(ProtoEntity *) - The workhorse of the constructors. Initializes
* everything and does not call other Entity constructors.
* <li> Entity(EntityResponse *) - Constructor which is used by the Transaction class
* to create an Entity from the server's response, calls Entity(ProtoEntity).
* <li> Entity(IdResponse *) - Constructor which is used by the Transaction
* class to create an Entity from the servers's response. calls Entity(),
* then moves the data to the wrapped ProtoEntity.
* <li> Entity(Entity&&) - Move constructor, calls Entity(ProtoEntity *), then
* moves the messages and resets the original,
*/
class Entity : public ScalarProtoMessageWrapper<ProtoEntity> {
public:
/**
* Copy constructor.
*/
inline Entity(const Entity &original)
: Entity(ProtoMessageWrapper::CopyProtoMessage(original.wrapped)) {
this->errors.wrapped->CopyFrom(*original.errors.wrapped);
@@ -671,6 +734,58 @@ public:
parents.wrapped = this->wrapped->mutable_parents();
};
~Entity() = default;
/**
* Move constructor.
*/
explicit inline Entity(Entity &&original) : Entity(original.wrapped) {
original.wrapped = nullptr;
original.value.wrapped = nullptr;
original.data_type.wrapped = nullptr;
original.properties.wrapped = nullptr;
original.parents.wrapped = nullptr;
this->errors = std::move(original.errors);
this->warnings = std::move(original.warnings);
this->infos = std::move(original.infos);
};
/**
* Move assignment operator.
*/
auto operator=(Entity &&other) -> Entity & {
this->wrapped = other.wrapped;
other.wrapped = nullptr;
this->data_type = std::move(other.data_type);
this->value = std::move(other.value);
this->properties = std::move(other.properties);
this->parents = std::move(other.parents);
this->file_descriptor = std::move(other.file_descriptor);
this->errors = std::move(other.errors);
this->warnings = std::move(other.warnings);
this->infos = std::move(other.infos);
return *this;
}
/**
* Copy assignment operator.
*/
auto operator=(const Entity &other) -> Entity & {
this->wrapped->CopyFrom(*other.wrapped);
this->data_type = other.data_type;
this->value = other.value;
this->properties = other.properties;
this->parents = other.parents;
this->file_descriptor.local_path = boost::filesystem::path(other.file_descriptor.local_path);
this->file_descriptor.file_transmission_id->CopyFrom(
*other.file_descriptor.file_transmission_id);
this->file_descriptor.wrapped->CopyFrom(*other.file_descriptor.wrapped);
this->errors = other.errors;
this->warnings = other.warnings;
this->infos = other.infos;
return *this;
}
[[nodiscard]] inline auto GetId() const noexcept -> const std::string & {
return this->wrapped->id();
};
@@ -787,6 +902,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:
inline auto GetNextFileId() -> std::string {
std::string str = "0123456789abcdef";
Loading