Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenlib/BLI_cpp_type.hh
- This file was moved from source/blender/functions/FN_cpp_type.hh.
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| #pragma once | #pragma once | ||||
| /** \file | /** \file | ||||
| * \ingroup fn | * \ingroup bli | ||||
| * | * | ||||
| * The `CPPType` class is the core of a runtime-type-system. It allows working with arbitrary C++ | * The `CPPType` class allows working with arbitrary C++ types in a generic way. An instance of | ||||
| * types in a generic way. An instance of `CPPType` wraps exactly one type like `int` or | * #CPPType wraps exactly one type like `int` or `std::string`. With #CPPType one can write generic | ||||
| * `std::string`. | * data structures and algorithms that work on types that are only known at run-time. | ||||
| * | * | ||||
| * Every type has a size and an alignment. Every function dealing with C++ types in a generic way, | * Every type has a size and an alignment. Every function dealing with C++ types in a generic way, | ||||
| * has to make sure that alignment rules are followed. The methods provided by a CPPType instance | * has to make sure that alignment rules are followed. The methods provided by a #CPPType instance | ||||
| * will check for correct alignment as well. | * will check for correct alignment as well. | ||||
| * | * | ||||
| * Every type has a name that is for debugging purposes only. It should not be used as identifier. | * Every type has a name that is for debugging purposes only. It should not be used as identifier. | ||||
| * | * | ||||
| * To check if two instances of CPPType represent the same type, only their pointers have to be | * To check if two instances of CPPType represent the same type, only their pointers have to be | ||||
| * compared. Any C++ type has at most one corresponding CPPType instance. | * compared. Any C++ type has at most one corresponding CPPType instance. | ||||
| * | * | ||||
| * A CPPType instance comes with many methods that allow dealing with types in a generic way. Most | * A #CPPType instance comes with many methods that allow dealing with types in a generic way. Most | ||||
| * methods come in three variants. Using the construct-default methods as example: | * methods come in three variants. Using the default-construct methods as example: | ||||
HooglyBoogly: `as example` -> `as an example` | |||||
| * - default_construct(void *ptr): | * - `default_construct(void *ptr)`: | ||||
| * Constructs a single instance of that type at the given pointer. | * Constructs a single instance of that type at the given pointer. | ||||
| * - default_construct_n(void *ptr, int64_t n): | * - `default_construct_n(void *ptr, int64_t n)`: | ||||
| * Constructs n instances of that type in an array that starts at the given pointer. | * Constructs n instances of that type in an array that starts at the given pointer. | ||||
| * - default_construct_indices(void *ptr, IndexMask mask): | * - `default_construct_indices(void *ptr, IndexMask mask)`: | ||||
| * Constructs multiple instances of that type in an array that starts at the given pointer. | * Constructs multiple instances of that type in an array that starts at the given pointer. | ||||
| * Only the indices referenced by `mask` will by constructed. | * Only the indices referenced by `mask` will by constructed. | ||||
| * | * | ||||
| * In some cases default-construction does nothing (e.g. for trivial types like int). The | * In some cases default-construction does nothing (e.g. for trivial types like int). The | ||||
| * `default_value` method provides some default value anyway that can be copied instead. What the | * `default_value` method provides some default value anyway that can be copied instead. What the | ||||
| * default value is, depends on the type. Usually it is something like 0 or an empty string. | * default value is, depends on the type. Usually it is something like 0 or an empty string. | ||||
| * | * | ||||
| * | * | ||||
| Show All 30 Lines | enum class CPPTypeFlags { | ||||
| Hashable = 1 << 0, | Hashable = 1 << 0, | ||||
| Printable = 1 << 1, | Printable = 1 << 1, | ||||
| EqualityComparable = 1 << 2, | EqualityComparable = 1 << 2, | ||||
| BasicType = Hashable | Printable | EqualityComparable, | BasicType = Hashable | Printable | EqualityComparable, | ||||
| }; | }; | ||||
| ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable) | ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable) | ||||
| namespace blender::fn { | namespace blender { | ||||
| /** Utility class to pass template parameters to constructor of `CPPType`. */ | /** Utility class to pass template parameters to constructor of `CPPType`. */ | ||||
| template<typename T, CPPTypeFlags Flags> struct CPPTypeParam { | template<typename T, CPPTypeFlags Flags> struct CPPTypeParam { | ||||
| }; | }; | ||||
| class CPPType : NonCopyable, NonMovable { | class CPPType : NonCopyable, NonMovable { | ||||
| private: | private: | ||||
| int64_t size_ = 0; | int64_t size_ = 0; | ||||
| ▲ Show 20 Lines • Show All 538 Lines • ▼ Show 20 Lines | public: | ||||
| } | } | ||||
| template<typename T> bool is() const | template<typename T> bool is() const | ||||
| { | { | ||||
| return this == &CPPType::get<std::decay_t<T>>(); | return this == &CPPType::get<std::decay_t<T>>(); | ||||
| } | } | ||||
| }; | }; | ||||
| } // namespace blender::fn | } // namespace blender | ||||
| /* Utility for allocating an uninitialized buffer for a single value of the given #CPPType. */ | /* Utility for allocating an uninitialized buffer for a single value of the given #CPPType. */ | ||||
| #define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name) \ | #define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name) \ | ||||
| blender::DynamicStackBuffer<64, 64> stack_buffer_for_##variable_name((type).size(), \ | blender::DynamicStackBuffer<64, 64> stack_buffer_for_##variable_name((type).size(), \ | ||||
| (type).alignment()); \ | (type).alignment()); \ | ||||
| void *variable_name = stack_buffer_for_##variable_name.buffer(); | void *variable_name = stack_buffer_for_##variable_name.buffer(); | ||||
as example -> as an example