static bool isTrivialAssignment(FnSymbol* fn, FnSet& visited) { if (! isAssignment(fn)) return false; if (isTrivial(fn, visited)) return true; return false; }
void TilesetCategory::loadBrush(xmlNodePtr node, wxArrayString& warnings) { std::string strVal; std::string brush_name; int intVal = 0; readXMLValue(node, "after", brush_name); if(readXMLValue(node, "afteritem", intVal)) { ItemType& it = item_db[intVal]; if(it.id != 0)// Verify that we have a valid item { brush_name = (it.raw_brush? it.raw_brush->getName() : ""); } } if(xmlStrcmp(node->name,(const xmlChar*)"brush") == 0) { if(readXMLString(node, "name", strVal)) { Brush* brush = tileset.brushes.getBrush(strVal); if(brush) { std::vector<Brush*>::iterator insert_here = brushlist.end(); if(brush_name.size()) { for(std::vector<Brush*>::iterator iter = brushlist.begin(); iter != brushlist.end(); ++iter) { if((*iter)->getName() == brush_name) { insert_here = ++iter; break; } } } brush->flagAsVisible(); brushlist.insert(insert_here, brush); } else { warnings.push_back(wxT("Brush \"") + wxstr(strVal) + wxT("\" doesn't exist.")); } } } else if(xmlStrcmp(node->name,(const xmlChar*)"item") == 0) { int fromid = 0, toid = 0; if(!readXMLInteger(node, "id", fromid)) { if(!readXMLInteger(node, "fromid", fromid)) { warnings.push_back(wxT("Couldn't read raw ids.")); } readXMLInteger(node, "toid", toid); } toid = std::max(toid, fromid); std::vector<Brush*>::iterator insert_here = brushlist.end(); if(brush_name.size()) { for(std::vector<Brush*>::iterator iter = brushlist.begin(); iter != brushlist.end(); ++iter) { if((*iter)->getName() == brush_name) { insert_here = ++iter; break; } } } std::vector<Brush*> temp_vec; for(int id = fromid; id <= toid; ++id) { ItemType& it = item_db[id]; if(it.id == 0) // Verify that we have a valid item { warnings.push_back(wxT("Unknown item id #") + i2ws(id) + wxT(".")); } else { RAWBrush* brush; if(it.raw_brush) { brush = it.raw_brush; } else { brush = it.raw_brush = newd RAWBrush(it.id); it.has_raw = true; tileset.brushes.addBrush(brush); // This will take care of cleaning up afterwards } if(it.doodad_brush == NULL && !isTrivial()) { it.doodad_brush = brush; } brush->flagAsVisible(); temp_vec.push_back(brush); } } brushlist.insert(insert_here, temp_vec.begin(), temp_vec.end()); } }
ompl::base::PathPtr ompl::base::ProblemDefinition::isStraightLinePathValid() const { PathPtr path; if (control::SpaceInformationPtr sic = std::dynamic_pointer_cast<control::SpaceInformation, SpaceInformation>(si_)) { unsigned int startIndex; if (isTrivial(&startIndex, nullptr)) { control::PathControl *pc = new control::PathControl(sic); pc->append(startStates_[startIndex]); control::Control *null = sic->allocControl(); sic->nullControl(null); pc->append(startStates_[startIndex], null, 0.0); sic->freeControl(null); path.reset(pc); } else { control::Control *nc = sic->allocControl(); State *result1 = sic->allocState(); State *result2 = sic->allocState(); sic->nullControl(nc); for (unsigned int k = 0 ; k < startStates_.size() && !path ; ++k) { const State *start = startStates_[k]; if (start && si_->isValid(start) && si_->satisfiesBounds(start)) { sic->copyState(result1, start); for (unsigned int i = 0 ; i < sic->getMaxControlDuration() && !path ; ++i) if (sic->propagateWhileValid(result1, nc, 1, result2)) { if (goal_->isSatisfied(result2)) { control::PathControl *pc = new control::PathControl(sic); pc->append(start); pc->append(result2, nc, (i + 1) * sic->getPropagationStepSize()); path.reset(pc); break; } std::swap(result1, result2); } } } sic->freeState(result1); sic->freeState(result2); sic->freeControl(nc); } } else { std::vector<const State*> states; GoalState *goal = dynamic_cast<GoalState*>(goal_.get()); if (goal) if (si_->isValid(goal->getState()) && si_->satisfiesBounds(goal->getState())) states.push_back(goal->getState()); GoalStates *goals = dynamic_cast<GoalStates*>(goal_.get()); if (goals) for (unsigned int i = 0; i < goals->getStateCount(); ++i) if (si_->isValid(goals->getState(i)) && si_->satisfiesBounds(goals->getState(i))) states.push_back(goals->getState(i)); if (states.empty()) { unsigned int startIndex; if (isTrivial(&startIndex)) { auto *pg = new geometric::PathGeometric(si_, startStates_[startIndex], startStates_[startIndex]); path.reset(pg); } } else { for (unsigned int i = 0 ; i < startStates_.size() && !path ; ++i) { const State *start = startStates_[i]; if (start && si_->isValid(start) && si_->satisfiesBounds(start)) { for (unsigned int j = 0 ; j < states.size() && !path ; ++j) if (si_->checkMotion(start, states[j])) { auto *pg = new geometric::PathGeometric(si_, start, states[j]); path.reset(pg); break; } } } } } return path; }
// The argument is assumed to be an assignment function. // It is deemed to be simple if it contains only 'move', 'addr of', '=', // 'return' primitives and calls only simple assignments (recursively). // We also require that it return void (for now). // The FLAG_TRIVIAL_ASSIGNMENT is used to ensure that we visit each such // function only once. static bool isTrivial(FnSymbol* fn, FnSet& visited) { // Visit each function only once. if (visited.find(fn) != visited.end()) { // Found it. if (fn->hasFlag(FLAG_TRIVIAL_ASSIGNMENT)) return true; else return false; } visited.insert(fn); // We assume that compiler-generated assignments are field-by-field copies. // Note that this overloads the meaning of this flag with: // "Assignment operations flagged as 'compiler generated' shall contain only // field assignments and assignment primitives." // We can then assume that all nested calls are field extractions or // assignments, and we only have to check the latter. if (! fn->hasFlag(FLAG_COMPILER_GENERATED)) return false; // After all compiler-supplied assignments use the new signature, this can // become an assert. if (fn->retType != dtVoid) return false; // The base argument types must match. ArgSymbol* lhs = fn->getFormal(1); ArgSymbol* rhs = fn->getFormal(2); if (lhs->type->getValType() != rhs->type->getValType()) return false; // Assume this is a field-by-field copy. // If none of the fields of this record (or tuple) has a user-defined // assignment (recursively), then it can be replaced by a bulk copy. // Traverse the call expressions in the body of the function. // These should all be one of the allowed primitives or calls to simple // assignments. If anything else, the assignment is "interesting", and // cannot be replaced. std::vector<BaseAST*> asts; collect_asts_STL(fn->body, asts); for_vector(BaseAST, ast, asts) { if (CallExpr* call = toCallExpr(ast)) { if (FnSymbol* fieldAsgn = call->isResolved()) { if (isAssignment(fieldAsgn)) if (! isTrivial(fieldAsgn, visited)) return false; } else { // This is a primitive. switch(call->primitive->tag) { default: return false; // These are the allowable primitives. case PRIM_MOVE: case PRIM_ASSIGN: case PRIM_ADDR_OF: case PRIM_DEREF: case PRIM_GET_MEMBER: case PRIM_GET_MEMBER_VALUE: case PRIM_SET_MEMBER: case PRIM_RETURN: // We expect return _void. break; } } } } fn->addFlag(FLAG_TRIVIAL_ASSIGNMENT); return true; }
// returns the order of subgroup (0 means infinite). // Fast, requires initialization of the parent group int SGOfFreeNilpotentGroupRep::order() const { if( isTrivial() ) return 1; else return 0; }
/// TODO: add trivial marker for tagtypes bool isTrivial(const TypePtr& type) { auto ttype = type.isa<TagTypePtr>(); if(!ttype) { if (core::lang::isArray(type)) { // in case of an array, check the enclosed type for triviality return isTrivial(core::lang::ArrayType(type).getElementType()); } // non-tag-type & non-array types are always trivial return true; } auto record = ttype->getRecord(); IRBuilder builder(type->getNodeManager()); auto containsCtor = [&](const LambdaExprPtr& ctor)->bool { return any(record->getConstructors(), [&](const ExpressionPtr& cur) { return *builder.normalize(cur) == *builder.normalize(ctor); }); }; auto containsMemberFunction = [&](const MemberFunctionPtr& member)->bool { return any(record->getMemberFunctions(), [&](const MemberFunctionPtr& cur) { return *builder.normalize(cur) == *builder.normalize(member); }); }; auto thisType = builder.refType(builder.tagTypeReference(record->getName())); ParentsPtr parents = (record.isa<StructPtr>()) ? record.as<StructPtr>()->getParents() : builder.parents(); // check for trivial constructors bool trivialDefaultConstructor = containsCtor(builder.getDefaultConstructor(thisType, parents, record->getFields())); if (!trivialDefaultConstructor) return false; bool trivialCopyConstructor = containsCtor(builder.getDefaultCopyConstructor(thisType, parents, record->getFields())); if (!trivialCopyConstructor) return false; bool trivialMoveConstructor = containsCtor(builder.getDefaultMoveConstructor(thisType, parents, record->getFields())); if (!trivialMoveConstructor) return false; // check for trivial copy and move assignments bool trivialCopyAssignment = containsMemberFunction(builder.getDefaultCopyAssignOperator(thisType, parents, record->getFields())); if (!trivialCopyAssignment) return false; bool trivialMoveAssignment = containsMemberFunction(builder.getDefaultMoveAssignOperator(thisType, parents, record->getFields())); if (!trivialMoveAssignment) return false; // check for trivial, non-virtual destructor if(record->getDestructor().as<LambdaExprPtr>()->getBody().size() != 0 || record->getDestructorVirtual().getValue()) return false; // check for virtual member functions for(auto memFun : record->getMemberFunctions()) { if(memFun->getVirtualFlag().getValue()) return false; } if(!record->getPureVirtualMemberFunctions().empty()) return false; // check for virtual & non-trivial base classes if(ttype->isStruct()) { auto stype = ttype->getStruct(); for(auto par : stype->getParents()) { if(par->getVirtual().getValue()) return false; // if our direct base class is non-trivial, we cannot be trivial per-se if(!isTrivial(par->getType())) return false; } } // check that all non-static members are trivial for(auto field : record->getFields()) { auto fieldType = field->getType(); if(!isTrivial(fieldType)) return false; //check cpp_ref field types if(analysis::isRefType(fieldType) && lang::isCppReference(fieldType)) { //TODO this is an over approximation which has to be refined return false; } } return true; }