Added bazaar/ADT/List.h.

git-svn-id: svn://ultimatepp.org/upp/trunk@6254 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
novo 2013-08-23 03:49:53 +00:00
parent 0c7a353e22
commit 40f507ed4d
5 changed files with 354 additions and 0 deletions

60
bazaar/ADT/ADT.cpp Normal file
View 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
View 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
View 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
View 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
View file

@ -0,0 +1,4 @@
#ifndef _ADT_icpp_init_stub
#define _ADT_icpp_init_stub
#include "Core/init"
#endif