Improve dcast
* document `dcast` * make `dcast` not only cast exact, but also upwards * add `dcast` test * rename `dcast` -> `dynamicCast`
This commit is contained in:
@@ -92,18 +92,25 @@ public:
|
||||
virtual void accept(ConstModelVisitor& v) const = 0;
|
||||
|
||||
public:
|
||||
//! Return this class casted to Target, or nullptr if impossible
|
||||
/**
|
||||
@brief Return this class casted to Target
|
||||
@test AutomatableModelTest.cpp
|
||||
@param doThrow throw an assertion if the cast fails, instead of
|
||||
returning a nullptr
|
||||
@return the casted class if Target is the exact or a base class of
|
||||
*this, nullptr otherwise
|
||||
*/
|
||||
template<class Target>
|
||||
Target* dcast(bool doThrow = false)
|
||||
Target* dynamicCast(bool doThrow = false)
|
||||
{
|
||||
DCastVisitor<Target> vis; accept(vis);
|
||||
if(doThrow && !vis.result) Q_ASSERT(false);
|
||||
return vis.result;
|
||||
}
|
||||
|
||||
//! Return this class casted to const Target, or nullptr if impossible
|
||||
//! const overload, see overloaded function
|
||||
template<class Target>
|
||||
const Target* dcast(bool doThrow = false) const
|
||||
const Target* dynamicCast(bool doThrow = false) const
|
||||
{
|
||||
ConstDCastVisitor<Target> vis; accept(vis);
|
||||
if(doThrow && !vis.result) Q_ASSERT(false);
|
||||
@@ -312,6 +319,7 @@ protected:
|
||||
|
||||
|
||||
private:
|
||||
// dynamicCast implementation
|
||||
template<class Target>
|
||||
struct DCastVisitor : public ModelVisitor
|
||||
{
|
||||
@@ -319,6 +327,7 @@ private:
|
||||
void visit(Target& tar) { result = &tar; }
|
||||
};
|
||||
|
||||
// dynamicCast implementation
|
||||
template<class Target>
|
||||
struct ConstDCastVisitor : public ConstModelVisitor
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef MODELVISITOR_H
|
||||
#define MODELVISITOR_H
|
||||
|
||||
class AutomatableModel;
|
||||
class BoolModel;
|
||||
class IntModel;
|
||||
class FloatModel;
|
||||
@@ -32,21 +33,28 @@ class ComboBoxModel;
|
||||
|
||||
class ModelVisitor
|
||||
{
|
||||
template<class ParentType = AutomatableModel, class ModelType>
|
||||
void up(ModelType& m) { visit(static_cast<ParentType&>(m)); }
|
||||
public:
|
||||
virtual void visit(BoolModel& ) {}
|
||||
virtual void visit(IntModel& ) {}
|
||||
virtual void visit(FloatModel& ) {}
|
||||
virtual void visit(ComboBoxModel& ) {}
|
||||
virtual void visit(AutomatableModel& ) {}
|
||||
virtual void visit(BoolModel& m);
|
||||
virtual void visit(IntModel& );
|
||||
virtual void visit(FloatModel& );
|
||||
virtual void visit(ComboBoxModel& );
|
||||
virtual ~ModelVisitor();
|
||||
};
|
||||
|
||||
class ConstModelVisitor
|
||||
{
|
||||
template<class ParentType = AutomatableModel, class ModelType>
|
||||
void up(const ModelType& m) {
|
||||
visit(static_cast<const ParentType&>(m)); }
|
||||
public:
|
||||
virtual void visit(const BoolModel& ) {}
|
||||
virtual void visit(const IntModel& ) {}
|
||||
virtual void visit(const FloatModel& ) {}
|
||||
virtual void visit(const ComboBoxModel& ) {}
|
||||
virtual void visit(const AutomatableModel& ) {}
|
||||
virtual void visit(const BoolModel& m);
|
||||
virtual void visit(const IntModel& m);
|
||||
virtual void visit(const FloatModel& m);
|
||||
virtual void visit(const ComboBoxModel& m);
|
||||
virtual ~ConstModelVisitor();
|
||||
};
|
||||
|
||||
|
||||
@@ -24,5 +24,18 @@
|
||||
|
||||
#include "ModelVisitor.h"
|
||||
|
||||
#include "AutomatableModel.h"
|
||||
#include "ComboBoxModel.h"
|
||||
|
||||
void ModelVisitor::visit(BoolModel &m) { up(m); }
|
||||
void ModelVisitor::visit(IntModel &m) { up(m); }
|
||||
void ModelVisitor::visit(FloatModel &m) { up(m); }
|
||||
void ModelVisitor::visit(ComboBoxModel &m) { up<IntModel>(m); }
|
||||
|
||||
void ConstModelVisitor::visit(const BoolModel &m) { up(m); }
|
||||
void ConstModelVisitor::visit(const IntModel &m) { up(m); }
|
||||
void ConstModelVisitor::visit(const FloatModel &m) { up(m); }
|
||||
void ConstModelVisitor::visit(const ComboBoxModel &m) { up<IntModel>(m); }
|
||||
|
||||
ModelVisitor::~ModelVisitor() {}
|
||||
ConstModelVisitor::~ConstModelVisitor() {}
|
||||
|
||||
@@ -14,6 +14,7 @@ ADD_EXECUTABLE(tests
|
||||
QTestSuite
|
||||
$<TARGET_OBJECTS:lmmsobjs>
|
||||
|
||||
src/core/AutomatableModelTest.cpp
|
||||
src/core/ProjectVersionTest.cpp
|
||||
src/core/RelativePathsTest.cpp
|
||||
|
||||
|
||||
53
tests/src/core/AutomatableModelTest.cpp
Normal file
53
tests/src/core/AutomatableModelTest.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* AutomatableModelTest.cpp
|
||||
*
|
||||
* Copyright (c) 2019-2019 Johannes Lorenz <j.git$$$lorenz-ho.me, $$$=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "QTestSuite.h"
|
||||
|
||||
#include "AutomatableModel.h"
|
||||
#include "ComboBoxModel.h"
|
||||
|
||||
class AutomatableModelTest : QTestSuite
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void CastTests()
|
||||
{
|
||||
ComboBoxModel comboModel;
|
||||
AutomatableModel* amPtr = &comboModel;
|
||||
QCOMPARE(nullptr, amPtr->dynamicCast<FloatModel>());
|
||||
QVERIFY(nullptr != amPtr->dynamicCast<AutomatableModel>());
|
||||
QVERIFY(nullptr != amPtr->dynamicCast<IntModel>());
|
||||
QVERIFY(nullptr != amPtr->dynamicCast<ComboBoxModel>());
|
||||
|
||||
IntModel intModel;
|
||||
IntModel* imPtr = &intModel;
|
||||
QCOMPARE(nullptr, imPtr->dynamicCast<FloatModel>());
|
||||
QVERIFY(nullptr != imPtr->dynamicCast<AutomatableModel>());
|
||||
QVERIFY(nullptr != imPtr->dynamicCast<IntModel>());
|
||||
QCOMPARE(nullptr, imPtr->dynamicCast<ComboBoxModel>());
|
||||
}
|
||||
} AutomatableModelTests;
|
||||
|
||||
#include "AutomatableModelTest.moc"
|
||||
Reference in New Issue
Block a user