STL (Standard Template Library... and Beyond!)
๐ A highly-versatile, performance-driven bank of data collections, structures, and algorithmic ranges for the Dart and Flutter ecosystem.
๐ ๏ธ Quick Install
dart pub add stl
or for Flutter:
flutter pub add stl
๐ Support the Project
If you find stl heavily supercharging your Dart architecture, please consider leaving a Like ๐ on pub.dev and a Star โญ on GitHub. It massively fuels the continuous development of this library!
๐ The Vision
Originally inspired by the strict blueprints of the C++ Standard Template Library (STL), this package has heavily evolved into a comprehensive bank of diverse collections for all your data structure needs. Whether you require familiar sequential containers, complex associative maps, specialized utility adapters, or bleeding-edge C++23 functional ranges, stl drastically supercharges your Dart architecture! โจ
๐ฏ Why use this package over standard Dart tools?
- ๐ฆ Massive Bank of Collections: Unlock custom abilities via
Vector,Deque,Stack,ForwardList, and more! - ๐ Next-Gen Iteration: Introducing Ranges! Seamlessly generate subsets, zips, Cartesian products, and infinite loops on the fly without breaking your memory limit.
- โก Deterministic Performance: Predictable time complexity ($O(1)$, $O(\log n)$, etc.) with heavily optimized system-level logic.
- ๐ Familiar yet Dart-y API: Native
Iterablemixins seamlessly integrated with perfectly replicated C++ architectural rules, wrapped cleanly in standard DartcamelCasefor maximum ecosystem interoperability. - ๐จ Ready for Everything: Perfect for logic-heavy Flutter apps, scalable game engines, dynamic state management, or enterprise backend systems.
๐ The Standard Library Bank
Instead of strictly separating containers, mathematics, and utilities, here is a taste of the massively diverse types available natively in stl. The library is heavily integrated, so these types interact with each other seamlessly!
| Type | Category | Description |
|---|---|---|
๐ Vector<T> |
Dynamic array with contiguous memory behavior, strict bounds checking, and powerful modifiers. | |
๐ Point |
Represents an exact 2D coordinate (x, y) in Euclidean space utilizing precise vector math. |
|
๐ฏ Pair<T1, T2> |
Native C++ utility structure to hold heterogeneous objects. Features gorgeous Dart 3 Record translation. | |
๐ข I8 -> I64 |
Zero-cost signed integer wrappers. Provides automatic arithmetic wrap-around and strict bounds. | |
๐งต <string> |
Advanced text processing, Regex wrapper, $O(N+M)$ search algorithms (KMP, Boyer-Moore), and std::format string templating. |
|
๐งฎ cmath |
Missing mathematically safe operations including clamp(), lerp(), and overflow-safe robust hypot() updated with over 100 new functions as part of the project target-200. |
|
๐บ๏ธ HashMap<K, V> |
Unordered key-value map utilizing a fast hash table under the hood, matching std::unordered_map. |
|
โญ Circle |
Computes absolute Pi area boundaries natively supporting affine transformations via CRTP. | |
๐ <algorithm> |
Brings lowerBound(), rotate(), nextPermutation(), foldLeft(), foldRight(), findLast(), startsWith(), endsWith(), contains() and more. Now 70+ functions. |
|
๐ญ Deque<T> |
Double-ended queue allowing extremely fast front/back algorithmic insertions without reallocation. | |
โจ Optional<T> |
A beautifully sealed functional wrapper representing possibly-absent values without raw null checks. |
|
๐ข U8 -> U64 |
Zero-cost unsigned integer variants mathematically bounding state within non-negative bit frames. | |
๐ฒ Rectangle |
Basic bounding box dimensions implicitly supporting translations, scaling, and centroid physics. | |
๐งฒ Complex |
Full-scale complex numbers implementation with operator overloading and utility algorithms. | |
๐ฒ SortedSet<T> |
Red-Black Tree backed strictly sorted unique container mirroring C++ std::set. Guaranteed $O(\log n)$ performance. |
|
๐บ๏ธ SortedMap<K, V> |
Red-Black Tree backed strictly sorted key-value map mirroring C++ std::map. Guaranteed $O(\log n)$ performance. |
|
๐ด RedBlackTree<K, V> |
Core strict self-balancing tree providing guaranteed non-mutating $O(\log n)$ lookups and modifications. | |
๐ Variant<T0...> |
Type-safe discriminated union handling distinct architectural alternatives elegantly via switches. | |
๐บ Triangle |
Evaluates Herons theorem natively from coordinates, dynamically supporting spatial rotation. | |
๐ฅ Stack<T> |
Custom LIFO (Last-In, First-Out) adapter. Operates flawlessly over any given sequence. | |
๐ข Int8 -> Int64 |
Hardware-backed signed equivalents dynamically enforcing strict boundaries natively via OS/V8 buffers. | |
๐ StringView |
Zero-allocation string reference utility enabling high-performance substring manipulations. | |
๐ช Span<T> |
Non-owning, zero-allocation view over any List<T>. Bounds-checked access, $O(1)$ slicing, full Iterable<T> support. Mirrors C++20 std::span. |
|
๐ MultiMap<K, V> |
Sorted tree container mapping keys to multiple values natively matching std::multimap. |
|
๐ Polygon |
Exact polygon structure generating precise surface areas dynamically utilizing the Shoelace formula. | |
๐ฌ number_theory |
Highly-optimized logic for gcd(), lcm(), isPrime(), primeFactorization(), and midpoint(). |
|
๐ SList<T> |
Doubly linked list enabling $O(1)$ bidirectional manipulations mirroring C++ std::list. |
|
๐ฝ Any |
Generic type-safe bounding box safely encapsulating abstract data with strictly enforced extraction. | |
โ๏ธ Ellipse |
Advanced shape beautifully approximating mathematical perimeters implicitly employing Ramanujan's formula. | |
๐ก๏ธ Expected<T,E> |
Functional wrapper representing either a value or an error. Mimics C++23 <expected> exception-free design. |
|
๐๏ธ Tuple |
Flexible C++ std::tuple adapter smoothly bridging heterogeneous collections and Dart 3 records natively. |
|
โก <functional> |
Standard function objects (Plus, Less, LogicalAnd, etc.) and invoke utility for algorithmic pipelines. |
|
โ ๏ธ <stdexcept> |
Standard C++ exception hierarchy (LogicError, RuntimeError, InvalidArgument, etc.) natively in Dart. |
|
๐ฒ <random> |
Predictable C++11 statistical random utilities featuring mt19937 engines, NormalDistribution, and more! |
|
โฑ๏ธ <chrono> |
Highly portable C++ style SystemClock and SteadyClock for time tracking across Native and Web targets, with new expansion, ull-featured time |
|
library. Five new source files are added; the existing chrono.dart gains |
||
TimePoint factory/conversion methods, DurationExtension, and two new |
||
| duration literals. |
| ๐งฎ <ratio> | | Compile-time friendly exact rational fractions (
Ratio) and standard SI prefix multipliers (milli, micro). |
| ๐ <iterator>| | Adapter hooks bridging iterables (
ReverseIterator, BackInsertIterator) for fluent mutations. |
| ๐ซ NonEmptyList<T> | | Immutable singly-linked list guaranteed non-empty at the type level. Mirrors Haskell
NonEmpty a = a :| [a]. |
| ๐ช NonEmptyVector<T> | | Mutable non-empty wrapper over
Vector<T>. Enforces non-empty invariant on every removeAt call. |
| ๐ฒ FingerTree<T> | | Persistent 2-3 finger tree with O(1) amortized
prepend/append, O(log n) concat and splitAt. |
| โ
Validated<E, A> | | Error-accumulating result type.
zip() collects errors from both sides โ ideal for form validation pipelines. |
| ๐ค Zipper<T> | | Immutable cursor-based sequence navigation inspired by Huet (1997).
moveLeft/moveRight/replace/delete. |
| ๐ฏ StateMonad<S, A> | | Pure stateful computation
S โ (A, S). Monadic map/flatMap, get/put/modify/pure constructors. |
| ๐ข IotaRange | | Lazy integer sequence
[start, end) โ infinite when end is omitted. Mirrors std::views::iota. |
| 1๏ธโฃ SingleRange<T> | | Wraps exactly one value as a one-element range. Mirrors
std::views::single. |
| โ๏ธ SplitRange<T> | | Splits an iterable on a delimiter, yielding
List<T> segments. Mirrors std::views::split. |
| ๐๏ธ ChunkByRange<T> | | Groups consecutive elements into chunks while a binary predicate holds. Mirrors
std::views::chunk_by. |
| โญ๏ธ TakeWhileRange<T> | | Yields elements from the front while a predicate holds, halting at the first failure. Mirrors
std::views::take_while. |
| โฉ DropWhileRange<T> | | Skips elements from the front while a predicate holds, then yields all remaining elements. Mirrors
std::views::drop_while. |
| ๐ KeysRange<K,V> | | Extracts keys from
Pair<K,V> iterables. Composes with HashMap, SortedMap, MultiMap. Mirrors std::views::keys. |
| ๐ ValuesRange<K,V> | | Extracts values from
Pair<K,V> iterables. Dual complement of KeysRange. Mirrors std::views::values. |
| ๐ง ImmutableSet<T> | | Persistent copy-on-write set. Full set algebra (
union, intersection, difference, symmetricDifference). New in 0.7.5. |
| ๐๏ธ FlatSet<T> | | C++23
std::flat_set โ array-backed sorted set. Cache-friendly $O(\log n)$ binary-search lookups. New in 0.7.5. |
| ๐บ๏ธ FlatMap<K,V> | | C++23
std::flat_map โ array-backed sorted map. Parallel sorted keys/values lists, $O(\log n)$ access. New in 0.7.5. |
| ๐ธ๏ธ Graph<V> | | Directed/undirected weighted graph with BFS, DFS, Dijkstra, Bellman-Ford, topological sort, Prim, and Kruskal. Mirrors C++26
<graph>. |
| ๐ <linalg> | | General MรN linear algebra:
Vec, Mat, LU/QR/Cholesky decompositions, BLAS Level 1/2/3 kernels, and eigenvalue solvers. Mirrors C++26 <linalg>. |
๐ Geometry Module โ Computational Geometry & Linear Algebra
The flagship non-C++ feature of stl. Going far beyond anything in the C++ standard, the geometry module is a complete computational geometry and linear algebra engine โ inspired by CGAL, GLM, and game engine math libraries.
๐บ๏ธ 2D Shapes & Primitives
| Class | Description |
|---|---|
Point<T> |
2D vector with +, -, *, /, dot, cross, normalize(), lerp(), angleTo(), midpointTo() |
Circle |
Area, perimeter, containsPoint(), intersectsCircle(), tangentLength(), affine transforms |
Rectangle |
Area, containsPoint(), intersects(), corners (4 vertices), affine transforms |
Triangle |
Heron's formula, circumcenter, incenter, circumradius, inradius, isAcute/Right/Obtuse/Equilateral/Isoceles |
Polygon |
Shoelace area, isConvex, containsPoint() (ray casting), area-weighted centroid |
Ellipse |
Ramanujan perimeter, area, affine transforms |
LineSegment |
Length, midpoint, intersection tests |
Ray2D |
origin, direction, at(t), intersectSegment(), intersectCircle() |
Capsule |
Stadium shape via spine + radius, area, perimeter, containsPoint() |
Arc |
Circular arc: arcLength, chordLength, containsAngle() |
QuadraticBezier |
Degree-2 Bรฉzier: evaluate(t), derivative(t), arcLength(), splitAt(t) |
CubicBezier |
Degree-3 Bรฉzier: evaluate(t), derivative(t), arcLength(), splitAt(t) |
๐ 3D Primitives
| Class | Description |
|---|---|
Point3D |
3D vector with +, -, *, /, dot(), cross(), normalize(), lerp(), distanceTo() |
Sphere3D |
Volume ($\frac{4}{3}\pi r^3$), surface area ($4\pi r^2$), containsPoint(), intersectsSphere() |
Plane3D |
Normal + distance form, distanceTo(), reflect(), project(), containsPoint() |
Ray3D |
at(t), intersectSphere(), intersectPlane() |
Triangle3D |
normal, area, centroid, containsPoint() (barycentric), toTriangle() |
๐ข Linear Algebra
| Class | Description |
|---|---|
Matrix2x2 |
Determinant, inverse, transpose, rotation(angle), full arithmetic |
Matrix3x3 |
Determinant, inverse (cofactor), rotationX/Y/Z(angle), full arithmetic |
Matrix4x4 |
Homogeneous transforms: translation(), scale(), perspective(), transform(Point3D) |
Quaternion |
Unit quaternion: slerp(), fromAxisAngle(), toMatrix3x3(), toEulerAngles(), conjugate, inverse |
๐งฎ Linear Algebra Module โ <linalg> (C++26)
A full general-purpose linear algebra engine inspired by C++26 std::linalg (P1673) and BLAS. Operates on arbitrary MรN real matrices โ complementing the fixed-size geometry matrices above.
Vec โ Mathematical Vector
| Member | Description |
|---|---|
Vec(List<double>), Vec.zeros(n), Vec.ones(n), Vec.filled(n,v), Vec.basis(n,i) |
Constructors |
dot(Vec) |
Inner product $\mathbf{x} \cdot \mathbf{y}$ |
cross(Vec) |
Cross product $\mathbf{x} \times \mathbf{y}$ ($\mathbb{R}^3$ only) |
outer(Vec) โ Mat |
Outer product $\mathbf{x}\mathbf{y}^\top$ |
norm([p]) |
$L^1$, $L^2$, $L^\infty$ norms |
normalize() |
Unit vector |
+, -, *, /, unary - |
Element-wise and scalar arithmetic |
Mat โ General MรN Matrix
| Member | Description |
|---|---|
Mat(List<List<double>>), Mat.zeros, Mat.identity, Mat.diagonal, Mat.fromColumns, Mat.fromRows |
Constructors |
transpose() |
$A^\top$ |
trace() |
$\sum_i a_{ii}$ |
frobenius() |
$|A|_F$ |
determinant() |
Via LU factorisation |
inverse() |
Via LU factorisation |
submatrix(r,c,rows,cols) |
Block extraction |
+, -, *, scaled, divided |
Arithmetic |
Decompositions
| Class | Factorisation | solve |
|---|---|---|
LUDecomposition |
$A = P \cdot L \cdot U$ (partial pivot) | $Ax = b$ via forward/back substitution |
QRDecomposition |
$A = Q \cdot R$ (Householder) | Least-squares $\min |Ax - b|$ |
CholeskyDecomposition |
$A = L \cdot L^\top$ (SPD only) | $Ax = b$ via $L$ / $L^\top$ substitution |
BLAS Kernels
| Level | Functions |
|---|---|
| 1 | dot, nrm2, asum, iamax, axpy, scal |
| 2 | gemv ($\alpha A\mathbf{x} + \beta\mathbf{y}$), ger (rank-1 update) |
| 3 | gemm ($\alpha AB + \beta C$), trmm (triangular multiply) |
Eigenvalue Solvers
| Function | Method | Use Case |
|---|---|---|
powerIteration(Mat) |
Power method | Dominant eigenvalue |
symmetricEigen(Mat) |
Jacobi iteration | All eigenpairs, symmetric $A$ |
qrEigen(Mat) |
QR + Wilkinson shifts | All eigenvalues, general real $A$ |
โ๏ธ Computational Geometry Algorithms
| Function | Algorithm | Complexity |
|---|---|---|
convexHull(points) |
Graham scan | $O(n \log n)$ |
closestPairOfPoints(points) |
Divide & conquer | $O(n \log n)$ |
segmentIntersection(a, b) |
Parametric test | $O(1)$ |
pointInPolygon(p, poly) |
Ray casting | $O(n)$ |
triangulate(polygon) |
Ear clipping | $O(n^2)$ |
๐ Example โ 3D Pipeline: Quaternion Rotation + Matrix Transform + RayโSphere Intersection
import 'package:stl/stl.dart';
import 'dart:math' as math;
void main() {
// โโ 2D Bรฉzier Curve โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
final bezier = CubicBezier(
p0: Point(x: 0.0, y: 0.0),
p1: Point(x: 1.0, y: 2.0),
p2: Point(x: 3.0, y: 3.0),
p3: Point(x: 4.0, y: 0.0),
);
final mid = bezier.evaluate(0.5);
print('Bรฉzier midpoint: $mid'); // Point(2.0, 1.875)
print('Arc length โ ${bezier.arcLength(100).toStringAsFixed(3)}');
// โโ 2D Convex Hull โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
final cloud = [
Point(x: 0.0, y: 0.0), Point(x: 1.0, y: 1.0),
Point(x: 2.0, y: 0.5), Point(x: 0.5, y: 2.0),
Point(x: 1.5, y: 1.5), Point(x: -1.0, y: 0.5),
];
final hull = convexHull(cloud);
print('Convex hull: ${hull.length} vertices');
// โโ 3D Quaternion Rotation โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// Rotate point P = (1, 0, 0) by 90ยฐ around the Y-axis.
// Expected result: (0, 0, -1)
final q = Quaternion.fromAxisAngle(
axis: Point3D(x: 0, y: 1, z: 0),
angle: math.pi / 2,
);
final p = Point3D(x: 1, y: 0, z: 0);
final rotated = q.rotate(p);
print('Rotated: $rotated'); // Point3D(โ0, 0, โ-1)
// โโ Matrix4x4 Transform Pipeline โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// Build a model matrix: translate(2,3,0) * rotateZ(45ยฐ) * scale(2)
final model = Matrix4x4.translation(tx: 2, ty: 3, tz: 0)
.multiply(Matrix4x4.rotationZ(math.pi / 4))
.multiply(Matrix4x4.scale(sx: 2, sy: 2, sz: 2));
final vertex = model.transform(Point3D(x: 1, y: 0, z: 0));
print('Transformed vertex: $vertex');
// โโ RayโSphere Intersection โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
final ray = Ray3D(
origin: Point3D(x: -5, y: 0, z: 0),
direction: Point3D(x: 1, y: 0, z: 0),
);
final sphere = Sphere3D(center: Point3D(x: 0, y: 0, z: 0), radius: 1.0);
final hit = ray.intersectSphere(sphere);
print('Ray hits sphere at t=${hit?.toStringAsFixed(3)}'); // t=4.000
// โโ Triangle Circumcenter โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
final tri = Triangle(
p1: Point(x: 0.0, y: 0.0),
p2: Point(x: 4.0, y: 0.0),
p3: Point(x: 0.0, y: 3.0),
);
print('Circumcenter: ${tri.circumcenter}'); // Point(2.0, 1.5)
print('Inradius: ${tri.inradius.toStringAsFixed(3)}');
// โโ Polygon Convexity & Point-in-Polygon โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
final square = Polygon([
Point(x: 0.0, y: 0.0), Point(x: 4.0, y: 0.0),
Point(x: 4.0, y: 4.0), Point(x: 0.0, y: 4.0),
]);
print('Is convex: ${square.isConvex}'); // true
print('Contains (2,2): ${square.containsPoint(Point(x: 2.0, y: 2.0))}'); // true
}
ฮป Haskell-Inspired Functional Module
Expanding beyond C++ into the richness of functional programming, stl now includes 6 types directly inspired by Haskell and functional language idioms. These types prioritise immutability, type-level guarantees, and composable error handling โ patterns that are extremely powerful in Dart 3.
๐ฆ Non-Empty Collections
NonEmptyList<T>โ An immutable singly-linked structure mirroring Haskell'sNonEmpty a = a :| [a]. Theheadandlastgetters are always non-nullable. Supportsmap,flatMap,reduce,fold,prepend,append,concat. Constructed viaNonEmptyList.of(head, [tail])orNonEmptyList.fromIterable(iterable).NonEmptyVector<T>โ A mutable non-empty wrapper over the existingVector<T>. Enforces the non-empty invariant at everyremoveAtcall โ throwsInvalidArgumentif removal would empty the container. MirrorsVector's full API with non-nullablefirstandlast.FingerTree<T>โ A full persistent 2-3 finger tree based on Hinze & Paterson (2006). Provides O(1) amortizedprependandappend, O(log n)concatandsplitAt, and O(1)length. All operations return new instances โ the tree is entirely immutable.
var ft = FingerTree<int>.fromIterable([1, 2, 3, 4, 5]);
print(ft.first); // 1
print(ft.last); // 5
final (left, right) = ft.splitAt(3);
print(left.toList()); // [1, 2, 3]
print(right.toList()); // [4, 5]
print(left.concat(right).toList()); // [1, 2, 3, 4, 5]
๐ก๏ธ Error-Accumulating Results
Validated<E, A>โ A sealed result type (Valid<E,A>/Invalid<E,A>) that accumulates all errors rather than short-circuiting on the first. The key operationzip()merges twoValidatedvalues, collecting errors from both sides simultaneously. Ideal for form and data validation pipelines.
Validated<String, int> age = Validated.valid(25);
Validated<String, String> name = Validated.valid('Alice');
final combined = age.zip(name); // Valid((25, 'Alice'))
// Both errors are preserved:
final bad1 = Validated<String, int>.invalid('Age must be positive');
final bad2 = Validated<String, int>.invalid('Age out of range');
print(bad1.zip(bad2)); // Invalid(['Age must be positive', 'Age out of range'])
๐ค Sequence Navigation
Zipper<T>โ An immutable cursor over a sequence, inspired by Huet's Zipper (1997). Maintainsleft(reversed context),focus, andright. All navigation (moveLeft,moveRight,replace,insert,delete) returns a newZipper<T>.toList()reconstructs the full sequence at any cursor position.
final z = Zipper.fromList([1, 2, 3, 4, 5]);
final z2 = z.moveRight().moveRight(); // focus = 3
final z3 = z2.replace(99);
print(z3.toList()); // [1, 2, 99, 4, 5]
print(z3.index); // 2
๐ฏ Pure Stateful Computation
StateMonad<S, A>โ Encapsulates a functionS โ (A, S)that threads state through a computation pipeline without any mutable variables. Uses Dart 3 records as the return type. Providesmap,flatMap(monadic bind), and static constructorspure,get,put,modify.
// Count the number of times a value is accessed
final readAndCount = StateMonad<int, String>((count) => ('hello', count + 1));
final pipeline = readAndCount
.flatMap((v) => StateMonad<int, String>((count) => ('$v world', count + 1)));
final (value, accessCount) = pipeline.run(0);
print(value); // hello world
print(accessCount); // 2
๐งฌ Ranges Module (Inspired by C++23)
Welcome to functional magic! Inspired deeply by C++23 std::views, our Ranges module allows you to cleanly manipulate, combine, generate, and stream data iteratively without aggressively eager memory consumption. Operations are performed lazily, bringing algorithmic elegance to your pipeline.
๐ฅ Spotlight Ranges
๐ NumberLine (Iota)
Mimicking std::views::iota. Generate precise linear layouts of floating-point boundaries, or standard integer jumps, in mathematically optimized $O(1)$ operations instead of building massive explicit arrays.
// Custom Step Increment of 4 (0 to 20):
final evens = NumberLine(0, 20, step: 4);
print(evens.toList()); // [0, 4, 8, 12, 16]
// Highly mathematically optimized checks:
print(evens.contains(12)); // True! (Does NOT iterate over memory)
๐ ZipRange (Parallel Iteration)
Mimics std::views::zip. Dynamically clamp two different structured iterables together until the shortest one expires. Phenomenal for generating maps!
final keys = ['Player1', 'Player2', 'Player3'];
final scores = [9500, 8400]; // Uneven length!
final zipped = ZipRange(keys, scores);
final scoreMap = Map.fromEntries(zipped.map((p) => p.toMapEntry()));
// Results: {'Player1': 9500, 'Player2': 8400}
๐ฒ ChunkRange (Data Fragmentation)
Mimics std::views::chunk. Need to batch network packets or paginate rendering blocks? ChunkRange divides collections precisely into requested sizing constraints.
final data = [1, 2, 3, 4, 5, 6, 7];
final pagination = ChunkRange(data, 3);
print(pagination.toList());
// Results: [[1, 2, 3], [4, 5, 6], [7]]
๐งฉ CartesianRange (Combinations)
Mimics std::views::cartesian_product. Produces flat combinatorial intersections elegantly.
final suits = ['Hearts', 'Spades'];
final ranks = ['King', 'Queen'];
final deck = CartesianRange(suits, ranks);
// Yields Pairs: (Hearts, King), (Hearts, Queen), (Spades, King), (Spades, Queen)
โพ๏ธ RepeatRange (Infinite Streams)
Mimics std::views::repeat. Repeat specific data continuously or infinitely. Perfect for mock data pipelines!
final zeroes = RepeatRange(0);
print(zeroes.take(5).toList()); // [0, 0, 0, 0, 0]
โ๏ธ TakeRange & DropRange (Slicing)
Mimics std::views::take and std::views::drop. Extract or ignore sections of an iterable pipeline iteratively without explicitly allocating memory-heavy sublists.
final data = NumberLine(1, 10).toList();
final middle = TakeRange(DropRange(data, 3), 4);
print(middle.toList()); // [4, 5, 6, 7]
๐งช FilterRange & TransformRange (Functional Hooks)
Mimics std::views::filter and std::views::transform. Eagerly processes data dynamically through custom conditional predicates and data type mutating hooks.
final data = [1, 2, 3, 4, 5];
// Keep evens, then multiply by 10
final tens = TransformRange<int, int>(FilterRange(data, (int n) => n % 2 == 0), (int n) => n * 10);
print(tens.toList()); // [20, 40]
๐ JoinRange (Stream Flattening)
Mimics std::views::join. Instantly reassembles an iterable of iterables back into a perfectly contiguous 1-dimensional functional flow without recursive allocations.
final arrays = [[1, 2], [], [3, 4, 5], [6]];
final stream = JoinRange(arrays);
print(stream.toList()); // [1, 2, 3, 4, 5, 6]
๐ข IotaRange (Lazy Integer Sequences)
Mimics std::views::iota. Generates a lazy bounded or infinite integer sequence without allocating any backing array. Essential for index generation and arithmetic progressions.
// Bounded sequence [0, 5)
print(IotaRange(0, 5).toList()); // [0, 1, 2, 3, 4]
// Infinite sequence โ safe via take()
print(IotaRange(10).take(4).toList()); // [10, 11, 12, 13]
1๏ธโฃ SingleRange (One-Element Views)
Mimics std::views::single. Wraps a single value as a range, making it composable with every other range adapter without allocating a list.
final seed = SingleRange(42);
print(seed.toList()); // [42]
// Compose with JoinRange to prepend a value
final result = JoinRange([SingleRange(0), IotaRange(1, 4)]);
print(result.toList()); // [0, 1, 2, 3]
โ๏ธ SplitRange (Delimiter Splitting)
Mimics std::views::split. Splits any iterable on a delimiter element, yielding each segment as a List<T>. Works on integers, strings, or any comparable element type.
final csv = [1, 0, 2, 3, 0, 4];
final segments = SplitRange(csv, 0);
print(segments.toList()); // [[1], [2, 3], [4]]
// String characters
final words = SplitRange('hello world'.split(''), ' ');
// [['h','e','l','l','o'], ['w','o','r','l','d']]
๐๏ธ ChunkByRange (Predicate Grouping)
Mimics std::views::chunk_by. Groups consecutive elements into List<T> chunks while a binary predicate pred(prev, curr) returns true, starting a new chunk the moment it fails.
final data = [1, 1, 2, 2, 2, 3, 1, 1];
// Group runs of equal values
final groups = ChunkByRange(data, (a, b) => a == b);
print(groups.toList()); // [[1, 1], [2, 2, 2], [3], [1, 1]]
// Group ascending runs
final runs = ChunkByRange([1, 2, 3, 1, 2], (a, b) => b >= a);
print(runs.toList()); // [[1, 2, 3], [1, 2]]
โญ๏ธ TakeWhileRange & DropWhileRange (Predicate Slicing)
Mimics std::views::take_while and std::views::drop_while. Unlike count-based TakeRange/DropRange, these stop or skip based on a predicate, enabling expressive data trimming without knowing element counts in advance. Safe on infinite sources.
final data = [2, 4, 6, 7, 8, 10];
// Take while even โ stops at 7, never checks 8 or 10
final evens = TakeWhileRange(data, (n) => n.isEven);
print(evens.toList()); // [2, 4, 6]
// Drop while even โ skips 2, 4, 6; yields everything from 7 onward
final fromOdd = DropWhileRange(data, (n) => n.isEven);
print(fromOdd.toList()); // [7, 8, 10]
// Safe on infinite IotaRange โ take numbers below 5
final below5 = TakeWhileRange(IotaRange(0), (n) => n < 5);
print(below5.toList()); // [0, 1, 2, 3, 4]
// Compose: extract the inner non-zero span
final signal = [0, 0, 1, 3, 5, 0, 0];
final inner = TakeWhileRange(
DropWhileRange(signal, (n) => n == 0),
(n) => n != 0,
);
print(inner.toList()); // [1, 3, 5]
๐ KeysRange & ValuesRange (Map Projection)
Mimics std::views::keys and std::views::values. Project the keys or values out of any Pair<K, V> iterable, composing seamlessly with HashMap, SortedMap, and MultiMap.
final map = SortedMap<String, int>((a, b) => a.compareTo(b));
map['alpha'] = 1;
map['beta'] = 2;
map['gamma'] = 3;
// Extract only keys
print(KeysRange(map).toList()); // [alpha, beta, gamma]
// Extract only values
print(ValuesRange(map).toList()); // [1, 2, 3]
๐ป Spotlight Integrations
By blending C++ architectures with Dart's IterableMixin, stl gives you incredible syntactical power:
๐ Vector Memory Architecture
final vec = Vector<String>(['Apple', 'Banana']);
vec.pushBack('Cherry');
vec.popBack();
print(vec.front()); // "Apple"
๐ฏ The Powerful Pair & Dart 3 Records
// Effortless Pair initialization
var duo = makePair(99, 'Balloons');
// Native Dart 3 tuple/record unwrapping
var (count, item) = duo.record;
// Native deep equality
var sibling = makePair(99, 'Balloons');
print(duo == sibling); // True!
๐ฅ Iterable Adapters (Stack)
final stack = Stack<int>.from([1, 2, 3]); // Top element is 3
var removed = stack.pop(); // Removes and returns 3
// Instantly iterable safely from top-to-bottom!
for (var item in stack) {
print(item); // 2, then 1
}
๐ฒ Autonomous Red-Black Trees (SortedSet & SortedMap)
final sorted = SortedSet<String>((a, b) => b.length.compareTo(a.length));
sorted.insert("Strawberry");
sorted.insert("Apple");
sorted.insert("A");
print(sorted.toList());
// ["Strawberry", "Apple", "A"] (Strictly maintained via non-mutating O(log n) tree operations!)
๏ฟฝ๏ธ Graph Module โ Directed & Undirected Graphs
Inspired by C++26 <graph> and Boost.Graph, the graph module delivers a full-featured weighted graph container with a rich suite of traversal and optimization algorithms โ all in a clean, idiomatic Dart API.
๐งฉ Core API
| Method / Property | Description |
|---|---|
addVertex(V) |
Registers a vertex; returns false if it already exists. |
removeVertex(V) |
Removes a vertex and all its incident edges. |
addEdge(V, V, {weight}) |
Adds a weighted edge (and its reverse for undirected graphs). |
removeEdge(V, V) |
Removes the edge (and reverse for undirected). |
hasVertex(V) / hasEdge(V, V) |
Membership queries. |
neighborsOf(V) |
Returns List<Edge<V>> of outgoing edges. |
degreeOf(V) |
Number of edges incident on the vertex. |
vertices / edges |
Unmodifiable snapshots. |
vertexCount / edgeCount |
Sizes. |
clear() |
Resets the graph entirely. |
๐ Algorithms
| Algorithm | Method | Complexity |
|---|---|---|
| Breadth-First Search | bfs(start) |
$O(V + E)$ |
| Depth-First Search | dfs(start) |
$O(V + E)$ |
| Shortest paths (non-negative) | dijkstra(start) |
$O((V + E) \log V)$ |
| Shortest paths (negative weights) | bellmanFord(start) |
$O(V \cdot E)$ |
| Topological ordering | topologicalSort() |
$O(V + E)$ |
| Minimum spanning tree | prim([start]) |
$O((V + E) \log V)$ |
| Minimum spanning tree | kruskal() |
$O(E \log E)$ |
| Connectivity check | isConnected |
$O(V + E)$ |
| Acyclicity check | isAcyclic |
$O(V + E)$ |
Note:
bellmanFordreturnsnullwhen a negative-weight cycle is detected.topologicalSortreturnsnullwhen the directed graph contains a cycle.
๐ Example
import 'package:stl/stl.dart';
void main() {
// โโ Undirected weighted graph โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
final g = Graph<String>();
g.addEdge('A', 'B', weight: 4.0);
g.addEdge('A', 'C', weight: 2.0);
g.addEdge('B', 'C', weight: 1.0);
g.addEdge('B', 'D', weight: 5.0);
// BFS and DFS traversal
print(g.bfs('A')); // [A, B, C, D] (level order)
print(g.dfs('A')); // [A, B, C, D] (depth order)
// Dijkstra shortest paths from A
final dist = g.dijkstra('A');
print('AโD: ${dist["D"]}'); // 6.0 (AโCโBโD: 2+1+5=8? no AโBโD=9, AโCโB=3, +5=8... min is AโBโD=9)
// Prim minimum spanning tree
final mst = g.prim();
final weight = mst.fold(0.0, (s, e) => s + e.weight);
print('MST weight: $weight'); // 8.0
// โโ Directed acyclic graph (topological sort) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
final dag = Graph<String>(directed: true);
dag.addEdge('Math', 'Algorithms');
dag.addEdge('Math', 'Data Structures');
dag.addEdge('Algorithms', 'Thesis');
dag.addEdge('Data Structures', 'Thesis');
print(dag.topologicalSort()); // [Math, Algorithms, Data Structures, Thesis]
print(dag.isAcyclic); // true
// โโ Bellman-Ford with negative edges โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
final bf = Graph<int>(directed: true);
bf.addEdge(0, 1, weight: 4.0);
bf.addEdge(0, 2, weight: 5.0);
bf.addEdge(1, 3, weight: -3.0);
print(bf.bellmanFord(0)); // {0: 0.0, 1: 4.0, 2: 5.0, 3: 1.0}
}
## ๐ช `Span
Libraries
- stl
- Support for doing something awesome.