Skip to content
Snippets Groups Projects
Commit 09a9da2f authored by Olivier BICHLER's avatar Olivier BICHLER
Browse files

Improved getAttr() binding strategy

parent c6e608e9
No related branches found
No related tags found
No related merge requests found
...@@ -44,7 +44,7 @@ public: ...@@ -44,7 +44,7 @@ public:
* exist * exist
* \note at() throws if the Attribute does not exist, using find to test for Attribute existance * \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 #ifdef PYBIND
// If attribute does not exist in C++, it might have been created in Python // If attribute does not exist in C++, it might have been created in Python
...@@ -52,16 +52,16 @@ public: ...@@ -52,16 +52,16 @@ public:
if (it == mAttrs.end()) { if (it == mAttrs.end()) {
auto itPy = mAttrsPy.find(name); auto itPy = mAttrsPy.find(name);
if (itPy != mAttrsPy.end()) { 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 #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 // 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 template<class T> const T& getAttr(const std::string& name) const
{ {
#ifdef PYBIND #ifdef PYBIND
...@@ -70,14 +70,15 @@ public: ...@@ -70,14 +70,15 @@ public:
if (it == mAttrs.end()) { if (it == mAttrs.end()) {
auto itPy = mAttrsPy.find(name); auto itPy = mAttrsPy.find(name);
if (itPy != mAttrsPy.end()) { 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 #endif
return libany::any_cast<const T&>(mAttrs.at(name)); return libany::any_cast<const T&>(mAttrs.at(name));
} }
*/
///\brief Add a new Attribute, identified by its name. If it already exists, asserts. ///\brief Add a new Attribute, identified by its name. If it already exists, asserts.
///\tparam T expected Attribute type ///\tparam T expected Attribute type
///\param name Attribute name ///\param name Attribute name
...@@ -178,9 +179,6 @@ public: ...@@ -178,9 +179,6 @@ public:
#endif #endif
private: private:
// Stores C++ attributes only
std::map<std::string, libany::any> mAttrs;
#ifdef PYBIND #ifdef PYBIND
// Stores C++ attributes (copy) and Python-only attributes // Stores C++ attributes (copy) and Python-only attributes
// Code should be compiled with -fvisibility=hidden // Code should be compiled with -fvisibility=hidden
...@@ -188,6 +186,11 @@ private: ...@@ -188,6 +186,11 @@ private:
// “‘SomeClass’ declared with greater visibility than the type of its // “‘SomeClass’ declared with greater visibility than the type of its
// field ‘SomeClass::member’ [-Wattributes]” // field ‘SomeClass::member’ [-Wattributes]”
std::map<std::string, py::object> mAttrsPy; 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 #endif
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment