diff options
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_cpp_type.hh | 27 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_cpp_type_make.hh | 16 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_cpp_types.hh | 44 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_cpp_types_make.hh | 29 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_parameter_pack_utils.hh | 7 | ||||
-rw-r--r-- | source/blender/blenlib/CMakeLists.txt | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/cpp_type.cc | 29 | ||||
-rw-r--r-- | source/blender/blenlib/intern/cpp_types.cc | 98 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_cpp_type_test.cc | 2 |
9 files changed, 207 insertions, 49 deletions
diff --git a/source/blender/blenlib/BLI_cpp_type.hh b/source/blender/blenlib/BLI_cpp_type.hh index 568ccbb5a64..2f61583589b 100644 --- a/source/blender/blenlib/BLI_cpp_type.hh +++ b/source/blender/blenlib/BLI_cpp_type.hh @@ -74,6 +74,7 @@ #include "BLI_index_mask.hh" #include "BLI_map.hh" #include "BLI_math_base.h" +#include "BLI_parameter_pack_utils.hh" #include "BLI_string_ref.hh" #include "BLI_utility_mixins.hh" @@ -94,10 +95,6 @@ ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable) namespace blender { -/** Utility class to pass template parameters to constructor of `CPPType`. */ -template<typename T, CPPTypeFlags Flags> struct CPPTypeParam { -}; - class CPPType : NonCopyable, NonMovable { private: int64_t size_ = 0; @@ -148,7 +145,8 @@ class CPPType : NonCopyable, NonMovable { std::string debug_name_; public: - template<typename T, CPPTypeFlags Flags> CPPType(CPPTypeParam<T, Flags>, StringRef debug_name); + template<typename T, CPPTypeFlags Flags> + CPPType(TypeTag<T> /*type*/, TypeForValue<CPPTypeFlags, Flags> /*flags*/, StringRef debug_name); virtual ~CPPType() = default; /** @@ -173,7 +171,7 @@ class CPPType : NonCopyable, NonMovable { template<typename T> static const CPPType &get() { /* Store the #CPPType locally to avoid making the function call in most cases. */ - static const CPPType &type = CPPType::get_impl<std::remove_cv_t<T>>(); + static const CPPType &type = CPPType::get_impl<std::decay_t<T>>(); return type; } template<typename T> static const CPPType &get_impl(); @@ -745,30 +743,26 @@ class CPPType : NonCopyable, NonMovable { } } - template<typename T> struct type_tag { - using type = T; - }; - private: template<typename Fn> struct TypeTagExecutor { const Fn &fn; template<typename T> void operator()() const { - fn(type_tag<T>{}); + fn(TypeTag<T>{}); } void operator()() const { - fn(type_tag<void>{}); + fn(TypeTag<void>{}); } }; public: /** * Similar to #to_static_type but is easier to use with a lambda function. The function is - * expected to take a single `auto type_tag` parameter. To extract the static type, use: - * `using T = typename decltype(type_tag)::type;` + * expected to take a single `auto TypeTag` parameter. To extract the static type, use: + * `using T = typename decltype(TypeTag)::type;` * * If the current #CPPType is not in #Types, the type tag is `void`. */ @@ -779,6 +773,11 @@ class CPPType : NonCopyable, NonMovable { } }; +/** + * Initialize and register basic cpp types. + */ +void register_cpp_types(); + } // namespace blender /* Utility for allocating an uninitialized buffer for a single value of the given #CPPType. */ diff --git a/source/blender/blenlib/BLI_cpp_type_make.hh b/source/blender/blenlib/BLI_cpp_type_make.hh index 1f494624821..725e73dbb5d 100644 --- a/source/blender/blenlib/BLI_cpp_type_make.hh +++ b/source/blender/blenlib/BLI_cpp_type_make.hh @@ -206,7 +206,9 @@ template<typename T> uint64_t hash_cb(const void *value) namespace blender { template<typename T, CPPTypeFlags Flags> -CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name) +CPPType::CPPType(TypeTag<T> /*type*/, + TypeForValue<CPPTypeFlags, Flags> /*flags*/, + const StringRef debug_name) { using namespace cpp_type_util; @@ -278,9 +280,15 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name) } // namespace blender -#define BLI_CPP_TYPE_MAKE(IDENTIFIER, TYPE_NAME, FLAGS) \ +/** Create a new #CPPType that can be accessed through `CPPType::get<T>()`. */ +#define BLI_CPP_TYPE_MAKE(TYPE_NAME, FLAGS) \ template<> const blender::CPPType &blender::CPPType::get_impl<TYPE_NAME>() \ { \ - static CPPType cpp_type{blender::CPPTypeParam<TYPE_NAME, FLAGS>(), STRINGIFY(IDENTIFIER)}; \ - return cpp_type; \ + static CPPType type{blender::TypeTag<TYPE_NAME>(), \ + TypeForValue<CPPTypeFlags, FLAGS>(), \ + STRINGIFY(TYPE_NAME)}; \ + return type; \ } + +/** Register a #CPPType created with #BLI_CPP_TYPE_MAKE. */ +#define BLI_CPP_TYPE_REGISTER(TYPE_NAME) blender::CPPType::get<TYPE_NAME>() diff --git a/source/blender/blenlib/BLI_cpp_types.hh b/source/blender/blenlib/BLI_cpp_types.hh new file mode 100644 index 00000000000..596090b95e5 --- /dev/null +++ b/source/blender/blenlib/BLI_cpp_types.hh @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "BLI_cpp_type.hh" +#include "BLI_vector.hh" + +namespace blender { + +/** + * Contains information about how to deal with a #Vector<T> generically. + */ +class VectorCPPType { + public: + /** The #Vector<T> itself. */ + const CPPType &self; + /** The type stored in the vector. */ + const CPPType &value; + + template<typename ValueType> VectorCPPType(TypeTag<ValueType> /*value_type*/); + + /** + * Try to find the #VectorCPPType that corresponds to a #CPPType. + */ + static const VectorCPPType *get_from_self(const CPPType &self); + /** + * Try to find the #VectorCPPType that wraps a vector containing the given value type. + * This only works when the vector type has been created with #BLI_VECTOR_CPP_TYPE_MAKE. + */ + static const VectorCPPType *get_from_value(const CPPType &value); + + template<typename ValueType> static const VectorCPPType &get() + { + static const VectorCPPType &type = VectorCPPType::get_impl<std::decay_t<ValueType>>(); + return type; + } + + template<typename ValueType> static const VectorCPPType &get_impl(); + + private: + void register_self(); +}; + +} // namespace blender diff --git a/source/blender/blenlib/BLI_cpp_types_make.hh b/source/blender/blenlib/BLI_cpp_types_make.hh new file mode 100644 index 00000000000..ba729c4cc69 --- /dev/null +++ b/source/blender/blenlib/BLI_cpp_types_make.hh @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "BLI_cpp_type_make.hh" +#include "BLI_cpp_types.hh" + +namespace blender { + +template<typename ValueType> +inline VectorCPPType::VectorCPPType(TypeTag<ValueType> /*value_type*/) + : self(CPPType::get<Vector<ValueType>>()), value(CPPType::get<ValueType>()) +{ + this->register_self(); +} + +} // namespace blender + +/** Create a new #VectorCPPType that can be accessed through `VectorCPPType::get<T>()`. */ +#define BLI_VECTOR_CPP_TYPE_MAKE(VALUE_TYPE) \ + BLI_CPP_TYPE_MAKE(blender::Vector<VALUE_TYPE>, CPPTypeFlags::None) \ + template<> const blender::VectorCPPType &blender::VectorCPPType::get_impl<VALUE_TYPE>() \ + { \ + static blender::VectorCPPType type{blender::TypeTag<VALUE_TYPE>{}}; \ + return type; \ + } + +/** Register a #VectorCPPType created with #BLI_VECTOR_CPP_TYPE_MAKE. */ +#define BLI_VECTOR_CPP_TYPE_REGISTER(VALUE_TYPE) blender::VectorCPPType::get<VALUE_TYPE>() diff --git a/source/blender/blenlib/BLI_parameter_pack_utils.hh b/source/blender/blenlib/BLI_parameter_pack_utils.hh index d1ef7bcbc65..36ceea1f4b8 100644 --- a/source/blender/blenlib/BLI_parameter_pack_utils.hh +++ b/source/blender/blenlib/BLI_parameter_pack_utils.hh @@ -24,6 +24,13 @@ template<typename T, T Element> struct TypeForValue { }; /** + * A struct that allows passing in a type as a function parameter. + */ +template<typename T> struct TypeTag { + using type = T; +}; + +/** * A type that encodes a list of values of the same type. * This is similar to #std::integer_sequence, but a bit more general. It's main purpose it to also * support enums instead of just ints. diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 693a4d98675..782056615be 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -57,7 +57,7 @@ set(SRC intern/cache_mutex.cc intern/compute_context.cc intern/convexhull_2d.c - intern/cpp_type.cc + intern/cpp_types.cc intern/delaunay_2d.cc intern/dot_export.cc intern/dynlib.c @@ -190,6 +190,8 @@ set(SRC BLI_convexhull_2d.h BLI_cpp_type.hh BLI_cpp_type_make.hh + BLI_cpp_types.hh + BLI_cpp_types_make.hh BLI_delaunay_2d.h BLI_devirtualize_parameters.hh BLI_dial_2d.h diff --git a/source/blender/blenlib/intern/cpp_type.cc b/source/blender/blenlib/intern/cpp_type.cc deleted file mode 100644 index 38de32d3ec8..00000000000 --- a/source/blender/blenlib/intern/cpp_type.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_color.hh" -#include "BLI_cpp_type_make.hh" -#include "BLI_float4x4.hh" -#include "BLI_math_vec_types.hh" - -BLI_CPP_TYPE_MAKE(bool, bool, CPPTypeFlags::BasicType) - -BLI_CPP_TYPE_MAKE(float, float, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(float2, blender::float2, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(float3, blender::float3, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(float4x4, blender::float4x4, CPPTypeFlags::BasicType) - -BLI_CPP_TYPE_MAKE(int8, int8_t, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(int16, int16_t, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(int32, int32_t, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(int64, int64_t, CPPTypeFlags::BasicType) - -BLI_CPP_TYPE_MAKE(uint8, uint8_t, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(uint16, uint16_t, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(uint32, uint32_t, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(uint64, uint64_t, CPPTypeFlags::BasicType) - -BLI_CPP_TYPE_MAKE(ColorGeometry4f, blender::ColorGeometry4f, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(ColorGeometry4b, blender::ColorGeometry4b, CPPTypeFlags::BasicType) - -BLI_CPP_TYPE_MAKE(string, std::string, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(StringVector, blender::Vector<std::string>, CPPTypeFlags::None) diff --git a/source/blender/blenlib/intern/cpp_types.cc b/source/blender/blenlib/intern/cpp_types.cc new file mode 100644 index 00000000000..eb8f03d942f --- /dev/null +++ b/source/blender/blenlib/intern/cpp_types.cc @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_color.hh" +#include "BLI_cpp_type_make.hh" +#include "BLI_cpp_types_make.hh" +#include "BLI_float4x4.hh" +#include "BLI_math_vec_types.hh" + +namespace blender { + +static auto &get_vector_from_self_map() +{ + static Map<const CPPType *, const VectorCPPType *> map; + return map; +} + +static auto &get_vector_from_value_map() +{ + static Map<const CPPType *, const VectorCPPType *> map; + return map; +} + +void VectorCPPType::register_self() +{ + get_vector_from_self_map().add_new(&this->self, this); + get_vector_from_value_map().add_new(&this->value, this); +} + +const VectorCPPType *VectorCPPType::get_from_self(const CPPType &self) +{ + const VectorCPPType *type = get_vector_from_self_map().lookup_default(&self, nullptr); + BLI_assert(type == nullptr || type->self == self); + return type; +} + +const VectorCPPType *VectorCPPType::get_from_value(const CPPType &value) +{ + const VectorCPPType *type = get_vector_from_value_map().lookup_default(&value, nullptr); + BLI_assert(type == nullptr || type->value == value); + return type; +} + +} // namespace blender + +BLI_CPP_TYPE_MAKE(bool, CPPTypeFlags::BasicType) + +BLI_CPP_TYPE_MAKE(float, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(blender::float2, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(blender::float3, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(blender::float4x4, CPPTypeFlags::BasicType) + +BLI_CPP_TYPE_MAKE(int8_t, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(int16_t, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(int32_t, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(int64_t, CPPTypeFlags::BasicType) + +BLI_CPP_TYPE_MAKE(uint8_t, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(uint16_t, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(uint32_t, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(uint64_t, CPPTypeFlags::BasicType) + +BLI_CPP_TYPE_MAKE(blender::ColorGeometry4f, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(blender::ColorGeometry4b, CPPTypeFlags::BasicType) + +BLI_CPP_TYPE_MAKE(std::string, CPPTypeFlags::BasicType) + +BLI_VECTOR_CPP_TYPE_MAKE(std::string) + +namespace blender { + +void register_cpp_types() +{ + BLI_CPP_TYPE_REGISTER(bool); + + BLI_CPP_TYPE_REGISTER(float); + BLI_CPP_TYPE_REGISTER(blender::float2); + BLI_CPP_TYPE_REGISTER(blender::float3); + BLI_CPP_TYPE_REGISTER(blender::float4x4); + + BLI_CPP_TYPE_REGISTER(int8_t); + BLI_CPP_TYPE_REGISTER(int16_t); + BLI_CPP_TYPE_REGISTER(int32_t); + BLI_CPP_TYPE_REGISTER(int64_t); + + BLI_CPP_TYPE_REGISTER(uint8_t); + BLI_CPP_TYPE_REGISTER(uint16_t); + BLI_CPP_TYPE_REGISTER(uint32_t); + BLI_CPP_TYPE_REGISTER(uint64_t); + + BLI_CPP_TYPE_REGISTER(blender::ColorGeometry4f); + BLI_CPP_TYPE_REGISTER(blender::ColorGeometry4b); + + BLI_CPP_TYPE_REGISTER(std::string); + + BLI_VECTOR_CPP_TYPE_REGISTER(std::string); +} + +} // namespace blender diff --git a/source/blender/blenlib/tests/BLI_cpp_type_test.cc b/source/blender/blenlib/tests/BLI_cpp_type_test.cc index 5823d54f51b..57077db53dd 100644 --- a/source/blender/blenlib/tests/BLI_cpp_type_test.cc +++ b/source/blender/blenlib/tests/BLI_cpp_type_test.cc @@ -76,7 +76,7 @@ struct TestType { } // namespace blender::tests -BLI_CPP_TYPE_MAKE(TestType, blender::tests::TestType, CPPTypeFlags::BasicType) +BLI_CPP_TYPE_MAKE(blender::tests::TestType, CPPTypeFlags::BasicType) namespace blender::tests { |