Skip to content

Commit

Permalink
Add xtd::iclonable interface
Browse files Browse the repository at this point in the history
  • Loading branch information
gammasoft71 committed Apr 1, 2024
1 parent 6de3e92 commit a92802f
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/xtd.core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ add_sources(
include/xtd/guid
include/xtd/iasync_result.h
include/xtd/iasync_result
include/xtd/iclonable.h
include/xtd/iclonable
include/xtd/icomparable.h
include/xtd/icomparable
include/xtd/iequatable.h
Expand Down
2 changes: 2 additions & 0 deletions src/xtd.core/include/xtd/iclonable
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#pragma once
#include "iclonable.h"
33 changes: 33 additions & 0 deletions src/xtd.core/include/xtd/iclonable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/// @file
/// @brief Contains xtd::iclonable interface.
/// @copyright Copyright (c) 2024 Gammasoft. All rights reserved.
#pragma once
#include "interface.h"
#include "object.h"

/// @brief The xtd namespace contains all fundamental classes to access Hardware, Os, System, and more.
namespace xtd {
template<typename type_t>
/// @brief Supports cloning, which creates a new instance of a class with the same value as an existing instance.
/// @par Namespace
/// xtd
/// @par Library
/// xtd.core
/// @ingroup xtd_core interfaces
/// @remarks The xtd::iclonable interface enables you to provide a customized implementation that creates a copy of an existing object. The xtd::iclonable interface contains one member, the xtd::iclonable::clone method, which is intended to provide cloning support beyond that supplied by xtd::object::memberwise_clone. For more information about cloning, deep versus shallow copies, and examples, see the xtd::object::memberwise_clone method.
/// @par Notes to Implementers
/// The xtd::iclonable interface simply requires that your implementation of the xtd::iclonable::clone() method return a copy of the current object instance. It does not specify whether the cloning operation performs a deep copy, a shallow copy, or something in between. Nor does it require all property values of the original instance to be copied to the new instance. For example, the xtd::iclonable::clone() method performs a shallow copy of all properties; it always sets this property value to false in the cloned object. Because callers of xtd::iclonable::clone() cannot depend on the method performing a predictable cloning operation, we recommend that xtd::iclonable not be implemented in public APIs.
class iclonable interface_ {
public:
/// @name Public Methods

/// @{
/// @brief Creates a new object that is a copy of the current instance.
/// @return A new object that is a copy of this instance.
/// @remarks The resulting clone must be of the same type as, or compatible with, the original instance.
/// @remarks An implementation of xtd::iclonable::clone can perform either a deep copy or a shallow copy. In a deep copy, all objects are duplicated; in a shallow copy, only the top-level objects are duplicated and the lower levels contain references. Because callers of xtd::iclonable::clone cannot depend on the method performing a predictable cloning operation, we recommend that xtd::iclonable not be implemented in public APIs.
/// @remarks See xtd::object::memberwise_clone for more information on cloning, deep versus shallow copies, and examples.
virtual std::unique_ptr<xtd::object> clone() const noexcept = 0;
/// @}
};
}
10 changes: 9 additions & 1 deletion src/xtd.core/include/xtd/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,16 @@ namespace xtd {
/// @brief Creates a shallow copy of the current object.
/// @return A shallow copy of the current object.
/// @par Examples
/// The following code example shows how to copy an instance of a class using memberwise_clone.
/// The following example illustrates the xtd::object::memberwise_clone method. It defines a `shallow_copy` method that calls the xtd::object::memberwise_clone method to perform a shallow copy operation on a `person` object. It also defines a `deep_copy` method that performs a deep copy operation on a `person` object.
/// @include object_memberwise_clone.cpp
/// In this example, the `perso::iId_info` property returns an IdInfo object. As the output from the example shows, when a `person` object is cloned by calling the xtd::object::memberwise_clone method, the cloned `person` object is an independent copy of the original object, except that they share the same `perso::iId_info` object reference. As a result, modifying the clone's `perso::iId_info` property changes the original object's `perso::iId_info` property. On the other hand, when a deep copy operation is performed, the cloned `person` object, including its `perso::iId_info` property, can be modified without affecting the original object.
/// @remarks The xtd::object::memberwise_clone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.
/// @remarks For example, consider an object called X that references objects A and B. Object B, in turn, references object C. A shallow copy of X creates new object X2 that also references objects A and B. In contrast, a deep copy of X creates a new object X2 that references the new objects A2 and B2, which are copies of A and B. B2, in turn, references the new object C2, which is a copy of C. The example illustrates the difference between a shallow and a deep copy operation.
/// @remarks There are numerous ways to implement a deep copy operation if the shallow copy operation performed by the xtd::object::memberwise_clone method does not meet your needs. These include the following:
/// * Call a class constructor of the object to be copied to create a second object with property values taken from the first object. This assumes that the values of an object are entirely defined by its class constructor.
/// * Call the xtd::object::memberwise_clone method to create a shallow copy of an object, and then assign new objects whose values are the same as the original object to any properties or fields whose values are reference types. The `deep_copy` method in the example illustrates this approach.
/// * Serialize the object to be deep copied, and then restore the serialized data to a different object variable.
/// * Use reflection with recursion to perform the deep copy operation.
template<typename object_t>
std::unique_ptr<object_t> memberwise_clone() const noexcept {return std::make_unique<object_t>(dynamic_cast<const object_t&>(*this));}

Expand Down
1 change: 1 addition & 0 deletions src/xtd.core/include/xtd/xtd.core.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
#include "get_out_rdbuf.h"
#include "guid.h"
#include "iasync_result.h"
#include "iclonable.h"
#include "icomparable.h"
#include "iequatable.h"
#include "index_out_of_range_exception.h"
Expand Down
1 change: 1 addition & 0 deletions src/xtd.forms/include/xtd/forms/control.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <xtd/any>
#include <xtd/async_result>
#include <xtd/optional>
#include <xtd/iclonable>
#include <xtd/iequatable>
#include <xtd/isynchronize_invoke>
#include <cstdint>
Expand Down

0 comments on commit a92802f

Please sign in to comment.