diff --git a/examples/test26.cpp b/examples/test26.cpp new file mode 100644 index 0000000..db7f673 --- /dev/null +++ b/examples/test26.cpp @@ -0,0 +1,42 @@ +#include "tclap/CmdLine.h" +#include + +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(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 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; +} diff --git a/include/tclap/ArgTraits.h b/include/tclap/ArgTraits.h index 0b2c18f..df1fe50 100644 --- a/include/tclap/ArgTraits.h +++ b/include/tclap/ArgTraits.h @@ -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 -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(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 static short test(typename C::ValueCategory*); + template static long test(...); + static const bool hasTrait = sizeof(test(0)) == sizeof(short); + + template + struct DefaultArgTrait { + typedef ValueLike ValueCategory; + }; + + template + struct DefaultArgTrait { + typedef typename C::ValueCategory ValueCategory; + }; + +public: + typedef typename DefaultArgTrait::ValueCategory ValueCategory; }; #endif diff --git a/include/tclap/StandardTraits.h b/include/tclap/StandardTraits.h index 46d7f6f..de28422 100644 --- a/include/tclap/StandardTraits.h +++ b/include/tclap/StandardTraits.h @@ -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 { - typedef ValueLike ValueCategory; -}; - -/** - * ints have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -/** - * shorts have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -/** - * chars have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -#ifdef HAVE_LONG_LONG -/** - * long longs have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; -#endif - -// ====================================================================== -// Unsigned integer types -// ====================================================================== - -/** - * unsigned longs have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -/** - * unsigned ints have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -/** - * unsigned shorts have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -/** - * unsigned chars have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -// Microsoft implements size_t awkwardly. -#if defined(_MSC_VER) && defined(_M_X64) -/** - * size_ts have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; -#endif - - -#ifdef HAVE_LONG_LONG -/** - * unsigned long longs have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; -#endif - -// ====================================================================== -// Float types -// ====================================================================== - -/** - * floats have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -/** - * doubles have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -// ====================================================================== -// Other types -// ====================================================================== - -/** - * bools have value-like semantics. - */ -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - - -/** - * wchar_ts have value-like semantics. - */ -#ifndef TCLAP_DONT_DECLARE_WCHAR_T_ARGTRAITS -template<> -struct ArgTraits { - typedef ValueLike ValueCategory; -}; -#endif - -/** - * Strings have string like argument traits. - */ +// Strings have string like argument traits. template<> struct ArgTraits { typedef StringLike ValueCategory; diff --git a/tests/test87.out b/tests/test87.out new file mode 100644 index 0000000..46786e9 --- /dev/null +++ b/tests/test87.out @@ -0,0 +1 @@ +1 2 3 diff --git a/tests/test87.sh b/tests/test87.sh new file mode 100755 index 0000000..1230dc7 --- /dev/null +++ b/tests/test87.sh @@ -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