1121 lines
22 KiB
C++
1121 lines
22 KiB
C++
/*
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2011, University in Hagen, Department of Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
2012, May Simone Jandt
|
|
|
|
1 Defines and Includes
|
|
|
|
*/
|
|
|
|
#ifndef JLIST_H
|
|
#define JLIST_H
|
|
|
|
#include <ostream>
|
|
#include "ListUtils.h"
|
|
#include "NestedList.h"
|
|
#include "../../Tools/Flob/DbArray.h"
|
|
#include "Symbols.h"
|
|
#include "Attribute.h"
|
|
#include "StandardTypes.h"
|
|
#include "JRouteInterval.h"
|
|
#include "RouteLocation.h"
|
|
#include "NetDistanceGroup.h"
|
|
|
|
namespace jnetwork {
|
|
/*
|
|
1 class ~List~
|
|
|
|
Template class that enables us to use a sorted list of an Attribute of
|
|
kind DATA as attribute in relations.
|
|
|
|
*/
|
|
|
|
template<class ListElem>
|
|
class JList: public Attribute
|
|
{
|
|
|
|
/*
|
|
1.1 Public deklarations
|
|
|
|
*/
|
|
public:
|
|
|
|
/*
|
|
1.1.1. Constructors and deconstructors
|
|
|
|
*/
|
|
|
|
explicit JList(bool defined);
|
|
JList(const JList<ListElem>& other);
|
|
explicit JList(const ListElem& elem);
|
|
|
|
~JList();
|
|
|
|
/*
|
|
1.1.1 Getter and Setter for private Attributes
|
|
|
|
*/
|
|
|
|
DbArray<ListElem> GetList() const;
|
|
|
|
void SetList(const DbArray<ListElem> inList);
|
|
|
|
/*
|
|
1.1.1 Overwrite Methods from Attribute
|
|
|
|
*/
|
|
|
|
void CopyFrom(const Attribute* right);
|
|
StorageType GetStorageType() const;
|
|
size_t HashValue() const;
|
|
JList* Clone() const;
|
|
bool Adjacent(const Attribute* attrib) const;
|
|
static int Compare(const void* ls, const void* rs);
|
|
int Compare(const Attribute* rhs) const;
|
|
int Compare(const JList<ListElem>& in) const;
|
|
int NumOfFLOBs () const;
|
|
Flob* GetFLOB(const int n);
|
|
void Clear();
|
|
void Destroy();
|
|
size_t Sizeof() const;
|
|
std::ostream& Print(std::ostream& os) const;
|
|
static const std::string BasicType();
|
|
static const bool checkType(const ListExpr type);
|
|
|
|
/*
|
|
1.1.1 Standard Methods
|
|
|
|
*/
|
|
|
|
JList<ListElem>& operator=(const JList<ListElem>& other);
|
|
|
|
bool operator==(const JList<ListElem>& other) const;
|
|
bool operator!=(const JList<ListElem>& other) const;
|
|
bool operator<(const JList<ListElem>& other) const;
|
|
bool operator<=(const JList<ListElem>& other) const;
|
|
bool operator>(const JList<ListElem>& other) const;
|
|
bool operator>=(const JList<ListElem>& other) const;
|
|
|
|
JList<ListElem>& operator+=(const ListElem& e);
|
|
JList<ListElem>& operator+=(const JList<ListElem>& other);
|
|
|
|
JList<ListElem>& operator-=(const ListElem& e);
|
|
JList<ListElem>& operator-=(const JList<ListElem>& other);
|
|
|
|
|
|
/*
|
|
1.1.1 Operators for Secondo Integration
|
|
|
|
*/
|
|
|
|
static ListExpr Out(ListExpr typeInfo, Word value);
|
|
static Word In(const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct);
|
|
static Word Create(const ListExpr typeInfo);
|
|
static void Delete( const ListExpr typeInfo, Word& w );
|
|
static void Close( const ListExpr typeInfo, Word& w );
|
|
static Word Clone( const ListExpr typeInfo, const Word& w );
|
|
static void* Cast( void* addr );
|
|
static bool KindCheck( ListExpr type, ListExpr& errorInfo );
|
|
static int SizeOf();
|
|
static ListExpr Property();
|
|
static std::string Example();
|
|
|
|
/*
|
|
1.1.1 Helpful Operators
|
|
|
|
1.1.1.1 ~GetNoOfComponents~
|
|
|
|
Returns the number of list elements.
|
|
|
|
*/
|
|
|
|
int GetNoOfComponents() const;
|
|
|
|
/*
|
|
1.1.1.1 ~Get~
|
|
|
|
Returns the element at position ~i~ as ~res~.
|
|
|
|
*/
|
|
|
|
void Get(const int i, ListElem& res) const;
|
|
void Get(const int i, ListElem* res) const;
|
|
|
|
/*
|
|
1.1.1.1 ~isEmpty~
|
|
|
|
Returns true if the ~elemlist~ is empty or not defined.
|
|
|
|
*/
|
|
|
|
bool IsEmpty() const;
|
|
|
|
/*
|
|
1.1.1.1 ~Contains~
|
|
|
|
Checks if a ~e~ is in the list. If ~e~ is in the list then ~true~ is
|
|
returned and the position in the list is given by ~pos~. Elsewhere ~false~
|
|
is returned and ~pos~ is -1;
|
|
|
|
*/
|
|
|
|
bool Contains(const ListElem& e, int& pos);
|
|
|
|
/*
|
|
1.1.1.1 ~TrimToSize~
|
|
|
|
Reduces the list size to the number of elements.
|
|
|
|
*/
|
|
|
|
void TrimToSize();
|
|
|
|
/*
|
|
1.1.1.1 ~Restrict~
|
|
|
|
Restricts the list to the given values
|
|
|
|
*/
|
|
|
|
JList<ListElem>& Restrict(const ListElem& sub);
|
|
JList<ListElem>& Restrict(const JList<ListElem>& sub);
|
|
void Restrict(const std::vector<std::pair<int,int> >& interval){
|
|
Attribute::Restrict(interval);
|
|
}
|
|
|
|
/*
|
|
1.1.1.1 Controll Bulkload of lists
|
|
|
|
StartBulkload enables insertion of elements in random order into an empty list.
|
|
|
|
*/
|
|
|
|
void StartBulkload();
|
|
|
|
/*
|
|
EndBulkload ensures that the list elements inserted during bulkload are pretty
|
|
sorted.
|
|
|
|
*/
|
|
|
|
void EndBulkload();
|
|
|
|
/*
|
|
1.1 Private declarations
|
|
|
|
*/
|
|
|
|
private:
|
|
|
|
/*
|
|
1.1.1 Attributes
|
|
|
|
*/
|
|
|
|
DbArray<ListElem> elemlist;
|
|
bool activBulkload;
|
|
|
|
/*
|
|
1.1.1 Default Constructors
|
|
|
|
Private because should only be used in Cast-Function.
|
|
|
|
*/
|
|
|
|
JList();
|
|
|
|
/*
|
|
1.1.1. Operations
|
|
|
|
1.1.1.1 ~Put~
|
|
|
|
Writes the data of ~p~ at position ~i~ of ~elemlist~. Private danger of
|
|
conflict with sorted criteria.
|
|
|
|
*/
|
|
|
|
bool Put(const int i, const ListElem& p);
|
|
|
|
/*
|
|
1.1.1 ~RemoveDuplicates~
|
|
|
|
Duplicates will be removed from list.
|
|
|
|
*/
|
|
|
|
void RemoveDuplicates();
|
|
|
|
/*
|
|
1.1.1 ~Sort~
|
|
|
|
Sorts the elementlist and removes duplicates.
|
|
|
|
*/
|
|
|
|
void Sort();
|
|
|
|
};
|
|
|
|
/*
|
|
1 Definition of Listclasses.
|
|
|
|
*/
|
|
|
|
typedef JList<CcInt> JListInt;
|
|
typedef JList<JRouteInterval> JListRInt;
|
|
typedef JList<RouteLocation> JListRLoc;
|
|
typedef JList<NetDistanceGroup> JListNDG;
|
|
|
|
/*
|
|
1 Implementation of class ~JList~
|
|
|
|
1.1. Constructors and deconstructors
|
|
|
|
*/
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>::JList():Attribute()
|
|
{}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>::JList(bool defined): Attribute(defined), elemlist(0),
|
|
activBulkload(false)
|
|
{}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>::JList(const JList<ListElem>& other) :
|
|
Attribute(other.IsDefined()), elemlist(other.GetList().Size()),
|
|
activBulkload(false)
|
|
{
|
|
if (other.IsDefined())
|
|
elemlist.copyFrom(other.GetList());
|
|
}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>::JList(const ListElem& inId) :
|
|
Attribute(true), elemlist(0), activBulkload(false)
|
|
{
|
|
elemlist.Append(inId);
|
|
}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>::~JList()
|
|
{}
|
|
|
|
/*
|
|
1.1 Getter and Setter for private Attributes
|
|
|
|
*/
|
|
|
|
template<class ListElem>
|
|
DbArray<ListElem> JList<ListElem>::GetList() const
|
|
{
|
|
assert(IsDefined());
|
|
return elemlist;
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::SetList(const DbArray<ListElem> inList)
|
|
{
|
|
elemlist.copyFrom(inList);
|
|
Sort();
|
|
RemoveDuplicates();
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::StartBulkload()
|
|
{
|
|
SetDefined(true);
|
|
activBulkload = true;
|
|
elemlist.clean();
|
|
elemlist.TrimToSize();
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::EndBulkload()
|
|
{
|
|
if (!IsDefined())
|
|
{
|
|
Clear();
|
|
SetDefined(false);
|
|
}
|
|
else
|
|
{
|
|
activBulkload = false;
|
|
Sort();
|
|
RemoveDuplicates();
|
|
TrimToSize();
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
1.1 Override Methods from Attribute
|
|
|
|
*/
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::CopyFrom(const Attribute* right)
|
|
{
|
|
*this = *((JList<ListElem>*)right);
|
|
}
|
|
|
|
template<class ListElem>
|
|
Attribute::StorageType JList<ListElem>::GetStorageType() const
|
|
{
|
|
return Default;
|
|
}
|
|
|
|
template<class ListElem>
|
|
size_t JList<ListElem>::HashValue() const
|
|
{
|
|
size_t result = 0;
|
|
if (IsDefined())
|
|
{
|
|
ListElem e(false);
|
|
for(int i = 0; i < elemlist.Size(); i++)
|
|
{
|
|
elemlist.Get(i, e);
|
|
result += e.HashValue();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>* JList<ListElem>::Clone() const
|
|
{
|
|
return new JList<ListElem>(*this);
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::Adjacent(const Attribute* attrib) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
template<class ListElem>
|
|
int JList<ListElem>::Compare(const void* ls, const void* rs)
|
|
{
|
|
JList<ListElem> lhs(*(JList<ListElem>*) ls);
|
|
JList<ListElem> rhs(*(JList<ListElem>*) rs);
|
|
return lhs.Compare(rhs);
|
|
}
|
|
|
|
template<class ListElem>
|
|
int JList<ListElem>::Compare(const Attribute* rhs) const
|
|
{
|
|
JList<ListElem> in(*(JList<ListElem>*) rhs);
|
|
return Compare(in);
|
|
}
|
|
|
|
template<class ListElem>
|
|
int JList<ListElem>::Compare(const JList<ListElem>& in) const
|
|
{
|
|
assert(!activBulkload && !in.activBulkload);
|
|
if (!IsDefined() && !in.IsDefined()) return 0;
|
|
else
|
|
{
|
|
if (IsDefined() && !in.IsDefined()) return 1;
|
|
else
|
|
{
|
|
if (!IsDefined() && in.IsDefined()) return -1;
|
|
else
|
|
{
|
|
if (elemlist.Size() < in.elemlist.Size()) return -1;
|
|
else
|
|
{
|
|
if (elemlist.Size() > in.elemlist.Size()) return 1;
|
|
else
|
|
{
|
|
ListElem p1(false);
|
|
ListElem p2(false);
|
|
for(int i = 0; i < elemlist.Size(); i++)
|
|
{
|
|
elemlist.Get(i,p1);
|
|
in.elemlist.Get(i,p2);
|
|
int res = p1.Compare (p2);
|
|
if (res != 0) return res;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template<class ListElem>
|
|
int JList<ListElem>::NumOfFLOBs() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
template<class ListElem>
|
|
Flob* JList<ListElem>::GetFLOB(const int n)
|
|
{
|
|
if (n == 0) return &elemlist;
|
|
else return 0;
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::Clear()
|
|
{
|
|
elemlist.clean();
|
|
activBulkload = false;
|
|
SetDefined(true);
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::Destroy()
|
|
{
|
|
elemlist.Destroy();
|
|
}
|
|
|
|
template<class ListElem>
|
|
size_t JList<ListElem>::Sizeof() const
|
|
{
|
|
return sizeof(JList<ListElem>);
|
|
}
|
|
|
|
template<class ListElem>
|
|
std::ostream& JList<ListElem>::Print(std::ostream& os) const
|
|
{
|
|
if (IsDefined())
|
|
{
|
|
os << "Begin List: " << endl;
|
|
ListElem p(false);
|
|
for (int i = 0; i < elemlist.Size(); i++)
|
|
{
|
|
os << i << ". ";
|
|
elemlist.Get(i,p);
|
|
p.Print(os);
|
|
os << endl;
|
|
}
|
|
os << endl << "end of List." << endl;
|
|
}
|
|
else
|
|
{
|
|
os << "List is " << Symbol::UNDEFINED() << endl;
|
|
}
|
|
return os;
|
|
}
|
|
|
|
template<class ListElem>
|
|
const std::string JList<ListElem>::BasicType()
|
|
{
|
|
return "list" + ListElem::BasicType();
|
|
}
|
|
|
|
template<class ListElem>
|
|
const bool JList<ListElem>::checkType(const ListExpr type)
|
|
{
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
|
|
/*
|
|
1.4 Standard Methods
|
|
|
|
*/
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>& JList<ListElem>::operator=(const JList<ListElem>& other)
|
|
{
|
|
SetDefined(other.IsDefined());
|
|
if (other.IsDefined())
|
|
{
|
|
elemlist.copyFrom(other.GetList());
|
|
activBulkload = other.activBulkload;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::operator==(const JList<ListElem>& other) const
|
|
{
|
|
return (Compare(other) == 0);
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::operator!=(const JList< ListElem >& other) const
|
|
{
|
|
return (Compare(other) != 0);
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::operator<(const JList< ListElem >& other) const
|
|
{
|
|
return (Compare(other) < 0);
|
|
}
|
|
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::operator<=(const JList<ListElem>& other) const
|
|
{
|
|
return (Compare(other)<1);
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::operator>(const JList<ListElem>& other) const
|
|
{
|
|
return (Compare(other) > 0 );
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::operator>=(const JList<ListElem>& other) const
|
|
{
|
|
return (Compare(other) > -1);
|
|
}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>& JList<ListElem>::operator+=(const ListElem& e)
|
|
{
|
|
if (IsDefined() && e.IsDefined())
|
|
{
|
|
if(activBulkload)
|
|
elemlist.Append(e);
|
|
else
|
|
{
|
|
int pos = 0;
|
|
elemlist.Find(&e, ListElem::Compare, pos);
|
|
ListElem actElem, nextElem;
|
|
elemlist.Get(pos,actElem);
|
|
if (actElem.Compare(e) != 0)
|
|
{
|
|
nextElem = actElem;
|
|
elemlist.Put(pos, e);
|
|
pos++;
|
|
while(pos < elemlist.Size())
|
|
{
|
|
elemlist.Get(pos, actElem);
|
|
elemlist.Put(pos, nextElem);
|
|
nextElem = actElem;
|
|
pos++;
|
|
}
|
|
elemlist.Append(nextElem);
|
|
}
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>& JList<ListElem>::operator+=(const JList<ListElem>& l)
|
|
{
|
|
if (IsDefined() && l.IsDefined())
|
|
{
|
|
DbArray<ListElem> source = l.GetList();
|
|
if (activBulkload)
|
|
{
|
|
elemlist.Append(source);
|
|
}
|
|
else
|
|
{
|
|
int i = 0;
|
|
int j = 0;
|
|
ListElem actElem, actSource;
|
|
DbArray<ListElem>* result = new DbArray<ListElem>(0);
|
|
while (i < elemlist.Size() && j < source.Size())
|
|
{
|
|
elemlist.Get(i,actElem);
|
|
source.Get(j,actSource);
|
|
switch(actElem.Compare(actSource))
|
|
{
|
|
case -1:
|
|
{
|
|
result->Append(actElem);
|
|
i++;
|
|
break;
|
|
}
|
|
|
|
case 0:
|
|
{
|
|
result->Append(actElem);
|
|
i++;
|
|
j++;
|
|
break;
|
|
}
|
|
|
|
case 1:
|
|
{
|
|
result->Append(actSource);
|
|
j++;
|
|
break;
|
|
}
|
|
|
|
default: //should never happen
|
|
{
|
|
assert(false);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
while (i < elemlist.Size())
|
|
{
|
|
elemlist.Get(i, actElem);
|
|
result->Append(actElem);
|
|
i++;
|
|
}
|
|
while (j < source.Size())
|
|
{
|
|
elemlist.Get(j, actSource);
|
|
result->Append(actSource);
|
|
j++;
|
|
}
|
|
elemlist.clean();
|
|
elemlist.copyFrom(*result);
|
|
result->Destroy();
|
|
delete result;
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>& JList<ListElem>::operator-=(const ListElem& e)
|
|
{
|
|
if (IsDefined() && e.IsDefined() && !IsEmpty())
|
|
{
|
|
int pos;
|
|
if (elemlist.Find(&e, ListElem::Compare, pos)){
|
|
ListElem actElem;
|
|
elemlist.Get(pos, actElem);
|
|
if (actElem == e)
|
|
{
|
|
pos++;
|
|
while(pos < elemlist.Size())
|
|
{
|
|
elemlist.Get(pos, actElem);
|
|
elemlist.Put(pos-1, actElem);
|
|
pos++;
|
|
}
|
|
elemlist.resize(elemlist.Size()-1);
|
|
}
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>& JList<ListElem>::operator-=(const JList<ListElem>& l)
|
|
{
|
|
if (IsDefined() && l.IsDefined() && !IsEmpty() && !l.IsEmpty())
|
|
{
|
|
int i = 0;
|
|
int j = 0;
|
|
ListElem actElem, actSource;
|
|
DbArray<ListElem>* result = new DbArray<ListElem>(0);
|
|
DbArray<ListElem> source = l.GetList();
|
|
while (i < elemlist.Size() && j < source.Size())
|
|
{
|
|
elemlist.Get(i,actElem);
|
|
source.Get(j,actSource);
|
|
switch(actElem.Compare(actSource))
|
|
{
|
|
case -1:
|
|
{
|
|
result->Append(actElem);
|
|
i++;
|
|
break;
|
|
}
|
|
|
|
case 0:
|
|
{
|
|
j++;
|
|
i++;
|
|
break;
|
|
}
|
|
|
|
case 1:
|
|
{
|
|
j++;
|
|
break;
|
|
}
|
|
|
|
default: //should never happen
|
|
{
|
|
assert(false);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
while(i < elemlist.Size())
|
|
{
|
|
elemlist.Get(i,actElem);
|
|
result->Append(actElem);
|
|
i++;
|
|
}
|
|
elemlist.clean();
|
|
elemlist.copyFrom(*result);
|
|
result->Destroy();
|
|
delete result;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
/*
|
|
1.5 Operators for Secondo Integration
|
|
|
|
*/
|
|
|
|
template<class ListElem>
|
|
ListExpr JList<ListElem>::Out(ListExpr typeInfo, Word value)
|
|
{
|
|
JList<ListElem>* source = (JList<ListElem>*) value.addr;
|
|
if (source->IsDefined())
|
|
{
|
|
if(source->elemlist.Size() == 0) return nl->TheEmptyList();
|
|
else
|
|
{
|
|
NList result(nl->TheEmptyList());
|
|
ListElem e(false);
|
|
bool first = true;
|
|
for (int i = 0; i < source->elemlist.Size(); i++)
|
|
{
|
|
source->elemlist.Get(i,e);
|
|
Word w = SetWord(&e);
|
|
NList elem(ListElem::Out(nl->TheEmptyList(), w));
|
|
if (first)
|
|
{
|
|
result = elem.enclose();
|
|
first = false;
|
|
}
|
|
else
|
|
{
|
|
result.append(elem);
|
|
}
|
|
}
|
|
return result.listExpr();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return nl->SymbolAtom(Symbol::UNDEFINED());
|
|
}
|
|
}
|
|
|
|
template<class ListElem>
|
|
Word JList<ListElem>::In(const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct)
|
|
{
|
|
if(nl->IsEqual(instance,Symbol::UNDEFINED()))
|
|
{
|
|
correct=true;
|
|
return SetWord(new JList<ListElem>(false));
|
|
}
|
|
|
|
ListExpr rest = instance;
|
|
ListExpr first = nl->TheEmptyList();
|
|
correct = true;
|
|
JList<ListElem>* in = new JList<ListElem>(true);
|
|
in->StartBulkload();
|
|
while( !nl->IsEmpty( rest ) )
|
|
{
|
|
first = nl->First( rest );
|
|
rest = nl->Rest( rest );
|
|
Word w = ListElem::In(nl->TheEmptyList(), first, errorPos,
|
|
errorInfo, correct);
|
|
if (correct)
|
|
{
|
|
ListElem* e = (ListElem*) w.addr;
|
|
in->operator+=(*e);
|
|
e->DeleteIfAllowed();
|
|
e = 0;
|
|
}
|
|
else
|
|
{
|
|
in->DeleteIfAllowed();
|
|
in = 0;
|
|
return SetWord(Address(0));
|
|
}
|
|
}
|
|
in->EndBulkload();
|
|
return SetWord(in);
|
|
}
|
|
|
|
template<class ListElem>
|
|
Word JList<ListElem>::Create(const ListExpr typeInfo)
|
|
{
|
|
return SetWord(new JList<ListElem>(false));
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::Delete( const ListExpr typeInfo, Word& w )
|
|
{
|
|
((JList<ListElem>*) w.addr)->Destroy();
|
|
delete ((JList<ListElem>*) w.addr);
|
|
w.addr = 0;
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::Close( const ListExpr typeInfo, Word& w )
|
|
{
|
|
delete ((JList<ListElem>*) w.addr);
|
|
w.addr = 0;
|
|
}
|
|
|
|
template<class ListElem>
|
|
Word JList<ListElem>::Clone( const ListExpr typeInfo, const Word& w )
|
|
{
|
|
return new JList<ListElem>(*((JList<ListElem>*) w.addr));
|
|
}
|
|
|
|
template<class ListElem>
|
|
void* JList<ListElem>::Cast( void* addr )
|
|
{
|
|
return (new (addr) JList<ListElem>);
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::KindCheck( ListExpr type, ListExpr& errorInfo )
|
|
{
|
|
return checkType(type);
|
|
}
|
|
|
|
template<class ListElem>
|
|
int JList<ListElem>::SizeOf()
|
|
{
|
|
return sizeof(JList<ListElem>);
|
|
}
|
|
|
|
template<class ListElem>
|
|
ListExpr JList<ListElem>::Property()
|
|
{
|
|
return nl->TwoElemList(
|
|
nl->FourElemList(
|
|
nl->StringAtom("Signature"),
|
|
nl->StringAtom("Example Type List"),
|
|
nl->StringAtom("List Rep"),
|
|
nl->StringAtom("Example List")),
|
|
nl->FourElemList(
|
|
nl->StringAtom("-> " + Kind::DATA()),
|
|
nl->StringAtom(BasicType()),
|
|
nl->TextAtom("("+ ListElem::BasicType() + " ... " +
|
|
ListElem::BasicType() + "), list of " +
|
|
ListElem::BasicType()+"."),
|
|
nl->TextAtom("("+ Example() + ")")));
|
|
}
|
|
|
|
template<class ListElem>
|
|
std::string JList<ListElem>::Example(){
|
|
return ListElem::Example();
|
|
}
|
|
|
|
|
|
/*
|
|
1.1 Helpful Operators
|
|
|
|
*/
|
|
|
|
template<class ListElem>
|
|
int JList<ListElem>::GetNoOfComponents()const
|
|
{
|
|
if (IsDefined()) return elemlist.Size();
|
|
else return -1;
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::Get(const int i, ListElem& res) const
|
|
{
|
|
if (!IsDefined() || IsEmpty() || i < 0 || i>= elemlist.Size())
|
|
res.SetDefined(false);
|
|
else
|
|
elemlist.Get(i, res);
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::Get(const int i, ListElem* res) const
|
|
{
|
|
if (!IsDefined() || IsEmpty() || i < 0 || i >= elemlist.Size())
|
|
res->SetDefined(false);
|
|
else
|
|
elemlist.Get(i, res);
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::Put(const int i, const ListElem& p)
|
|
{
|
|
assert (0 <= i && i < elemlist.Size());
|
|
ListElem right(false);
|
|
ListElem left(false);
|
|
if (i > 0)
|
|
Get(i-1,left);
|
|
if (i < elemlist.Size()-1)
|
|
Get(i+1,right);
|
|
if ((left.IsDefined() && right.IsDefined() && left < p && p < right) ||
|
|
(left.IsDefined() && !right.IsDefined() && left < p) ||
|
|
(!left.IsDefined() && right.IsDefined() && p < right))
|
|
{
|
|
elemlist.Put(i,p);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::Contains(const ListElem& e, int& pos)
|
|
{
|
|
if(!IsDefined()) return false;
|
|
else return elemlist.Find(&e,ListElem::Compare, pos);
|
|
}
|
|
|
|
template<class ListElem>
|
|
bool JList<ListElem>::IsEmpty() const
|
|
{
|
|
if (IsDefined())
|
|
return (elemlist.Size() == 0);
|
|
else
|
|
return true;
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::Sort()
|
|
{
|
|
activBulkload = !elemlist.Sort(ListElem::Compare);
|
|
}
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::RemoveDuplicates()
|
|
{
|
|
if (IsDefined() && GetNoOfComponents() > 1 && !activBulkload)
|
|
{
|
|
ListElem lastElem(false);
|
|
ListElem curElem(false);
|
|
DbArray<ListElem> help(elemlist.Size());
|
|
help.copyFrom(elemlist);
|
|
elemlist.clean();
|
|
help.Get(0,lastElem);
|
|
if (lastElem.IsDefined()) elemlist.Append(lastElem);
|
|
for (int i = 1; i < help.Size(); i++)
|
|
{
|
|
help.Get(i,curElem);
|
|
if (curElem.IsDefined() && lastElem.Compare(curElem) != 0)
|
|
{
|
|
elemlist.Append(curElem);
|
|
lastElem = curElem;
|
|
}
|
|
}
|
|
help.Destroy();
|
|
TrimToSize();
|
|
}
|
|
}
|
|
|
|
|
|
template<class ListElem>
|
|
void JList<ListElem>::TrimToSize()
|
|
{
|
|
elemlist.TrimToSize();
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~Restrict~
|
|
|
|
*/
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>& JList<ListElem>::Restrict(const ListElem& sub)
|
|
{
|
|
if (IsDefined() && sub.IsDefined() && !IsEmpty())
|
|
{
|
|
int pos = 0;
|
|
if (Contains(sub,pos))
|
|
{
|
|
elemlist.clean();
|
|
elemlist.Append(sub);
|
|
}
|
|
else
|
|
elemlist.clean();
|
|
TrimToSize();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<class ListElem>
|
|
JList<ListElem>& JList<ListElem>::Restrict(const JList<ListElem>& sub)
|
|
{
|
|
if (IsDefined() && sub.IsDefined() && !IsEmpty())
|
|
{
|
|
int i = 0;
|
|
int j = 0;
|
|
ListElem actElem, actSource;
|
|
DbArray<ListElem>* result = new DbArray<ListElem>(0);
|
|
DbArray<ListElem> source = sub.GetList();
|
|
while (i < elemlist.Size() && j < source.Size())
|
|
{
|
|
elemlist.Get(i,actElem);
|
|
source.Get(j,actSource);
|
|
switch(actElem.Compare(actSource))
|
|
{
|
|
case -1:
|
|
{
|
|
i++;
|
|
break;
|
|
}
|
|
|
|
case 0:
|
|
{
|
|
result->Append(actElem);
|
|
j++;
|
|
i++;
|
|
break;
|
|
}
|
|
|
|
case 1:
|
|
{
|
|
j++;
|
|
break;
|
|
}
|
|
|
|
default: //should never happen
|
|
{
|
|
assert(false);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
elemlist.clean();
|
|
elemlist.copyFrom(*result);
|
|
result->Destroy();
|
|
delete result;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
} // end of namespace jnetwork
|
|
|
|
/*
|
|
1 Overwrite output operator
|
|
|
|
*/
|
|
|
|
|
|
template<class ListElem>
|
|
std::ostream& operator<<(std::ostream& os, const jnetwork::JList<ListElem>& l)
|
|
{
|
|
l.Print(os);
|
|
return os;
|
|
}
|
|
|
|
|
|
#endif // JLIST_H
|
|
|