Skip to content

Commit

Permalink
Add casts for std::unique_ptr
Browse files Browse the repository at this point in the history
Signed-off-by: Sébastien LAIGRE <[email protected]>
  • Loading branch information
sebalaig authored and mathbagu committed Dec 21, 2021
1 parent e8c99e2 commit 9df6b24
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,21 @@
#ifndef POWSYBL_STDCXX_UPCAST_HPP
#define POWSYBL_STDCXX_UPCAST_HPP

#include <memory>
#include <type_traits>

namespace stdcxx {

template <typename Derived, typename Base, typename = typename std::enable_if<std::is_base_of<Base, Derived>::value>::type>
std::unique_ptr<Derived> downcast(std::unique_ptr<Base>& ptr) {
return std::unique_ptr<Derived>(dynamic_cast<Derived*>(ptr.release()));
}

template <typename Base, typename Derived, typename = typename std::enable_if<std::is_base_of<Base, Derived>::value>::type>
std::unique_ptr<Base> upcast(std::unique_ptr<Derived>& ptr) {
return std::unique_ptr<Base>(ptr.release());
}

template <typename Derived, typename Base, typename = typename std::enable_if<std::is_base_of<Base, Derived>::value>::type>
const Base& upcast(const Derived& value) {
return value;
Expand Down
2 changes: 1 addition & 1 deletion src/iidm/BusBreakerVoltageLevelViews.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "BusBreakerVoltageLevelViews.hpp"

#include <powsybl/iidm/Switch.hpp>
#include <powsybl/stdcxx/upcast.hpp>
#include <powsybl/stdcxx/cast.hpp>

#include "BusBreakerVoltageLevel.hpp"
#include "BusBreakerVoltageLevelTopology.hpp"
Expand Down
2 changes: 1 addition & 1 deletion src/iidm/CalculatedBus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#include <powsybl/iidm/Switch.hpp>
#include <powsybl/iidm/SynchronousComponentsManager.hpp>
#include <powsybl/iidm/TopologyVisitor.hpp>
#include <powsybl/stdcxx/cast.hpp>
#include <powsybl/stdcxx/math.hpp>
#include <powsybl/stdcxx/upcast.hpp>

#include "NodeBreakerVoltageLevel.hpp"
#include "NodeTerminal.hpp"
Expand Down
2 changes: 1 addition & 1 deletion src/iidm/ConfiguredBus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
#include <powsybl/iidm/SynchronousComponentsManager.hpp>
#include <powsybl/iidm/TopologyVisitor.hpp>
#include <powsybl/iidm/ValidationUtils.hpp>
#include <powsybl/stdcxx/cast.hpp>
#include <powsybl/stdcxx/format.hpp>
#include <powsybl/stdcxx/math.hpp>
#include <powsybl/stdcxx/memory.hpp>
#include <powsybl/stdcxx/upcast.hpp>

#include "BusBreakerVoltageLevel.hpp"
#include "BusTerminal.hpp"
Expand Down
2 changes: 1 addition & 1 deletion src/iidm/NodeBreakerVoltageLevelViews.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#include <powsybl/iidm/BusbarSection.hpp>
#include <powsybl/iidm/Switch.hpp>
#include <powsybl/stdcxx/upcast.hpp>
#include <powsybl/stdcxx/cast.hpp>

#include "CalculatedBus.hpp"
#include "NodeBreakerVoltageLevel.hpp"
Expand Down
1 change: 1 addition & 0 deletions test/stdcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

set(UNIT_TEST_SOURCES
stdcxx.cpp
CastTest.cpp
DateTimeTest.cpp
DemangleTest.cpp
MathTest.cpp
Expand Down
84 changes: 84 additions & 0 deletions test/stdcxx/CastTest.cpp
Original file line number Diff line number Diff line change
@@ -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 <memory>

#include <boost/test/unit_test.hpp>

#include <powsybl/stdcxx/cast.hpp>
#include <powsybl/stdcxx/make_unique.hpp>

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<BaseClass> basePtr = stdcxx::make_unique<DerivedClass>();
BOOST_CHECK_EQUAL(1, basePtr->getBaseAttr());
basePtr->setBaseAttr(11);
BOOST_CHECK_EQUAL(11, basePtr->getBaseAttr());

std::unique_ptr<DerivedClass> derivedPtr = stdcxx::downcast<DerivedClass>(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<BaseClass> otherBasePtr = stdcxx::upcast<BaseClass>(derivedPtr);
BOOST_CHECK(!derivedPtr);
BOOST_CHECK_EQUAL(111, otherBasePtr->getBaseAttr());
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace stdcxx

0 comments on commit 9df6b24

Please sign in to comment.