API — ICoreEssentials/Geometry
The public contract of 2 header(s) under src/ICoreEssentials/Geometry — 2 class/struct definition(s), 39 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
| Header | Defines | Declarations | Bases |
|---|---|---|---|
ICorePoint.h | ICorePoint | 19 | — |
ICoreRect.h | ICoreRect | 20 | — |
ICorePoint.h#
src/ICoreEssentials/Geometry/ICorePoint.h
ICorePoint#
ICorePoint.h:114 · class · 19 declaration(s)
ICorePoint -- a coordinate in the MODEL, not on a screen.
class ICorePoint {
public:
// ⚠ THE STORAGE IS AN OPAQUE BUFFER (H1.9, 2026-08-14) holding two plain
// doubles this project owns -- there is no Qt type inside, and never was
// since B28. 16 bytes / align 8.
//
// Like ICoreChar, this type declares NONE of the five special members and
// stays TRIVIALLY COPYABLE: the state is two doubles, so the implicit copy
// is a 16-byte memcpy and it is correct. That is load-bearing rather than
// tidy. A point is passed and returned BY VALUE at 146 call sites and in
// every arithmetic operator below; a user-declared copy constructor would
// stop it travelling in registers at all of them, which is exactly the cost
// this rollout is not supposed to add to a 16-byte value.
//
// The .cpp static_asserts the size, the alignment and both trivialities, so
// a future change that breaks the assumption is a build error.
static constexpr std::size_t kNativeStorageSize = 16;
static constexpr std::size_t kNativeStorageAlign = 8;
// Default-constructs to (0, 0), matching QPointF. Several call sites rely
// on it -- `const ICorePoint& offset = ICorePoint()` is the "no offset"
// default of ICoreRecipeFileTransfer::importRecipeText and of
// ICoreTemplateLibrary::instantiate.
//
// ⚠ NOT `= default` any more: a defaulted default constructor would leave
// the buffer uninitialised, where the two members it replaced carried
// `= 0.0` initialisers. That would turn "no offset" into garbage.
ICorePoint();
ICorePoint(double x, double y);
// Implicit -- see the design note. This is how a coordinate arrives from
// the screen side (QGraphicsItem::pos(), a QRectF corner, a port's
// connection coordinates) and becomes a model coordinate.
ICorePoint(const QPointF& p);
// EXPLICIT -- see the design note. Qt already converts QPoint -> QPointF,
// so an implicit one here would tie against Qt's own overloads.
explicit ICorePoint(const QPoint& p);
double x() const noexcept;
double y() const noexcept;
void setX(double x) noexcept;
void setY(double y) noexcept;
// EXACT, matching qIsNull -- see the second warning in the header note.
bool isNull() const noexcept;
// Arithmetic as members -- see the design note. The right operand accepts a
// QPointF too, through the implicit constructor above, which is what lets a
// migrated expression mix with an unmigrated screen-side getter without a
// cast: `offset + anchor->pos()`.
ICorePoint operator+(const ICorePoint& o) const;
ICorePoint operator-(const ICorePoint& o) const;
ICorePoint operator*(double f) const;
// The assert is QPointF::operator/'s own precondition (qpoint.h:215,
// Q_ASSERT(!qFuzzyIsNull(c))), kept rather than quietly dropped: this is a
// Debug build, so removing it would turn a diagnosed division by zero into
// a silent infinity -- a behaviour change smuggled in under a storage swap.
ICorePoint operator/(double d) const;
ICorePoint operator-() const;
ICorePoint& operator+=(const ICorePoint& o);
ICorePoint& operator-=(const ICorePoint& o);
// FUZZY, reproducing QPointF exactly -- see the header note. Do not
// "simplify" these to == ; the differential test will fail, which is what
// it is for.
bool operator==(const ICorePoint& o) const noexcept;
bool operator!=(const ICorePoint& o) const noexcept;
// Named accessor, NOT a conversion operator -- see the design note. Every
// use of it is a model coordinate crossing to the screen side, and it is
// meant to be visible.
//
// Returns BY VALUE now; it used to return `const QPointF&` into the member,
// and that reference is precisely what a storage swap cannot honour. All 20
// call sites were audited first and every one consumes the result
// immediately as a function argument (offsetPosition, optimizePath,
// translateBranch, addCornerAtEnd, push_back, mapToGlobal), so none was
// binding it to a stored reference. A QPointF is 16 bytes, so the copy is
// free; the audit, not the size, is what made this safe.
QPointF toQPointF() const noexcept;
};
ICoreRect.h#
src/ICoreEssentials/Geometry/ICoreRect.h
ICoreRect#
ICoreRect.h:56 · class · 20 declaration(s)
ICoreRect -- an axis-aligned area in the MODEL, not on a screen.
class ICoreRect {
public:
// ⚠ THE STORAGE IS AN OPAQUE BUFFER (H1.8, 2026-08-14) holding four plain
// doubles this project owns -- no Qt type is inside, and none has been
// since B28. 32 bytes / align 8.
//
// As with ICorePoint, this type declares NONE of the five special members
// and stays TRIVIALLY COPYABLE, because the state is four doubles and the
// implicit copy is a correct 32-byte memcpy. The .cpp static_asserts the
// size, the alignment and both trivialities.
static constexpr std::size_t kNativeStorageSize = 32;
static constexpr std::size_t kNativeStorageAlign = 8;
// Default-constructs to a null rect, matching QRectF.
//
// ⚠ NOT `= default`: that would leave the buffer uninitialised, where the
// four members it replaced carried `= 0.0` initialisers.
ICoreRect();
ICoreRect(double x, double y, double w, double h);
// Implicit -- an area always arrives from the screen side. See ICorePoint.h.
ICoreRect(const QRectF& r);
// EXPLICIT -- Qt already converts QRect -> QRectF. See the design note.
// width()/height() rather than right()-left()+1: QRectF's own QRect
// constructor (qrect.h:678) spells it the second way and the two are
// identical, since QRect::right() is x+w-1.
explicit ICoreRect(const QRect& r);
// QRectF's edge convention, NOT QRect's: right() is x + width, with no
// -1 anywhere (qrect.h:524). Getting this wrong is the classic QRect/QRectF
// confusion and would move every edge by one unit.
double left() const noexcept;
double right() const noexcept;
double top() const noexcept;
double bottom() const noexcept;
double width() const noexcept;
double height() const noexcept;
ICorePoint topLeft() const;
ICorePoint bottomLeft() const;
ICorePoint topRight() const;
ICorePoint bottomRight() const;
ICorePoint center() const;
// QRectF::contains, reproduced: edge-INCLUSIVE, and false for any rect with
// a zero extent in either axis even when the point sits exactly on it. The
// negative-extent handling is why this is not simply four comparisons -- a
// rect built by a drag up-and-left has negative width until it is
// normalized(), and it still has to contain the points it visually covers.
bool contains(const ICorePoint& p) const noexcept;
// EXACT, like ICorePoint::isNull and unlike ICorePoint::operator==
// (qrect.h:686). A rect is null when BOTH extents are zero -- note that
// this is not isEmpty(), which Qt defines as either extent <= 0 and which
// has no call site here.
bool isNull() const noexcept;
// The two transforms that genuinely produce a new area. normalized() is
// what a drag rectangle needs (the user may drag up and left); adjusted()
// is the snap threshold around a tab bar.
ICoreRect normalized() const;
// qrect.h:841 -- note the width term is w + x2 - x1, not w + x2.
ICoreRect adjusted(double dx1, double dy1, double dx2, double dy2) const;
ICoreRect translated(const ICorePoint& offset) const;
// NOTHING CONVERTS OUT. ICorePoint keeps a toQPointF() because 20 call
// sites hand a point to an StudioObjects-declared sink; a rect never
// crosses that boundary, so the accessor this file used to carry had no
// caller at all and was deleted (Rule 3). That is what made B28's swap
// free of call-site risk on this half: the Qt member was reachable
// from nowhere outside the class, so replacing it changed no signature.
};