added linkedList and test for linkedList
This commit is contained in:
@@ -4,6 +4,8 @@ include $(TOP)/configure/CONFIG
|
||||
|
||||
INC += pvType.h
|
||||
INC += noDefaultMethods.h
|
||||
INC += linkedListVoid.h
|
||||
INC += linkedList.h
|
||||
INC += lock.h
|
||||
INC += requester.h
|
||||
INC += serialize.h
|
||||
@@ -15,6 +17,7 @@ INC += serializeHelper.h
|
||||
LIBSRCS += byteBuffer.cpp
|
||||
LIBSRCS += bitSet.cpp
|
||||
LIBSRCS += serializeHelper.cpp
|
||||
LIBSRCS += linkedListVoid.cpp
|
||||
|
||||
LIBRARY=pvMisc
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/* linkedList.h */
|
||||
#ifndef LINKEDLIST_H
|
||||
#define LINKEDLIST_H
|
||||
#include "pvIntrospect.h"
|
||||
#include "linkedListVoid.h"
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
template <typename T>
|
||||
class LinkedList;
|
||||
|
||||
template <typename T>
|
||||
class LinkedListNode : private LinkedListVoidNode {
|
||||
public:
|
||||
LinkedListNode(T *object) : LinkedListVoidNode(object){}
|
||||
~LinkedListNode() {}
|
||||
T *getObject() { return (T *)LinkedListVoidNode::getObject();}
|
||||
bool isOnList() {return LinkedListVoidNode::isOnList();}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class LinkedList : private LinkedListVoid {
|
||||
public:
|
||||
LinkedList() : LinkedListVoid() {}
|
||||
~LinkedList() {}
|
||||
int getLength() {return LinkedListVoid::getLength();}
|
||||
void addTail(LinkedListNode<T> *listNode)
|
||||
{
|
||||
LinkedListVoid::addTail((LinkedListVoidNode *)listNode);
|
||||
}
|
||||
void addHead(LinkedListNode<T> *listNode)
|
||||
{
|
||||
LinkedListVoid::addHead((LinkedListVoidNode *)listNode);
|
||||
}
|
||||
void insertAfter(LinkedListNode<T> *listNode,
|
||||
LinkedListNode<T> *addNode)
|
||||
{
|
||||
LinkedListVoid::insertAfter(
|
||||
(LinkedListVoidNode *)listNode,(LinkedListVoidNode *)addNode);
|
||||
}
|
||||
void insertBefore(LinkedListNode<T> *listNode,
|
||||
LinkedListNode<T> *addNode)
|
||||
{
|
||||
LinkedListVoid::insertBefore((LinkedListVoidNode *)listNode,
|
||||
(LinkedListVoidNode *)addNode);
|
||||
}
|
||||
LinkedListNode<T> *removeTail(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::removeTail();
|
||||
}
|
||||
LinkedListNode<T> *removeHead(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::removeHead();
|
||||
}
|
||||
void remove(LinkedListNode<T> *listNode){
|
||||
LinkedListVoid::remove((LinkedListVoidNode *)listNode);
|
||||
}
|
||||
void remove(T *object){
|
||||
LinkedListVoid::remove(object);
|
||||
}
|
||||
LinkedListNode<T> *getHead(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getHead();
|
||||
}
|
||||
LinkedListNode<T> *getTail(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getTail();
|
||||
}
|
||||
LinkedListNode<T> *getNext(LinkedListNode<T> *listNode){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getNext(
|
||||
(LinkedListVoidNode *)listNode);
|
||||
}
|
||||
LinkedListNode<T> *getPrev(LinkedListNode<T> *listNode){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getPrev(
|
||||
(LinkedListVoidNode *)listNode);
|
||||
}
|
||||
bool isEmpty() { return LinkedListVoid::isEmpty();}
|
||||
bool contains(T *object) { return LinkedListVoid::contains(object);}
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
#endif /* LINKEDLIST_H */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
/* linkedListVoid.cpp */
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include "lock.h"
|
||||
#include "pvType.h"
|
||||
#include "pvIntrospect.h"
|
||||
#include "linkedListVoid.h"
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static volatile int64 totalNodeConstruct = 0;
|
||||
static volatile int64 totalNodeDestruct = 0;
|
||||
static volatile int64 totalListConstruct = 0;
|
||||
static volatile int64 totalListDestruct = 0;
|
||||
static Mutex *globalMutex = 0;
|
||||
static String alreadyOnList("already on list");
|
||||
|
||||
int64 LinkedListVoidNode::getTotalConstruct()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
return totalNodeConstruct;
|
||||
}
|
||||
|
||||
int64 LinkedListVoidNode::getTotalDestruct()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
return totalNodeDestruct;
|
||||
}
|
||||
|
||||
int64 LinkedListVoid::getTotalConstruct()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
return totalListConstruct;
|
||||
}
|
||||
|
||||
int64 LinkedListVoid::getTotalDestruct()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
return totalListDestruct;
|
||||
}
|
||||
|
||||
|
||||
void LinkedListVoid::init() {
|
||||
static Mutex mutex = Mutex();
|
||||
Lock xx(&mutex);
|
||||
if(globalMutex==0) globalMutex = new Mutex();
|
||||
}
|
||||
|
||||
LinkedListVoidNode::LinkedListVoidNode(void *object)
|
||||
: object(object),before(0),after(0)
|
||||
{
|
||||
LinkedListVoid::init();
|
||||
Lock xx(globalMutex);
|
||||
totalNodeConstruct++;
|
||||
}
|
||||
|
||||
LinkedListVoidNode::LinkedListVoidNode(bool isHead)
|
||||
: object(this),before(this),after(this)
|
||||
{
|
||||
LinkedListVoid::init();
|
||||
Lock xx(globalMutex);
|
||||
totalNodeConstruct++;
|
||||
}
|
||||
|
||||
LinkedListVoidNode::~LinkedListVoidNode()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
totalNodeDestruct++;
|
||||
}
|
||||
|
||||
void *LinkedListVoidNode::getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
bool LinkedListVoidNode::isOnList()
|
||||
{
|
||||
if(before==0 && after==0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkedListVoid::LinkedListVoid()
|
||||
: head(new LinkedListVoidNode(true)),length(0)
|
||||
{
|
||||
LinkedListVoid::init();
|
||||
Lock xx(globalMutex);
|
||||
totalListConstruct++;
|
||||
}
|
||||
|
||||
LinkedListVoid::~LinkedListVoid()
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
delete head;
|
||||
totalListDestruct++;
|
||||
}
|
||||
|
||||
int LinkedListVoid::getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::addTail(LinkedListVoidNode *node)
|
||||
{
|
||||
if(node->before!=0 || node->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
node->before = head->before;
|
||||
node->after = head;
|
||||
head->before->after = node;
|
||||
head->before = node;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::addHead(LinkedListVoidNode *node)
|
||||
{
|
||||
if(node->before!=0 || node->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
node->after = head->after;
|
||||
node->before = head;
|
||||
head->after->before = node;
|
||||
head->after = node;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::insertAfter(LinkedListVoidNode *node,
|
||||
LinkedListVoidNode *addNode)
|
||||
{
|
||||
LinkedListVoidNode *existingNode = node;
|
||||
LinkedListVoidNode *newNode = addNode;
|
||||
if(existingNode->after==0 || existingNode->before==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
}
|
||||
if(newNode->before!=0 || newNode->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
newNode->after = existingNode->after;
|
||||
newNode->before = existingNode;
|
||||
existingNode->after->before = newNode;
|
||||
existingNode->after = newNode;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::insertBefore(LinkedListVoidNode *node,
|
||||
LinkedListVoidNode *addNode)
|
||||
{
|
||||
LinkedListVoidNode *existingNode = node;
|
||||
LinkedListVoidNode *newNode = addNode;
|
||||
if(existingNode->after==0 || existingNode->before==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
}
|
||||
if(newNode->before!=0 || newNode->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
newNode->after = existingNode;
|
||||
newNode->before = existingNode->before;
|
||||
existingNode->before->after = newNode;
|
||||
existingNode->before = newNode;
|
||||
++length;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::removeTail()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
LinkedListVoidNode *node = head->before;
|
||||
remove(head->before);
|
||||
return node;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::removeHead()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
LinkedListVoidNode *node = head->after;
|
||||
remove(head->after);
|
||||
return node;
|
||||
}
|
||||
|
||||
void LinkedListVoid::remove(LinkedListVoidNode *listNode)
|
||||
{
|
||||
LinkedListVoidNode *node = listNode;
|
||||
if(node->before==0 || node->after==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
}
|
||||
LinkedListVoidNode *prev = node->before;
|
||||
LinkedListVoidNode *next = node->after;
|
||||
node->after = node->before = 0;
|
||||
prev->after = next;
|
||||
next->before = prev;
|
||||
length--;
|
||||
}
|
||||
|
||||
void LinkedListVoid::remove(void * object)
|
||||
{
|
||||
LinkedListVoidNode *node = getHead();
|
||||
while(node!=0) {
|
||||
if(node->getObject()==object) {
|
||||
remove(node);
|
||||
return;
|
||||
}
|
||||
node = getNext(node);
|
||||
}
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getHead()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
return head->after;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getTail()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
return head->before;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getNext(LinkedListVoidNode *listNode)
|
||||
{
|
||||
if(listNode->after==head) return 0;
|
||||
return listNode->after;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getPrev(LinkedListVoidNode *listNode)
|
||||
{
|
||||
if(listNode->before==head) return 0;
|
||||
return listNode->before;
|
||||
}
|
||||
|
||||
bool LinkedListVoid::isEmpty()
|
||||
{
|
||||
if(head->after==head) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LinkedListVoid::contains(void * object)
|
||||
{
|
||||
LinkedListVoidNode *node = getHead();
|
||||
while(node!=0) {
|
||||
if(node->getObject()==object) {
|
||||
return true;
|
||||
}
|
||||
node = getNext(node);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,69 @@
|
||||
/* linkedListVoid.h */
|
||||
#ifndef LINKEDLISTVOID_H
|
||||
#define LINKEDLISTVOID_H
|
||||
#include "pvIntrospect.h"
|
||||
#include "noDefaultMethods.h"
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class LinkedListVoid;
|
||||
class LinkedListVoidNode;
|
||||
|
||||
class LinkedListVoidNode {
|
||||
public:
|
||||
~LinkedListVoidNode();
|
||||
static int64 getTotalConstruct();
|
||||
static int64 getTotalDestruct();
|
||||
void *getObject();
|
||||
bool isOnList();
|
||||
protected:
|
||||
LinkedListVoidNode(void *object);
|
||||
private:
|
||||
LinkedListVoidNode(bool isHead);
|
||||
friend class LinkedListVoid;
|
||||
void *object;
|
||||
LinkedListVoidNode *before;
|
||||
LinkedListVoidNode *after;
|
||||
// do not implement the following
|
||||
LinkedListVoidNode(const LinkedListVoidNode&);
|
||||
LinkedListVoidNode & operator=(const LinkedListVoidNode&);
|
||||
};
|
||||
|
||||
class LinkedListVoid {
|
||||
public:
|
||||
~LinkedListVoid();
|
||||
static int64 getTotalConstruct();
|
||||
static int64 getTotalDestruct();
|
||||
int getLength();
|
||||
void addTail(LinkedListVoidNode *listNode);
|
||||
void addHead(LinkedListVoidNode *listNode);
|
||||
void insertAfter(LinkedListVoidNode *listNode,
|
||||
LinkedListVoidNode *addNode);
|
||||
void insertBefore(LinkedListVoidNode *listNode,
|
||||
LinkedListVoidNode *addNode);
|
||||
LinkedListVoidNode *removeTail();
|
||||
LinkedListVoidNode *removeHead();
|
||||
void remove(LinkedListVoidNode *listNode);
|
||||
void remove(void * object);
|
||||
LinkedListVoidNode *getHead();
|
||||
LinkedListVoidNode *getTail();
|
||||
LinkedListVoidNode *getNext(LinkedListVoidNode *listNode);
|
||||
LinkedListVoidNode *getPrev(LinkedListVoidNode *listNode);
|
||||
bool isEmpty();
|
||||
bool contains(void * object);
|
||||
protected:
|
||||
LinkedListVoid();
|
||||
private:
|
||||
static void init();
|
||||
friend class LinkedListVoidNode;
|
||||
LinkedListVoidNode *head;
|
||||
int length;
|
||||
// do not implement the following
|
||||
LinkedListVoid(const LinkedListVoid&);
|
||||
LinkedListVoid & operator=(const LinkedListVoid&);
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* LINKEDLISTVOID_H */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user