Regina - Moving from 6.x to 7.0

This page relates only to C++ and Python programmers.

Over time, Regina makes changes and improvements to its C++ and Python interfaces. This page explains how you will need to update your C++ code and/or Python scripts to work with Regina 7.0 and later.

Now that Regina 7.0 is available, you should also read the separate page:

If you have older code (from 2020 or earlier), you can also read the separate pages on:

Changes from Regina 6.x to 7.0

First, you should read the summary of the major behavioural changes, available here online. This discusses some sweeping changes across the entire API, such as:

If you have not read that summary, you should stop and read it now before continuing here.

Beyond this, there are a few general rules that have been applied across the API:

Errors and "unsolved scenarios" used to be handled using null/zero/empty return values, or sometimes using optional "error arguments" (e.g., a bool pointer argument that would return success or failure). Now Regina handles such scenarios using std::optional and exceptions:

These notes above cover most of the widespread API changes. However, there are many additional changes to specific headers, classes, functions and constants. These are listed in the table below, along with suggestions for how you should change your code. Any changes in the behaviour of these routines or classes are noted in the comments column.

Deprecated code Replacement Comments
file/xml*.h All low-level XML parsing code is now private to Regina's engine, and so these XML parsing headers are no longer installed. The only public access to Regina's XML parsing code is via regina::open().
surfaces/*.h surface/*.h Renamed to match angle/*.h and hypersurface/*.h, which also use the singular (not the plural).
triangulation/homologicaldata.h triangulation/dim3/homologicaldata.h  
The old type registries have been removed. Normal surfaces and hypersurfaces no longer have different subclasses for different coordinate systems; instead each surface or hypersurface stores a NormalEncoding or HyperEncoding. Most of the remaining registry functionality is still available through virtual functions and/or the redesigned PacketInfo, NormalInfo and HyperInfo classes.
Since the move to C++17, these utilities have either become unnecessary or been replaced with simpler alternatives.
Classes, Enums and Type Aliases
AngleStructureVector Angle structures now hold their coordinates using a plain Vector<Integer>.
BitmaskLenN, for all N Bitmask1<uint8_t>, Bitmask1<uint16_t>, etc.  
CensusHits, CensusHitIterator std::list<CensusHit>, std::list<CensusHit>::const_iterator  
DiscSetTetData<T>::DataPtr DiscSetTetData<T>::Data*  
EnumConstraints ValidityConstraints This class has been completely redesigned (hence the rename); you will need to read the ValidityConstraints documentation before using it.
FuncDelete, FuncNew, FuncNewCopyPtr, FuncNewCopyRef, FuncNewCopyClonePtr C++ provides good alternatives for these nowadays.
GluingPermSearcher<3>::PurgeFlags regina::CensusPurge, regina::CensusPurgeFlags  
Handlebody (non-orientable case) The Handlebody class now only represents orientable handlebodies, since the non-orientable case was never fully implemented.
HyperInfo<coords> HyperInfo (non-templated) Most of the old templated HyperInfo functionality is now accessible through HyperEncoding(coords). The new non-templated HyperInfo class just has some descriptive name functions, accessible at both compile time and runtime.
L31Pillow TrivialTri The old L31Pillow is now one of the many ad-hoc cases handled by TrivialTri.
LessDeref Just use a lambda if you need to.
LightweightSequence<T>::SubsequenceCompareFirstPtr LightweightSequence<T>::SubsequenceCompareFirst This inner class has been significantly redesigned, and now works with containers whose keys are sequences (not pointers to sequences).
ListOnCall This class was not thread-safe, and did not add anything non-trivial.
LPConstraint...::Coefficients The interface for describing linear programming constraints has changed significantly. Typical users should not be affected, but do read the API docs if you are writing constraint classes of your own.
LPConstraintEuler LPConstraintEulerPositive  
Matrix<T>::Coefficient Matrix<T>::value_type  
NNativeLong NativeLong  
NormalInfo<coords> NormalInfo (non-templated) Most of the old templated NormalInfo functionality is now accessible through NormalEncoding(coords). The new non-templated NormalInfo class just has some descriptive name functions, accessible at both compile time and runtime.
NormalSurfaceVector, NormalHypersurfaceVector and subclasses Normal (hyper)surfaces now hold their coordinates using a plain Vector<LargeInteger>, and use a NormalEncoding or HyperEncoding to indicate the coordinate system and other details of the vector representation.
PacketInfo<...> PacketInfo (non-templated) Most of the old templated PacketInfo functionality is no longer necessary. The new non-templated class has just a single name() function, accessible at both compile time and runtime.
PDF Attachment This class now supports all kinds of file attachments (not just PDF documents).
Perm<4..7>::Code Perm<4..7>::Code1 This is an obsolete type of permutation code; you should rework your code to use second-generation codes instead.
Property<T> std::optional<T> or std::unique_ptr<T>, depending on your storage policy  
QitmaskLenN, for all N Qitmask1<uint8_t>, Qitmask1<uint16_t>, etc.  
Ray Vector<LargeInteger>  
Returns, ReturnsTraits  
SafePtr, SafePointeeBase Now that the packet tree uses std::shared_ptr, these classes are unnecessary.
SatBlockStarter, SatBlockStarterSearcher, SatBlockStarterSet SatRegion::find(), SatBlockModel The new routine SatRegion::find() is a simpler and more flexible replacement for the old SatBlockStarterSearcher infrastructure. Individual "model blocks" for starting a search now use SatBlockModel instead of SatBlockStarter.
SFSAltSet SFSAlt This class has had a significant redesign (hence the rename). Instead of creating an SFSAltSet, call the static function SFSAlt::altSet().
SFSpace::classType SFSpace::ClassType  
SigIsoList SigCensus::IsoList  
SnapPeaException as a base class for other SnapPea-related exception types The subclasses SnapPeaFatalError and SnapPeaMemoryFull now derive from standard C++ exception types.
SurfaceFilter as a concrete class that accepts all surfaces A default-constructed SurfaceFilterProperties SurfaceFilter is now an abstract base class, and you cannot instantiate it directly.
SurfaceFilterInfo<...> The various virtual functions in SurfaceFilter  
Triangulation<dim>::VertexIterator, etc.
auto or decltype(...)  
TritmaskN, for all N   These were not used at all, and did not support tritmasks of arbitrary length.
Vector<T>::Element Vector<T>::value_type  
Member Routines
AbelianGroup::addTorsionElement(), AbelianGroup::addTorsionElements() AbelianGroup::addTorsion() The new addTorsion() is much faster than these old deprecated routines.
AngleStructure::rawVector() AngleStructure::vector()  
AngleStructures::enumerate(), AngleStructures::enumerateTautDD() AngleStructures class constructor The new class constructor that performs this enumeration will not insert the new list into the packet tree, and will never start in a background thread.
Ban...::init() Class constructors The linear programming "ban constraint" classes have been redesigned, and the tableaux is now passed to the class constructor instead of a separate init() function.
CensusHit::next() Census hits are now returned in a std::list, and so the next() function is no longer relevant.
DoubleDescription::enumerateExtremalRays() DoubleDescription::enumerate()  
Example<3>::poincareHomologySphere() Example<3>::poincare()  
Face<dim, subdim>::buildLinkDetail() Face<dim, subdim>::buildLinkInclusion() This returns only an isomorphism; you can use buildLink() to fetch the corresponding triangulated link. The labelling option has been removed completely.
FaceEmbedding<dim, subdim> constructor that takes (simplex, face number) FaceEmbedding<dim, subdim> constructor that takes (simplex, embedding permutation) End users would typically not use these constructors, since FaceEmbedding objects are constructed for you as part of the triangulation skeleton.
FileInfo::type(), FileInfo::typeDescription() FileFormat::format(), FileFormat::formatDescription() This change reflects the fact that Regina now supports more than one generation of XML file format.
GlobalDirs::pythonLibs() Nothing has been installed to this path since Regina 5.0.
GluingPerms<dim>::facetPairing() GluingPerms<dim>::pairing()  
GluingPerms<dim>::gluingPerm() GluingPerms<dim>::perm()  
GluingPerms<dim>::inputError() The input stream constructor now throws an exception on error.
GluingPermSearcher<dim> enumeration functions The API for enumerating permutation sets has been significantly reorganised; see GluingPermSearcher<dim>::runSearch() for details.
GluingPermSearcher<dim> functions inherited from GluingPerms<dim> GluingPermSearcher<dim> no longer derives from GluingPerms<dim>. Instead, GluingPermSearcher<dim>::runSearch() will pass a GluingPerms<dim> reference to your callback function.
GluingPermSearcher<dim>::completePermSet() GluingPermSearcher<dim>::isComplete()  
GluingPermSearcher<dim>::inputError() The input stream constructor now throws an exception on error.
GluingPermSearcher<dim>::readTaggedData() GluingPermSearcher<dim>::fromTaggedData() This function now throws an exception on error instead of returning null.
GroupExpression::addStringFirst(), GroupExpression::addStringLast() GroupExpression::addTermFirst(string), GroupExpression::addTermLast(string)  
GroupExpression::toTeX() GroupExpression::tex()  
GroupExpression::writeText() GroupExpression::writeTextShort(...)  
GroupPresentation::intelligentSimplifyDetail(), GroupPresentation::smallCancellationDetail(), GroupPresentation::intelligentNielsenDetail(), GroupPresentation::homologicalAlignmentDetail(), GroupPresentation::prettyRewritingDetail() GroupPresentation::intelligentSimplify(), GroupPresentation::smallCancellation(), GroupPresentation::intelligentNielsen(), GroupPresentation::homologicalAlignment(), GroupPresentation::prettyRewriting() The "non-detail" versions of these functions now return a std::optional<HomGroupPresentation> instead of a bool.
GroupPresentation::toTeX() GroupPresentation::tex()  
Handlebody::handles() Handlebody::genus()  
Handlebody::isOrientable() The Handlebody class now only represents orientable handlebodies, and so this routine always returns true.
HilbertCD::enumerateHilbertBasis(), HilbertDual::enumerateHilbertBasis(), HilbertPrimal::enumerateHilbertBasis() HilbertCD::enumerate(), HilbertDual::enumerate(), HilbertPrimal::enumerate()  
HomGroupPresentation::composeWith() Multiplication operator (g * h)  
HomGroupPresentation::range() HomGroupPresentation::codomain() The function has not changed; it has simply been renamed to more accurately reflect what it returns.
HomMarkedAbelianGroup::range() HomMarkedAbelianGroup::codomain() The function has not changed; it has simply been renamed to more accurately reflect what it returns.
HomMarkedAbelianGroup::writeReducedMatrix() HomMarkedAbelianGroup::detail(), HomMarkedAbelianGroup::writeTextLong()  
LayeredSolidTorus::formsLayeredSolidTorusBase(), LayeredSolidTorus::formsLayeredSolidTorusTop() LayeredSolidTorus::recogniseFromBase(), LayeredSolidTorus::recogniseFromTop()  
Link::swapContents() Link::swap()  
LPData<...>::dump(), LPMatrix<...>::dump() The usual Output routines: str(), detail(), etc.  
LPInitialTableaux<...>::constraintsBroken() The LPInitialTableaux class constructor now throws an exception on such an error.
Manifold::homologyH1() Manifold::homology()  
Manifold::TeXName() Manifold::texName()  
MarkedAbelianGroup::equalTo() Equality operators (==, !=)  
MarkedAbelianGroup::M(), MarkedAbelianGroup::N(), MarkedAbelianGroup::boundaryMap(), MarkedAbelianGroup::writeAsBoundary() MarkedAbelianGroup::m(), MarkedAbelianGroup::n(), MarkedAbelianGroup::boundaryOf(), MarkedAbelianGroup::asBoundary()  
MarkedAbelianGroup::rankCC(), MarkedAbelianGroup::minNumberOfGenerators(), MarkedAbelianGroup::minNumberCycleGens() MarkedAbelianGroup::ccRank(), MarkedAbelianGroup::snfRank(), MarkedAbelianGroup::cycleRank()  
Matrix<T>::initialise() Constructor that takes a list of entries The initialise() function was only ever available through Python, not C++.
Matrix<T>::swapColumns() Matrix<T>::swapCols()  
Matrix<T>::writeMatrix() Matrix<T>::writeTextLong()  
Matrix2::Matrix2(const long[2][2]) Matrix2::Matrix2(long, long, long, long)  
Matrix2::operator =(const long[2][2]) matrix = Matrix2(a, b, c, d)  
ModelLinkGraph::swapContents() ModelLinkGraph::swap()  
NormalSurface::countCoords(), NormalHypersurface::countCoords() surface.vector().size()  
NormalSurface::orientedTriangles(), NormalSurface::orientedQuads(), NormalSurface::systemAllowsOriented() Regina 7.0 no longer supports transversely oriented normal surfaces; these will be reimplemented in a future release using a completely different suite of classes.
NormalSurface::sameSurface(), NormalHypersurface::sameSurface() Equality operators (==, !=)  
NormalSurface::systemAllowsAlmostNormal(), NormalSurface::systemAllowsSpun() NormalSurface::couldBeAlmostNormal(), NormalSurface::couldBeNonCompact()  
NormalSurface::rawVector(), NormalSurface::writeRawVector(), NormalHypersurface::rawVector(), NormalHypersurface::writeRawVector() NormalSurface::vector(), NormalHypersurface::vector()  
NormalSurfaces::allowsOriented() Regina 7.0 no longer supports transversely oriented normal surfaces; these will be reimplemented in a future release using a completely different suite of classes.
NormalSurfaces::allowsSpun() NormalSurfaces::allowsNonCompact()  
NormalSurfaces::enumerate(), NormalHypersurfaces::enumerate() NormalSurfaces and NormalHypersurfaces class constructors The class constructors throw exceptions on error instead of returning null, will not insert new lists into the packet tree, and will never start in a background thread.
NormalSurfaces::quadToStandard(), NormalSurfaces::quadOctToStandardAN(), NormalSurfaces::standardToQuad(), NormalSurfaces::standardANToQuadOct(), NormalSurfaces::filterForDisjointPairs(), NormalSurfaces::filterForLocallyCompatiblePairs(), NormalSurfaces::filterForPotentiallyIncompressible() NormalSurfaces class constructor that takes a NormalTransform argument The new class constructor will throw an exception on error instead of returning null, and will not insert the new list into the packet tree.
NormalSurfaces::writeAllSurfaces() NormalSurfaces::writeTextLong() or NormalSurfaces::detail()  
Packet::clone() Packet::cloneAsSibling() Renamed to emphasise that this function is not a plain copy operation, and might not succeed.
Packet::dependsOnParent(), Packet::isPacketEditable() There are no longer any packet types that depend on their parents, and so these routines always return false and true respectively.
Packet::firstTreePacket(const std::string&), Packet::nextTreePacket(const std::string&) Packet::firstTreePacket(PacketType), Packet::nextTreePacket(PacketType)  
Packet::isGrandparentOf() Packet::isAncestorOf()  
Packet::safeDelete() This is no longer required, since packets are managed exclusively by std::shared_ptr.
Marked final in Regina 7.0 to ensure it cannot be reimplemented
PacketListener::packetBeingDestroyed() The rename emphasises the fact that this is called when the destructor is already in progress.
PacketListener::unregisterFromAllPackets() PacketListener::unlisten()
PDF::savePDF() Attachment::save()
Perm<n> constructor that takes one or two C-style arrays Perm<n> constructor that takes a std::array  
Perm<n>::index(), Perm<n>::atIndex() Perm<n>::orderedSnIndex(), Perm<n>::orderedSn[]
Perm<4..7>::permCode(), Perm<4..7>::setPermCode(), Perm<4..7>::fromPermCode(), Perm<4..7>::isPermCode() Perm<4..7>::permCode1(), Perm<4..7>::setPermCode1(), Perm<4..7>::fromPermCode1(), Perm<4..7>::isPermCode1() These functions use an obsolete type of permutation code; you should rework your code to use second-generation codes instead.
Perm<n>::preImageOf() Perm<n>::pre()
Rational::doubleApproxCheck() Rational::doubleApprox() The doubleApprox() function now throws an exception if the rational is out of range.
Rational::TeX() Rational::tex()  
SatAnnulus::attachLST() member function SatAnnulus::attachLST() static function SatAnnulus now only allows const access to the triangulation, and so this has become a static function that takes additional non-const tetrahedron and permutation arguments.
SatBlock::nAnnuli() SatBlock::countAnnuli()  
SatBlock::isBlock...(), SatBlock::clone() and copy constructors, from SatBlock as well as its subclasses SatRegion::beginsRegion() SatBlock and its subclasses can only be created through larger recognition routines such as SatRegion::beginsRegion().
...::insertBlock(), from subclasses of SatBlock ...::model() The relevant subclasses of SatBlock now have a new model() routine, which returns a SatBlockModel by value.
SatBlock::setAdjacent(), SatBlock::transform() SatBlock and its subclasses are now read-only.
SatBlockSpec constructors SatBlockSpec now only supports move and swap operations, due to its new ownership semantics.
SatRegion::expand() All publicly accessible functions that create a SatRegion will expand it automatically.
SatRegion::numberOfBlocks(), SatRegion::numberOfBoundaryAnnuli() SatRegion::countBlocks(), SatRegion::countBoundaryAnnuli()  
SigCensus::run() SigCensus::formCensus() You can no longer create a SigCensus manually; instead you must use the static formCensus() routine.
Signature::cycleCmp() This is now a private member function, since it was very specialised.
Signature::parse() The string-based Signature constructor Now throws an exception on error, instead of returning null.
SnapPeaTriangulation::filledTriangulation() SnapPeaTriangulation::filledPartial() or SnapPeaTriangulation::filledAll() Instead of a polymorphic return type, these routines now have return types that are known precisely at compile time.
StandardTriangulation::homologyH1() StandardTriangulation::homology()  
StandardTriangulation::TeXName() StandardTriangulation::texName()  
Tangle::swapContents() Tangle::swap()  
TreeDecomposition constructor that takes a C-style array of adjacencies Constructor that takes a Matrix<bool> or a std::vector of rows  
TreeTraversal::constraintsBroken() The class constructor now throws an exception in this scenario.  
TreeTraversal::verify() Each variant of verify() just tested a single wmatrix multiplication, which you can perform yourself if necessary.
In Python, homology<k>() becomes homology(k). In both C++ and Python, homology() is an alias for homology<1>().
Triangulation<dim>::insertConstruction() Triangulation<dim>::fromGluings() The interface for fromGluings() is very different from insertConstruction(), but both have the same aim of allowing users to hard-code entire triangulations in code.
Triangulation<dim>::isIdenticalTo() a == b  
Triangulation<dim>::splitIntoComponents() Triangulation<dim>::triangulateComponents() The new triangulateComponents() routine does not create packets or interact with the packet tree at all.
Triangulation<dim>::swapContents() Triangulation<dim>::swap()  
Triangulation<3>::connectedSumDecomposition() Triangulation<3>::summands() The new summands() routine does not create packets or interact with the packet tree at all, and throws an exception on error.
Triangulation<3>::findStrictAngleStructure() Triangulation<3>::hasStrictAngleStructure(),
Call strictAngleStructure() only when you already know a solution exist, since it will throw an exception otherwise. If you do not know whether a solution exists, call hasStrictAngleStructure() first.
Combine with Triangulation<3>::insertTriangulation() if you need to insert one of these into an existing triangulation.
Triangulation<3>::insertRehydration() Triangulation<3>::rehydrate() Combine with Triangulation<3>::insertTriangulation() if you need to insert a rehydration into an existing triangulation.
Triangulation<3>::makeZeroEfficient() Triangulation<3>w::summands() The new summands() routine (which computes connected sum decompositions) now comes with formal guarantees of zero-efficiency.
TxICore::TeXName() TxICore::texName  
Vector<T>::setElement() vector[i] = value  
Vertex<3>::link() Vertex<3>::linkType() This was removed because link() will be used for a different purpose in a future release.
Global Routines
Class constants Face<dim, subdim>::allowsNonOrientableLinks, Face<dim, subdim>::allowsInvalidFaces  
basicTokenise(output_iterator, string) basicTokenise(string) The tokens are now returned by value as a std::vector of strings.
clonePtr() Class copy constructors  
duplicate() ::strdup()  
forCoords(), forFilter(), forPacket() The old type registries have been removed. Normal surfaces and hypersurfaces no longer have different subclasses for different coordinate systems; instead each surface or hypersurface stores a NormalEncoding or HyperEncoding. Most of the remaining registry functionality is still available through virtual functions and/or the redesigned PacketInfo, NormalInfo and HyperInfo classes.
formSigCensus() SigCensus::formCensus The new function uses a typesafe template-based mechanism instead of function pointers and void* arguments.
makeZeroVector() Class constructor Vector<T>(len)  
readIsoSigList() readSigList<ObjectType>() Instead of passing a dimension at runtime, you should set the ObjectType template parameter to be Triangulation<dim> or Link.
valueOf(str, Integer&),
valueOf(str, LargeInteger&),
where str is a string
integer = str Errors are detected via exceptions, instead of using a boolean return value.
Class Constants
BoolSet::sNone, BoolSet::sTrue, BoolSet::sFalse, BoolSet::sBoth BoolSet(), true, false, BoolSet(true, true)  
DiscType::NONE DiscType()  
FileInfo::TYPE_XML REGINA_XML_GEN_1 or REGINA_XML_GEN_2, from the new FileFormat enum type This change reflects the fact that Regina now supports more than one generation of XML file format.
GluingPermSearcher<dim>::dataTag_ (also in subclasses) ...::dataTag  
Perm<n>::invSk Perm<k>::inverse() For those k that had inverse lookup tables, the inverse() functions are just as fast.
0, 1, -1  
Global Constants
NS_FILTER_DEFAULT NS_FILTER_LEGACY_DEFAULT The corresponding class SurfaceFilter is now an abstract base class, and can no longer be instantiated directly.
These are now arrays, not macros, and so the syntax has changed.
Only affects C++, not Python.

Back to main page ... Back to main page ...