aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-04-09 19:48:49 +0000
committerChris Lattner <sabre@nondot.org>2002-04-09 19:48:49 +0000
commit73e214244f2403b5ba0ef81b8839600f3c8ffebc (patch)
tree245e635c686ace9b5ebbcaf39d622a92f9db594e
parentb62fc4a9b11662ec2c5fa190b513eae0a0810ce1 (diff)
downloadexternal_llvm-73e214244f2403b5ba0ef81b8839600f3c8ffebc.zip
external_llvm-73e214244f2403b5ba0ef81b8839600f3c8ffebc.tar.gz
external_llvm-73e214244f2403b5ba0ef81b8839600f3c8ffebc.tar.bz2
Move FunctionArgument out of iOther.h into Argument.h and rename class to
be 'Argument' instead of FunctionArgument. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2216 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/DataStructure/FunctionRepBuilder.cpp18
-rw-r--r--lib/Analysis/DataStructure/NodeImpl.cpp3
-rw-r--r--lib/Analysis/Expressions.cpp2
-rw-r--r--lib/Analysis/InductionVariable.cpp2
-rw-r--r--lib/Bytecode/Reader/Reader.cpp3
-rw-r--r--lib/Bytecode/Writer/SlotCalculator.cpp1
-rw-r--r--lib/Bytecode/Writer/Writer.cpp2
-rw-r--r--lib/CodeGen/InstrSelection/InstrForest.cpp2
-rw-r--r--lib/Linker/LinkModules.cpp5
-rw-r--r--lib/Target/SparcV9/InstrSelection/InstrForest.cpp2
-rw-r--r--lib/Transforms/IPO/InlineSimple.cpp1
-rw-r--r--lib/Transforms/IPO/MutateStructTypes.cpp6
-rw-r--r--lib/Transforms/IPO/OldPoolAllocate.cpp7
-rw-r--r--lib/Transforms/Instrumentation/TraceValues.cpp2
-rw-r--r--lib/Transforms/Scalar/InductionVars.cpp2
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp4
-rw-r--r--lib/Transforms/Utils/Linker.cpp5
-rw-r--r--lib/VMCore/AsmWriter.cpp17
-rw-r--r--lib/VMCore/Linker.cpp5
-rw-r--r--lib/VMCore/SlotCalculator.cpp1
20 files changed, 51 insertions, 39 deletions
diff --git a/lib/Analysis/DataStructure/FunctionRepBuilder.cpp b/lib/Analysis/DataStructure/FunctionRepBuilder.cpp
index 965185a..eda16bc 100644
--- a/lib/Analysis/DataStructure/FunctionRepBuilder.cpp
+++ b/lib/Analysis/DataStructure/FunctionRepBuilder.cpp
@@ -143,26 +143,28 @@ void FunctionRepBuilder::initializeWorkList(Function *Func) {
// the worklists...
//
for (Function::ArgumentListType::iterator I = Func->getArgumentList().begin(),
- E = Func->getArgumentList().end(); I != E; ++I)
+ E = Func->getArgumentList().end(); I != E; ++I) {
+ Value *Arg = (Value*)(*I);
// Only process arguments that are of pointer type...
- if (PointerType *PT = dyn_cast<PointerType>((*I)->getType())) {
- ArgDSNode *Arg = new ArgDSNode(*I);
- ArgNodes.push_back(Arg);
+ if (PointerType *PT = dyn_cast<PointerType>(Arg->getType())) {
+ ArgDSNode *ArgNode = new ArgDSNode(*I);
+ ArgNodes.push_back(ArgNode);
// Add a critical shadow value for it to represent what it is pointing
// to and add this to the value map...
ShadowDSNode *Shad = new ShadowDSNode(PT->getElementType(),
Func->getParent(), true);
ShadowNodes.push_back(Shad);
- ValueMap[*I].add(PointerVal(Shad), *I);
+ ValueMap[Arg].add(PointerVal(Shad), Arg);
// The value of the argument is the shadow value...
- Arg->getLink(0).add(Shad);
+ ArgNode->getLink(0).add(Shad);
// Make sure that all users of the argument are processed...
- addAllUsesToWorkList(*I);
+ addAllUsesToWorkList(Arg);
}
-
+ }
+
// Iterate over the instructions in the method. Create nodes for malloc and
// call instructions. Add all uses of these to the worklist of instructions
// to process.
diff --git a/lib/Analysis/DataStructure/NodeImpl.cpp b/lib/Analysis/DataStructure/NodeImpl.cpp
index 05ed884..6c986fe 100644
--- a/lib/Analysis/DataStructure/NodeImpl.cpp
+++ b/lib/Analysis/DataStructure/NodeImpl.cpp
@@ -11,6 +11,7 @@
#include "llvm/BasicBlock.h"
#include "llvm/iMemory.h"
#include "llvm/iOther.h"
+#include "llvm/Argument.h"
#include "Support/STLExtras.h"
#include <algorithm>
#include <sstream>
@@ -288,7 +289,7 @@ void CallDSNode::mapNode(map<const DSNode*, DSNode*> &NodeMap,
MapPVS(ArgLinks[i], Old->ArgLinks[i], NodeMap);
}
-ArgDSNode::ArgDSNode(FunctionArgument *FA)
+ArgDSNode::ArgDSNode(Argument *FA)
: DSNode(ArgNode, FA->getType()), FuncArg(FA) {
}
diff --git a/lib/Analysis/Expressions.cpp b/lib/Analysis/Expressions.cpp
index 0f37c5f..e78fb1e 100644
--- a/lib/Analysis/Expressions.cpp
+++ b/lib/Analysis/Expressions.cpp
@@ -245,7 +245,7 @@ ExprType analysis::ClassifyExpression(Value *Expr) {
std::cerr << "Bizarre thing to expr classify: " << Expr << "\n";
return Expr;
case Value::GlobalVariableVal: // Global Variable & Function argument:
- case Value::FunctionArgumentVal: // nothing known, return variable itself
+ case Value::ArgumentVal: // nothing known, return variable itself
return Expr;
case Value::ConstantVal: // Constant value, just return constant
Constant *CPV = cast<Constant>(Expr);
diff --git a/lib/Analysis/InductionVariable.cpp b/lib/Analysis/InductionVariable.cpp
index 11d1a2c..1550174 100644
--- a/lib/Analysis/InductionVariable.cpp
+++ b/lib/Analysis/InductionVariable.cpp
@@ -28,7 +28,7 @@ using analysis::ExprType;
static bool isLoopInvariant(const Value *V, const cfg::Loop *L) {
- if (isa<Constant>(V) || isa<FunctionArgument>(V) || isa<GlobalValue>(V))
+ if (isa<Constant>(V) || isa<Argument>(V) || isa<GlobalValue>(V))
return true;
const Instruction *I = cast<Instruction>(V);
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
index d7c8af3..fff2d02 100644
--- a/lib/Bytecode/Reader/Reader.cpp
+++ b/lib/Bytecode/Reader/Reader.cpp
@@ -19,6 +19,7 @@
#include "llvm/ConstantVals.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
+#include "llvm/Argument.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
@@ -280,7 +281,7 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
const FunctionType::ParamTypes &Params = MTy->getParamTypes();
for (FunctionType::ParamTypes::const_iterator It = Params.begin();
It != Params.end(); ++It) {
- FunctionArgument *FA = new FunctionArgument(*It);
+ Argument *FA = new Argument(*It);
if (insertValue(FA, Values) == -1) {
Error = "Error reading method arguments!\n";
delete M; return failure(true);
diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp
index 4a8312e..8bd0b49 100644
--- a/lib/Bytecode/Writer/SlotCalculator.cpp
+++ b/lib/Bytecode/Writer/SlotCalculator.cpp
@@ -19,6 +19,7 @@
#include "llvm/iOther.h"
#include "llvm/DerivedTypes.h"
#include "llvm/SymbolTable.h"
+#include "llvm/Argument.h"
#include "Support/DepthFirstIterator.h"
#include "Support/STLExtras.h"
#include <algorithm>
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index 0b883ac..ab22db3 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -73,7 +73,7 @@ void BytecodeWriter::outputConstants(bool isFunction) {
ValNo = Type::FirstDerivedTyID; // Start emitting at the derived types...
// Scan through and ignore function arguments...
- for (; ValNo < Plane.size() && isa<FunctionArgument>(Plane[ValNo]); ValNo++)
+ for (; ValNo < Plane.size() && isa<Argument>(Plane[ValNo]); ValNo++)
/*empty*/;
unsigned NC = ValNo; // Number of constants
diff --git a/lib/CodeGen/InstrSelection/InstrForest.cpp b/lib/CodeGen/InstrSelection/InstrForest.cpp
index 95803cd..e2f45a0 100644
--- a/lib/CodeGen/InstrSelection/InstrForest.cpp
+++ b/lib/CodeGen/InstrSelection/InstrForest.cpp
@@ -298,7 +298,7 @@ InstrForest::buildTreeForInstruction(Instruction *instr)
&& !instr->isTerminator();
if (includeAddressOperand || isa<Instruction>(operand) ||
- isa<Constant>(operand) || isa<FunctionArgument>(operand) ||
+ isa<Constant>(operand) || isa<Argument>(operand) ||
isa<GlobalVariable>(operand))
{
// This operand is a data value
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 9637f74..086c6c6 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -18,6 +18,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/ConstantVals.h"
+#include "llvm/Argument.h"
#include <iostream>
using std::cerr;
using std::string;
@@ -301,10 +302,10 @@ static bool LinkFunctionBody(Function *Dest, const Function *Src,
for (Function::ArgumentListType::const_iterator
I = Src->getArgumentList().begin(),
E = Src->getArgumentList().end(); I != E; ++I) {
- const FunctionArgument *SMA = *I;
+ const Argument *SMA = *I;
// Create the new method argument and add to the dest method...
- FunctionArgument *DMA = new FunctionArgument(SMA->getType(),SMA->getName());
+ Argument *DMA = new Argument(SMA->getType(), SMA->getName());
Dest->getArgumentList().push_back(DMA);
// Add a mapping to our local map
diff --git a/lib/Target/SparcV9/InstrSelection/InstrForest.cpp b/lib/Target/SparcV9/InstrSelection/InstrForest.cpp
index 95803cd..e2f45a0 100644
--- a/lib/Target/SparcV9/InstrSelection/InstrForest.cpp
+++ b/lib/Target/SparcV9/InstrSelection/InstrForest.cpp
@@ -298,7 +298,7 @@ InstrForest::buildTreeForInstruction(Instruction *instr)
&& !instr->isTerminator();
if (includeAddressOperand || isa<Instruction>(operand) ||
- isa<Constant>(operand) || isa<FunctionArgument>(operand) ||
+ isa<Constant>(operand) || isa<Argument>(operand) ||
isa<GlobalVariable>(operand))
{
// This operand is a data value
diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp
index 461f597..0a58eab 100644
--- a/lib/Transforms/IPO/InlineSimple.cpp
+++ b/lib/Transforms/IPO/InlineSimple.cpp
@@ -23,6 +23,7 @@
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/Type.h"
+#include "llvm/Argument.h"
#include <algorithm>
#include <map>
#include <iostream>
diff --git a/lib/Transforms/IPO/MutateStructTypes.cpp b/lib/Transforms/IPO/MutateStructTypes.cpp
index e06ee61..fcad5fa 100644
--- a/lib/Transforms/IPO/MutateStructTypes.cpp
+++ b/lib/Transforms/IPO/MutateStructTypes.cpp
@@ -22,6 +22,7 @@
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include "llvm/iOther.h"
+#include "llvm/Argument.h"
#include "Support/STLExtras.h"
#include <algorithm>
using std::map;
@@ -337,9 +338,8 @@ void MutateStructTypes::transformMethod(Function *m) {
// Okay, first order of business, create the arguments...
for (unsigned i = 0, e = M->getArgumentList().size(); i != e; ++i) {
- const FunctionArgument *OFA = M->getArgumentList()[i];
- FunctionArgument *NFA = new FunctionArgument(ConvertType(OFA->getType()),
- OFA->getName());
+ const Argument *OFA = M->getArgumentList()[i];
+ Argument *NFA = new Argument(ConvertType(OFA->getType()), OFA->getName());
NewMeth->getArgumentList().push_back(NFA);
LocalValueMap[OFA] = NFA; // Keep track of value mapping
}
diff --git a/lib/Transforms/IPO/OldPoolAllocate.cpp b/lib/Transforms/IPO/OldPoolAllocate.cpp
index 731e9e9..4b5c830 100644
--- a/lib/Transforms/IPO/OldPoolAllocate.cpp
+++ b/lib/Transforms/IPO/OldPoolAllocate.cpp
@@ -20,6 +20,7 @@
#include "llvm/ConstantVals.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/Argument.h"
#include "Support/DepthFirstIterator.h"
#include "Support/STLExtras.h"
#include <algorithm>
@@ -677,8 +678,8 @@ void PoolAllocate::transformFunction(TransformFunctionInfo &TFI,
// Add arguments to the function... starting with all of the old arguments
vector<Value*> ArgMap;
for (unsigned i = 0, e = TFI.Func->getArgumentList().size(); i != e; ++i) {
- const FunctionArgument *OFA = TFI.Func->getArgumentList()[i];
- FunctionArgument *NFA = new FunctionArgument(OFA->getType(),OFA->getName());
+ const Argument *OFA = TFI.Func->getArgumentList()[i];
+ Argument *NFA = new Argument(OFA->getType(), OFA->getName());
NewFunc->getArgumentList().push_back(NFA);
ArgMap.push_back(NFA); // Keep track of the arguments
}
@@ -690,7 +691,7 @@ void PoolAllocate::transformFunction(TransformFunctionInfo &TFI,
Name = "retpool";
else
Name = ArgMap[TFI.ArgInfo[i].ArgNo]->getName(); // Get the arg name
- FunctionArgument *NFA = new FunctionArgument(PoolTy, Name+".pool");
+ Argument *NFA = new Argument(PoolTy, Name+".pool");
NewFunc->getArgumentList().push_back(NFA);
}
diff --git a/lib/Transforms/Instrumentation/TraceValues.cpp b/lib/Transforms/Instrumentation/TraceValues.cpp
index 7f7321d..20ad1d8 100644
--- a/lib/Transforms/Instrumentation/TraceValues.cpp
+++ b/lib/Transforms/Instrumentation/TraceValues.cpp
@@ -257,7 +257,7 @@ static inline void InsertCodeToShowFunctionEntry(Function *M, Function *Printf){
unsigned ArgNo = 0;
for (Function::ArgumentListType::const_iterator
I = argList.begin(), E = argList.end(); I != E; ++I, ++ArgNo) {
- InsertVerbosePrintInst(*I, BB, BBI,
+ InsertVerbosePrintInst((Value*)*I, BB, BBI,
" Arg #" + utostr(ArgNo), Printf);
}
}
diff --git a/lib/Transforms/Scalar/InductionVars.cpp b/lib/Transforms/Scalar/InductionVars.cpp
index 55b2275..9931a6b 100644
--- a/lib/Transforms/Scalar/InductionVars.cpp
+++ b/lib/Transforms/Scalar/InductionVars.cpp
@@ -37,7 +37,7 @@ using std::cerr;
// an interval invariant computation.
//
static bool isLoopInvariant(cfg::Interval *Int, Value *V) {
- assert(isa<Constant>(V) || isa<Instruction>(V) || isa<FunctionArgument>(V));
+ assert(isa<Constant>(V) || isa<Instruction>(V) || isa<Argument>(V));
if (!isa<Instruction>(V))
return true; // Constants and arguments are always loop invariant
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index b569a53..e6cf765 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/lib/Transforms/Scalar/SCCP.cpp
@@ -140,7 +140,7 @@ private:
// getValueState - Return the InstVal object that corresponds to the value.
// This function is neccesary because not all values should start out in the
- // underdefined state... FunctionArgument's should be overdefined, and
+ // underdefined state... Argument's should be overdefined, and
// constants should be marked as constants. If a value is not known to be an
// Instruction object, then use this accessor to get its value from the map.
//
@@ -150,7 +150,7 @@ private:
if (Constant *CPV = dyn_cast<Constant>(V)) { // Constants are constant
ValueState[CPV].markConstant(CPV);
- } else if (isa<FunctionArgument>(V)) { // FuncArgs are overdefined
+ } else if (isa<Argument>(V)) { // Arguments are overdefined
ValueState[V].markOverdefined();
}
// All others are underdefined by default...
diff --git a/lib/Transforms/Utils/Linker.cpp b/lib/Transforms/Utils/Linker.cpp
index 9637f74..086c6c6 100644
--- a/lib/Transforms/Utils/Linker.cpp
+++ b/lib/Transforms/Utils/Linker.cpp
@@ -18,6 +18,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/ConstantVals.h"
+#include "llvm/Argument.h"
#include <iostream>
using std::cerr;
using std::string;
@@ -301,10 +302,10 @@ static bool LinkFunctionBody(Function *Dest, const Function *Src,
for (Function::ArgumentListType::const_iterator
I = Src->getArgumentList().begin(),
E = Src->getArgumentList().end(); I != E; ++I) {
- const FunctionArgument *SMA = *I;
+ const Argument *SMA = *I;
// Create the new method argument and add to the dest method...
- FunctionArgument *DMA = new FunctionArgument(SMA->getType(),SMA->getName());
+ Argument *DMA = new Argument(SMA->getType(), SMA->getName());
Dest->getArgumentList().push_back(DMA);
// Add a mapping to our local map
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index e5f9114..6cdbf9d 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -20,6 +20,7 @@
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/SymbolTable.h"
+#include "llvm/Argument.h"
#include "Support/StringExtras.h"
#include "Support/STLExtras.h"
#include <algorithm>
@@ -30,7 +31,7 @@ using std::vector;
using std::ostream;
static const Module *getModuleFromVal(const Value *V) {
- if (const FunctionArgument *MA = dyn_cast<const FunctionArgument>(V))
+ if (const Argument *MA = dyn_cast<const Argument>(V))
return MA->getParent() ? MA->getParent()->getParent() : 0;
else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V))
return BB->getParent() ? BB->getParent()->getParent() : 0;
@@ -46,7 +47,7 @@ static const Module *getModuleFromVal(const Value *V) {
static SlotCalculator *createSlotCalculator(const Value *V) {
assert(!isa<Type>(V) && "Can't create an SC for a type!");
- if (const FunctionArgument *FA = dyn_cast<const FunctionArgument>(V)) {
+ if (const Argument *FA = dyn_cast<const Argument>(V)) {
return new SlotCalculator(FA->getParent(), true);
} else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
return new SlotCalculator(I->getParent()->getParent(), true);
@@ -286,7 +287,7 @@ private :
void printConstant(const Constant *CPV);
void printGlobal(const GlobalVariable *GV);
void printFunction(const Function *F);
- void printFunctionArgument(const FunctionArgument *FA);
+ void printArgument(const Argument *FA);
void printBasicBlock(const BasicBlock *BB);
void printInstruction(const Instruction *I);
ostream &printType(const Type *Ty);
@@ -397,7 +398,7 @@ void AssemblyWriter::printFunction(const Function *M) {
if (!M->isExternal()) {
for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
- bind_obj(this, &AssemblyWriter::printFunctionArgument));
+ bind_obj(this, &AssemblyWriter::printArgument));
} else {
// Loop over the arguments, printing them...
const FunctionType *MT = M->getFunctionType();
@@ -432,10 +433,10 @@ void AssemblyWriter::printFunction(const Function *M) {
Table.purgeFunction();
}
-// printFunctionArgument - This member is called for every argument that
+// printArgument - This member is called for every argument that
// is passed into the function. Simply print it out
//
-void AssemblyWriter::printFunctionArgument(const FunctionArgument *Arg) {
+void AssemblyWriter::printArgument(const Argument *Arg) {
// Insert commas as we go... the first arg doesn't get a comma
if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
@@ -679,7 +680,7 @@ void Type::print(std::ostream &o) const {
o << getDescription();
}
-void FunctionArgument::print(std::ostream &o) const {
+void Argument::print(std::ostream &o) const {
o << getType() << " " << getName();
}
@@ -710,7 +711,7 @@ CachedWriter &CachedWriter::operator<<(const Value *V) {
case Value::ConstantVal:
Out << " "; AW->write(V->getType());
Out << " " << cast<Constant>(V)->getStrValue(); break;
- case Value::FunctionArgumentVal:
+ case Value::ArgumentVal:
AW->write(V->getType()); Out << " " << V->getName(); break;
case Value::TypeVal: AW->write(cast<const Type>(V)); break;
case Value::InstructionVal: AW->write(cast<Instruction>(V)); break;
diff --git a/lib/VMCore/Linker.cpp b/lib/VMCore/Linker.cpp
index 9637f74..086c6c6 100644
--- a/lib/VMCore/Linker.cpp
+++ b/lib/VMCore/Linker.cpp
@@ -18,6 +18,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/ConstantVals.h"
+#include "llvm/Argument.h"
#include <iostream>
using std::cerr;
using std::string;
@@ -301,10 +302,10 @@ static bool LinkFunctionBody(Function *Dest, const Function *Src,
for (Function::ArgumentListType::const_iterator
I = Src->getArgumentList().begin(),
E = Src->getArgumentList().end(); I != E; ++I) {
- const FunctionArgument *SMA = *I;
+ const Argument *SMA = *I;
// Create the new method argument and add to the dest method...
- FunctionArgument *DMA = new FunctionArgument(SMA->getType(),SMA->getName());
+ Argument *DMA = new Argument(SMA->getType(), SMA->getName());
Dest->getArgumentList().push_back(DMA);
// Add a mapping to our local map
diff --git a/lib/VMCore/SlotCalculator.cpp b/lib/VMCore/SlotCalculator.cpp
index 4a8312e..8bd0b49 100644
--- a/lib/VMCore/SlotCalculator.cpp
+++ b/lib/VMCore/SlotCalculator.cpp
@@ -19,6 +19,7 @@
#include "llvm/iOther.h"
#include "llvm/DerivedTypes.h"
#include "llvm/SymbolTable.h"
+#include "llvm/Argument.h"
#include "Support/DepthFirstIterator.h"
#include "Support/STLExtras.h"
#include <algorithm>