Use a shared pointer for the options map
Fixes #132. Since the map of options is shared between Options and ParseResult, they should use a shared pointer instead of a reference so that ParseResult can be returned without referencing destroyed memory.
This commit is contained in:
parent
b528324107
commit
c713b44d92
@ -1110,7 +1110,9 @@ namespace cxxopts
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
ParseResult(
|
ParseResult(
|
||||||
const std::unordered_map<std::string, std::shared_ptr<OptionDetails>>&,
|
const std::shared_ptr<
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
|
||||||
|
>,
|
||||||
std::vector<std::string>,
|
std::vector<std::string>,
|
||||||
bool allow_unrecognised,
|
bool allow_unrecognised,
|
||||||
int&, char**&);
|
int&, char**&);
|
||||||
@ -1118,8 +1120,8 @@ namespace cxxopts
|
|||||||
size_t
|
size_t
|
||||||
count(const std::string& o) const
|
count(const std::string& o) const
|
||||||
{
|
{
|
||||||
auto iter = m_options.find(o);
|
auto iter = m_options->find(o);
|
||||||
if (iter == m_options.end())
|
if (iter == m_options->end())
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1132,9 +1134,9 @@ namespace cxxopts
|
|||||||
const OptionValue&
|
const OptionValue&
|
||||||
operator[](const std::string& option) const
|
operator[](const std::string& option) const
|
||||||
{
|
{
|
||||||
auto iter = m_options.find(option);
|
auto iter = m_options->find(option);
|
||||||
|
|
||||||
if (iter == m_options.end())
|
if (iter == m_options->end())
|
||||||
{
|
{
|
||||||
throw option_not_present_exception(option);
|
throw option_not_present_exception(option);
|
||||||
}
|
}
|
||||||
@ -1182,8 +1184,9 @@ namespace cxxopts
|
|||||||
const std::string& name
|
const std::string& name
|
||||||
);
|
);
|
||||||
|
|
||||||
const std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
|
const std::shared_ptr<
|
||||||
&m_options;
|
std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
|
||||||
|
> m_options;
|
||||||
std::vector<std::string> m_positional;
|
std::vector<std::string> m_positional;
|
||||||
std::vector<std::string>::iterator m_next_positional;
|
std::vector<std::string>::iterator m_next_positional;
|
||||||
std::unordered_set<std::string> m_positional_set;
|
std::unordered_set<std::string> m_positional_set;
|
||||||
@ -1196,6 +1199,8 @@ namespace cxxopts
|
|||||||
|
|
||||||
class Options
|
class Options
|
||||||
{
|
{
|
||||||
|
typedef std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
|
||||||
|
OptionMap;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Options(std::string program, std::string help_string = "")
|
Options(std::string program, std::string help_string = "")
|
||||||
@ -1205,6 +1210,7 @@ namespace cxxopts
|
|||||||
, m_positional_help("positional parameters")
|
, m_positional_help("positional parameters")
|
||||||
, m_show_positional(false)
|
, m_show_positional(false)
|
||||||
, m_allow_unrecognised(false)
|
, m_allow_unrecognised(false)
|
||||||
|
, m_options(std::make_shared<OptionMap>())
|
||||||
, m_next_positional(m_positional.end())
|
, m_next_positional(m_positional.end())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1308,7 +1314,7 @@ namespace cxxopts
|
|||||||
bool m_show_positional;
|
bool m_show_positional;
|
||||||
bool m_allow_unrecognised;
|
bool m_allow_unrecognised;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<OptionDetails>> m_options;
|
std::shared_ptr<OptionMap> m_options;
|
||||||
std::vector<std::string> m_positional;
|
std::vector<std::string> m_positional;
|
||||||
std::vector<std::string>::iterator m_next_positional;
|
std::vector<std::string>::iterator m_next_positional;
|
||||||
std::unordered_set<std::string> m_positional_set;
|
std::unordered_set<std::string> m_positional_set;
|
||||||
@ -1466,7 +1472,9 @@ namespace cxxopts
|
|||||||
inline
|
inline
|
||||||
ParseResult::ParseResult
|
ParseResult::ParseResult
|
||||||
(
|
(
|
||||||
const std::unordered_map<std::string, std::shared_ptr<OptionDetails>>& options,
|
const std::shared_ptr<
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
|
||||||
|
> options,
|
||||||
std::vector<std::string> positional,
|
std::vector<std::string> positional,
|
||||||
bool allow_unrecognised,
|
bool allow_unrecognised,
|
||||||
int& argc, char**& argv
|
int& argc, char**& argv
|
||||||
@ -1606,9 +1614,9 @@ inline
|
|||||||
void
|
void
|
||||||
ParseResult::add_to_option(const std::string& option, const std::string& arg)
|
ParseResult::add_to_option(const std::string& option, const std::string& arg)
|
||||||
{
|
{
|
||||||
auto iter = m_options.find(option);
|
auto iter = m_options->find(option);
|
||||||
|
|
||||||
if (iter == m_options.end())
|
if (iter == m_options->end())
|
||||||
{
|
{
|
||||||
throw option_not_exists_exception(option);
|
throw option_not_exists_exception(option);
|
||||||
}
|
}
|
||||||
@ -1622,8 +1630,8 @@ ParseResult::consume_positional(std::string a)
|
|||||||
{
|
{
|
||||||
while (m_next_positional != m_positional.end())
|
while (m_next_positional != m_positional.end())
|
||||||
{
|
{
|
||||||
auto iter = m_options.find(*m_next_positional);
|
auto iter = m_options->find(*m_next_positional);
|
||||||
if (iter != m_options.end())
|
if (iter != m_options->end())
|
||||||
{
|
{
|
||||||
auto& result = m_results[iter->second];
|
auto& result = m_results[iter->second];
|
||||||
if (!iter->second->value().is_container())
|
if (!iter->second->value().is_container())
|
||||||
@ -1737,9 +1745,9 @@ ParseResult::parse(int& argc, char**& argv)
|
|||||||
for (std::size_t i = 0; i != s.size(); ++i)
|
for (std::size_t i = 0; i != s.size(); ++i)
|
||||||
{
|
{
|
||||||
std::string name(1, s[i]);
|
std::string name(1, s[i]);
|
||||||
auto iter = m_options.find(name);
|
auto iter = m_options->find(name);
|
||||||
|
|
||||||
if (iter == m_options.end())
|
if (iter == m_options->end())
|
||||||
{
|
{
|
||||||
if (m_allow_unrecognised)
|
if (m_allow_unrecognised)
|
||||||
{
|
{
|
||||||
@ -1774,9 +1782,9 @@ ParseResult::parse(int& argc, char**& argv)
|
|||||||
{
|
{
|
||||||
const std::string& name = result[1];
|
const std::string& name = result[1];
|
||||||
|
|
||||||
auto iter = m_options.find(name);
|
auto iter = m_options->find(name);
|
||||||
|
|
||||||
if (iter == m_options.end())
|
if (iter == m_options->end())
|
||||||
{
|
{
|
||||||
if (m_allow_unrecognised)
|
if (m_allow_unrecognised)
|
||||||
{
|
{
|
||||||
@ -1814,7 +1822,7 @@ ParseResult::parse(int& argc, char**& argv)
|
|||||||
++current;
|
++current;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& opt : m_options)
|
for (auto& opt : *m_options)
|
||||||
{
|
{
|
||||||
auto& detail = opt.second;
|
auto& detail = opt.second;
|
||||||
auto& value = detail->value();
|
auto& value = detail->value();
|
||||||
@ -1892,7 +1900,7 @@ Options::add_one_option
|
|||||||
std::shared_ptr<OptionDetails> details
|
std::shared_ptr<OptionDetails> details
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto in = m_options.emplace(option, details);
|
auto in = m_options->emplace(option, details);
|
||||||
|
|
||||||
if (!in.second)
|
if (!in.second)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -26,7 +26,8 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
#include "cxxopts.hpp"
|
#include "cxxopts.hpp"
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
cxxopts::ParseResult
|
||||||
|
parse(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -131,11 +132,20 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
std::cout << "Arguments remain = " << argc << std::endl;
|
std::cout << "Arguments remain = " << argc << std::endl;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
} catch (const cxxopts::OptionException& e)
|
} catch (const cxxopts::OptionException& e)
|
||||||
{
|
{
|
||||||
std::cout << "error parsing options: " << e.what() << std::endl;
|
std::cout << "error parsing options: " << e.what() << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
auto result = parse(argc, argv);
|
||||||
|
auto arguments = result.arguments();
|
||||||
|
std::cout << "Saw " << arguments.size() << " arguments" << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user