Sto costruendo un generatore di diagrammi usando Boost Graph e Program Options. Esistono, ad esempio, due tipi di componenti C e W, ciascuno con 1 sorgente, 1 sink e alcuni parametri aggiuntivi per specificare la topologia in mezzo. Mi piacerebbe essere in grado di unirli insieme nella sequenza fornita dall'ordine degli argomenti della riga di comando.Come si estrae la sequenza di opzioni analizzate usando le opzioni del programma di potenziamento?
Ad esempio:
./bin/make_graph -c4,5,1 -w3,3 -c3,1,2
dovrebbe creare un grafico simile al seguente:
C -- W -- C
Ma:
./bin/make_graph -c4,5,1 -c3,1,2 -w3,3
dovrebbe creare un grafico simile al seguente:
C -- C -- W
Utilizzando boost :: program_options, non è stato possibile determinare come estrarre l'ordine esatto poiché "compone" le opzioni dello stesso string_key in una mappa con valore_type == vettore < stringa> (nel mio caso).
iterando sulla mappa, l'ordine è perso. C'è un modo per non duplicare l'analisi, ma avere una funzione chiamata (forse una richiamata) ogni volta che viene analizzata un'opzione? Non sono riuscito a trovare documentazione in questa direzione. Qualche altro suggerimento?
di convincervi che io non sto inventando, ecco cosa ho finora:
namespace bpo = boost::program_options;
std::vector<std::string> args_cat, args_grid, args_web;
bpo::options_description desc("Program options:");
desc.add_options()
.operator()("help,h","Displays this help message.")
.operator()("caterpillar,c",bpo::value< std::vector<std::string> >(&args_cat)->default_value(std::vector<std::string>(1,"4,7,2"), "4,7,2"),"Caterpillar tree with 3 parameters")
.operator()("grid,g",bpo::value< std::vector<std::string> >(&args_grid)->default_value(std::vector<std::string>(1,"3,4"), "3,4"),"Rectangular grid with 2 parameters")
.operator()("web,w",bpo::value< std::vector<std::string> >(&args_web)->default_value(std::vector<std::string>(1,"3,4"), "3,4"),"Web with 2 parameters")
;
bpo::variables_map ops;
bpo::store(bpo::parse_command_line(argc,argv,desc),ops);
bpo::notify(ops);
if((argc < 2) || (ops.count("help"))) {
std::cout << desc << std::endl;
return;
}
//TODO: remove the following scope block after testing
{
typedef bpo::variables_map::iterator OptionsIterator;
OptionsIterator it = ops.options.begin(), it_end = ops.options.end();
while(it != it_end) {
std::cout << it->first << ": ";
BOOST_FOREACH(std::string value, it->second) {
std::cout << value << " ";
}
std::cout << std::endl;
++it;
}
return;
}
mi rendo conto che avrei potuto includere anche il tipo come parametro e risolvere questo problema banalmente, ad esempio:
./bin/make_graph --component c,4,5,1 --component w,3,3 --component c,3,1,2
ma che si muove nella direzione di scrivere un parser/validatore stesso (magari anche senza utilizzare Boost Opzioni programma):
./bin/make_graph --custom c,4,5,1,w,3,3,c,3,1,2
./bin/make_graph c,4,5,1,w,3,3,c,3,1,2
Come raccomanderesti di farlo in modo elegante?
Grazie in anticipo!
PS: ho cercato su SO per "[boost] + sequenza opzioni programma" e "[boost-programma-opzioni] + ordine" (e le loro varianti) prima di postare questo, quindi mi scuso in anticipo se questo si rivela essere un duplicato.
Grazie. Sono d'accordo per quanto riguarda i file di configurazione. La mia motivazione era di evitare l'I/O dei file su un numero elevato di esecuzioni. – scribbleink