mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Added bazaar/ADT/List.h.
git-svn-id: svn://ultimatepp.org/upp/trunk@6254 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
0c7a353e22
commit
40f507ed4d
5 changed files with 354 additions and 0 deletions
60
bazaar/ADT/ADT.cpp
Normal file
60
bazaar/ADT/ADT.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
// vi: noexpandtab:tabstop=4
|
||||
|
||||
#include <Core/Core.h>
|
||||
#include "ADT.h"
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
#if 0
|
||||
CONSOLE_APP_MAIN
|
||||
{
|
||||
// SList tests.
|
||||
{
|
||||
using ADT::SListNode;
|
||||
using ADT::SList;
|
||||
|
||||
struct Node : public SListNode<Node> {
|
||||
Node(int i) : i(i) {}
|
||||
const int i;
|
||||
};
|
||||
|
||||
typedef SList<Node> List;
|
||||
Node n0(0), n1(1), n2(2), n3(3), n4(4), n5(5);
|
||||
List list;
|
||||
|
||||
list.PushFront(&n0).PushFront(&n1).PushFront(&n2).PushFront(&n3).PushFront(&n4);
|
||||
|
||||
for (SList<Node>::ForwardRange r = list.ForwardR(); !r.IsEmpty(); r.PopFront())
|
||||
r.Front();
|
||||
|
||||
for (SList<Node>::ForwardRange r = list.ForwardR(); !r.IsEmpty(); r.PopFront())
|
||||
Cout() << r.Front().i << " ";
|
||||
Cout() << EOL;
|
||||
}
|
||||
|
||||
// DList tests.
|
||||
{
|
||||
using ADT::DListNode;
|
||||
using ADT::DList;
|
||||
|
||||
struct Node : public DListNode<Node>
|
||||
{
|
||||
Node(int i) : i(i) {}
|
||||
const int i;
|
||||
};
|
||||
|
||||
typedef DList<Node> List;
|
||||
Node n0(0), n1(1), n2(2), n3(3), n4(4), n5(5);
|
||||
List list;
|
||||
|
||||
list << n0 << n1 << n2 << n3 << n4;
|
||||
ASSERT(list.GetLast() == &n4);
|
||||
|
||||
for (DList<Node>::ForwardRange r = list.ForwardR(); !r.IsEmpty(); r.PopFront())
|
||||
r.Front();
|
||||
|
||||
n1.ReplaceThisWith(&n5);
|
||||
n0.RemoveThis();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
23
bazaar/ADT/ADT.h
Normal file
23
bazaar/ADT/ADT.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// vi: noexpandtab:tabstop=4
|
||||
|
||||
#ifndef _ADT_ADT_h
|
||||
#define _ADT_ADT_h
|
||||
|
||||
#ifdef flagNONAMESPACE
|
||||
#define NAMESPACE_ADT
|
||||
#define END_ADT_NAMESPACE
|
||||
#define ADT
|
||||
#else
|
||||
#define NAMESPACE_ADT namespace adt {
|
||||
#define END_ADT_NAMESPACE }
|
||||
#define ADT adt
|
||||
#endif
|
||||
|
||||
NAMESPACE_ADT
|
||||
|
||||
#include "List.h"
|
||||
|
||||
END_ADT_NAMESPACE
|
||||
|
||||
|
||||
#endif
|
||||
13
bazaar/ADT/ADT.upp
Normal file
13
bazaar/ADT/ADT.upp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
description "Abstract Data Types\377";
|
||||
|
||||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
List.h,
|
||||
ADT.h,
|
||||
ADT.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "SSE2";
|
||||
|
||||
254
bazaar/ADT/List.h
Normal file
254
bazaar/ADT/List.h
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
// vi: noexpandtab:tabstop=4
|
||||
|
||||
#ifndef _ADT_List_h
|
||||
#define _ADT_List_h
|
||||
|
||||
template<class T>
|
||||
struct SListNode {
|
||||
SListNode() : next(NULL) {}
|
||||
|
||||
T* GetNext() const { return next; }
|
||||
void SetNext(T* other) { next = other; }
|
||||
|
||||
// Return removed node.
|
||||
T* RemoveNext() const {
|
||||
T* n = GetNext();
|
||||
SetNext(n->GetNext());
|
||||
return n;
|
||||
}
|
||||
|
||||
void InsertAfterThis(T* first, T* last) {
|
||||
last->SetNext(next);
|
||||
SetNext(first);
|
||||
}
|
||||
void InsertAfterThis(T* other) {
|
||||
InsertAfterThis(other, other);
|
||||
}
|
||||
|
||||
private:
|
||||
T* next;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct DListNode {
|
||||
DListNode() : prev(NULL), next(NULL) {}
|
||||
|
||||
T* GetPrev() const { return prev; }
|
||||
T* GetNext() const { return next; }
|
||||
|
||||
void SetPrev(T* other) { prev = other; }
|
||||
void SetNext(T* other) { next = other; }
|
||||
|
||||
void RemoveThis() const {
|
||||
GetPrev()->SetNext(next);
|
||||
GetNext()->SetPrev(prev);
|
||||
}
|
||||
// Return removed node.
|
||||
T* RemoveNext() {
|
||||
T* n = GetNext();
|
||||
n->RemoveThis();
|
||||
return n;
|
||||
}
|
||||
// Return removed node.
|
||||
T* RemovePrev() {
|
||||
T* n = GetPrev();
|
||||
n->RemoveThis();
|
||||
return n;
|
||||
}
|
||||
|
||||
void ReplaceThisWith(T* first, T* last) const {
|
||||
GetPrev()->SetNext(first);
|
||||
GetNext()->SetPrev(last);
|
||||
|
||||
first->SetPrev(prev);
|
||||
last->SetNext(next);
|
||||
}
|
||||
void ReplaceThisWith(T* other) const {
|
||||
ReplaceThisWith(other, other);
|
||||
}
|
||||
|
||||
void InsertAfterThis(T* first, T* last) {
|
||||
first->SetPrev(next->prev);
|
||||
GetNext()->SetPrev(last);
|
||||
|
||||
// Code below is from SListNode::InsertAfterThis().
|
||||
last->SetNext(next);
|
||||
SetNext(first);
|
||||
}
|
||||
void InsertAfterThis(T* other) {
|
||||
InsertAfterThis(other, other);
|
||||
}
|
||||
|
||||
void InsertBeforeThis(T* first, T* last) {
|
||||
last->SetNext(next->prev);
|
||||
first->SetPrev(prev);
|
||||
|
||||
GetPrev()->SetNext(first);
|
||||
SetPrev(last);
|
||||
}
|
||||
void InsertBeforeThis(T* other) {
|
||||
InsertBeforeThis(other, other);
|
||||
}
|
||||
|
||||
private:
|
||||
T* prev;
|
||||
T* next;
|
||||
};
|
||||
|
||||
// Intrusive single-linked list with sentinel.
|
||||
// Names PushFront and PopFront are kept for compatibility with DList.
|
||||
template<class T>
|
||||
struct SList {
|
||||
typedef SList<T> SelfType;
|
||||
|
||||
SList() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
sentinel.SetNext((T*)&sentinel);
|
||||
}
|
||||
|
||||
T* GetFirst() const { return (T*)sentinel.GetNext(); }
|
||||
T* GetEnd () const { return (T*)&sentinel; }
|
||||
|
||||
bool IsEmpty() const { return sentinel.GetNext() == (const T*)&sentinel; }
|
||||
bool IsFirst(const T* node) const { return node == sentinel.GetNext(); }
|
||||
bool IsNull (const T* node) const { return node == (const T*)&sentinel; }
|
||||
|
||||
SelfType& PushFront(T* first, T* last) {
|
||||
sentinel.InsertAfterThis(first, last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SelfType& PushFront(T* node) {
|
||||
return PushFront(node, node);
|
||||
}
|
||||
|
||||
T* PopFront() const {
|
||||
ASSERT(!IsEmpty());
|
||||
return sentinel.RemoveNext();
|
||||
}
|
||||
///
|
||||
SelfType& operator <<(T& n) { return PushFront(&n); }
|
||||
|
||||
///
|
||||
struct ForwardRange {
|
||||
typedef T ValueType;
|
||||
|
||||
ForwardRange(const SList<T>& l) : list(&l), n(const_cast<T*>(l.GetFirst())) {}
|
||||
|
||||
bool IsEmpty() const { return list->IsNull(n); }
|
||||
void PopFront() { ASSERT(!IsEmpty()); n = n->GetNext(); }
|
||||
T& Front() const { return *n; }
|
||||
|
||||
protected:
|
||||
const SList<T>* list;
|
||||
T* n;
|
||||
};
|
||||
|
||||
ForwardRange ForwardR() const { return ForwardRange(*this); }
|
||||
|
||||
private:
|
||||
SListNode<T> sentinel;
|
||||
};
|
||||
|
||||
// Intrusive double-linked list with sentinel.
|
||||
template<class T>
|
||||
struct DList {
|
||||
typedef DList<T> SelfType;
|
||||
|
||||
DList() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
sentinel.SetNext((T*)&sentinel);
|
||||
sentinel.SetPrev((T*)&sentinel);
|
||||
}
|
||||
|
||||
T* GetFirst() const { return (T*)sentinel.GetNext(); }
|
||||
T* GetLast () const { return (T*)sentinel.GetPrev(); }
|
||||
T* GetEnd () const { return (T*)&sentinel; }
|
||||
|
||||
bool IsEmpty() const { return sentinel.GetNext() == (const T*)&sentinel; }
|
||||
bool IsFirst(const T* node) const { return node == sentinel.GetNext(); }
|
||||
bool IsLast (const T* node) const { return node == sentinel.GetPrev(); }
|
||||
bool IsNull (const T* node) const { return node == (const T*)&sentinel; }
|
||||
|
||||
SelfType& PushFront(T* first, T* last) {
|
||||
sentinel.InsertAfterThis(first, last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SelfType& PushBack(T* first, T* last) {
|
||||
sentinel.InsertBeforeThis(first, last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SelfType& PushFront(T* node) {
|
||||
return PushFront(node, node);
|
||||
}
|
||||
|
||||
SelfType& PushBack(T* node) {
|
||||
return PushBack(node, node);
|
||||
}
|
||||
|
||||
T* PopFront() const {
|
||||
return Remove(GetFirst());
|
||||
}
|
||||
|
||||
T* PopBack() const {
|
||||
return Remove(GetLast());
|
||||
}
|
||||
|
||||
static T* Remove(T* node) {
|
||||
node->Remove();
|
||||
return node;
|
||||
}
|
||||
|
||||
SelfType& PushFront(DList<T>& other) {
|
||||
if (!other.IsEmpty())
|
||||
PushFront(other.GetFirst(), other.GetLast());
|
||||
return *this;
|
||||
}
|
||||
void PickPushFront(DList<T>& other) {
|
||||
PushFront(other);
|
||||
other.Clear();
|
||||
}
|
||||
|
||||
SelfType& PushBack(DList<T>& other) {
|
||||
if (!other.IsEmpty())
|
||||
PushBack(other.GetFirst(), other.GetLast());
|
||||
return *this;
|
||||
}
|
||||
void PickPushBack(DList<T>& other) {
|
||||
PushBack(other);
|
||||
other.Clear();
|
||||
}
|
||||
|
||||
///
|
||||
SelfType& operator <<(T& n) { return PushBack(&n); }
|
||||
|
||||
///
|
||||
struct ForwardRange {
|
||||
typedef T ValueType;
|
||||
|
||||
ForwardRange(const DList<T>& l) : list(&l), n(const_cast<T*>(l.GetFirst())) {}
|
||||
|
||||
bool IsEmpty() const { return list->IsNull(n); }
|
||||
void PopFront() { ASSERT(!IsEmpty()); n = n->GetNext(); }
|
||||
T& Front() const { return *n; }
|
||||
|
||||
protected:
|
||||
const DList<T>* list;
|
||||
T* n;
|
||||
};
|
||||
|
||||
ForwardRange ForwardR() const { return ForwardRange(*this); }
|
||||
|
||||
private:
|
||||
DListNode<T> sentinel;
|
||||
};
|
||||
|
||||
#endif
|
||||
4
bazaar/ADT/init
Normal file
4
bazaar/ADT/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _ADT_icpp_init_stub
|
||||
#define _ADT_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue