]> Creatis software - cpPlugins.git/blob - lib/tclap/ArgTraits.h
...
[cpPlugins.git] / lib / tclap / ArgTraits.h
1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2
3 /******************************************************************************
4  *
5  *  file:  ArgTraits.h
6  *
7  *  Copyright (c) 2007, Daniel Aarno, Michael E. Smoot .
8  *  All rights reserved.
9  *
10  *  See the file COPYING in the top directory of this distribution for
11  *  more information.
12  *
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.
20  *
21  *****************************************************************************/
22
23 // This is an internal tclap file, you should probably not have to
24 // include this directly
25
26 #ifndef TCLAP_ARGTRAITS_H
27 #define TCLAP_ARGTRAITS_H
28
29 namespace TCLAP {
30
31 // We use two empty structs to get compile type specialization
32 // function to work
33
34 /**
35  * A value like argument value type is a value that can be set using
36  * operator>>. This is the default value type.
37  */
38 struct ValueLike {
39     typedef ValueLike ValueCategory;
40         virtual ~ValueLike() {}
41 };
42
43 /**
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>>.
47  */
48 struct StringLike {
49         virtual ~StringLike() {}
50 };
51
52 /**
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.
56  */
57 struct StringLikeTrait {
58     typedef StringLike ValueCategory;
59         virtual ~StringLikeTrait() {}
60 };
61
62 /**
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.
66  */
67 struct ValueLikeTrait {
68     typedef ValueLike ValueCategory;
69         virtual ~ValueLikeTrait() {}
70 };
71
72 /**
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
78  * the type.
79  */
80 template<typename T>
81 class ArgTraits {
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,
84         // use it.
85         //
86         // 2) If no specialization exists but X has the typename
87         // X::ValueCategory, use the specialization for X::ValueCategory.
88         //
89         // 3) If neither (1) nor (2) defines the trait, use the default
90         // which is ValueLike.
91
92         // This is the "how":
93         //
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);
103
104         template <typename C, bool>
105         struct DefaultArgTrait {
106                 typedef ValueLike ValueCategory;
107         };
108
109         template <typename C>
110         struct DefaultArgTrait<C, true> {
111                 typedef typename C::ValueCategory ValueCategory;
112         };
113
114 public:
115         typedef typename DefaultArgTrait<T, hasTrait>::ValueCategory ValueCategory;
116 };
117
118 } // namespace
119
120 #endif
121