Skip to content

Commit

Permalink
Add qgsgeometry_cast
Browse files Browse the repository at this point in the history
Because it
- is faster than dynamic_cast
- doesn't rely on RTTI
- encapsulates type checking in one place
  • Loading branch information
m-kuhn committed Aug 12, 2017
1 parent 5fd19d5 commit a6800d6
Show file tree
Hide file tree
Showing 23 changed files with 301 additions and 55 deletions.
25 changes: 13 additions & 12 deletions python/core/geometry/qgsabstractgeometry.sip
Expand Up @@ -28,29 +28,29 @@ class QgsAbstractGeometry
%ConvertToSubClassCode
if ( dynamic_cast<QgsPoint *>( sipCpp ) != NULL )
sipType = sipType_QgsPoint;
else if ( dynamic_cast<QgsLineString *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsLineString *>( sipCpp ) != NULL )
sipType = sipType_QgsLineString;
else if ( dynamic_cast<QgsCircularString *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsCircularString *>( sipCpp ) != NULL )
sipType = sipType_QgsCircularString;
else if ( dynamic_cast<QgsCompoundCurve *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsCompoundCurve *>( sipCpp ) != NULL )
sipType = sipType_QgsCompoundCurve;
else if ( dynamic_cast<QgsTriangle *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsTriangle *>( sipCpp ) != NULL )
sipType = sipType_QgsTriangle;
else if ( dynamic_cast<QgsPolygonV2 *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsPolygonV2 *>( sipCpp ) != NULL )
sipType = sipType_QgsPolygonV2;
else if ( dynamic_cast<QgsCurvePolygon *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsCurvePolygon *>( sipCpp ) != NULL )
sipType = sipType_QgsCurvePolygon;
else if ( dynamic_cast<QgsMultiPointV2 *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiPointV2 *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiPointV2;
else if ( dynamic_cast<QgsMultiLineString *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiLineString *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiLineString;
else if ( dynamic_cast<QgsMultiPolygonV2 *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiPolygonV2 *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiPolygonV2;
else if ( dynamic_cast<QgsMultiSurface *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiSurface *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiSurface;
else if ( dynamic_cast<QgsMultiCurve *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiCurve *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiCurve;
else if ( dynamic_cast<QgsGeometryCollection *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsGeometryCollection *>( sipCpp ) != NULL )
sipType = sipType_QgsGeometryCollection;
else
sipType = 0;
Expand Down Expand Up @@ -527,6 +527,7 @@ struct QgsVertexId
VertexType type;
};


/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgscurve.sip
Expand Up @@ -156,6 +156,7 @@ class QgsCurve: QgsAbstractGeometry
%End



protected:

virtual void clearCache() const;
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgsgeometrycollection.sip
Expand Up @@ -141,6 +141,7 @@ Adds a geometry and takes ownership. Returns true in case of success.
virtual bool dropZValue();
virtual bool dropMValue();


protected:

virtual bool wktOmitChildType() const;
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgsmulticurve.sip
Expand Up @@ -49,6 +49,7 @@ Adds a geometry and takes ownership. Returns true in case of success

virtual QgsAbstractGeometry *boundary() const /Factory/;


};

/************************************************************************
Expand Down
2 changes: 2 additions & 0 deletions python/core/geometry/qgsmultisurface.sip
Expand Up @@ -42,6 +42,8 @@ Adds a geometry and takes ownership. Returns true in case of success
%End

virtual QgsAbstractGeometry *boundary() const /Factory/;


};

/************************************************************************
Expand Down
36 changes: 22 additions & 14 deletions src/core/geometry/qgsabstractgeometry.h
Expand Up @@ -53,31 +53,31 @@ class CORE_EXPORT QgsAbstractGeometry

#ifdef SIP_RUN
SIP_CONVERT_TO_SUBCLASS_CODE
if ( dynamic_cast<QgsPoint *>( sipCpp ) != NULL )
if ( qgsgeometry_cast<QgsPoint *>( sipCpp ) != NULL )
sipType = sipType_QgsPoint;
else if ( dynamic_cast<QgsLineString *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsLineString *>( sipCpp ) != NULL )
sipType = sipType_QgsLineString;
else if ( dynamic_cast<QgsCircularString *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsCircularString *>( sipCpp ) != NULL )
sipType = sipType_QgsCircularString;
else if ( dynamic_cast<QgsCompoundCurve *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsCompoundCurve *>( sipCpp ) != NULL )
sipType = sipType_QgsCompoundCurve;
else if ( dynamic_cast<QgsTriangle *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsTriangle *>( sipCpp ) != NULL )
sipType = sipType_QgsTriangle;
else if ( dynamic_cast<QgsPolygonV2 *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsPolygonV2 *>( sipCpp ) != NULL )
sipType = sipType_QgsPolygonV2;
else if ( dynamic_cast<QgsCurvePolygon *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsCurvePolygon *>( sipCpp ) != NULL )
sipType = sipType_QgsCurvePolygon;
else if ( dynamic_cast<QgsMultiPointV2 *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiPointV2 *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiPointV2;
else if ( dynamic_cast<QgsMultiLineString *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiLineString *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiLineString;
else if ( dynamic_cast<QgsMultiPolygonV2 *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiPolygonV2 *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiPolygonV2;
else if ( dynamic_cast<QgsMultiSurface *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiSurface *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiSurface;
else if ( dynamic_cast<QgsMultiCurve *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsMultiCurve *>( sipCpp ) != NULL )
sipType = sipType_QgsMultiCurve;
else if ( dynamic_cast<QgsGeometryCollection *>( sipCpp ) != NULL )
else if ( qgsgeometry_cast<QgsGeometryCollection *>( sipCpp ) != NULL )
sipType = sipType_QgsGeometryCollection;
else
sipType = 0;
Expand Down Expand Up @@ -132,7 +132,7 @@ class CORE_EXPORT QgsAbstractGeometry
* \see geometryType
* \see wktTypeStr
*/
QgsWkbTypes::Type wkbType() const { return mWkbType; }
inline QgsWkbTypes::Type wkbType() const { return mWkbType; }

/** Returns the WKT type string of the geometry.
* \see geometryType
Expand Down Expand Up @@ -490,4 +490,12 @@ struct CORE_EXPORT QgsVertexId
VertexType type;
};

#ifndef SIP_RUN
template <class T>
inline T qgsgeometry_cast( const QgsAbstractGeometry *geom )
{
return const_cast<T>( reinterpret_cast<T>( 0 )->cast( geom ) );
}
#endif

#endif //QGSABSTRACTGEOMETRYV2
16 changes: 16 additions & 0 deletions src/core/geometry/qgscircularstring.h
Expand Up @@ -114,6 +114,22 @@ class CORE_EXPORT QgsCircularString: public QgsCurve

double xAt( int index ) const override;
double yAt( int index ) const override;
#ifndef SIP_RUN

/**
* Cast the \a geom to a QgsCircularString.
* Should be used by qgsgeometry_cast<QgsCircularString *>( geometry ).
*
* \note Not available in Python. Objects will be automatically be converted to the appropriate target type.
* \since QGIS 3.0
*/
inline const QgsCircularString *cast( const QgsAbstractGeometry *geom ) const
{
if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::CircularString )
return static_cast<const QgsCircularString *>( geom );
return nullptr;
}
#endif

protected:

Expand Down
2 changes: 1 addition & 1 deletion src/core/geometry/qgscompoundcurve.cpp
Expand Up @@ -37,7 +37,7 @@ QgsCompoundCurve::~QgsCompoundCurve()

bool QgsCompoundCurve::operator==( const QgsCurve &other ) const
{
const QgsCompoundCurve *otherCurve = dynamic_cast< const QgsCompoundCurve * >( &other );
const QgsCompoundCurve *otherCurve = qgsgeometry_cast< const QgsCompoundCurve * >( &other );
if ( !otherCurve )
return false;

Expand Down
16 changes: 16 additions & 0 deletions src/core/geometry/qgscompoundcurve.h
Expand Up @@ -126,6 +126,22 @@ class CORE_EXPORT QgsCompoundCurve: public QgsCurve

double xAt( int index ) const override;
double yAt( int index ) const override;
#ifndef SIP_RUN

/**
* Cast the \a geom to a QgsCompoundCurve.
* Should be used by qgsgeometry_cast<QgsCompoundCurve *>( geometry ).
*
* \note Not available in Python. Objects will be automatically be converted to the appropriate target type.
* \since QGIS 3.0
*/
inline const QgsCompoundCurve *cast( const QgsAbstractGeometry *geom ) const
{
if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::CompoundCurve )
return static_cast<const QgsCompoundCurve *>( geom );
return nullptr;
}
#endif

protected:

Expand Down
20 changes: 20 additions & 0 deletions src/core/geometry/qgscurve.h
Expand Up @@ -134,6 +134,26 @@ class CORE_EXPORT QgsCurve: public QgsAbstractGeometry
*/
QPolygonF asQPolygonF() const;

#ifndef SIP_RUN

/**
* Cast the \a geom to a QgsCurve.
* Should be used by qgsgeometry_cast<QgsCurve *>( geometry ).
*
* \note Not available in Python. Objects will be automatically be converted to the appropriate target type.
* \since QGIS 3.0
*/
inline const QgsCurve *cast( const QgsAbstractGeometry *geom ) const
{
QgsWkbTypes::Type type = geom->wkbType();
if ( geom && QgsWkbTypes::geometryType( type ) == QgsWkbTypes::LineGeometry && QgsWkbTypes::isSingleType( type ) )
{
return static_cast<const QgsCurve *>( geom );
}
return nullptr;
}
#endif


protected:

Expand Down
16 changes: 16 additions & 0 deletions src/core/geometry/qgscurvepolygon.h
Expand Up @@ -140,6 +140,22 @@ class CORE_EXPORT QgsCurvePolygon: public QgsSurface
virtual bool dropZValue() override;
virtual bool dropMValue() override;

#ifndef SIP_RUN

/**
* Cast the \a geom to a QgsCurvePolygon.
* Should be used by qgsgeometry_cast<QgsCurvePolygon *>( geometry ).
*
* \note Not available in Python. Objects will be automatically be converted to the appropriate target type.
* \since QGIS 3.0
*/
inline const QgsCurvePolygon *cast( const QgsAbstractGeometry *geom ) const
{
if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::CurvePolygon )
return static_cast<const QgsCurvePolygon *>( geom );
return nullptr;
}
#endif
protected:

QgsCurve *mExteriorRing = nullptr;
Expand Down

0 comments on commit a6800d6

Please sign in to comment.