Copse.SimpleSerializer
0.3.0-alpha.1
See the version list below for details.
dotnet add package Copse.SimpleSerializer --version 0.3.0-alpha.1
NuGet\Install-Package Copse.SimpleSerializer -Version 0.3.0-alpha.1
<PackageReference Include="Copse.SimpleSerializer" Version="0.3.0-alpha.1" />
<PackageVersion Include="Copse.SimpleSerializer" Version="0.3.0-alpha.1" />
<PackageReference Include="Copse.SimpleSerializer" />
paket add Copse.SimpleSerializer --version 0.3.0-alpha.1
#r "nuget: Copse.SimpleSerializer, 0.3.0-alpha.1"
#:package Copse.SimpleSerializer@0.3.0-alpha.1
#addin nuget:?package=Copse.SimpleSerializer&version=0.3.0-alpha.1&prerelease
#tool nuget:?package=Copse.SimpleSerializer&version=0.3.0-alpha.1&prerelease
Copse
LINQ for trees. ITreenumerable<T> is to trees what IEnumerable<T> is to sequences — a lazy,
composable abstraction supporting depth-first and breadth-first traversal with 40+ operations:
Where, Select, GetLeaves, PruneBefore, LeaffixAggregate, Union, and more.
No equality contract required: node types need not implement IEquatable<T> or override
GetHashCode.
Install
dotnet add package Copse.Linq --prerelease
Copse.Linq transitively brings in Copse and Copse.Core. Targets net48, net8.0, and netstandard2.0.
Examples
Adapt any tree type by implementing IChildEnumerator<T> — a struct Copse calls to enumerate each
node's children:
using Copse;
using Copse.Linq;
using Copse.Treenumerables;
using System.Linq;
// Node n has children 2n and 2n+1 — a complete binary tree capped at 7.
struct BinaryChildren : IChildEnumerator<int>
{
private int _next;
private bool _disposed;
public BinaryChildren(int parent) { _next = parent * 2; _disposed = false; }
public bool MoveNext(out NodeAndSiblingIndex<int> result)
{
if (_disposed || _next > 7) { result = default; return false; }
result = new NodeAndSiblingIndex<int>(_next, _next % 2);
_next++;
return true;
}
public void Dispose() => _disposed = true;
}
ITreenumerable<int> tree = new Treenumerable<int, BinaryChildren>(
ctx => new BinaryChildren(ctx.Node), 1);
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Once you have an ITreenumerable<T>, the full operation set is available. All operations are lazy
and compose without materializing intermediate trees:
int[] preOrder = tree.PreOrderTraversal().ToArray(); // [1, 2, 4, 5, 3, 6, 7]
int[] leaves = tree.GetLeaves().ToArray(); // [4, 5, 6, 7]
// Select transforms values while preserving tree structure
int[] doubled = tree
.Select(ctx => ctx.Node * 2)
.PreOrderTraversal()
.ToArray(); // [2, 4, 8, 10, 6, 12, 14]
// PruneBefore removes a node and its descendants when the predicate is true
int[] topTwo = tree
.PruneBefore(ctx => ctx.Position.Depth >= 2)
.GetLeaves()
.ToArray(); // [2, 3]
Where is structural. A filtered-out node's children are promoted to the nearest remaining
ancestor — unlike IEnumerable.Where, which is a flat element filter:
// Remove even nodes. Children of 2 (which are 4 and 5) become children of 1.
// 4 and 6 are also removed but have no children, so they simply vanish.
int[] filtered = tree
.Where(ctx => ctx.Node % 2 != 0)
.PreOrderTraversal()
.ToArray();
// Result tree: 1(5, 3(7)) => [1, 5, 3, 7]
LeaffixAggregate folds bottom-up: leaves are seeded first, then each parent is computed from
its children's accumulated results:
int subtreeSum = tree
.LeaffixAggregate(
leaf => leaf.Node,
(node, kids) => node.Node + kids.Sum())
.First();
// 28 (1 + 2 + 3 + 4 + 5 + 6 + 7)
Packages
| Package | Description |
|---|---|
Copse.Core |
Interfaces, enums, and position types (ITreenumerable<T>, NodePosition, NodeTraversalStrategies, …) |
Copse |
Depth-first and breadth-first traversal engine |
Copse.Linq |
LINQ-style tree operations (Where, Select, GetLeaves, PruneBefore, LeaffixAggregate, Union, …) |
Copse.SimpleSerializer |
Text-format tree serialization for debugging and testing |
Documentation
Full documentation is coming to copselib.org (WIP). For now, the examples above and the source are the reference.
Benchmarks
Performance results are published at copselib.github.io/copse-dotnet.
License
MIT — see LICENSE. © 2023–2026 Jason Boyd.
The disposable utilities in Copse.Disposables (CompositeDisposable, RefCountDisposable,
Disposable.Create, …) are adapted from System.Reactive
(MIT, © .NET Foundation and Contributors) — same names, same semantics, no new concepts.
See THIRD-PARTY-NOTICES.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8
- Copse (>= 0.3.0-alpha.1)
- Copse.Core (>= 0.3.0-alpha.1)
- System.Memory (>= 4.5.5)
-
.NETStandard 2.0
- Copse (>= 0.3.0-alpha.1)
- Copse.Core (>= 0.3.0-alpha.1)
- System.Memory (>= 4.5.5)
-
net8.0
- Copse (>= 0.3.0-alpha.1)
- Copse.Core (>= 0.3.0-alpha.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.3.0-alpha.19 | 43 | 8/24/2026 |
| 0.3.0-alpha.18 | 56 | 8/17/2026 |
| 0.3.0-alpha.17 | 55 | 8/5/2026 |
| 0.3.0-alpha.16 | 54 | 8/5/2026 |
| 0.3.0-alpha.15 | 51 | 8/5/2026 |
| 0.3.0-alpha.14 | 65 | 8/5/2026 |
| 0.3.0-alpha.13 | 62 | 8/4/2026 |
| 0.3.0-alpha.12 | 60 | 8/4/2026 |
| 0.3.0-alpha.11 | 63 | 8/4/2026 |
| 0.3.0-alpha.10 | 59 | 8/4/2026 |
| 0.3.0-alpha.9 | 61 | 8/2/2026 |
| 0.3.0-alpha.8 | 64 | 8/2/2026 |
| 0.3.0-alpha.7 | 61 | 8/2/2026 |
| 0.3.0-alpha.6 | 64 | 7/17/2026 |
| 0.3.0-alpha.5 | 66 | 7/10/2026 |
| 0.3.0-alpha.4 | 57 | 7/10/2026 |
| 0.3.0-alpha.3 | 69 | 7/10/2026 |
| 0.3.0-alpha.2 | 66 | 7/9/2026 |
| 0.3.0-alpha.1 | 62 | 7/6/2026 |
| 0.2.0-alpha.1 | 58 | 7/6/2026 |