1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
3 /******************************************************************************
7 * Copyright (c) 2007, Daniel Aarno, Michael E. Smoot .
10 * See the file COPYING in the top directory of this distribution for
13 * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19 * DEALINGS IN THE SOFTWARE.
21 *****************************************************************************/
23 // This is an internal tclap file, you should probably not have to
24 // include this directly
26 #ifndef TCLAP_ARGTRAITS_H
27 #define TCLAP_ARGTRAITS_H
31 // We use two empty structs to get compile type specialization
35 * A value like argument value type is a value that can be set using
36 * operator>>. This is the default value type.
39 typedef ValueLike ValueCategory;
40 virtual ~ValueLike() {}
44 * A string like argument value type is a value that can be set using
45 * operator=(string). Useful if the value type contains spaces which
46 * will be broken up into individual tokens by operator>>.
49 virtual ~StringLike() {}
53 * A class can inherit from this object to make it have string like
54 * traits. This is a compile time thing and does not add any overhead
55 * to the inherenting class.
57 struct StringLikeTrait {
58 typedef StringLike ValueCategory;
59 virtual ~StringLikeTrait() {}
63 * A class can inherit from this object to make it have value like
64 * traits. This is a compile time thing and does not add any overhead
65 * to the inherenting class.
67 struct ValueLikeTrait {
68 typedef ValueLike ValueCategory;
69 virtual ~ValueLikeTrait() {}
73 * Arg traits are used to get compile type specialization when parsing
74 * argument values. Using an ArgTraits you can specify the way that
75 * values gets assigned to any particular type during parsing. The two
76 * supported types are StringLike and ValueLike. ValueLike is the
77 * default and means that operator>> will be used to assign values to
82 // This is a bit silly, but what we want to do is:
83 // 1) If there exists a specialization of ArgTraits for type X,
86 // 2) If no specialization exists but X has the typename
87 // X::ValueCategory, use the specialization for X::ValueCategory.
89 // 3) If neither (1) nor (2) defines the trait, use the default
90 // which is ValueLike.
94 // test<T>(0) (where 0 is the NULL ptr) will match
95 // test(typename C::ValueCategory*) iff type T has the
96 // corresponding typedef. If it does not test(...) will be
97 // matched. This allows us to determine if T::ValueCategory
98 // exists by checking the sizeof for the test function (return
99 // value must have different sizeof).
100 template<typename C> static short test(typename C::ValueCategory*);
101 template<typename C> static long test(...);
102 static const bool hasTrait = sizeof(test<T>(0)) == sizeof(short);
104 template <typename C, bool>
105 struct DefaultArgTrait {
106 typedef ValueLike ValueCategory;
109 template <typename C>
110 struct DefaultArgTrait<C, true> {
111 typedef typename C::ValueCategory ValueCategory;
115 typedef typename DefaultArgTrait<T, hasTrait>::ValueCategory ValueCategory;