switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / Console / Traits.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Traits public header */
30
31 #ifndef HH_SENF_Scheduler_Console_Traits_
32 #define HH_SENF_Scheduler_Console_Traits_ 1
33
34 // Custom includes
35 #include <iostream>
36 #include <boost/intrusive_ptr.hpp>
37 #include <boost/type_traits/is_same.hpp>
38 #include <senf/Utils/intrusive_refcount.hh>
39 #include "Parse.hh"
40
41 #include "Traits.ih"
42 //#include "Traits.mpp"
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
44
45 namespace senf {
46 namespace console {
47
48     /** \brief Customize argument parsing
49
50         ArgumentTraits provides argument parsing, Additionally, this class provides a way to get a
51         string-description of a type and to convert a value back into it's string representation
52         used to display default values.
53
54         The default implementation provided here
55         \li will use senf_console_parse_argument() to parse a value. This functions default
56             implementation uses \c boost::lexical_cast and thereby \c iostreams to convert an
57             argument consisting of a single input token into the required type.
58         \li will name types by returning the last component of the fully scoped name (e.g. \c
59             "string" for \c std::string).
60         \li Will format values (for default value display) by forwarding the value to the
61             ReturnValueTraits of that type.
62
63         To customize just the argument parsing, just provide an implementation of
64         senf_console_parse_argument(). Alternatively or to customize type naming or default value
65         formatting, specialize ArgumentTraits  for the type.
66      */
67     template <class Type>
68     struct ArgumentTraits
69     {
70         typedef Type type;
71
72         static bool const singleToken =
73             boost::is_same< typeof(senf_console_parse_argument(
74                                        *static_cast<ParseCommandInfo::TokensRange const *>(0),
75                                        *static_cast<Type*>(0))),
76                             bool >::value;
77
78         static void parse(ParseCommandInfo::TokensRange const & tokens, Type & out);
79                                         ///< Parse token range into value
80                                         /**< This function needs to parse \a tokens and write the
81                                              parsed value into \a out. This function needs to parse
82                                              the \e complete list of tokens, additional tokens must
83                                              be considered as syntax error.
84                                              \throws SyntaxErrorException
85                                              \param[in] tokens tokens to parse
86                                              \param[out] out parsed value */
87
88         static std::string description(); ///< String description of type
89                                         /**< Returns the string description of \a Type. Used to
90                                              generate online help. */
91         static std::string str(Type const & value); ///< Stringify value
92                                         /**< To show default values in the online help, this
93                                              function converts a value back into a one-line string
94                                              representation. The default implementation uses the
95                                              ReturnValueTraits for this conversion. */
96     };
97
98     /** \brief Argument parser
99
100         \see ArgumentTraits
101
102         \related ArgumentTraits
103      */
104     template <class Type>
105     bool senf_console_parse_argument(ParseCommandInfo::TokensRange const & tokens, Type & out);
106
107
108     /** \brief Customize return value formating
109
110         ReturnValueTraits provides return value formatting. The default implementation provided here
111         will forward the call directly to senf_console_format_value(). The default implementation of
112         that function will write the \a value to \a os using standard iostream formatting.
113
114         To customize this behavior for some type, either provide an implementation of
115         senf_console_format_value() in the types namespace or provide a specialization of
116         ReturnValueTraits.
117
118         The output should \e not end in a newline since one is added automatically.
119      */
120     template <class Type>
121     struct ReturnValueTraits
122     {
123         typedef Type type;
124
125         static void format(Type const & value, std::ostream & os);
126                                         ///< Write \a value to \a os
127     };
128
129     /** \brief Return value formatter
130
131         \see ReturnValuetraits
132
133         \related ReturnValueTraits
134      */
135     template <class Type>
136     void senf_console_format_value(Type const & value, std::ostream & os);
137
138
139     /** \brief Parse token range
140
141         This helper will invoke the correct ArgumentTraits::parse function to parse the input tokens
142         into the passed in variable.
143
144         \see ArgumentTraits
145      */
146     template <class Type>
147     void parse(ParseCommandInfo::TokensRange const & tokens, Type & out);
148
149     /** \brief Format value
150
151         This helper will call the correct ArgumentTraits::str function to format \a value
152
153         \see ArgumentTraits
154      */
155     template <class Type>
156     std::string str(Type const & value);
157
158     /** \brief Format return value
159
160         This helper will invoke the correct ReturnValueTraits::format function to write \a value
161         into the \a out stream.
162
163         \see ReturnValueTraits
164      */
165     template <class Type>
166     void format(Type const & value, std::ostream & os);
167
168
169     /** \brief Register enum type for argument parsing
170
171         Enum types need to be registered explicitly to support parsing.
172         \code
173         enum Foo { Foo1, Foo2 };
174         SENF_CONSOLE_REGISTER_ENUM( Foo, (Foo1)(Foo2) );
175         \endcode
176         This macro will register an enum type and it's enumerators defined at namespace scope. See
177         \ref SENF_CONSOLE_REGISTER_ENUM_MEMBER to register a member enum type.
178
179         By default, the keys used to represent the enumerator values in the console are identical to
180         the enumerator names in C++ (In the example above \c Foo1 and \c Foo2). You may however
181         override this default key using the
182         '<tt>key(&quot;</tt><i>key</i><tt>&quot;, </tt><i>enumerator</i><tt>)</tt>' modifier:
183         \code
184         enum Foo { Foo1, Foo2 };
185         SENF_CONSOLE_REGISTER_ENUM( Foo, (key("1", Foo1), Foo2) );
186         \endcode
187         This will register the first enumerator \c Foo1 under the name '\c 1'.
188
189         \note All enumerator keys must be unique ignoring case.
190
191         The enum parser will accept any unique initial substring ignoring case as valid enum value.
192
193         \ingroup console_commands
194      */
195 #   define SENF_CONSOLE_REGISTER_ENUM(Type, Values) \
196         SENF_CONSOLE_REGISTER_ENUM_(BOOST_PP_EMPTY(), Type, Values)
197
198     /** \brief Register enum type for argument parsing
199
200         Enum types need to be registered explicitly to support parsing.
201         \code
202         class SomeClass
203         {
204             enum Foo { Foo1, Foo2 };
205         };
206
207         SENF_CONSOLE_REGISTER_ENUM_MEMBER( SomeClass, Foo, (Foo1)(Foo2) );
208         \endcode This macro will register an enum type and it's enumerators defined in a class. See
209         \ref SENF_CONSOLE_REGISTER_ENUM to register an enum type declared at namespace scope.
210
211         \ingroup console_commands
212      */
213 #   define SENF_CONSOLE_REGISTER_ENUM_MEMBER(Class, Type, Values) \
214         SENF_CONSOLE_REGISTER_ENUM_(Class::, Type, Values)
215
216
217     /** \brief Format boolean value as \c true / \c false */
218     void formatTrueFalse(bool value, std::ostream & os);
219
220     /** \brief Format boolean value as \c yes / \c no */
221     void formatYesNo(bool value, std::ostream & os);
222
223     /** \brief Format boolean value as \c enabled / \c disabled */
224     void formatEnabledDisabled(bool value, std::ostream & os);
225
226     /** \brief Format boolean value as \c on / \c off */
227     void formatOnOff(bool value, std::ostream & os);
228
229     /** \brief Format boolean value as \c 1 / \c 0 */
230     void formatOneZero(bool value, std::ostream & os);
231
232
233 #ifndef DOXYGEN
234
235     // Parse bool: true/false, yes/no, enabled/disabled, 0/1
236     template <>
237     struct ArgumentTraits<bool>
238     {
239         typedef bool type;
240         static bool const singleToken = true;
241
242         static void parse(ParseCommandInfo::TokensRange const & tokens, bool & out);
243         static std::string description();
244         static std::string str(bool value);
245     };
246
247     template <>
248     struct ReturnValueTraits<bool>
249     {
250         typedef bool type;
251
252         static void format(bool value, std::ostream & os);
253     };
254
255     template <> struct ArgumentTraits<char> : public detail::CharArgumentTraits<char> {};
256     template <> struct ReturnValueTraits<char> : public detail::CharReturnValueTraits<char> {};
257     template <> struct ArgumentTraits<signed char> : public detail::CharArgumentTraits<signed char> {};
258     template <> struct ReturnValueTraits<signed char> : public detail::CharReturnValueTraits<signed char> {};
259     template <> struct ArgumentTraits<unsigned char> : public detail::CharArgumentTraits<unsigned char> {};
260     template <> struct ReturnValueTraits<unsigned char> : public detail::CharReturnValueTraits<unsigned char> {};
261
262 #endif
263
264 }}
265
266 //-/////////////////////////////////////////////////////////////////////////////////////////////////
267 #include "Traits.cci"
268 #include "Traits.ct"
269 #include "Traits.cti"
270 #endif
271
272 \f
273 // Local Variables:
274 // mode: c++
275 // fill-column: 100
276 // comment-column: 40
277 // c-file-style: "senf"
278 // indent-tabs-mode: nil
279 // ispell-local-dictionary: "american"
280 // compile-command: "scons -u test"
281 // End: