static bool isTrivialAssignment(FnSymbol* fn, FnSet& visited)
{
  if (! isAssignment(fn))
    return false;
  if (isTrivial(fn, visited))
    return true;

  return false;
}
Beispiel #2
0
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;
}
Beispiel #5
0
// 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;
}
Beispiel #6
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;
	}