[Lemon-commits] alpar: r3234 - in lemon/trunk: demo lemon tools

Lemon SVN svn at lemon.cs.elte.hu
Mon Mar 12 14:26:58 CET 2007


Author: alpar
Date: Mon Mar 12 14:26:56 2007
New Revision: 3234

Modified:
   lemon/trunk/demo/arg_parser_demo.cc
   lemon/trunk/lemon/arg_parser.cc
   lemon/trunk/lemon/arg_parser.h
   lemon/trunk/tools/lgf-gen.cc

Log:
An improved version of ArgParser: You don't need to give an explicit storage
for each option.
TODO: Documentation must be updated


Modified: lemon/trunk/demo/arg_parser_demo.cc
==============================================================================
--- lemon/trunk/demo/arg_parser_demo.cc	(original)
+++ lemon/trunk/demo/arg_parser_demo.cc	Mon Mar 12 14:26:56 2007
@@ -27,15 +27,15 @@
   double d;
   bool b,sil;
   bool g1,g2,g3;
-  ap.option("n", "an integer input", i, true)
-    .option("val", "a double input", d)
+  ap.refOption("n", "an integer input", i, true)
+    .refOption("val", "a double input", d)
     .synonym("vals","val")
-    .option("name", "a string input", s)
-    .option("f", "a switch", b)
-    .option("nohelp", "", sil)
-    .option("gra","Choise A",g1)
-    .option("grb","Choise B",g2)
-    .option("grc","Choise C",g3)
+    .refOption("name", "a string input", s)
+    .refOption("f", "a switch", b)
+    .refOption("nohelp", "", sil)
+    .refOption("gra","Choise A",g1)
+    .refOption("grb","Choise B",g2)
+    .refOption("grc","Choise C",g3)
     .optionGroup("gr","gra")
     .optionGroup("gr","grb")
     .optionGroup("gr","grc")

Modified: lemon/trunk/lemon/arg_parser.cc
==============================================================================
--- lemon/trunk/lemon/arg_parser.cc	(original)
+++ lemon/trunk/lemon/arg_parser.cc	Mon Mar 12 14:26:56 2007
@@ -28,18 +28,104 @@
 
   ArgParser::ArgParser(int argc, char **argv) :_argc(argc), _argv(argv),
 					       _command_name(argv[0]) {
-    option("-help","Print a short help message",_showHelp,this);
+    refOption("-help","Print a short help message",_showHelp,this);
     synonym("help","-help");
     synonym("h","-help");
 
   }
 
