Files
workinf_Blender_Wasm/blender-5.2.0/source/blender/makesdna/DNA_defs.h
2026-08-12 04:47:48 -04:00

171 lines
5.0 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup DNA
*
* Group generic defines for all DNA headers may use in this file.
*/
#pragma once
/* `makesdna` ignores. */
#ifdef DNA_DEPRECATED_ALLOW
/* allow use of deprecated items */
# define DNA_DEPRECATED
#else
# if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
# define DNA_DEPRECATED [[deprecated]]
# else
# define DNA_DEPRECATED
# endif
#endif
/* GCC considers default member initialization in constructors deprecated.
* This macro helps silence that while still warning in other cases */
#if defined(__GNUC__) || defined(__clang__)
/* clang-format off */
# define DNA_DEPRECATED_IGNORE(statement) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \
statement \
_Pragma("GCC diagnostic pop")
/* clang-format on */
#else
# define DNA_DEPRECATED_IGNORE(statement) statement
#endif
#ifdef __GNUC__
# define DNA_PRIVATE_ATTR __attribute__((deprecated))
#else
# define DNA_PRIVATE_ATTR
#endif
/* poison pragma */
#ifdef DNA_DEPRECATED_ALLOW
# define DNA_DEPRECATED_GCC_POISON 0
#else
/* enable the pragma if we can */
# ifdef __GNUC__
# define DNA_DEPRECATED_GCC_POISON 1
# else
# define DNA_DEPRECATED_GCC_POISON 0
# endif
#endif
/* hrmf, we need a better include then this */
#include "../blenlib/BLI_sys_types.h" /* needed for int64_t only! */
namespace blender {
/* non-id name variables should use this length */
#define MAX_NAME 64
/* #DNA_DEFINE_CXX_METHODS is used to define C++ methods which are needed for proper/safe resource
* management, making unsafe (from an ownership perspective: i.e. pointers which sometimes needs to
* be set to nullptr on copy, sometimes needs to be dupalloc-ed) operations explicit, and taking
* care of compiler specific warnings when dealing with members marked with DNA_DEPRECATED.
*
* The `class_name` argument is to match the structure name the macro is used from.
*
* Typical usage example:
*
* struct Object {
* DNA_DEFINE_CXX_METHODS(Object)
* };
*/
/* Forward-declared here since there is no simple header file to be pulled for this functionality.
* Avoids pulling `string.h` from this header to get access to #memcpy. */
void _DNA_internal_memcpy(void *dst, const void *src, size_t size);
void _DNA_internal_memzero(void *dst, size_t size);
void _DNA_internal_swap(void *a, void *b, size_t size);
namespace dna::internal {
template<class T> class ShallowDataConstRef {
public:
constexpr explicit ShallowDataConstRef(const T &ref) : ref_(ref) {}
const T *get_pointer() const
{
return &ref_;
}
private:
const T &ref_;
};
class ShallowZeroInitializeTag {};
} // namespace dna::internal
#define DNA_DEFINE_CXX_METHODS(class_name) \
DNA_DEPRECATED_IGNORE(class_name() = default;) \
~class_name() = default; \
/* Delete copy and assignment, which are not safe for resource ownership. */ \
class_name(const class_name &other) = delete; \
class_name(class_name &&other) noexcept = delete; \
class_name &operator=(const class_name &other) = delete; \
class_name &operator=(class_name &&other) = delete; \
/* Support for shallow copy. */ \
/* NOTE: Calling the default constructor works-around deprecated warning generated by GCC. */ \
class_name(const dna::internal::ShallowDataConstRef<class_name> ref) : class_name() \
{ \
_DNA_internal_memcpy(this, ref.get_pointer(), sizeof(class_name)); \
} \
class_name &operator=(const dna::internal::ShallowDataConstRef<class_name> ref) \
{ \
if (this != ref.get_pointer()) { \
_DNA_internal_memcpy(this, ref.get_pointer(), sizeof(class_name)); \
} \
return *this; \
} \
/* Create object which memory is filled with zeros. */ \
class_name(const dna::internal::ShallowZeroInitializeTag /*tag*/) : class_name() \
{ \
_DNA_internal_memzero(this, sizeof(class_name)); \
} \
class_name &operator=(const dna::internal::ShallowZeroInitializeTag /*tag*/) \
{ \
_DNA_internal_memzero(this, sizeof(class_name)); \
return *this; \
}
namespace dna {
/* Creates shallow copy of the given object.
* The entire object is copied as-is using memory copy.
*
* Typical usage:
* Object temp_object = dna::shallow_copy(*input_object);
*
* From the implementation detail go via copy constructor/assign operator defined in the structure.
*/
template<typename T>
[[nodiscard]] inline internal::ShallowDataConstRef<T> shallow_copy(const T &other)
{
return internal::ShallowDataConstRef(other);
}
template<typename T> inline void shallow_copy_array(T *dst, const T *src, const int64_t size)
{
_DNA_internal_memcpy(dst, src, sizeof(T) * size_t(size));
}
/* DNA object initializer which leads to an object which underlying memory is filled with zeroes.
*/
[[nodiscard]] inline internal::ShallowZeroInitializeTag shallow_zero_initialize()
{
return internal::ShallowZeroInitializeTag();
}
template<typename T> inline void shallow_swap(T &a, T &b)
{
_DNA_internal_swap(&a, &b, sizeof(T));
}
} // namespace dna
} // namespace blender