Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FormerLurker/ArcWelderLib.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'TCLAP/tclap/ArgTraits.h')
-rw-r--r--TCLAP/tclap/ArgTraits.h44
1 files changed, 39 insertions, 5 deletions
diff --git a/TCLAP/tclap/ArgTraits.h b/TCLAP/tclap/ArgTraits.h
index 7ae85a9..0ccf5e3 100644
--- a/TCLAP/tclap/ArgTraits.h
+++ b/TCLAP/tclap/ArgTraits.h
@@ -5,6 +5,7 @@
* file: ArgTraits.h
*
* Copyright (c) 2007, Daniel Aarno, Michael E. Smoot .
+ * Copyright (c) 2017 Google LLC
* All rights reserved.
*
* See the file COPYING in the top directory of this distribution for
@@ -73,13 +74,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;
};
} // namespace