diff --git a/config/ac_cxx_have_long_long.m4 b/config/ac_cxx_have_long_long.m4 new file mode 100644 index 0000000..d0dd85c --- /dev/null +++ b/config/ac_cxx_have_long_long.m4 @@ -0,0 +1,19 @@ +dnl @synopsis AC_CXX_HAVE_LONG_LONG +dnl +dnl If the C++ implementation have a long long type +dnl +AC_DEFUN([AC_CXX_HAVE_LONG_LONG], +[AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([],[long long x = 1; return 0;], + ac_cv_cxx_have_long_long=yes, ac_cv_cxx_have_long_long=no) + +if test "$ac_cv_cxx_have_long_long" = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, + [define if the C++ implementation have long long]) +else + AC_DEFINE(HAVE_LONG_LONG, 0, + [define if the C++ implementation have long long]) +fi +AC_LANG_RESTORE +]) diff --git a/configure.in b/configure.in index 88848b3..b2ccb05 100644 --- a/configure.in +++ b/configure.in @@ -6,6 +6,7 @@ AM_INIT_AUTOMAKE(tclap,1.1.0) AC_PROG_CXX AC_CXX_HAVE_SSTREAM AC_CXX_HAVE_STRSTREAM +AC_CXX_HAVE_LONG_LONG AC_CHECK_PROG(DOT,dot,YES,NO) AC_PROG_RANLIB AC_PROG_INSTALL diff --git a/examples/Makefile.am b/examples/Makefile.am index fe7df3b..8c37d6f 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,6 +1,6 @@ noinst_PROGRAMS = test1 test2 test3 test4 test5 test6 test7 test8 test9 \ - test10 test11 test12 test13 + test10 test11 test12 test13 test14 test15 test16 test1_SOURCES = test1.cpp test2_SOURCES = test2.cpp @@ -15,6 +15,9 @@ test10_SOURCES = test10.cpp test11_SOURCES = test11.cpp test12_SOURCES = test12.cpp test13_SOURCES = test13.cpp +test14_SOURCES = test14.cpp +test15_SOURCES = test15.cpp +test16_SOURCES = test16.cpp INCLUDES = -I$(top_srcdir)/include diff --git a/examples/test14.cpp b/examples/test14.cpp new file mode 100644 index 0000000..e194845 --- /dev/null +++ b/examples/test14.cpp @@ -0,0 +1,56 @@ +#include "tclap/CmdLine.h" +#include +#include + +// Define a simple 3D vector type +template +struct Vect : public TCLAP::StringLikeTrait { + //typedef TCLAP::StringLike ValueCategory; + T v[LEN]; + + // operator= will be used to assign to the vector + Vect& operator=(const std::string &str) + { + std::istringstream iss(str); + for (size_t n = 0; n < LEN; n++) { + if (!(iss >> v[n])) { + std::ostringstream oss; + oss << " is not a vector of size " << LEN; + throw TCLAP::ArgParseException(str + oss.str()); + } + } + + if (!iss.eof()) { + std::ostringstream oss; + oss << " is not a vector of size " << LEN; + throw TCLAP::ArgParseException(str + oss.str()); + } + + return *this; + } + + std::ostream& print(std::ostream &os) const + { + std::copy(v, v + LEN, std::ostream_iterator(os, " ")); + return os; + } + +}; + +int main(int argc, char *argv[]) +{ + TCLAP::CmdLine cmd("Command description message", ' ', "0.9"); + TCLAP::ValueArg< Vect > vec("v", "vect", "vector", + true, Vect(), + "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/examples/test15.cpp b/examples/test15.cpp new file mode 100644 index 0000000..62cd95b --- /dev/null +++ b/examples/test15.cpp @@ -0,0 +1,56 @@ +#include "tclap/CmdLine.h" +#include +#include + +// Define a simple 3D vector type +template +struct Vect { + typedef TCLAP::StringLike ValueCategory; + T v[LEN]; + + // operator= will be used to assign to the vector + Vect& operator=(const std::string &str) + { + std::istringstream iss(str); + for (size_t n = 0; n < LEN; n++) { + if (!(iss >> v[n])) { + std::ostringstream oss; + oss << " is not a vector of size " << LEN; + throw TCLAP::ArgParseException(str + oss.str()); + } + } + + if (!iss.eof()) { + std::ostringstream oss; + oss << " is not a vector of size " << LEN; + throw TCLAP::ArgParseException(str + oss.str()); + } + + return *this; + } + + std::ostream& print(std::ostream &os) const + { + std::copy(v, v + LEN, std::ostream_iterator(os, " ")); + return os; + } + +}; + +int main(int argc, char *argv[]) +{ + TCLAP::CmdLine cmd("Command description message", ' ', "0.9"); + TCLAP::ValueArg< Vect > vec("v", "vect", "vector", + true, Vect(), + "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/examples/test16.cpp b/examples/test16.cpp new file mode 100644 index 0000000..fae185c --- /dev/null +++ b/examples/test16.cpp @@ -0,0 +1,41 @@ +#include "tclap/CmdLine.h" +#include +#include + +namespace TCLAP { + template<> + struct ArgTraits< std::vector > { + typedef StringLike ValueCategory; + }; + + template<> + void SetString< std::vector >(std::vector &v, + const std::string &s) + { + std::istringstream iss(s); + while (iss) { + double tmp; + iss >> tmp; + v.push_back(tmp); + } + } +} + +int main(int argc, char *argv[]) +{ + TCLAP::CmdLine cmd("Command description message", ' ', "0.9"); + TCLAP::ValueArg< std::vector > vec("v", "vect", "vector", + true, std::vector(), + "3D vector", cmd); + try { + cmd.parse(argc, argv); + } catch(std::exception &e) { + std::cout << e.what() << std::endl; + return EXIT_FAILURE; + } + + const std::vector &v = vec.getValue(); + std::copy(v.begin(), v.end(), + std::ostream_iterator(std::cout, "\n")); + std::cout << std::endl; +} diff --git a/include/tclap/Arg.h b/include/tclap/Arg.h index beb6245..70f6223 100644 --- a/include/tclap/Arg.h +++ b/include/tclap/Arg.h @@ -49,6 +49,8 @@ typedef std::istrstream istringstream; #include #include #include +#include +#include namespace TCLAP { @@ -367,41 +369,6 @@ typedef std::vector::iterator ArgVectorIterator; */ typedef std::list::iterator VisitorListIterator; -// We use two empty structs to get compile type specialization -// function to work - -/** - * A value like argument value type is a value that can be set using - * operator>>. This is the default value type. - */ -struct ValueLike {}; - -/** - * A string like argument value type is a value that can be set using - * operator=(string). Usefull if the value type contains spaces which - * will be broken up into individual tokens by operator>>. - */ -struct StringLike {}; - -/** - * 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 string like and value like. - */ -template -struct ArgTraits { - typedef ValueLike ValueCategory; -}; - -/** - * Strings have string like argument traits. - */ -template<> -struct ArgTraits { - typedef StringLike ValueCategory; -}; - /* * Extract a value of type T from it's string representation contained * in strVal. The ValueLike parameter used to select the correct @@ -445,7 +412,7 @@ template void ExtractValue(T &destVal, const std::string& strVal, StringLike sl) { static_cast(sl); // Avoid warning about unused sl - destVal = strVal; + SetString(destVal, strVal); } ////////////////////////////////////////////////////////////////////// diff --git a/include/tclap/ArgTraits.h b/include/tclap/ArgTraits.h new file mode 100644 index 0000000..a89ed12 --- /dev/null +++ b/include/tclap/ArgTraits.h @@ -0,0 +1,81 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: ArgTraits.h + * + * Copyright (c) 2007, Daniel Aarno, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +// This is an internal tclap file, you should probably not have to +// include this directly + +#ifndef TCLAP_ARGTRAITS_H +#define TCLAP_ARGTRAITS_H + +namespace TCLAP { + +// We use two empty structs to get compile type specialization +// function to work + +/** + * A value like argument value type is a value that can be set using + * operator>>. This is the default value type. + */ +struct ValueLike { + typedef ValueLike ValueCategory; +}; + +/** + * A string like argument value type is a value that can be set using + * operator=(string). Usefull if the value type contains spaces which + * will be broken up into individual tokens by operator>>. + */ +struct StringLike {}; + +/** + * A class can inherit from this object to make it have string like + * traits. This is a compile time thing and does not add any overhead + * to the inherenting class. + */ +struct StringLikeTrait { + typedef StringLike ValueCategory; +}; + +/** + * A class can inherit from this object to make it have value like + * traits. This is a compile time thing and does not add any overhead + * to the inherenting class. + */ +struct ValueLikeTrait { + typedef ValueLike ValueCategory; +}; + +/** + * 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 string like and value like. + */ +template +struct ArgTraits { + typedef typename T::ValueCategory ValueCategory; + //typedef ValueLike ValueCategory; +}; + +#endif + +} // namespace diff --git a/include/tclap/StandardTraits.h b/include/tclap/StandardTraits.h new file mode 100644 index 0000000..8be880e --- /dev/null +++ b/include/tclap/StandardTraits.h @@ -0,0 +1,184 @@ +// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- + +/****************************************************************************** + * + * file: StandardTraits.h + * + * Copyright (c) 2007, Daniel Aarno, Michael E. Smoot . + * All rights reverved. + * + * See the file COPYING in the top directory of this distribution for + * more information. + * + * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *****************************************************************************/ + +// This is an internal tclap file, you should probably not have to +// include this directly + +#ifndef TCLAP_STANDARD_TRAITS_H +#define TCLAP_STANDARD_TRAITS_H + +#ifdef HAVE_CONFIG_H +#include // To check for long long +#endif + +namespace TCLAP { + +// ====================================================================== +// Integer types +// ====================================================================== + +/** + * 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; +}; + +#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. + */ +template<> +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * Strings have string like argument traits. + */ +template<> +struct ArgTraits { + typedef StringLike ValueCategory; +}; + +template +void SetString(T &dst, const std::string &src) +{ + dst = src; +} + +} // namespace + +#endif +