Search code examples
c++jsonboostboost-program-options

C++ Boost program options with json file


It is possible with boost program options library: http://www.boost.org/doc/libs/1_64_0/doc/html/program_options.html

to read json formatted file as an input file here?

Or if I have some config in json like file, I need to parse it myself, with for example: http://www.boost.org/doc/libs/1_64_0/doc/html/property_tree.html


Solution

  • I've met the same problem. Here is my implementation of JSON parser for program_options library, based on property_tree:

    template <class charT> void parseChildren(std::string prefix, boost::property_tree::ptree& tree, boost::program_options::parsed_options& options)
    {
        if (tree.size() == 0)
        {
            //cut first dot
            std::basic_string<charT> name = prefix.substr(1);
            std::basic_string<charT> value = tree.data();
    
            boost::program_options::basic_option<charT> opt;
            opt.string_key = name;
            opt.value.push_back(value);
            opt.unregistered = (options.description->find_nothrow(name, false) == nullptr);
            opt.position_key = -1;
            options.options.push_back(opt);
        }
        else
        {
            for (auto it = tree.begin(); it != tree.end(); ++it)
            {
                parseChildren<charT>(prefix + "." + it->first, it->second, options);
            }
        }
    }
    
    template <class charT>
    void parseJsonOptions(std::basic_istream<charT>& is, boost::program_options::parsed_options& options)
    {
            boost::property_tree::basic_ptree<std::basic_string<charT>, std::basic_string<charT>> pt;
            boost::property_tree::read_json(is, pt);
    
            parseChildren<charT>(std::basic_string<charT>(), pt, options);
    }
    
    template <class charT>
    boost::program_options::basic_parsed_options<charT> parse_json_config_file(std::basic_istream<charT>& is, const boost::program_options::options_description& desc, bool allow_unregistered = false)
    {     
        // do any option check here
    
        boost::program_options::parsed_options result(&desc);
        parseJsonOptions(is, result);
    
        return boost::program_options::basic_parsed_options<charT>(result);
    }
    

    Use it like:

    po::variables_map vm;
    std::ifstream configFileStream(configFilePath_.generic_string());
    
    store(parse_json_config_file(configFileStream, algorithmsDesc_), vm);
    notify(vm);