-  ArgParser &ArgParser::option(const std::string &name,
+  ArgParser::~ArgParser()
+  {
+    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
+      if(i->second.self_delete)
+	switch(i->second.type) {
+	case BOOL:
+	  delete i->second.bool_p;
+	  break;
+	case STRING:
+	  delete i->second.string_p;
+	  break;
+	case DOUBLE:
+	  delete i->second.double_p;
+	  break;
+	case INTEGER:
+	  delete i->second.int_p;
+	  break;
+	case UNKNOWN:
+	  break;
+	case FUNC:
+	  break;
+	}
+  }
+  
+
+  ArgParser &ArgParser::intOption(const std::string &name,
+			       const std::string &help,
+			       int value, bool obl)
+  {
+    ParData p;
+    p.int_p=new int(value);
+    p.self_delete=true;
+    p.help=help;
+    p.type=INTEGER;
+    p.mandatory=obl;
+    p.self_delete=true;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::doubleOption(const std::string &name,
+			       const std::string &help,
+			       double value, bool obl)
+  {
+    ParData p;
+    p.double_p=new double(value);
+    p.self_delete=true;
+    p.help=help;
+    p.type=DOUBLE;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::boolOption(const std::string &name,
+			       const std::string &help,
+			       bool value, bool obl)
+  {
+    ParData p;
+    p.bool_p=new bool(value);
+    p.self_delete=true;
+    p.help=help;
+    p.type=BOOL;
+    p.mandatory=obl;
+    _opts[name]=p;
+
+    value = false;
+
+    return *this;
+  }
+
+  ArgParser &ArgParser::stringOption(const std::string &name,
+			       const std::string &help,
+			       std::string value, bool obl)
+  {
+    ParData p;
+    p.string_p=new std::string(value);
+    p.self_delete=true;
+    p.help=help;
+    p.type=STRING;
+    p.mandatory=obl;
+    _opts[name]=p;
+    return *this;
+  }
+
+  ArgParser &ArgParser::refOption(const std::string &name,
 			       const std::string &help,
 			       int &value, bool obl)
   {
     ParData p;
     p.int_p=&value;
+    p.self_delete=false;
     p.help=help;
     p.type=INTEGER;
     p.mandatory=obl;
@@ -47,12 +133,13 @@
     return *this;
   }
 
-  ArgParser &ArgParser::option(const std::string &name,
+  ArgParser &ArgParser::refOption(const std::string &name,
 			       const std::string &help,
 			       double &value, bool obl)
   {
     ParData p;
     p.double_p=&value;
+    p.self_delete=false;
     p.help=help;
     p.type=DOUBLE;
     p.mandatory=obl;
@@ -60,12 +147,13 @@
     return *this;
   }
 
-  ArgParser &ArgParser::option(const std::string &name,
+  ArgParser &ArgParser::refOption(const std::string &name,
 			       const std::string &help,
 			       bool &value, bool obl)
   {
     ParData p;
     p.bool_p=&value;
+    p.self_delete=false;
     p.help=help;
     p.type=BOOL;
     p.mandatory=obl;
@@ -76,12 +164,13 @@
     return *this;
   }
 
-  ArgParser &ArgParser::option(const std::string &name,
+  ArgParser &ArgParser::refOption(const std::string &name,
 			       const std::string &help,
 			       std::string &value, bool obl)
   {
     ParData p;
     p.string_p=&value;
+    p.self_delete=false;
     p.help=help;
     p.type=STRING;
     p.mandatory=obl;
@@ -89,19 +178,21 @@
     return *this;
   }
 
-  ArgParser &ArgParser::option(const std::string &name,
+  ArgParser &ArgParser::refOption(const std::string &name,
 			       const std::string &help,
 			       void (*func)(void *),void *data)
   {
     ParData p;
     p.func_p.p=func;
     p.func_p.data=data;
+    p.self_delete=false;
     p.help=help;
     p.type=FUNC;
     p.mandatory=false;
     _opts[name]=p;
     return *this;
   }
+
   ArgParser &ArgParser::optionGroup(const std::string &group,
 				    const std::string &opt)
   {
@@ -377,5 +468,5 @@
 
     return *this;
   }  
-    
+
 }

Modified: lemon/trunk/lemon/arg_parser.h
==============================================================================
--- lemon/trunk/lemon/arg_parser.h	(original)
+++ lemon/trunk/lemon/arg_parser.h	Mon Mar 12 14:26:56 2007
@@ -70,9 +70,9 @@
       bool ingroup;
       bool has_syn;
       bool syn;
-	     
+      bool self_delete;
       ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
-		  has_syn(false), syn(false) {}
+		  has_syn(false), syn(false), self_delete(false) {}
     };
 
     typedef std::map<std::string,ParData> Opts;
@@ -108,13 +108,59 @@
     ///\e
     ArgParser(int argc, char **argv);
 
+    ~ArgParser();
+
     ///Add a new integer type option
 
     ///\param name The name of the option. The leading '-' must be omitted.
     ///\param help A help string.
     ///\retval value The value of the argument will be written to this variable.
     ///\param obl Indicate if the option is mandatory.
-    ArgParser &option(const std::string &name,
+    ArgParser &intOption(const std::string &name,
+		    const std::string &help,
+		    int value=0, bool obl=false);
+
+    ///Add a new floating type option
+
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\retval value The value of the argument will be written to this variable.
+    ///\param obl Indicate if the option is mandatory.
+    ArgParser &doubleOption(const std::string &name,
+		      const std::string &help,
+		      double value=0, bool obl=false);
+
+    ///Add a new bool type option
+
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\retval value The value of the argument will be written to this variable.
+    ///\param obl Indicate if the option is mandatory.
+    ////\note A mandatory bool obtion is of very little use.)
+    ArgParser &boolOption(const std::string &name,
+		      const std::string &help,
+		      bool value=false, bool obl=false);
+
+    ///Add a new string type option
+
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\retval value The value of the argument will be written to this variable.
+    ///\param obl Indicate if the option is mandatory.
+    ArgParser &stringOption(const std::string &name,
+		      const std::string &help,
+		      std::string value="", bool obl=false);
+    
+
+
+
+    ///Add a new integer type option
+
+    ///\param name The name of the option. The leading '-' must be omitted.
+    ///\param help A help string.
+    ///\retval value The value of the argument will be written to this variable.
+    ///\param obl Indicate if the option is mandatory.
+    ArgParser &refOption(const std::string &name,
 		    const std::string &help,
 		    int &value, bool obl=false);
 
@@ -124,7 +170,7 @@
     ///\param help A help string.
     ///\retval value The value of the argument will be written to this variable.
     ///\param obl Indicate if the option is mandatory.
-    ArgParser &option(const std::string &name,
+    ArgParser &refOption(const std::string &name,
 		      const std::string &help,
 		      double &value, bool obl=false);
 
@@ -135,7 +181,7 @@
     ///\retval value The value of the argument will be written to this variable.
     ///\param obl Indicate if the option is mandatory.
     ////\note A mandatory bool obtion is of very little use.)
-    ArgParser &option(const std::string &name,
+    ArgParser &refOption(const std::string &name,
 		      const std::string &help,
 		      bool &value, bool obl=false);
 
@@ -145,7 +191,7 @@
     ///\param help A help string.
     ///\retval value The value of the argument will be written to this variable.
     ///\param obl Indicate if the option is mandatory.
-    ArgParser &option(const std::string &name,
+    ArgParser &refOption(const std::string &name,
 		      const std::string &help,
 		      std::string &value, bool obl=false);
     
@@ -156,7 +202,7 @@
     ///\retval func The function to be called when the option is given. It
     ///  must be of type "void f(void *)"
     ///\param data Data to be passed to \c func
-    ArgParser &option(const std::string &name,
+    ArgParser &refOption(const std::string &name,
 		    const std::string &help,
 		    void (*func)(void *),void *data);
 
@@ -232,7 +278,51 @@
       Opts::iterator i = _opts.find(op);
       return i!=_opts.end()?i->second.set:false;
     }
+
+
+    class RefType 
+    {
+      ArgParser &_parser;
+      std::string _name;
+    public:
+      RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
+      operator bool() 
+      {
+	Opts::iterator i = _parser._opts.find(_name);
+	if(i==_parser._opts.end()) exit(3); ///\todo throw exception instead
+	else if(i->second.type!=ArgParser::BOOL) exit(3);
+	else return *(i->second.bool_p);
+      }
+      operator std::string()
+      {
+	Opts::iterator i = _parser._opts.find(_name);
+	if(i==_parser._opts.end()) exit(3); ///\todo throw exception instead
+	else if(i->second.type!=ArgParser::STRING) exit(3);
+	else return *(i->second.string_p);
+      }
+      operator double() 
+      {
+	Opts::iterator i = _parser._opts.find(_name);
+	if(i==_parser._opts.end()) exit(3); ///\todo throw exception instead
+	else if(i->second.type!=ArgParser::DOUBLE) exit(3);
+	else return *(i->second.double_p);
+      }
+      operator int() 
+      {
+	Opts::iterator i = _parser._opts.find(_name);
+	if(i==_parser._opts.end()) exit(3); ///\todo throw exception instead
+	else if(i->second.type!=ArgParser::INTEGER) exit(3);
+	else return *(i->second.int_p);
+      }
+
+    };
+
+    RefType operator[](const std::string &n)
+    {
+      return RefType(*this, n);
+    }
     
+      
   };
 }
 

Modified: lemon/trunk/tools/lgf-gen.cc
==============================================================================
--- lemon/trunk/tools/lgf-gen.cc	(original)
+++ lemon/trunk/tools/lgf-gen.cc	Mon Mar 12 14:26:56 2007
@@ -29,6 +29,7 @@
 #include <cmath>
 #include <algorithm>
 #include <lemon/unionfind.h>
+#include <lemon/time_measure.h>
 
 using namespace lemon;
 
@@ -36,8 +37,10 @@
 
 UGRAPH_TYPEDEFS(ListUGraph);
 
+bool progress=true;
+
 int N;
-int girth;
+// int girth;
 
 ListUGraph g;
 
@@ -234,31 +237,44 @@
 }
 
 void minTree() {
+  int en=0;
+  int pr=0;
   std::vector<Pedge> pedges;
+  Timer T;
+  std::cout << T.realTime() << "s: Setting up the edges...\n";
   for(NodeIt n(g);n!=INVALID;++n) 
-    for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
-      {
-	Pedge p;
-	p.a=n;
-	p.b=m;
-	p.len=(coords[m]-coords[n]).normSquare();
-	pedges.push_back(p);
-      }
+    {
+      for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
+	{
+	  Pedge p;
+	  p.a=n;
+	  p.b=m;
+	  p.len=(coords[m]-coords[n]).normSquare();
+	  pedges.push_back(p);
+	}
+      en++;
+      if(progress && en>=pr*double(N)/100) 
+	{
+	  std::cout << pr << "%  \r" << std::flush;
+	  pr++;
+	}
+    }
+  std::cout << T.realTime() << "s: Sorting the edges...\n";
   std::sort(pedges.begin(),pedges.end(),pedgeLess);
+  std::cout << T.realTime() << "s: Creating the tree...\n";
   ListUGraph::NodeMap<int> comp(g);
   UnionFind<ListUGraph::NodeMap<int> > uf(comp);
   for (NodeIt it(g); it != INVALID; ++it)
-    uf.insert(it);
-
-  int en=0;
+    uf.insert(it);  
   for(std::vector<Pedge>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
     {
       if ( uf.join(pi->a,pi->b) ) {
 	g.addEdge(pi->a,pi->b);
-	en++;
-	if(en>=N-1) return;
+	if(en>=N-1)
+	  break;
       }
     }
+  std::cout << T.realTime() << "s: Done\n";
 }
 
 
@@ -267,34 +283,34 @@
 {
   ArgParser ap(argc,argv);
 
-  bool eps;
+//   bool eps;
   bool disc_d, square_d, gauss_d;
-  bool tsp_a,two_a,tree_a;
+//   bool tsp_a,two_a,tree_a;
   int num_of_cities=1;
   double area=1;
   N=100;
-  girth=10;
+//   girth=10;
   std::string ndist("disc");
-  ap.option("n", "Number of nodes (default is 100)", N)
-    .option("g", "Girth parameter (default is 10)", girth)
-    .option("cities", "Number of cities (default is 1)", num_of_cities)
-    .option("area", "Full relative area of the cities (default is 1)", area)
-    .option("disc", "Nodes are evenly distributed on a unit disc (default)",disc_d)
+  ap.refOption("n", "Number of nodes (default is 100)", N)
+    .intOption("g", "Girth parameter (default is 10)", 10)
+    .refOption("cities", "Number of cities (default is 1)", num_of_cities)
+    .refOption("area", "Full relative area of the cities (default is 1)", area)
+    .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",disc_d)
     .optionGroup("dist", "disc")
-    .option("square", "Nodes are evenly distributed on a unit square", square_d)
+    .refOption("square", "Nodes are evenly distributed on a unit square", square_d)
     .optionGroup("dist", "square")
-    .option("gauss",
+    .refOption("gauss",
 	    "Nodes are located according to a two-dim gauss distribution",
 	    gauss_d)
     .optionGroup("dist", "gauss")
 //     .mandatoryGroup("dist")
     .onlyOneGroup("dist")
-    .option("eps", "Also generate .eps output (prefix.eps)",eps)
-    .option("2con", "Create a two connected planar graph",two_a)
+    .boolOption("eps", "Also generate .eps output (prefix.eps)")
+    .boolOption("2con", "Create a two connected planar graph")
     .optionGroup("alg","2con")
-    .option("tree", "Create a min. cost spanning tree",tree_a)
+    .boolOption("tree", "Create a min. cost spanning tree")
     .optionGroup("alg","tree")
-    .option("tsp", "Create a TSP tour",tsp_a)
+    .boolOption("tsp", "Create a TSP tour")
     .optionGroup("alg","tsp")
     .onlyOneGroup("alg")
     .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
@@ -352,18 +368,18 @@
 	}
     }
   
-  if(tsp_a) {
+  if(ap["tsp"]) {
     tsp();
     std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
   }
-  else if(two_a) {
+  else if(ap["2con"]) {
     std::cout << "Make triangles\n";
     //   triangle();
-    sparseTriangle(girth);
+    sparseTriangle(ap["g"]);
     std::cout << "Make it sparser\n";
-    sparse2(girth);
+    sparse2(ap["g"]);
   }
-  else if(tree_a) {
+  else if(ap["tree"]) {
     minTree();
   }
   
@@ -374,7 +390,7 @@
   for(UEdgeIt e(g);e!=INVALID;++e)
     tlen+=sqrt((coords[g.source(e)]-coords[g.target(e)]).normSquare());
   std::cout << "Total edge length  : " << tlen << std::endl;
-  if(eps)
+  if(ap["eps"])
     graphToEps(g,prefix+".eps").
       scale(600).nodeScale(.2).edgeWidthScale(.001).preScale(false).
       coords(coords).run();



More information about the Lemon-commits mailing list