using System; namespace Contours { public class Circuit where Parent: class where Child: class { public class Entry { readonly Child owner; Circuit circuit; Entry previous; Entry next; public Entry(Child owner) { this.owner = owner; } public Child getOwner() { return owner; } public Circuit getCircuit() { return circuit; } public Parent getParent() { Circuit circuit = getCircuit(); return circuit == null ? null : circuit.getOwner(); } public Entry getPreviousEntry() { return previous; } public Entry getNextEntry() { return next; } public Entry getPreviousEntryLinear() { Entry e = getPreviousEntry(); return e == null || e == circuit.last ? null : e; } public Entry getNextEntryLinear() { Entry e = getNextEntry(); return e == null || e == circuit.first ? null : e; } public Child getPrevious() { Entry e = getPreviousEntry(); return e == null ? null : e.getOwner(); } public Child getNext() { Entry e = getNextEntry(); return e == null ? null : e.getOwner(); } public Child getPreviousLinear() { Entry e = getPreviousEntryLinear(); return e == null ? null : e.getOwner(); } public Child getNextLinear() { Entry e = getNextEntryLinear(); return e == null ? null : e.getOwner(); } public void unlink() { if (previous != null) previous.next = next; if (next != null) next.previous = previous; if (circuit != null) { if (circuit.first == this) { circuit.first = next != this ? next : null; circuit.last = previous != this ? previous : null; } --circuit.count; circuit = null; } previous = null; next = null; } public void insertBack(Circuit circuit) { unlink(); if (circuit != null) { if (circuit.empty()) { this.circuit = circuit; previous = next = this; circuit.first = circuit.last = this; ++circuit.count; } else { insertAfterOf(circuit.getLastEntry()); } } } public void insertFront(Circuit circuit) { unlink(); if (circuit != null) { if (circuit.empty()) { this.circuit = circuit; previous = next = this; circuit.first = circuit.last = this; ++circuit.count; } else { insertBeforeOf(circuit.getFirstEntry()); } } } public void insertAfterOf(Entry entry) { if (entry == this) return; unlink(); if (entry == null || entry.getCircuit() == null) return; previous = entry; next = entry.next; previous.next = this; if (next != null) next.previous = this; circuit = entry.getCircuit(); if (circuit != null) { if (circuit.getLastEntry() == entry) circuit.last = this; ++circuit.count; } } public void insertBeforeOf(Entry entry) { if (entry == this) return; unlink(); if (entry == null || entry.getCircuit() == null) return; previous = entry.previous; next = entry; if (previous != null) previous.next = this; next.previous = this; circuit = entry.getCircuit(); if (circuit != null) { if (circuit.getFirstEntry() == entry) circuit.first = this; ++circuit.count; } } public void swapWith(Entry other) { if (other == this || other == null) return; Circuit otherCircuit = other.circuit; Entry otherPrevious = other.previous; Entry otherNext = other.next; other.circuit = circuit; other.previous = previous; other.next = next; if (otherCircuit != null) { if (otherCircuit.first == other) otherCircuit.first = this; if (otherCircuit.last == other) otherCircuit.last = this; } if (circuit != null) { if (circuit.first == this) circuit.first = other; if (circuit.last == this) circuit.last = other; } circuit = otherCircuit; previous = otherPrevious; next = otherNext; } } readonly Parent owner; Entry first; Entry last; int count = 0; public Circuit(Parent owner) { this.owner = owner; } public Parent getOwner() { return owner; } public int getCount() { return count; } public Entry getFirstEntry() { return first; } public Entry getLastEntry() { return last; } public Child getFirst() { Entry e = getFirstEntry(); return e == null ? null : e.getOwner(); } public Child getLast() { Entry e = getLastEntry(); return e == null ? null : e.getOwner(); } public bool empty() { return getFirstEntry() == null; } public void clear() { while(!empty()) getFirstEntry().unlink(); } } }