mirror of
https://github.com/cuberite/TCLAP.git
synced 2025-08-03 17:56:17 -04:00
Merge branch 'traits'
Make all types have ValueLike traits by default. This allows new types to be added without any fuzz (no need to specify the traits) if it has operator>>. It also removes the need to manually specify the ArgTrait for all built in types (such as long, bool, char, float etc). ArgTraits now works in the following way: 1) If there exists a specialization of ArgTraits for type X, use it. 2) If no specialization exists but X has the typename X::ValueCategory, use the specialization for X::ValueCategory. 3) If neither (1) nor (2) defines the trait, use the default which is ValueLike. Conflicts: examples/Makefile.am examples/test24.cpp tests/Makefile.am tests/runtests.sh tests/test83.out tests/test83.sh
This commit is contained in:
commit
bd0440fdbd
42
examples/test26.cpp
Normal file
42
examples/test26.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "tclap/CmdLine.h"
|
||||
#include <iterator>
|
||||
|
||||
using namespace TCLAP;
|
||||
|
||||
// Define a simple 3D vector type
|
||||
struct Vect3D {
|
||||
double v[3];
|
||||
|
||||
std::ostream& print(std::ostream &os) const
|
||||
{
|
||||
std::copy(v, v + 3, std::ostream_iterator<double>(os, " "));
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
// operator>> will be used to assign to the vector since the default
|
||||
// is that all types are ValueLike.
|
||||
std::istream &operator>>(std::istream &is, Vect3D &v)
|
||||
{
|
||||
if (!(is >> v.v[0] >> v.v[1] >> v.v[2]))
|
||||
throw TCLAP::ArgParseException(" Argument is not a 3D vector");
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CmdLine cmd("Command description message", ' ', "0.9");
|
||||
ValueArg<Vect3D> vec("v", "vect", "vector",
|
||||
true, Vect3D(), "3D vector", cmd);
|
||||
|
||||
try {
|
||||
cmd.parse(argc, argv);
|
||||
} catch(std::exception &e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
vec.getValue().print(std::cout);
|
||||
std::cout << std::endl;
|
||||
}
|
@ -73,13 +73,46 @@ struct ValueLikeTrait {
|
||||
* Arg traits are used to get compile type specialization when parsing
|
||||
* argument values. Using an ArgTraits you can specify the way that
|
||||
* values gets assigned to any particular type during parsing. The two
|
||||
* supported types are StringLike and ValueLike.
|
||||
* supported types are StringLike and ValueLike. ValueLike is the
|
||||
* default and means that operator>> will be used to assign values to
|
||||
* the type.
|
||||
*/
|
||||
template<typename T>
|
||||
struct ArgTraits {
|
||||
typedef typename T::ValueCategory ValueCategory;
|
||||
virtual ~ArgTraits() {}
|
||||
//typedef ValueLike ValueCategory;
|
||||
class ArgTraits {
|
||||
// This is a bit silly, but what we want to do is:
|
||||
// 1) If there exists a specialization of ArgTraits for type X,
|
||||
// use it.
|
||||
//
|
||||
// 2) If no specialization exists but X has the typename
|
||||
// X::ValueCategory, use the specialization for X::ValueCategory.
|
||||
//
|
||||
// 3) If neither (1) nor (2) defines the trait, use the default
|
||||
// which is ValueLike.
|
||||
|
||||
// This is the "how":
|
||||
//
|
||||
// test<T>(0) (where 0 is the NULL ptr) will match
|
||||
// test(typename C::ValueCategory*) iff type T has the
|
||||
// corresponding typedef. If it does not test(...) will be
|
||||
// matched. This allows us to determine if T::ValueCategory
|
||||
// exists by checking the sizeof for the test function (return
|
||||
// value must have different sizeof).
|
||||
template<typename C> static short test(typename C::ValueCategory*);
|
||||
template<typename C> static long test(...);
|
||||
static const bool hasTrait = sizeof(test<T>(0)) == sizeof(short);
|
||||
|
||||
template <typename C, bool>
|
||||
struct DefaultArgTrait {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
struct DefaultArgTrait<C, true> {
|
||||
typedef typename C::ValueCategory ValueCategory;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef typename DefaultArgTrait<T, hasTrait>::ValueCategory ValueCategory;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -41,156 +41,10 @@
|
||||
|
||||
namespace TCLAP {
|
||||
|
||||
// ======================================================================
|
||||
// Integer types
|
||||
// ======================================================================
|
||||
// Integer types (signed, unsigned and bool) and floating point types all
|
||||
// have value-like semantics.
|
||||
|
||||
/**
|
||||
* longs have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<long> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
/**
|
||||
* ints have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<int> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
/**
|
||||
* shorts have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<short> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
/**
|
||||
* chars have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<char> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
/**
|
||||
* long longs have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<long long> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
// Unsigned integer types
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* unsigned longs have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<unsigned long> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
/**
|
||||
* unsigned ints have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<unsigned int> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
/**
|
||||
* unsigned shorts have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<unsigned short> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
/**
|
||||
* unsigned chars have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<unsigned char> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
// Microsoft implements size_t awkwardly.
|
||||
#if defined(_MSC_VER) && defined(_M_X64)
|
||||
/**
|
||||
* size_ts have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<size_t> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
/**
|
||||
* unsigned long longs have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<unsigned long long> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
// Float types
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* floats have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<float> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
/**
|
||||
* doubles have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<double> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
// Other types
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* bools have value-like semantics.
|
||||
*/
|
||||
template<>
|
||||
struct ArgTraits<bool> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* wchar_ts have value-like semantics.
|
||||
*/
|
||||
#ifndef TCLAP_DONT_DECLARE_WCHAR_T_ARGTRAITS
|
||||
template<>
|
||||
struct ArgTraits<wchar_t> {
|
||||
typedef ValueLike ValueCategory;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Strings have string like argument traits.
|
||||
*/
|
||||
// Strings have string like argument traits.
|
||||
template<>
|
||||
struct ArgTraits<std::string> {
|
||||
typedef StringLike ValueCategory;
|
||||
|
1
tests/test87.out
Normal file
1
tests/test87.out
Normal file
@ -0,0 +1 @@
|
||||
1 2 3
|
12
tests/test87.sh
Executable file
12
tests/test87.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# this tests whether all required args are listed as
|
||||
# missing when no arguments are specified
|
||||
# failure
|
||||
../examples/test26 -v "1 2 3" > tmp.out 2>&1
|
||||
|
||||
if cmp -s tmp.out $srcdir/test87.out; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
Loading…
x
Reference in New Issue
Block a user