From ba4f14bc6f53430c690128e6821546c53d365b8c Mon Sep 17 00:00:00 2001
From: NAUD Maxence <maxence.naud@cea.fr>
Date: Fri, 20 Oct 2023 12:13:11 +0000
Subject: [PATCH] [Fix] add getAttr function for const ref to Operator

---
 include/aidge/utils/StaticAttributes.hpp | 35 ++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/include/aidge/utils/StaticAttributes.hpp b/include/aidge/utils/StaticAttributes.hpp
index b67f69ae7..50ed0895e 100644
--- a/include/aidge/utils/StaticAttributes.hpp
+++ b/include/aidge/utils/StaticAttributes.hpp
@@ -22,8 +22,8 @@
 
 namespace Aidge {
 /**
- * @brief This class is designed to handle static attributes (i.e. known at compile-time) 
- * with named accessors, with minimal overhead (the name strings are not stored in each object 
+ * @brief This class is designed to handle static attributes (i.e. known at compile-time)
+ * with named accessors, with minimal overhead (the name strings are not stored in each object
  * instance and it remains possible to access attribute without overhead at compile-time).
 */
 template <class ATTRS_ENUM, class ...T>
@@ -97,6 +97,17 @@ public:
         AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute \"%s\" not found", name);
     }
 
+    template <typename R>
+    const R& getAttr(const char* name) const {
+        for (std::size_t i = 0; i < size(EnumStrings<ATTRS_ENUM>::data); ++i) {
+            if (strcmp(EnumStrings<ATTRS_ENUM>::data[i], name) == 0) {
+                return getAttr<R>(i);
+            }
+        }
+
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute \"%s\" not found", name);
+    }
+
     template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
     typename std::enable_if<(SIZE > 0), R&>::type getAttr(std::size_t i) {
         if (i == SIZE-1) {
@@ -117,6 +128,26 @@ public:
         AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute not found");
     }
 
+    template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
+    typename std::enable_if<(SIZE > 0), const R&>::type getAttr(std::size_t i) const {
+        if (i == SIZE-1) {
+            if (std::is_same<R, typename std::tuple_element<SIZE-1,std::tuple<T...>>::type>::value) {
+                return reinterpret_cast<const R&>(std::get<SIZE-1>(mAttrs));
+            }
+            else {
+                AIDGE_THROW_OR_ABORT(std::runtime_error, "wrong type for attribute with index %lu", i);
+            }
+        }
+        else {
+            return getAttr<R, SIZE-1>(i);
+        }
+    }
+
+    template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
+    [[noreturn]] typename std::enable_if<(SIZE == 0), const R&>::type getAttr(std::size_t /*i*/) const {
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute not found");
+    }
+
     template <std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value>
     constexpr typename std::enable_if<(SIZE > 0), const std::type_info&>::type getAttrType(std::size_t i) const {
         if (i == SIZE-1) {
-- 
GitLab