Files
secondo/Algebras/JNet/Direction.cpp
2026-01-23 17:03:45 +08:00

421 lines
7.8 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 Includes
*/
#include "Direction.h"
#include "ListUtils.h"
#include "NestedList.h"
#include "NList.h"
#include "Symbols.h"
#include "LogMsg.h"
extern NestedList* nl;
using namespace jnetwork;
using namespace std;
/*
1 Implementation of class ~Direction~
1.1 Constructors and Deconstructors
The default constructor should only be used in the Cast-Function.
*/
Direction::Direction():Attribute()
{}
Direction::Direction(const bool defined): Attribute(defined), side(Both)
{}
Direction::Direction(const Direction& other) : Attribute(other.IsDefined()),
side(Both)
{
if (other.IsDefined())
side = other.GetDirection();
}
Direction::Direction(const JSide inside) : Attribute(true), side(inside)
{ }
Direction::~Direction()
{}
/*
1.1 Getter and Setter
*/
JSide Direction::GetDirection() const
{
return side;
}
void Direction::SetSide(const JSide inside)
{
side = inside;
}
void Direction::SetDirection(const Direction& indir)
{
side = indir.GetDirection();
}
/*
1.1 Override Methods from Attribute
*/
void Direction::CopyFrom(const Attribute* right)
{
*this = *((Direction*)right);
}
Attribute::StorageType Direction::GetStorageType() const
{
return Default;
}
size_t Direction::HashValue() const
{
if (IsDefined()) return (size_t) side;
else return (size_t) 0;
}
Direction* Direction::Clone() const
{
return new Direction(*this);
}
bool Direction::Adjacent(const Attribute* attrib) const
{
return false;
}
int Direction::Compare(const void* ls, const void* rs)
{
Direction pl(*(Direction*) ls);
Direction pr(*(Direction*) rs);
return pl.Compare(pr);
}
int Direction::Compare(const Attribute* rhs) const
{
Direction in(*(Direction*) rhs);
return Compare(in);
}
int Direction::Compare(const Direction& indir) const
{
if (!IsDefined() && !indir.IsDefined()) return 0;
if (!IsDefined() && indir.IsDefined()) return -1;
if (IsDefined() && !indir.IsDefined()) return 1;
return Compare(side, indir.GetDirection());
}
int Direction::Compare(const JSide& a, const JSide& b) const
{
if (a == b) return 0;
if (a == Up) return -1;
if (b == Up) return 1;
if (b == Both) return -1;
return 1;
}
size_t Direction::Sizeof() const
{
return sizeof(Direction);
}
ostream& Direction::Print(ostream& os) const
{
os << "Direction: ";
if (IsDefined())
{
switch(side)
{
case Up:
os << "Up";
break;
case Down:
os << "Down";
break;
case Both:
os << "Both";
break;
}
}
else
{
os << Symbol::UNDEFINED();
}
os << endl;
return os;
}
const string Direction::BasicType()
{
return "jdirection";
}
const bool Direction::checkType(const ListExpr type)
{
return listutils::isSymbol(type, BasicType());
}
/*
1.1 Standard Operators
*/
Direction& Direction::operator=(const Direction& other)
{
SetDefined(other.IsDefined());
if (other.IsDefined()) side = other.GetDirection();
return *this;
}
bool Direction::operator==(const Direction& other) const
{
return (Compare(&other) == 0);
}
bool Direction::operator<(const Direction& other) const
{
return (Compare(&other) < 0);
}
bool Direction::operator<=(const Direction& other) const
{
return (Compare(&other) < 1);
}
bool Direction::operator>(const Direction& other) const
{
return (Compare(&other) > 0 );
}
bool Direction::operator>=(const Direction& other) const
{
return (Compare(&other) > -1);
}
bool Direction::operator!=(const Direction& other) const
{
return (Compare(&other) != 0);
}
/*
1.1 Operators for Secondo Integration
1.1.1 Converts the direction into a nested list.
*/
ListExpr Direction::Out(ListExpr typeInfo, Word value)
{
Direction* source = (Direction*) value.addr;
if (source->IsDefined())
{
switch(source->GetDirection())
{
case Up:
{
NList res("Up");
return res.enclose().listExpr();
break;
}
case Down:
{
NList res("Down");
return res.enclose().listExpr();
break;
}
case Both:
{
NList res("Both");
return res.enclose().listExpr();
break;
}
}
}
NList res(Symbol::UNDEFINED());
return res.enclose().listExpr();
}
/*
1.1.1 Constructs a Direction object from a nested list.
*/
Word Direction::In(const ListExpr typeInfo, const ListExpr instance,
const int errorPos, ListExpr& errorInfo, bool& correct)
{
NList in_inst(instance);
if (in_inst.length() == 1)
{
NList first = in_inst.first();
if (first.hasStringValue())
{
string s = first.str();
if (s == "Up")
{
correct = true;
return SetWord(new Direction((JSide)Up));
}
if (s == "Down"){
correct = true;
return SetWord(new Direction((JSide)Down));
}
if (s == "Both")
{
correct = true;
return SetWord(new Direction((JSide)Both));
}
if ( s == Symbol::UNDEFINED())
{
correct = true;
return SetWord(new Direction(false));
}
}
}
correct = false;
cmsg.inFunError("Direction must be Up, Down, Both or " + Symbol::UNDEFINED());
return SetWord(Address( 0 ));
}
Word Direction::Create(const ListExpr typeInfo)
{
return SetWord(new Direction(true));
}
void Direction::Delete( const ListExpr typeInfo, Word& w )
{
((Direction*) w.addr)->DeleteIfAllowed();
w.addr = 0;
}
void Direction::Close( const ListExpr typeInfo, Word& w )
{
((Direction*) w.addr)->DeleteIfAllowed();
w.addr = 0;
}
Word Direction::Clone( const ListExpr typeInfo, const Word& w )
{
return SetWord(new Direction(*(Direction*) w.addr));
}
void* Direction::Cast( void* addr )
{
return (new (addr) Direction);
}
bool Direction::KindCheck ( ListExpr type, ListExpr& errorInfo )
{
return checkType(type);
}
int Direction::SizeOf()
{
return sizeof(Direction);
}
ListExpr Direction::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("(<JSide>) where JSide is Up, Down or Both"),
nl->StringAtom("("+ Example() +")")));
}
/*
1 Helpful Operations
*/
string Direction::Example()
{
return "Up";
}
/*
1.1 SameSide
Returns true if the both direction values are equal or one of them is ~Both~.
*/
bool Direction::SameSide(const Direction& dir, const bool strict /*true*/)const
{
if (Compare(&dir) == 0)
return true;
else
{
if (strict)
return false;
else
{
if (!IsDefined() || !dir.IsDefined())
return false;
else
{
if (side == Both || dir.GetDirection() == Both)
return true;
else
return false;
}
}
}
}
/*
1 Implementation of overloaded output operator
*/
ostream& operator<<(ostream& os, const Direction& dir)
{
dir.Print(os);
return os;
}