fixes for Ubuntu Oneiric (g++ 4.6.1, boost 1.46.1)
[senf.git] / senf / Utils / Console / ParsedCommand.ih
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 ParsedCommand internal header */
30
31 #ifndef IH_SENF_Scheduler_Console_ParsedCommand_
32 #define IH_SENF_Scheduler_Console_ParsedCommand_ 1
33
34 // Custom includes
35 #include <boost/preprocessor/repetition/enum_trailing.hpp>
36 #include <boost/function.hpp>
37 #include <boost/intrusive_ptr.hpp>
38 #include "Parse.hh"
39
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41
42 namespace senf {
43 namespace console {
44
45     template < class FunctionTraits,
46                class ReturnType=typename FunctionTraits::result_type,
47                unsigned arity=FunctionTraits::arity >
48     class ParsedCommandOverload;
49
50     template < class Overload,
51                unsigned index=0,
52                bool flag=(index < unsigned(Overload::traits::arity)) >
53     class ParsedArgumentAttributor;
54
55 namespace detail {
56
57     /** \brief Internal: Argument information structure
58
59         This class is used to hold argument information for automatically parsed commands.
60
61         \see ParsedCommandOverloadBase
62      */
63     struct ArgumentInfoBase
64         : public intrusive_refcount
65     {
66         typedef boost::intrusive_ptr<ArgumentInfoBase> ptr;
67
68         std::string type;
69         std::string name;
70         std::string defaultDoc;
71         bool hasDefault;
72         std::string doc;
73         bool singleToken;
74
75         explicit ArgumentInfoBase(std::string const & type, bool singleToken=false);
76         virtual ~ArgumentInfoBase();
77
78         virtual std::string defaultValueStr() const = 0;
79     };
80
81     /** \brief Internal: Argument information structure
82
83         This class is used to hold argument information for automatically parsed commands.
84
85         \see ParsedCommandOverloadBase
86      */
87     template <class ParameterType>
88     struct ArgumentInfo
89         : public ArgumentInfoBase
90     {
91         typedef boost::intrusive_ptr<ArgumentInfo> ptr;
92         typedef boost::function<void (ParseCommandInfo::TokensRange const &,
93                                       ParameterType &)> Parser;
94
95         static ptr create();
96         ArgumentInfo();
97
98         ParameterType defaultValue;
99         Parser parser;
100
101         virtual std::string defaultValueStr() const;
102     };
103
104 #ifndef DOXYGEN
105
106     // FirstArgType returns void, if the function has no arguments, otherwise it returns arg1_type
107
108     template <class Traits, bool flag=(Traits::arity>0)>
109     struct FirstArgType
110     {
111         typedef void type;
112     };
113
114     template <class Traits>
115     struct FirstArgType<Traits,true>
116     {
117         typedef typename Traits::arg1_type type;
118     };
119
120     template <class FnunctionP, class Function, bool isFN=boost::is_function<Function>::value>
121     struct ParsedCommandTraits_i
122     {
123         static const bool is_callable = false;
124         static const bool is_member = false;
125         static const bool is_simple = false;
126     };
127
128     template <class FunctionP, class Function>
129     struct ParsedCommandTraits_i<FunctionP, Function, true>
130     {
131         typedef FunctionP base_type;
132         typedef typename senf::remove_any_pointer<base_type>::type function_type;
133         typedef boost::function_traits<function_type> base_traits;
134         typedef typename FirstArgType<base_traits>::type first_arg_type;
135
136         static const bool has_ostream_arg = boost::is_same<first_arg_type, std::ostream &>::value;
137
138         typedef typename boost::mpl::if_c<
139             has_ostream_arg,
140             typename function_traits_remove_arg<base_traits>::type,
141             base_traits>
142         ::type traits;
143
144         typedef typename senf::remove_cvref<typename base_traits::result_type>::type result_type;
145
146         static const bool is_callable = true;
147         static const bool is_member = boost::is_member_pointer<base_type>::value;
148         static const bool is_simple = false;
149
150         typedef typename senf::member_class<base_type>::type class_type;
151
152         typedef ParsedCommandOverload<traits> Overload;
153         typedef ParsedArgumentAttributor<Overload> Attributor;
154     };
155
156     // Disable auto-parsing for ParseCommandInfo arg -> register manually parsed command
157     template <class FunctionP>
158     struct ParsedCommandTraits_i<FunctionP, void (std::ostream &, ParseCommandInfo const &), true>
159     {
160         static const bool is_simple = true;
161     };
162
163     template <class FunctionP>
164     struct ParsedCommandTraits
165         : public ParsedCommandTraits_i< FunctionP,
166                                         typename senf::remove_any_pointer<FunctionP>::type >
167     {};
168
169     struct ParsedCommandAddNodeAccess;
170
171     // What is THIS about ??
172
173     // Ok, here's the dope: parsed commands may optionally have an std::ostream & first argument. If
174     // this argument is given, then the function will be called with the console output stream as
175     // it's first argument.
176     //
177     // This is implemented in the following way: ParsedCommandOverload (the class responsible for
178     // calling the callback) will ALWAYS pass the stream as first argument. If the user callback
179     // expects os as it's first argument, 'ignoreOneArg' will be false and the user supplied
180     // function will be directly passed to ParsedCommandOverload.
181     //
182     // If however, it does NOT take an std::ostream first argument, 'ignoreOneArg' will be true and
183     // the create member will use boost::bind to DROP the first argument.
184
185     template <class Traits,
186               bool ignoreOneArg=! Traits::has_ostream_arg,
187               unsigned arity=Traits::traits::arity>
188     struct CreateParsedCommandOverload
189     {};
190
191     template <class Traits, unsigned arity>
192     struct CreateParsedCommandOverload<Traits, false, arity>
193     {
194         typedef typename Traits::traits traits;
195
196         template <class Function>
197         static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
198             { return senf::console::ParsedCommandOverload<traits>::create(fn); };
199     };
200
201 #   define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY,                     \
202                                             SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp), \
203                                             4))
204 #   include BOOST_PP_ITERATE()
205
206 #endif
207
208 }}}
209
210 //-/////////////////////////////////////////////////////////////////////////////////////////////////
211 #endif
212
213 \f
214 // Local Variables:
215 // mode: c++
216 // fill-column: 100
217 // comment-column: 40
218 // c-file-style: "senf"
219 // indent-tabs-mode: nil
220 // ispell-local-dictionary: "american"
221 // compile-command: "scons -u test"
222 // End: