📄 portion.cc
字号:
}bool OutputPortion::IsReference(void) const{ return _ref; }//--------// Input//--------gPool InputPortion::pool(sizeof(InputPortion));InputPortion::InputPortion(gInput& value) : rep(new struct inputrep(&value)), _ref(false){ }InputPortion::InputPortion(const InputPortion *p, bool ref) : rep(p->rep), _ref(ref){ rep->nref++;}InputPortion::~InputPortion(){ if (--rep->nref == 0) delete rep;}gInput& InputPortion::Value(void) const{ return *rep->value; }PortionSpec InputPortion::Spec(void) const{ return PortionSpec(porINPUT); }void InputPortion::Output(gOutput& s) const{ Portion::Output(s); s << "(Input)"; }gText InputPortion::OutputString(void) const{ return "(Input)";}Portion* InputPortion::ValCopy(void) const{ return new InputPortion(this, false);}Portion* InputPortion::RefCopy(void) const{ Portion* p = new InputPortion(this, true); p->SetOriginal(Original()); return p;}bool InputPortion::IsReference(void) const{ return _ref; }//--------// List//--------gPool ListPortion::pool(sizeof(ListPortion));ListPortion::listrep::listrep(void) : value(new gList<Portion *>), _ContainsListsOnly(true), _DataType(porUNDEFINED), _IsNull(false), _ListDepth(1), nref(1){ }ListPortion::listrep::~listrep(){ for (int i = 1; i <= value->Length(); delete (*value)[i++]); delete value;}ListPortion::ListPortion(void) : rep(new listrep), _ref(false){ }ListPortion::ListPortion(const gList<Portion *> &value) : rep(new listrep), _ref(false){ for (int i = 1, length = value.Length(); i <= length; i++) Insert(value[i]->ValCopy(), i);}ListPortion::ListPortion(const ListPortion *p, bool ref) : rep(p->rep), _ref(ref){ rep->nref++;}ListPortion::~ListPortion(){ if (--rep->nref == 0) delete rep;}bool ListPortion::BelongsToGame( void* game ) const{ for (int i = 1; i <= rep->value->Length(); i++) if ((*rep->value)[i]->Spec().ListDepth == 0) { if ((*rep->value)[i]->Game() == game) return true; } else { if (((ListPortion*) (*rep->value)[i])->BelongsToGame(game)) return true; } return false;}bool ListPortion::MatchGameData( void* game, void* data ) const{ for (int i = 1; i <= rep->value->Length(); i++) { PortionSpec spec = (*rep->value)[i]->Spec(); if ((*rep->value)[i]->Spec().ListDepth == 0) { if (spec.Type & porEFSUPPORT) { if (((EfSupportPortion*) (*rep->value)[i])->Value() == data) return true; } if (spec.Type & porEFBASIS) { if (((EfBasisPortion*) (*rep->value)[i])->Value() == data) return true; } if (spec.Type & porEFPLAYER) { if (((EfPlayerPortion*) (*rep->value)[i])->Value() == data) return true; } if (spec.Type & porINFOSET) { if (((InfosetPortion*) (*rep->value)[i])->Value() == data) return true; } if (spec.Type & porNODE) { if (((NodePortion*) (*rep->value)[i])->Value() == data) return true; } if (spec.Type & porACTION) { if (((ActionPortion*) (*rep->value)[i])->Value() == data) return true; } } else { if (((ListPortion*) (*rep->value)[i])->MatchGameData(game, data)) return true; } } return false;}const gList<Portion *> &ListPortion::Value(void) const{ return *rep->value; }bool ListPortion::IsInteger(void) const{ if (rep->_DataType != porNUMBER) return false; bool result = true; for (int i = 1; result && i <= rep->value->Length(); i++) { Portion *p = (*rep->value)[i]; if (!p->Spec().Null) { if (p->Spec().ListDepth > 0) result = result && ((ListPortion *) p)->IsInteger(); else result = result && ((NumberPortion *) p)->Value().IsInteger(); } } return result;}PortionSpec ListPortion::Spec(void) const{ if (IsReference()) return Original()->Spec(); else return PortionSpec(rep->_DataType, rep->_ListDepth, rep->_IsNull); }Portion* ListPortion::ValCopy(void) const{ ListPortion* p = new ListPortion(*rep->value); if(p->rep->_DataType == porUNDEFINED) p->rep->_DataType = rep->_DataType; return p;}Portion* ListPortion::RefCopy(void) const{ ListPortion* p = new ListPortion(this, true); p->rep->_DataType = rep->_DataType; p->SetOriginal(Original()); return p;}void ListPortion::AssignFrom(Portion* p){ int i; int length; int result; gList <Portion *>& value = *(((ListPortion*) p)->rep->value); Flush(); for(i = 1, length = value.Length(); i <= length; i++) { result = Insert(value[i]->ValCopy(), i); if (!result) throw gclRuntimeError("Internal error in ListPortion"); } if (rep->_DataType == porUNDEFINED) rep->_DataType = ((ListPortion*) p)->rep->_DataType;}bool ListPortion::operator == (Portion* p) const{ bool result = true; int i; int length = rep->value->Length(); Portion* p1; Portion* p2; bool type_found; if(p->Spec() == Spec()) { if(rep->value->Length() == ((ListPortion*) p)->rep->value->Length()) { for(i = 1; i <= length; i++) { p1 = (*rep->value)[i]; p2 = (*(((ListPortion*) p)->rep->value))[i]; if(p1->Spec() == p2->Spec()) { if(p1->Spec().ListDepth > 0) result = result & (((ListPortion*) p1)->operator==(p2)); else result = result & PortionEqual(p1, p2, type_found); } else result = false; } } else result = false; } else result = false; return result;}bool ListPortion::ContainsListsOnly(void) const{ if (rep->value->Length() == 0) return false; else return rep->_ContainsListsOnly;}void ListPortion::SetDataType(unsigned long type){ rep->_DataType = type; }void ListPortion::Output(gOutput& s) const{ Output(s, 0); }void ListPortion::Output(gOutput& s, long ListLF) const{ Portion::Output(s); int i; int c; int length = rep->value->Length(); if(_WriteListBraces) s << '{'; else s << ' '; // if(_WriteListLF > ListLF) s << '\n'; if(length >= 1) { for(i = 1; i <= length; i++) { if(i > 1) { if(_WriteListCommas) s << ','; else s << ' '; if(_WriteListLF > gNumber(ListLF)) s << '\n'; if(_WriteListLF > gNumber(ListLF)) for(c = 0; c < (double) ((gNumber) (ListLF+1) * _WriteListIndent); c++) s << ' '; } else if(_WriteListLF > gNumber(ListLF)) s << ' '; if(_WriteListLF <= gNumber(ListLF)) s << ' '; if((*rep->value)[i]->Spec().ListDepth == 0) s << (*rep->value)[i]; else ((ListPortion*) (*rep->value)[i])->Output(s, ListLF + 1); } } else { if(_WriteListLF > gNumber(ListLF)) for(c = 0; c < (double) ((gNumber) (ListLF+1) * _WriteListIndent) - 1; c++) s << ' '; s << " (" << PortionSpecToText(rep->_DataType) << ')'; } s << ' '; if(_WriteListBraces) s << '}'; else s << ' ';}gText ListPortion::OutputString(void) const{ gText text( "{ " ); for (int i = 1; i <= Length(); i++) { if( i > 1 ) text += ", "; text += operator[](i)->OutputString(); } text += " }"; return text;}int ListPortion::Append(Portion* item){ return Insert(item, rep->value->Length() + 1); }int ListPortion::Insert(Portion* item, int index){ int result = 0; PortionSpec item_type = item->Spec(); if (item->Spec().ListDepth == 0) { if (item_type.Type == porNULL) item_type = ((NullPortion*) item)->DataType(); rep->_ContainsListsOnly = false; } if (rep->_DataType == porUNDEFINED) { // inserting into an empty list rep->_DataType = item_type.Type; ((ListPortion*) Original())->rep->_DataType = rep->_DataType; result = rep->value->Insert(item, index); } else { // inserting into an existing list if (PortionSpecMatch(item_type.Type, rep->_DataType)) { result = rep->value->Insert(item, index); } else if (item_type.Type == porUNDEFINED) { // inserting an empty list result = rep->value->Insert(item, index); if (item->Spec().ListDepth <= 0) throw gclRuntimeError("Internal error in ListPortion"); ((ListPortion*) item)->rep->_DataType = rep->_DataType; } else { delete item; throw gclRuntimeError("Type mismatch in list; list type = " + PortionSpecToText(rep->_DataType) + ", item type = " + PortionSpecToText(item_type.Type)); } } if (result > 0) { if (item->Spec().ListDepth + 1 > rep->_ListDepth) rep->_ListDepth = item->Spec().ListDepth + 1; } return result;}bool ListPortion::Contains(Portion* p2) const{ int i; int length = rep->value->Length(); bool type_found; Portion* p1; for(i = 1; i <= length; i++) { p1 = (*rep->value)[i]; if(PortionEqual(p1, p2, type_found)) return true; /* uncomment this to do recursive checking if(p1->Spec().ListDepth == 0) { if(PortionEqual(p1, p2, type_found)) return true; } else { if(p2->Spec().ListDepth > 0 && ((ListPortion*) p1)->operator==(p2)) return true; if(((ListPortion*) p1)->Contains(p2)) return true; } */ } return false;}Portion* ListPortion::Remove(int index){ Portion* result = 0; if(index >= 1 && index <= rep->value->Length()) result = rep->value->Remove(index); rep->_ContainsListsOnly = true; rep->_ListDepth = 1; if(rep->value->Length() > 0) { for (int i = 1; i <= rep->value->Length(); ++i ) { if( (*rep->value)[i]->Spec().ListDepth == 0 ) rep->_ContainsListsOnly = false; if( (*rep->value)[i]->Spec().ListDepth >= rep->_ListDepth ) rep->_ListDepth = (*rep->value)[i]->Spec().ListDepth + 1; } } return result;}int ListPortion::Length(void) const{ return rep->value->Length(); }void ListPortion::Flush(void){ int i, length; for (i = 1, length = rep->value->Length(); i <= length; i++) { delete Remove(1); }}Portion* ListPortion::operator[](int index) const{ if (index >= 1 && index <= rep->value->Length()) { if (!(*rep->value)[index]) throw gclRuntimeError("Internal error in ListPortion"); return (*rep->value)[index]; } else return 0;}Portion* ListPortion::SubscriptCopy(int index) const{ Portion* p; if (index >= 1 && index <= rep->value->Length()) { if (!(*rep->value)[index]) throw gclRuntimeError("Internal error in ListPortion"); if(IsReference()) p = (*rep->value)[index]->RefCopy(); else p = (*rep->value)[index]->ValCopy(); return p; } else return 0;}bool ListPortion::IsReference(void) const{ return _ref;}//---------------------------// Miscellaneous functions//---------------------------gOutput& operator<<(gOutput& s, Portion* p){ p->Output(s); return s;}bool PortionEqual(Portion* p1, Portion* p2, bool &type_found){ bool b = false; if(!(p1->Spec() == p2->Spec())) return false; if( p1->Spec().ListDepth > 0 ) return ((ListPortion*) p1)->operator==( (ListPortion*) p2 ); type_found = true; if(p1->Spec().Type & porBOOLEAN) b = (((BoolPortion*) p1)->Value() == ((BoolPortion*) p2)->Value()); else if(p1->Spec().Type & porNUMBER) b = (((NumberPortion*) p1)->Value()==((NumberPortion*) p2)->Value()); else if(p1->Spec().Type & porTEXT) b = (((TextPortion*) p1)->Value() == ((TextPortion*) p2)->Value()); else if(p1->Spec().Type & porNODE) b = (((NodePortion*) p1)->Value() == ((NodePortion*) p2)->Value()); else if(p1->Spec().Type & porACTION) b = (((ActionPortion*) p1)->Value() == ((ActionPortion*) p2)->Value()); else if(p1->Spec().Type & porINFOSET) b = (((InfosetPortion*) p1)->Value() == ((InfosetPortion*) p2)->Value()); else if(p1->Spec().Type & porEFOUTCOME) b = (((EfOutcomePortion*) p1)->Value() == ((EfOutcomePortion*) p2)->Value()); else if(p1->Spec().Type & porNFPLAYER) b = (((NfPlayerPortion*) p1)->Value() == ((NfPlayerPortion*) p2)->Value()); else if(p1->Spec().Type & porEFPLAYER) b = (((EfPlayerPortion*) p1)->Value() == ((EfPlayerPortion*) p2)->Value()); else if(p1->Spec().Type & porSTRATEGY) b = (((StrategyPortion*) p1)->Value() == ((StrategyPortion*) p2)->Value()); else if(p1->Spec().Type & porNFSUPPORT) b = (*(((NfSupportPortion*) p1)->Value()) == *(((NfSupportPortion*) p2)->Value())); else if(p1->Spec().Type & porEFSUPPORT) b = (*(((EfSupportPortion*) p1)->Value()) == *(((EfSupportPortion*) p2)->Value())); else if(p1->Spec().Type & porEFBASIS) b = (*(((EfBasisPortion*) p1)->Value()) == *(((EfBasisPortion*) p2)->Value())); else if(p1->Spec().Type & porMIXED) b = (*((MixedPortion*) p1)->Value() == *((MixedPortion*) p2)->Value()); else if(p1->Spec().Type & porBEHAV) b = (*((BehavPortion*) p1)->Value() == *((BehavPortion*) p2)->Value()); else if(p1->Spec().Type & porNFG) b = false; else if(p1->Spec().Type & porEFG) b = false; else if(p1->Spec().Type & porINPUT) b = false; else if(p1->Spec().Type & porOUTPUT) b = false; else if(p1->Spec().Type & porNULL) b = false; else { type_found = false; throw gclRuntimeError("Internal error in PortionEqual()"); } return b;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -