#pragma once #include "node.h" #include "srtskt.h" #include "memblock.h" class VChain; class VChainIterator; class VChainLink : public Link { friend class VChain; friend class VChainIterator; public: ~VChainLink(); Logical TestInstance() const; protected: VChainLink(VChain *vchain, Plug *plug); private: void SetupVChainLinks(VChainLink *next, VChainLink *prev); VChainLink *next; VChainLink *prev; }; #define VCHAINLINK_MEMORYBLOCK_ALLOCATION (100) template class VChainLinkOf : public VChainLink { public: VChainLinkOf(VChain *vchain, Plug *plug, const V &value); ~VChainLinkOf(); void* operator new(size_t); void operator delete(void *where); V GetValue() { return value; } V* GetValuePointer() { return &value; } private: static MemoryBlock *allocatedMemory; static CollectionSize allocationCount; V value; }; template MemoryBlock* VChainLinkOf::allocatedMemory = NULL; template CollectionSize VChainLinkOf::allocationCount = 0; template VChainLinkOf::VChainLinkOf(VChain *vchain, Plug *plug, const V &value) : VChainLink(vchain, plug) { this->value = value; } template VChainLinkOf::~VChainLinkOf() {} #if 0 template void *VChainLinkOf::operator new(size_t) { if (allocatedMemory == NULL) allocatedMemory = new MemoryBlock(sizeof(VChainLinkOf), VCHAINLINK_MEMORYBLOCK_ALLOCATION, VCHAINLINE_MEMORYBLOCK_ALLOCATION); Check(allocatedMemory); return allocatedMemory->New(); } template void VChainLinkOf::operator delete(void *where) { Check(allocatedMemory); allocatedMemory->Delete(where); } #else template void *VChainLinkOf::operator new(size_t) { Verify(allocationCount >= 0); if (allocationCount++ == 0) { allocatedMemory = new MemoryBlock(sizeof(VChainLinkOf), VCHAINLINK_MEMORYBLOCK_ALLOCATION, VCHAINLINK_MEMORYBLOCK_ALLOCATION, "VChainLinkOf"); Register_Object(allocatedMemory); } Verify(allocationCount < INT_MAX); Check(allocatedMemory); return allocatedMemory->New(); } template void VChainLinkOf::operator delete(void *where) { Check(allocatedMemory); allocatedMemory->Delete(where); if (--allocationCount == 0) { Unregister_Object(allocatedMemory); delete allocatedMemory; allocatedMemory = NULL; } Verify(allocationCount >= 0); } #endif class VChain : public SortedSocket { friend class VChainLink; friend class VChainIterator; public: VChain(Node *node, Logical has_unique_entries); ~VChain(); Logical TestInstance() const; static Logical TestClass(); static Logical ProfileClass(); protected: void AddImplementation(Plug *); void AddValueImplementation(Plug *plug, const void *value); Plug *FindImplementation(const void *value); private: virtual VChainLink *MakeVChainLink(Plug *plug, const void *value); virtual int CompareVChainLinks(VChainLink *link1, VChainLink *link2); virtual int CompareValueToVChainLink(const void *value, VChainLink *link); VChainLink *SearchForValue(const void *value); VChainLink *head; VChainLink *tail; }; #define VCHAIN_MEMORYBLOCK_ALLOCATION (100) template class VChainOf : public VChain { public: VChainOf(Node *node, Logical has_unique_entries); ~VChainOf(); void *operator new(size_t); void operator delete(void *where); void AddValue(T plug, const V &value) { AddValueImplementation(Cast_Object(Plug*, plug), &value); } T Find(const V &value) { return (T)FindImplementation(&value); } private: VChainLink *MakeVChainLink(Plug *plug, const void *value) { return new VChainLinkOf(this, plug, *(V*)value); } int CompareVChainLinks(VChainLink *link1, VChainLink *link2); int CompareValueToVChainLink(const void *value, VChainLink *link); static MemoryBlock *allocatedMemory; static CollectionSize allocationCount; }; template MemoryBlock* VChainOf::allocatedMemory = NULL; template CollectionSize VChainOf::allocationCount = 0; template VChainOf::VChainOf(Node *node, Logical has_unique_entries) : VChain(node, has_unique_entries) { } template VChainOf::~VChainOf() { } template int VChainOf::CompareVChainLinks(VChainLink *link1, VChainLink *link2) { V *ptr1 = Cast_Object(VChainLinkOf*, link1)->GetValuePointer(); V *ptr2 = Cast_Object(VChainLinkOf*, link2)->GetValuePointer(); Check_Pointer(ptr1); Check_Pointer(ptr2); if (*ptr1 == *ptr2) return 0; else return ((*ptr1 > *ptr2) ? 1 : -1); } template int VChainOf::CompareValueToVChainLink(const void *value, VChainLink *link) { Check_Pointer(value); V *ptr = Cast_Object(VChainLinkOf*, link)->GetValuePointer(); Check_Pointer(ptr); if (*(V*)value == *ptr) return 0; else return (*(V*)value > *ptr) ? 1 : -1; } #if 0 template void *VChainOf::operator new(size_t) { if (allocatedMemory == NULL) allocatedMemory = new MemoryBlock(sizeof(VChainOf), VCHAIN_MEMORYBLOCK_ALLOCATION, VCHAIN_MEMORYBLOCK_ALLOCATION); Check(allocatedMemory); return allocatedMemory->New(); } template void VChainOf::operator delete(void *where) { Check(allocatedMemory); allocatedMemory->Delete(where); } #else template void *VChainOf::operator new(size_t) { Verify(allocationCount >= 0); if (allocationCount++ == 0) { allocatedMemory = new MemoryBlock(sizeof(VChainOf), VCHAIN_MEMORYBLOCK_ALLOCATION, VCHAIN_MEMORYBLOCK_ALLOCATION, "VChainOf"); Register_Object(allocatedMemory); } Verify(allocationCount < INT_MAX); Check(allocatedMemory); return allocatedMemory->New(); } template void VChainOf::operator delete(void *where) { Check(allocatedMemory); allocatedMemory->Delete(where); if (--allocationCount == 0) { Unregister_Object(allocatedMemory); delete allocatedMemory; allocatedMemory = NULL; } Verify(allocationCount >= 0); } #endif class VChainIterator : public SortedIterator { public: VChainIterator(VChain *vchain); VChainIterator(const VChainIterator *iterator); ~VChainIterator(); Logical TestInstance() const; void First(); void Last(); void Next(); void Previous(); CollectionSize GetSize(); void Remove(); protected: void *ReadAndNextImplementation(); void *ReadAndPreviousImplementation(); void *GetCurrentImplementation(); void *GetNthImplementation(CollectionSize index); Plug *FindImplementation(const void *value); protected: VChainLink *currentLink; private: void ReceiveMemo(IteratorMemo memo, void *content); }; template class VChainIteratorOf : public VChainIterator { public: VChainIteratorOf(VChainOf *vchain); VChainIteratorOf(VChainOf &vchain); VChainIteratorOf(const VChainIteratorOf &iterator); ~VChainIteratorOf(); T ReadAndNext() { return (T)ReadAndNextImplementation(); } T ReadAndPrevious() { return (T)ReadAndPrevousImplementation(); } T GetCurrent() { return (T)GetCurrentImplementation(); } T GetNth(CollectionSize index) { return (T)GetNthImplementation(index); } T Find(const V &value) { return (T)FindImplementation(&value); } V GetValue() { return Cast_Object(VChainLinkOf*, currentLink)->GetValue(); } }; template VChainIteratorOf::VChainIteratorOf(VChainOf *vchain) : VChainIterator(vchain) { } template VChainIteratorOf::VChainIteratorOf(VChainOf &vchain) : VChainIterator(&vchain) { } template VChainIteratorOf::VChainIteratorOf(const VChainIteratorOf &iterator) : VChainIterator(&iterator) { } template VChainIteratorOf::~VChainIteratorOf() { }