Skip to content

Commit

Permalink
Default values for vector args.
Browse files Browse the repository at this point in the history
  • Loading branch information
abellgithub committed Oct 12, 2016
1 parent 9cefa5a commit c8a9fd5
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 10 deletions.
6 changes: 5 additions & 1 deletion include/pdal/util/Bounds.hpp
Expand Up @@ -560,7 +560,10 @@ class PDAL_DLL Bounds
BOX2D to2d() const;
bool is3d() const;

friend PDAL_DLL std::istream& operator >> (std::istream& in, Bounds& bounds);
friend PDAL_DLL std::istream& operator >> (std::istream& in,
Bounds& bounds);
friend PDAL_DLL std::ostream& operator << (std::ostream& out,
const Bounds& bounds);

private:
BOX3D m_box;
Expand Down Expand Up @@ -635,5 +638,6 @@ extern PDAL_DLL std::istream& operator>>(std::istream& istr, BOX2D& bounds);
extern PDAL_DLL std::istream& operator>>(std::istream& istr, BOX3D& bounds);

PDAL_DLL std::istream& operator >> (std::istream& in, Bounds& bounds);
PDAL_DLL std::ostream& operator << (std::ostream& in, Bounds& bounds);

} // namespace pdal
138 changes: 131 additions & 7 deletions include/pdal/util/ProgramArgs.hpp
Expand Up @@ -66,6 +66,9 @@ class ArgValList
{
if (s.empty())
return;

// Turn a short arg list into a set of short args: -afv -> -a -f -v
// so that each argval represents a single arg.
if (s.size() > 1 && s[0] == '-' && s[1] != '-')
for (size_t i = 1; i < s.size(); i++)
m_vals.push_back({std::string("-") + s[i]});
Expand Down Expand Up @@ -638,7 +641,8 @@ class BaseVArg : public Arg
\param description Argument description.
*/
BaseVArg(const std::string& longname, const std::string& shortname,
const std::string& description) : Arg(longname, shortname, description)
const std::string& description) : Arg(longname, shortname, description),
m_defaultProvided(false)
{}

/**
Expand Down Expand Up @@ -681,6 +685,17 @@ class BaseVArg : public Arg
throw arg_error(oss.str());
}
}

/**
Return whether a default value was provided for the argument.
\return Whether a default was provided.
*/
virtual bool defaultProvided() const
{ return m_defaultProvided; }

protected:
bool m_defaultProvided;
};

/**
Expand All @@ -692,7 +707,28 @@ class VArg : public BaseVArg
{
public:
/**
Constructor.
Constructor for arguments with default value.
\param longname Name of argument specified on command line with "--"
prefix.
\param shortname Optional name of argument specified on command
line with "-" prefix.
\param description Argument description.
\param variable Variable to which the argument value(s) should be bound.
\param def Default value.
*/
VArg(const std::string& longname, const std::string& shortname,
const std::string& description, std::vector<T>& variable,
std::vector<T> def) :
BaseVArg(longname, shortname, description), m_var(variable),
m_defaultVal(def)
{
m_var = def;
m_defaultProvided = true;
}

/**
Constructor for arguments without default value.
\param longname Name of argument specified on command line with "--"
prefix.
Expand Down Expand Up @@ -735,6 +771,8 @@ class VArg : public BaseVArg
oss << "Invalid value for argument '" << m_longname << "'.";
throw arg_error(oss.str());
}
if (!m_set)
m_var.clear();
m_var.push_back(var);
m_set = true;
}
Expand All @@ -748,13 +786,33 @@ class VArg : public BaseVArg
*/
virtual void reset()
{
m_var.clear();
m_var = m_defaultVal;
m_set = false;
m_hidden = false;
}

/**
Return a string representation of an Arg's default value, or an
empty string if none exists.
\return Default value as a string.
*/
virtual std::string defaultVal() const
{
std::string s;

for (size_t i = 0; i < m_defaultVal.size(); ++i)
{
if (i > 0)
s += ", ";
s += Utils::toString(m_defaultVal[i]);
}
return s;
}

private:
std::vector<T>& m_var;
std::vector<T> m_defaultVal;
};

/**
Expand All @@ -765,7 +823,28 @@ class VArg<std::string> : public BaseVArg
{
public:
/**
Constructor.
Constructor for arguments wit default value.
\param longname Name of argument specified on command line with "--"
prefix.
\param shortname Optional name of argument specified on command
line with "-" prefix.
\param description Argument description.
\param variable Variable to which the argument value(s) should be bound.
\param def Default value.
*/
VArg(const std::string& longname, const std::string& shortname,
const std::string& description, std::vector<std::string>& variable,
std::vector<std::string> def) :
BaseVArg(longname, shortname, description), m_var(variable),
m_defaultVal(def)
{
m_var = def;
m_defaultProvided = true;
}

