Zivid C++ API 2.14.0+e4a0c4a9-1
Pimpl.h
Go to the documentation of this file.
1/*******************************************************************************
2 * This file is part of the Zivid API
3 *
4 * Copyright 2015-2024 (C) Zivid AS
5 * All rights reserved.
6 *
7 * Zivid Software License, v1.0
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of Zivid AS nor the names of its contributors may be used
20 * to endorse or promote products derived from this software without specific
21 * prior written permission.
22 *
23 * 4. This software, with or without modification, must not be used with any
24 * other 3D camera than from Zivid AS.
25 *
26 * 5. Any software provided in binary form under this license must not be
27 * reverse engineered, decompiled, modified and/or disassembled.
28 *
29 * THIS SOFTWARE IS PROVIDED BY ZIVID AS "AS IS" AND ANY EXPRESS OR IMPLIED
30 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 * DISCLAIMED. IN NO EVENT SHALL ZIVID AS OR CONTRIBUTORS BE LIABLE FOR ANY
33 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Contact: Zivid Customer Success Team <customersuccess@zivid.com>
41 * Info: http://www.zivid.com
42 ******************************************************************************/
43
44#pragma once
45
46#include <memory>
47#include <stdexcept>
48#include <utility>
49
50// Todo(ZIVID-983): Make doxygen skip most content in this file, but not regular functions. Possibly by using NO_DOC
51
52// ------------------------------------------------------------------------------------------------------------------ //
53#define ZIVID_PIMPL_VALUE_SEMANTICS(ClassName, Attributes) \
54public: \
55 Attributes ~ClassName(); \
56 Attributes ClassName(const ClassName &other); \
57 Attributes ClassName &operator=(const ClassName &other); \
58 Attributes ClassName(ClassName &&other) noexcept; \
59 Attributes ClassName &operator=(ClassName &&other) noexcept; \
60 \
61 Attributes explicit ClassName(std::unique_ptr<class ClassName##Impl> &&impl); \
62 Attributes explicit ClassName(class ClassName##Impl &&impl); \
63 Attributes class ClassName##Impl &getImpl(); \
64 Attributes const class ClassName##Impl &getImpl() const; \
65 \
66private: \
67 std::unique_ptr<class ClassName##Impl> m_impl
68
69#define ZIVID_PIMPL_VALUE_SEMANTICS_CPP(ClassName) \
70 ClassName::ClassName(std::unique_ptr<ClassName##Impl> &&impl) \
71 : m_impl{ std::move(impl) } \
72 {} \
73 \
74 ClassName::ClassName(ClassName##Impl &&impl) \
75 : ClassName{ std::make_unique<ClassName##Impl>(std::move(impl)) } \
76 {} \
77 \
78 ClassName::ClassName(const ClassName &other) \
79 : ClassName{ ClassName##Impl{ other.getImpl() } } \
80 {} \
81 \
82 ClassName &ClassName::operator=(const ClassName &other) \
83 { \
84 if(this != &other) \
85 { \
86 *m_impl = other.getImpl(); \
87 } \
88 return *this; \
89 } \
90 \
91 ClassName##Impl &ClassName::getImpl() \
92 { \
93 return const_cast<ClassName##Impl &>(std::as_const(*this).getImpl()); \
94 } \
95 \
96 const ClassName##Impl &ClassName::getImpl() const \
97 { \
98 if(m_impl == nullptr) \
99 { \
100 throw std::runtime_error(#ClassName " is empty"); \
101 } \
102 return *m_impl; \
103 } \
104 \
105 ClassName::~ClassName() = default; \
106 ClassName::ClassName(ClassName &&other) noexcept = default; \
107 ClassName &ClassName::operator=(ClassName &&other) noexcept = default
108
109// ------------------------------------------------------------------------------------------------------------------ //
110#define ZIVID_PIMPL_MOVE_ONLY(ClassName, Attributes) \
111public: \
112 Attributes ~ClassName(); \
113 Attributes ClassName(const ClassName &other) = delete; \
114 Attributes ClassName &operator=(const ClassName &other) = delete; \
115 Attributes ClassName(ClassName &&other) noexcept; \
116 Attributes ClassName &operator=(ClassName &&other) noexcept; \
117 \
118 Attributes explicit ClassName(std::unique_ptr<class ClassName##Impl> &&impl); \
119 Attributes class ClassName##Impl &getImpl(); \
120 Attributes const class ClassName##Impl &getImpl() const; \
121 \
122private: \
123 std::unique_ptr<class ClassName##Impl> m_impl
124
125#define ZIVID_PIMPL_MOVE_ONLY_CPP(ClassName) \
126 ClassName::ClassName(std::unique_ptr<ClassName##Impl> &&impl) \
127 : m_impl{ std::move(impl) } \
128 {} \
129 \
130 ClassName##Impl &ClassName::getImpl() \
131 { \
132 return const_cast<ClassName##Impl &>(std::as_const(*this).getImpl()); \
133 } \
134 \
135 const ClassName##Impl &ClassName::getImpl() const \
136 { \
137 if(m_impl == nullptr) \
138 { \
139 throw std::runtime_error(#ClassName " is empty"); \
140 } \
141 return *m_impl; \
142 } \
143 \
144 ClassName::~ClassName() = default; \
145 ClassName::ClassName(ClassName &&other) noexcept = default; \
146 ClassName &ClassName::operator=(ClassName &&other) noexcept = default
147
148// ------------------------------------------------------------------------------------------------------------------ //
149#define ZIVID_PIMPL_REFERENCE_SEMANTICS(ClassName, Attributes) \
150public: \
151 Attributes ~ClassName(); \
152 Attributes ClassName(const ClassName &other); \
153 Attributes ClassName &operator=(const ClassName &other); \
154 Attributes ClassName(ClassName &&other) noexcept; \
155 Attributes ClassName &operator=(ClassName &&other) noexcept; \
156 Attributes explicit ClassName(std::shared_ptr<class ClassName##Impl> &&impl); \
157 Attributes class ClassName##Impl &getImpl(); \
158 Attributes const class ClassName##Impl &getImpl() const; \
159 \
160private: \
161 std::shared_ptr<class ClassName##Impl> m_impl
162
163#define ZIVID_PIMPL_REFERENCE_SEMANTICS_CPP(ClassName) \
164 ClassName::ClassName(std::shared_ptr<ClassName##Impl> &&impl) \
165 : m_impl{ std::move(impl) } \
166 {} \
167 \
168 ClassName##Impl &ClassName::getImpl() \
169 { \
170 return const_cast<ClassName##Impl &>(std::as_const(*this).getImpl()); \
171 } \
172 \
173 const ClassName##Impl &ClassName::getImpl() const \
174 { \
175 if(m_impl == nullptr) \
176 { \
177 throw std::runtime_error(#ClassName " is empty"); \
178 } \
179 return *m_impl; \
180 } \
181 \
182 ClassName::~ClassName() = default; \
183 ClassName::ClassName(const ClassName &other) = default; \
184 ClassName &ClassName::operator=(const ClassName &other) = default; \
185 ClassName::ClassName(ClassName &&other) noexcept = default; \
186 ClassName &ClassName::operator=(ClassName &&other) noexcept = default