I'm writing a physics simulation that reads in a whole bunch of system parameters with the boost::program_options
library and I'd like to "automatically" set some parameters that arise as combinations of the user-input values. For example, if I have
[parameters]
c0 = 299792458
dt = 0.004
as the speed of light and timestep in my input file, I'd like to set a value cdt = c0*dt
in the same structure I'm using to store c0
and dt
after both options get read. Notifiers, as I understand, are a way to process an input option with a function, but I haven't seen a way to do the same thing with multiple options -- what's the best way to go about doing this?
I do not see any direct option how to achieve this using boost program_options. Notifiers are being called after only one option is parsed. However you can combine several workarounds to achieve acceptable solution - store values in separate structure, let program_options to fill all computed values (directly or using setter function) after parsing is complete.
My simplified suggestion:
#include <boost/program_options.hpp>
#include <iostream>
using namespace boost::program_options;
struct SimulationConfig {
int c0;
float dt;
float cdt;
void setCdt() {
cdt = c0*dt;
}
};
int main(int argc, const char *argv[])
{
SimulationConfig config;
try
{
options_description desc{"Options"};
desc.add_options()
("help,h", "Help screen")
("c0", value<int>(&config.c0), "Speed of light")
("dt", value<float>(&config.dt), "Time interval");
variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
notify(vm);
if (vm.count("help"))
std::cout << desc << '\n';
else if (vm.count("c0") && vm.count("dt")) {
//config.cdt = vm["c0"].as<int>() * vm["dt"].as<float>();
config.setCdt();
std::cout << "Cdt is set to: " << config.cdt << std::endl;
}
}
catch (const error &ex)
{
std::cerr << ex.what() << '\n';
}
}