From 09a9da2f365d12758043d39fcfa0c4a7b7cd1647 Mon Sep 17 00:00:00 2001 From: Olivier BICHLER <olivier.bichler@cea.fr> Date: Tue, 3 Oct 2023 10:13:51 +0200 Subject: [PATCH] Improved getAttr() binding strategy --- include/aidge/utils/DynamicAttributes.hpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/include/aidge/utils/DynamicAttributes.hpp b/include/aidge/utils/DynamicAttributes.hpp index 8ee294ce3..41e2da940 100644 --- a/include/aidge/utils/DynamicAttributes.hpp +++ b/include/aidge/utils/DynamicAttributes.hpp @@ -44,7 +44,7 @@ public: * exist * \note at() throws if the Attribute does not exist, using find to test for Attribute existance */ - template<class T> T getAttr(const std::string& name) const + template<class T> T& getAttr(const std::string& name) { #ifdef PYBIND // If attribute does not exist in C++, it might have been created in Python @@ -52,16 +52,16 @@ public: if (it == mAttrs.end()) { auto itPy = mAttrsPy.find(name); if (itPy != mAttrsPy.end()) { - return itPy->second.cast<T>(); + // Insert the attribute back in C++ + mAttrs.emplace(std::make_pair(name, libany::any(itPy->second.cast<T>()))); } } #endif - return libany::any_cast<T>(mAttrs.at(name)); + return libany::any_cast<T&>(mAttrs.at(name)); } // Note: return by reference is not possible because py::object::cast() returns a temporary -/* template<class T> const T& getAttr(const std::string& name) const { #ifdef PYBIND @@ -70,14 +70,15 @@ public: if (it == mAttrs.end()) { auto itPy = mAttrsPy.find(name); if (itPy != mAttrsPy.end()) { - return itPy->second.cast<T>(); + // Insert the attribute back in C++ + mAttrs.emplace(std::make_pair(name, libany::any(itPy->second.cast<T>()))); } } #endif return libany::any_cast<const T&>(mAttrs.at(name)); } -*/ + ///\brief Add a new Attribute, identified by its name. If it already exists, asserts. ///\tparam T expected Attribute type ///\param name Attribute name @@ -178,9 +179,6 @@ public: #endif private: - // Stores C++ attributes only - std::map<std::string, libany::any> mAttrs; - #ifdef PYBIND // Stores C++ attributes (copy) and Python-only attributes // Code should be compiled with -fvisibility=hidden @@ -188,6 +186,11 @@ private: // “‘SomeClass’ declared with greater visibility than the type of its // field ‘SomeClass::member’ [-Wattributes]†std::map<std::string, py::object> mAttrsPy; + // Stores C++ attributes only + // mutable because it may be updated in getAttr() from Python + mutable std::map<std::string, libany::any> mAttrs; +#else + std::map<std::string, libany::any> mAttrs; #endif }; -- GitLab