cmdopt: print type argument type information

This commit is contained in:
Danny Robson 2016-03-11 13:16:20 +11:00
parent 76179f264b
commit 90386f63fe
3 changed files with 92 additions and 7 deletions

View File

@ -149,6 +149,15 @@ null::execute (const char *restrict)
}
//-----------------------------------------------------------------------------
const std::string&
null::example (void) const
{
static const std::string EXAMPLE;
return EXAMPLE;
}
///////////////////////////////////////////////////////////////////////////////
present::present (std::string _name, std::string _description, bool &_data):
base (std::move (_name), std::move (_description)),
@ -164,6 +173,15 @@ present::execute (void)
}
//-----------------------------------------------------------------------------
const std::string&
present::example (void) const
{
static const std::string EXAMPLE;
return EXAMPLE;
}
//-----------------------------------------------------------------------------
void
present::finish (void)
@ -443,12 +461,28 @@ parser::print_help (const int argc,
exit (0);
// find the longest long form argument so we can set field alignment
auto largest = std::max_element (m_long.begin (),
m_long.end (),
[] (const auto &a, const auto &b) {
return std::get<0> (a).size () < std::get<0> (b).size ();
auto largestwidth = std::max_element (
m_long.begin (),
m_long.end (),
[] (const auto &a, const auto &b)
{
return std::get<std::string> (a).size () < std::get<std::string> (b).size ();
});
int longwidth = std::get<0> (*largest).size ();
int longwidth = std::get<std::string> (*largestwidth).size ();
// find the longest example text
auto largestexample = std::max_element (
m_options.cbegin (),
m_options.cend (),
[] (const auto &a, const auto &b)
{
const auto &example_a = std::get<std::unique_ptr<option::base>> (a)->example ();
const auto &example_b = std::get<std::unique_ptr<option::base>> (b)->example ();
return example_a.size () > example_b.size ();
});
int longexample = std::get<std::unique_ptr<option::base>> (*largestexample)->example ().size ();
// field width requires an alignment. we don't care about preserving
// state as we're about to bail anyway
@ -459,8 +493,9 @@ parser::print_help (const int argc,
for (auto &o: m_options) {
std::cout << '\t'
<< '-' << std::get<0> (o) << '\t'
<< std::setw (longwidth) << std::get<1> (o) << '\t'
<< '-' << std::get<char> (o) << '\t'
<< std::setw (longwidth) << std::get<std::string> (o) << '\t'
<< std::setw (longexample) << std::get<std::unique_ptr<option::base>> (o)->example () << '\t'
<< std::setw (0) << std::get<2> (o)->description ()
<< '\n';
}

View File

@ -38,6 +38,8 @@ namespace util { namespace cmdopt {
virtual void start (void);
virtual void finish (void);
virtual const std::string& example (void) const = 0;
const std::string& name (void) const;
const std::string& description (void) const;
@ -62,6 +64,8 @@ namespace util { namespace cmdopt {
virtual void execute (void) override;
virtual void execute (const char *restrict) override;
virtual const std::string& example (void) const override;
};
@ -72,6 +76,8 @@ namespace util { namespace cmdopt {
using base::execute;
virtual void execute (void) override;
virtual const std::string& example (void) const override;
virtual void finish (void) override;
private:
@ -87,6 +93,8 @@ namespace util { namespace cmdopt {
using base::execute;
void execute (const char *restrict) override;
const std::string& example (void) const override;
T data (void) const;
T& data (void);
T& data (T);

View File

@ -21,6 +21,9 @@
#include <sstream>
#include "./introspection.hpp"
#include "./iterator.hpp"
namespace util { namespace cmdopt {
///////////////////////////////////////////////////////////////////////////
template <typename T>
@ -53,6 +56,45 @@ namespace util { namespace cmdopt {
}
//-------------------------------------------------------------------------
namespace detail {
template <typename T>
std::enable_if_t<!std::is_enum<T>::value, const std::string&>
value_example (void)
{
static const std::string EXAMPLE =
std::string {"<"} +
std::string {to_string<T> ()} +
std::string {">"};
return EXAMPLE;
}
template <typename T>
std::enable_if_t<std::is_enum<T>::value, const std::string&>
value_example (void)
{
static const std::string EXAMPLE = [] (void) {
std::ostringstream os;
std::copy (std::cbegin (enum_values<T>::values),
std::cend (enum_values<T>::values),
infix_iterator<T> (os, "|"));
return os.str ();
} ();
return EXAMPLE;
}
}
//-------------------------------------------------------------------------
template <typename T>
const std::string&
option::value<T>::example (void) const
{
return detail::value_example<T> ();
}
//-----------------------------------------------------------------------------
template <typename T>
T