Kuzu C++ API
Loading...
Searching...
No Matches
copy_constructors.h
Go to the documentation of this file.
1#pragma once
2#include <map>
3#include <memory>
4#include <unordered_map>
5#include <vector>
6// This file defines many macros for controlling copy constructors and move constructors on classes.
7
8// NOLINTBEGIN(bugprone-macro-parentheses): Although this is a good check in general, here, we
9// cannot add parantheses around the arguments, for it would be invalid syntax.
10#define DELETE_COPY_CONSTRUCT(Object) Object(const Object& other) = delete
11#define DELETE_COPY_ASSN(Object) Object& operator=(const Object& other) = delete
12
13#define DELETE_MOVE_CONSTRUCT(Object) Object(Object&& other) = delete
14#define DELETE_MOVE_ASSN(Object) Object& operator=(Object&& other) = delete
15
16#define DELETE_BOTH_COPY(Object) \
17 DELETE_COPY_CONSTRUCT(Object); \
18 DELETE_COPY_ASSN(Object)
19
20#define DELETE_BOTH_MOVE(Object) \
21 DELETE_MOVE_CONSTRUCT(Object); \
22 DELETE_MOVE_ASSN(Object)
23
24#define DEFAULT_MOVE_CONSTRUCT(Object) Object(Object&& other) = default
25#define DEFAULT_MOVE_ASSN(Object) Object& operator=(Object&& other) = default
26
27#define DEFAULT_BOTH_MOVE(Object) \
28 DEFAULT_MOVE_CONSTRUCT(Object); \
29 DEFAULT_MOVE_ASSN(Object)
30
31#define EXPLICIT_COPY_METHOD(Object) \
32 Object copy() const { \
33 return *this; \
34 }
35
36// EXPLICIT_COPY_DEFAULT_MOVE should be the default choice. It expects a PRIVATE copy constructor to
37// be defined, which will be used by an explicit `copy()` method. For instance:
38//
39// private:
40// MyClass(const MyClass& other) : field(other.field.copy()) {}
41//
42// public:
43// EXPLICIT_COPY_DEFAULT_MOVE(MyClass);
44//
45// Now:
46//
47// MyClass o1;
48// MyClass o2 = o1; // Compile error, copy assignment deleted.
49// MyClass o2 = o1.copy(); // OK.
50// MyClass o2(o1); // Compile error, copy constructor is private.
51#define EXPLICIT_COPY_DEFAULT_MOVE(Object) \
52 DELETE_COPY_ASSN(Object); \
53 DEFAULT_BOTH_MOVE(Object); \
54 EXPLICIT_COPY_METHOD(Object)
55
56// NO_COPY should be used for objects that for whatever reason, should never be copied, but can be
57// moved.
58#define DELETE_COPY_DEFAULT_MOVE(Object) \
59 DELETE_BOTH_COPY(Object); \
60 DEFAULT_BOTH_MOVE(Object)
61
62// NO_MOVE_OR_COPY exists solely for explicitness, when an object cannot be moved nor copied. Any
63// object containing a lock cannot be moved or copied.
64#define DELETE_COPY_AND_MOVE(Object) \
65 DELETE_BOTH_COPY(Object); \
66 DELETE_BOTH_MOVE(Object)
67// NOLINTEND(bugprone-macro-parentheses):
68
69template<typename T>
70static std::vector<T> copyVector(const std::vector<T>& objects) {
71 std::vector<T> result;
72 result.reserve(objects.size());
73 for (auto& object : objects) {
74 result.push_back(object.copy());
75 }
76 return result;
77}
78
79template<typename T>
80static std::vector<std::shared_ptr<T>> copyVector(const std::vector<std::shared_ptr<T>>& objects) {
81 std::vector<std::shared_ptr<T>> result;
82 result.reserve(objects.size());
83 for (auto& object : objects) {
84 T& ob = *object;
85 result.push_back(ob.copy());
86 }
87 return result;
88}
89
90template<typename T>
91static std::vector<std::unique_ptr<T>> copyVector(const std::vector<std::unique_ptr<T>>& objects) {
92 std::vector<std::unique_ptr<T>> result;
93 result.reserve(objects.size());
94 for (auto& object : objects) {
95 T& ob = *object;
96 result.push_back(ob.copy());
97 }
98 return result;
99}
100
101template<typename K, typename V>
102static std::unordered_map<K, V> copyUnorderedMap(const std::unordered_map<K, V>& objects) {
103 std::unordered_map<K, V> result;
104 for (auto& [k, v] : objects) {
105 result.insert({k, v.copy()});
106 }
107 return result;
108}
109
110template<typename K, typename V>
111static std::map<K, V> copyMap(const std::map<K, V>& objects) {
112 std::map<K, V> result;
113 for (auto& [k, v] : objects) {
114 result.insert({k, v.copy()});
115 }
116 return result;
117}