From b0b65e550c188f531aee6796b384227d88b88401 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Fri, 23 Aug 2024 20:36:47 +0200 Subject: [PATCH] dispatch_curve_creation based on template magic instead of dynamic casting --- src/ifcgeom/AbstractKernel.h | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ifcgeom/AbstractKernel.h b/src/ifcgeom/AbstractKernel.h index 26d6f090b8..87a6e4d623 100644 --- a/src/ifcgeom/AbstractKernel.h +++ b/src/ifcgeom/AbstractKernel.h @@ -102,14 +102,27 @@ namespace { } }; + template + struct TupleTypeIndex; + + template + struct TupleTypeIndex> { + static const std::size_t value = 0; + }; + + template + struct TupleTypeIndex> { + static const std::size_t value = 1 + TupleTypeIndex>::value; + }; + /* A compile-time for loop over the curve kinds */ template struct dispatch_curve_creation { static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr item, T& visitor) { - // @todo it should be possible to eliminate this dynamic_cast when there is a static equivalent to kind() - auto v = ifcopenshell::geometry::taxonomy::template dcast>(item); - if (v && item->kind() == v->kind()) { - visitor(v); + constexpr auto KindIndex = TupleTypeIndex, ifcopenshell::geometry::taxonomy::impl::KindsTuple>::value; + if (item->kind() == KindIndex) { + auto concrete_item = ifcopenshell::geometry::taxonomy::template cast>(item); + visitor(concrete_item); return true; } else { return dispatch_curve_creation::dispatch(item, visitor);