From 15eec8a161fadbdda54918352a5a1243a101e456 Mon Sep 17 00:00:00 2001 From: Tyler Dauwalder Date: Tue, 27 May 2003 08:01:08 +0000 Subject: [PATCH] Single-linked list courtesy Mr. Ingo Weinhold, here temporarily until we get our kernel C++ utils library up and running. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3352 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/udf/SLList.h | 288 +++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 src/add-ons/kernel/file_systems/udf/SLList.h diff --git a/src/add-ons/kernel/file_systems/udf/SLList.h b/src/add-ons/kernel/file_systems/udf/SLList.h new file mode 100644 index 0000000000..f979a442af --- /dev/null +++ b/src/add-ons/kernel/file_systems/udf/SLList.h @@ -0,0 +1,288 @@ +// SLList.h +// +// Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Except as contained in this notice, the name of a copyright holder shall +// not be used in advertising or otherwise to promote the sale, use or other +// dealings in this Software without prior written authorization of the +// copyright holder. + +#ifndef SL_LIST_H +#define SL_LIST_H + +#include + +// SLListStandardNode +template +struct SLListStandardNode { + SLListStandardNode(const Value &a) + : value(a), + next(NULL) + { + } + + Value value; + SLListStandardNode *next; +}; + +// SLListStandardNodeAllocator +template +class SLListStandardNodeAllocator +{ +public: + inline Node *Allocate(const Value &a) const + { + return new(nothrow) SLListStandardNode(a); + } + + inline void Free(Node *node) const + { + delete node; + } +}; + +// SLListValueNodeAllocator +template +class SLListValueNodeAllocator +{ +public: + inline Node *Allocate(const Value &a) const + { + return a; + } + + inline void Free(Node *node) const + { + } +}; + +// SLListStandardGetValue +template +class SLListStandardGetValue +{ +public: + inline Value &operator()(Node *node) const + { + return node->value; + } +}; + +// SLListValueNodeGetValue +template +class SLListValueNodeGetValue +{ +public: + inline Value &operator()(Node *node) const + { + return *node; + } +}; + +// for convenience +#define SL_LIST_TEMPLATE_LIST template +#define SL_LIST_CLASS_NAME SLList + +// SLList +template, + typename NodeAllocator = SLListStandardNodeAllocator, + typename GetValue = SLListStandardGetValue > +class SLList { +public: + class Iterator; + +public: + SLList(); + SLList(const NodeAllocator &nodeAllocator, const GetValue &getValue); + ~SLList(); + + bool Insert(const Value &value, Iterator *iterator = NULL); + bool Remove(const Value &value); + void Remove(Iterator &iterator); + void RemoveAll(); + + bool Find(const Value &value, Iterator *iterator = NULL) const; + void GetIterator(Iterator *iterator) const; + +private: + friend class Iterator; + + Node *fHead; + NodeAllocator fNodeAllocator; + GetValue fGetValue; +}; + +// Iterator +SL_LIST_TEMPLATE_LIST +class SL_LIST_CLASS_NAME::Iterator { +public: + Iterator() : fList(NULL), fCurrent(NULL) {} + ~Iterator() {} + + inline Value *GetCurrent() + { + return (fList && fCurrent ? &fList->fGetValue(fCurrent) : NULL); + } + + inline Value *GetNext() + { + if (fCurrent) + fCurrent = fCurrent->next; + return GetCurrent(); + } + + inline void Remove() + { + if (fList) + fList->Remove(*this); + } + +private: + friend class SL_LIST_CLASS_NAME; + + inline void _SetTo(SL_LIST_CLASS_NAME *list, Node *previous, Node *node) + { + fList = list; + fPrevious = previous; + fCurrent = node; + } + + inline SL_LIST_CLASS_NAME *_GetList() const { return fList; } + inline Node *_GetPreviousNode() const { return fPrevious; } + inline Node *_GetCurrentNode() const { return fCurrent; } + +private: + SL_LIST_CLASS_NAME *fList; + Node *fPrevious; + Node *fCurrent; +}; + +// constructor +SL_LIST_TEMPLATE_LIST +SL_LIST_CLASS_NAME::SLList() + : fHead(NULL)/*, + fNodeAllocator(), + fGetValue()*/ +{ +} + +// constructor +SL_LIST_TEMPLATE_LIST +SL_LIST_CLASS_NAME::SLList(const NodeAllocator &nodeAllocator, + const GetValue &getValue) + : fHead(NULL), + fNodeAllocator(nodeAllocator), + fGetValue(getValue) +{ +} + +// destructor +SL_LIST_TEMPLATE_LIST +SL_LIST_CLASS_NAME::~SLList() +{ + RemoveAll(); +} + +// Insert +SL_LIST_TEMPLATE_LIST +bool +SL_LIST_CLASS_NAME::Insert(const Value &value, Iterator *iterator) +{ + Node *node = fNodeAllocator.Allocate(value); + if (node) { + node->next = fHead; + fHead = node; + if (iterator) + iterator->_SetTo(this, NULL, node); + } + return node; +} + +// Remove +SL_LIST_TEMPLATE_LIST +bool +SL_LIST_CLASS_NAME::Remove(const Value &value) +{ + Iterator iterator; + bool result = Find(value, &iterator); + if (result) + iterator.Remove(); + return result; +} + +// Remove +SL_LIST_TEMPLATE_LIST +void +SL_LIST_CLASS_NAME::Remove(Iterator &iterator) +{ + Node *node = iterator._GetCurrentNode(); + if (iterator._GetList() == this && node) { + Node *previous = iterator._GetPreviousNode(); + iterator._SetTo(this, previous, node->next); + if (previous) + previous->next = node->next; + else + fHead = node->next; + fNodeAllocator.Free(node); + } +} + +// RemoveAll +SL_LIST_TEMPLATE_LIST +void +SL_LIST_CLASS_NAME::RemoveAll() +{ + for (Node *node = fHead; node; ) { + Node *next = node->next; + fNodeAllocator.Free(node); + node = next; + } + fHead = NULL; +} + +// Find +SL_LIST_TEMPLATE_LIST +bool +SL_LIST_CLASS_NAME::Find(const Value &value, Iterator *iterator) const +{ + Node *node = fHead; + Node *previous = NULL; + while (node && fGetValue(node) != value) { + previous = node; + node = node->next; + } + if (node && iterator) { + iterator->_SetTo(const_cast(this), previous, + node); + } + return node; +} + +// GetIterator +SL_LIST_TEMPLATE_LIST +void +SL_LIST_CLASS_NAME::GetIterator(Iterator *iterator) const +{ + if (iterator) + iterator->_SetTo(const_cast(this), NULL, fHead); +} + +#endif // SL_LIST_H