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