From 9df6b248e371ad45b1972b1f5bb79ec22271a01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20LAIGRE?= Date: Tue, 21 Dec 2021 10:38:55 +0100 Subject: [PATCH] Add casts for std::unique_ptr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien LAIGRE --- .../powsybl/stdcxx/{upcast.hpp => cast.hpp} | 11 +++ src/iidm/BusBreakerVoltageLevelViews.cpp | 2 +- src/iidm/CalculatedBus.cpp | 2 +- src/iidm/ConfiguredBus.cpp | 2 +- src/iidm/NodeBreakerVoltageLevelViews.cpp | 2 +- test/stdcxx/CMakeLists.txt | 1 + test/stdcxx/CastTest.cpp | 84 +++++++++++++++++++ 7 files changed, 100 insertions(+), 4 deletions(-) rename include/powsybl/stdcxx/{upcast.hpp => cast.hpp} (54%) create mode 100644 test/stdcxx/CastTest.cpp diff --git a/include/powsybl/stdcxx/upcast.hpp b/include/powsybl/stdcxx/cast.hpp similarity index 54% rename from include/powsybl/stdcxx/upcast.hpp rename to include/powsybl/stdcxx/cast.hpp index 3f8359863..87d3729c9 100644 --- a/include/powsybl/stdcxx/upcast.hpp +++ b/include/powsybl/stdcxx/cast.hpp @@ -8,10 +8,21 @@ #ifndef POWSYBL_STDCXX_UPCAST_HPP #define POWSYBL_STDCXX_UPCAST_HPP +#include #include namespace stdcxx { +template ::value>::type> +std::unique_ptr downcast(std::unique_ptr& ptr) { + return std::unique_ptr(dynamic_cast(ptr.release())); +} + +template ::value>::type> +std::unique_ptr upcast(std::unique_ptr& ptr) { + return std::unique_ptr(ptr.release()); +} + template ::value>::type> const Base& upcast(const Derived& value) { return value; diff --git a/src/iidm/BusBreakerVoltageLevelViews.cpp b/src/iidm/BusBreakerVoltageLevelViews.cpp index 508ea1e9c..668eaac90 100644 --- a/src/iidm/BusBreakerVoltageLevelViews.cpp +++ b/src/iidm/BusBreakerVoltageLevelViews.cpp @@ -8,7 +8,7 @@ #include "BusBreakerVoltageLevelViews.hpp" #include -#include +#include #include "BusBreakerVoltageLevel.hpp" #include "BusBreakerVoltageLevelTopology.hpp" diff --git a/src/iidm/CalculatedBus.cpp b/src/iidm/CalculatedBus.cpp index f7d9e41bd..30652f323 100644 --- a/src/iidm/CalculatedBus.cpp +++ b/src/iidm/CalculatedBus.cpp @@ -11,8 +11,8 @@ #include #include #include +#include #include -#include #include "NodeBreakerVoltageLevel.hpp" #include "NodeTerminal.hpp" diff --git a/src/iidm/ConfiguredBus.cpp b/src/iidm/ConfiguredBus.cpp index d49de45d7..3b8dcc7dd 100644 --- a/src/iidm/ConfiguredBus.cpp +++ b/src/iidm/ConfiguredBus.cpp @@ -16,10 +16,10 @@ #include #include #include +#include #include #include #include -#include #include "BusBreakerVoltageLevel.hpp" #include "BusTerminal.hpp" diff --git a/src/iidm/NodeBreakerVoltageLevelViews.cpp b/src/iidm/NodeBreakerVoltageLevelViews.cpp index ac63cfccf..e43dd82fb 100644 --- a/src/iidm/NodeBreakerVoltageLevelViews.cpp +++ b/src/iidm/NodeBreakerVoltageLevelViews.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include "CalculatedBus.hpp" #include "NodeBreakerVoltageLevel.hpp" diff --git a/test/stdcxx/CMakeLists.txt b/test/stdcxx/CMakeLists.txt index 99c710641..2485417d5 100644 --- a/test/stdcxx/CMakeLists.txt +++ b/test/stdcxx/CMakeLists.txt @@ -7,6 +7,7 @@ set(UNIT_TEST_SOURCES stdcxx.cpp + CastTest.cpp DateTimeTest.cpp DemangleTest.cpp MathTest.cpp diff --git a/test/stdcxx/CastTest.cpp b/test/stdcxx/CastTest.cpp new file mode 100644 index 000000000..915858a23 --- /dev/null +++ b/test/stdcxx/CastTest.cpp @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include + +#include +#include + +namespace stdcxx { + +BOOST_AUTO_TEST_SUITE(CaseTestSuite) + +class BaseClass { +public: + BaseClass() = default; + + virtual ~BaseClass() = default; + + int getBaseAttr() const; + + void setBaseAttr(int newValue); + +private: + int m_baseAttr = 1; +}; + +int BaseClass::getBaseAttr() const { + return m_baseAttr; +} + +void BaseClass::setBaseAttr(int newValue) { + m_baseAttr = newValue; +} + +class DerivedClass : public BaseClass { +public: + DerivedClass() = default; + + ~DerivedClass() override = default; + + int getDerivedAttr() const; + + void setDerivedAttr(int newValue); + +private: + int m_derivedAttr = 2; +}; + +int DerivedClass::getDerivedAttr() const { + return m_derivedAttr; +} + +void DerivedClass::setDerivedAttr(int newValue) { + m_derivedAttr = newValue; +} + +BOOST_AUTO_TEST_CASE(unique_ptrCastTest) { + std::unique_ptr basePtr = stdcxx::make_unique(); + BOOST_CHECK_EQUAL(1, basePtr->getBaseAttr()); + basePtr->setBaseAttr(11); + BOOST_CHECK_EQUAL(11, basePtr->getBaseAttr()); + + std::unique_ptr derivedPtr = stdcxx::downcast(basePtr); + BOOST_CHECK(!basePtr); + BOOST_CHECK_EQUAL(11, derivedPtr->getBaseAttr()); + BOOST_CHECK_EQUAL(2, derivedPtr->getDerivedAttr()); + derivedPtr->setBaseAttr(111); + derivedPtr->setDerivedAttr(22); + BOOST_CHECK_EQUAL(22, derivedPtr->getDerivedAttr()); + + std::unique_ptr otherBasePtr = stdcxx::upcast(derivedPtr); + BOOST_CHECK(!derivedPtr); + BOOST_CHECK_EQUAL(111, otherBasePtr->getBaseAttr()); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // namespace stdcxx