/**
Constructor for arguments without default value.
\param longname Name of argument specified on command line with "--"
prefix.
Expand Down Expand Up @@ -802,6 +881,8 @@ class VArg<std::string> : public BaseVArg
throw arg_error(oss.str());
}
m_rawVal = s;
if (!m_set)
m_var.clear();
m_var.reserve(m_var.size() + slist.size());
m_var.insert(m_var.end(), slist.begin(), slist.end());
m_set = true;
Expand All @@ -816,13 +897,33 @@ class VArg<std::string> : public BaseVArg
*/
virtual void reset()
{
m_var.clear();
m_var = m_defaultVal;
m_set = false;
m_hidden = false;
}

/**
Return a string representation of an Arg's default value, or an
empty string if none exists.
\return Default value as a string.
*/
virtual std::string defaultVal() const
{
std::string s;

for (size_t i = 0; i < m_defaultVal.size(); ++i)
{
if (i > 0)
s += ", ";
s += m_defaultVal[i];
}
return s;
}

private:
std::vector<std::string>& m_var;
std::vector<std::string> m_defaultVal;
};

/**
Expand Down Expand Up @@ -904,6 +1005,30 @@ class ProgramArgs
return *arg;
}

/**
Add a list-based (vector) argument with a default.
\param name Name of argument. Argument names are specified as
"longname[,shortname]", where shortname is an optional one-character
abbreviation.
\param description Description of the argument.
\param var Reference to variable to bind to argument.
\return Reference to the new argument.
*/
template<typename T>
Arg& add(const std::string& name, const std::string& description,
std::vector<T>& var, std::vector<T> def)
{
std::string longname, shortname;
splitName(name, longname, shortname);

Arg *arg = new VArg<T>(longname, shortname, description, var, def);
addLongArg(longname, arg);
addShortArg(shortname, arg);
m_args.push_back(std::unique_ptr<Arg>(arg));
return *arg;
}

/**
Add an argument to the list of arguments with a default.
Expand All @@ -912,8 +1037,7 @@ class ProgramArgs
abbreviation.
\param description Description of the argument.
\param var Reference to variable to bind to argument.
\param def Default value of argument. If not specified, a
default-constructed value is used.
\param def Default value of argument.
\return Reference to the new argument.
*/
template<typename T>
Expand Down
9 changes: 9 additions & 0 deletions src/util/Bounds.cpp
Expand Up @@ -313,4 +313,13 @@ std::istream& operator>>(std::istream& in, Bounds& bounds)
return in;
}

std::ostream& operator<<(std::ostream& out, const Bounds& bounds)
{
if (bounds.is3d())
out << bounds.to3d();
else
out << bounds.to2d();
return out;
}

} // namespace pdal
21 changes: 19 additions & 2 deletions test/unit/ProgramArgsTest.cpp
Expand Up @@ -268,13 +268,13 @@ TEST(ProgramArgsTest, vector)

std::string m_foo;
std::vector<int> m_bar;
std::vector<int> m_flub;
bool m_baz;

args.add("foo,f", "Foo description", m_foo, "foo").setPositional();
args.add("bar", "Foo description", m_bar).setOptionalPositional();
args.add("baz,z", "Foo description", m_baz);

// Go through exceptions procedurally.
args.add("flub", "Flub description", m_flub, {1, 3, 5});

StringList s = toStringList("--bar 23 --bar 45 Foo -z");
args.parse(s);
Expand All @@ -283,13 +283,18 @@ TEST(ProgramArgsTest, vector)
EXPECT_EQ(m_baz, true);
EXPECT_EQ(m_bar[0], 23);
EXPECT_EQ(m_bar[1], 45);
EXPECT_EQ(m_flub.size(), 3u);
EXPECT_EQ(m_flub[0], 1);
EXPECT_EQ(m_flub[1], 3);
EXPECT_EQ(m_flub[2], 5);

args.reset();
s = toStringList("Foo");
args.parse(s);
EXPECT_EQ(m_bar.size(), 0u);
EXPECT_EQ(m_foo, "Foo");
EXPECT_EQ(m_baz, false);
EXPECT_EQ(m_flub.size(), 3u);

args.reset();
s = toStringList("Fool 44 55 66");
Expand All @@ -300,6 +305,18 @@ TEST(ProgramArgsTest, vector)
EXPECT_EQ(m_bar[1], 55);
EXPECT_EQ(m_bar[2], 66);
EXPECT_EQ(m_baz, false);
EXPECT_EQ(m_flub.size(), 3u);

args.reset();
s = toStringList("--bar 23 --flub 2 Foo -z --flub 4");
args.parse(s);
EXPECT_EQ(m_foo, "Foo");
EXPECT_EQ(m_bar.size(), 1u);
EXPECT_EQ(m_baz, true);
EXPECT_EQ(m_bar[0], 23);
EXPECT_EQ(m_flub.size(), 2u);
EXPECT_EQ(m_flub[0], 2);
EXPECT_EQ(m_flub[1], 4);
}

TEST(ProgramArgsTest, stringvector)
Expand Down

0 comments on commit c8a9fd5

Please sign in to comment.