diff --git a/include/aidge/utils/StaticAttributes.hpp b/include/aidge/utils/StaticAttributes.hpp index 248fef3f3ed729f588e2c30aa0c9de5995cab229..fb800cffbcff5d4113961f8e62977417336f2cb8 100644 --- a/include/aidge/utils/StaticAttributes.hpp +++ b/include/aidge/utils/StaticAttributes.hpp @@ -18,6 +18,7 @@ #include <typeinfo> #include "aidge/utils/Attributes.hpp" +#include "aidge/utils/Utils.hpp" namespace Aidge { /** @@ -93,7 +94,7 @@ public: } } - assert(false && "attribute not found"); + 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> @@ -103,7 +104,7 @@ public: return reinterpret_cast<R&>(std::get<SIZE-1>(mAttrs)); } else { - assert(false && "wrong attribute type"); + AIDGE_THROW_OR_ABORT(std::runtime_error, "wrong type for attribute with index %lu", i); } } else { @@ -113,7 +114,7 @@ public: template <typename R, std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value> [[noreturn]] constexpr typename std::enable_if<(SIZE == 0), R&>::type getAttr(std::size_t /*i*/) { - assert(false && "attribute not found"); + AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute not found"); } template <std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value> @@ -127,10 +128,8 @@ public: } template <std::size_t SIZE = std::tuple_size<std::tuple<T...>>::value> - /*[[noreturn]]*/ constexpr typename std::enable_if<(SIZE == 0), const std::type_info&>::type getAttrType(std::size_t /*i*/) const { - assert(false && "attribute not found"); - return typeid(void); // avoid MSVC error C4716: "must return a value", despite [[noreturn]] attribute - // [[noreturn]] attribute is removed otherwise GCC complains because there is a return. + [[noreturn]] constexpr typename std::enable_if<(SIZE == 0), const std::type_info&>::type getAttrType(std::size_t /*i*/) const { + AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute not found"); } constexpr const std::tuple<T...>& getStaticAttributes() const { @@ -159,7 +158,7 @@ public: } } - assert(false && "attribute not found"); + AIDGE_THROW_OR_ABORT(std::runtime_error, "attribute \"%s\" not found", name.c_str()); } std::set<std::string> getAttrsName() const override final { @@ -179,7 +178,8 @@ public: return py::detail::accessor_policies::tuple_item::get(py::cast(mAttrs), static_cast<py::size_t>(i)); } } - throw py::value_error("Attribute : " + name + " does not exist." ); + + AIDGE_THROW_OR_ABORT(py::value_error, "attribute \"%s\" not found", name.c_str()); }; #endif diff --git a/include/aidge/utils/Utils.hpp b/include/aidge/utils/Utils.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7c0c03c82ff252b6175d3c9bbe5395bb05127c9f --- /dev/null +++ b/include/aidge/utils/Utils.hpp @@ -0,0 +1,37 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + + +#ifndef AIDGE_UTILS_H_ +#define AIDGE_UTILS_H_ + +#include <cstdio> + +#ifdef NO_EXCEPTIONS +#define AIDGE_THROW_OR_ABORT(ex, ...) \ +do { std::printf(__VA_ARGS__); std::abort(); } while (false) +#else +#include <stdexcept> +#define AIDGE_THROW_OR_ABORT(ex, ...) \ +do { \ + int n = 128; \ + std::unique_ptr<char[]> formatted; \ + formatted.reset(new char[n]); \ + const int len = std::snprintf(formatted.get(), n, __VA_ARGS__); \ + if (len >= n) { \ + formatted.reset(new char[len + 1]); \ + std::snprintf(formatted.get(), len + 1, __VA_ARGS__); \ + }; \ + throw ex(formatted.get()); \ +} while (false) +#endif + +#endif //AIDGE_UTILS_H_ \ No newline at end of file diff --git a/unit_tests/operator/Test_GenericOperator.cpp b/unit_tests/operator/Test_GenericOperator.cpp index c7b447e914b391c0b137e49cf7aed27703d4fcc0..8d634cc3a105c423b54b6003f41204aeb1fc5335 100644 --- a/unit_tests/operator/Test_GenericOperator.cpp +++ b/unit_tests/operator/Test_GenericOperator.cpp @@ -77,7 +77,7 @@ TEST_CASE("[core/operators] GenericOp(add & get attributes)", "[Operator]") { } } -TEST_CASE("[core/operator] GenericOp(type check)", "[.ass]") { +TEST_CASE("[core/operator] GenericOp(type check)", "[Operator]") { SECTION("WRONG TYPE FOR GETTER") { GenericOperator_Op Testop("TestOp", 1, 1, 1); Testop.addAttr<long>("longAttr", 3); diff --git a/unit_tests/utils/Test_StaticAttributes.cpp b/unit_tests/utils/Test_StaticAttributes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36c2e0454b415e1cb25cc3581016530a372b9e65 --- /dev/null +++ b/unit_tests/utils/Test_StaticAttributes.cpp @@ -0,0 +1,48 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <catch2/catch_test_macros.hpp> + +#include <string> +#include <vector> + +#include "aidge/utils/StaticAttributes.hpp" + +using namespace Aidge; + +enum class TestAttr { a, b, c, d }; + +namespace { +template <> +const char *const EnumStrings<TestAttr>::data[] = { + "a", + "b", + "c", + "d" +}; +} + +using Attributes_ = StaticAttributes<TestAttr, int, float, std::string, std::vector<bool>>; +template <TestAttr e> +using attr = typename Attributes_::template attr<e>; + +TEST_CASE("[core/attributes] StaticAttribute") { + SECTION("TestAttr") { + StaticAttributes<TestAttr, int, float, std::string, std::vector<bool>> attrs( + attr<TestAttr::a>(42), + attr<TestAttr::b>(18.75), + attr<TestAttr::c>("test"), + attr<TestAttr::d>({true, false, true})); + + REQUIRE(attrs.getAttr<int>("a") == 42); + REQUIRE_THROWS(attrs.getAttr<int>("inexistant")); + } +}