Utils: Add unit-test and documentation for type_traits.hh
[senf.git] / Console / ParsedCommand.cti
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief ParsedCommand inline template implementation */
25
26 #include "ParsedCommand.ih"
27
28 // Custom includes
29 #include "../Utils/membind.hh"
30 #include <boost/format.hpp>
31
32 #define prefix_ inline
33 ///////////////////////////////cti.p///////////////////////////////////////
34
35 ///////////////////////////////////////////////////////////////////////////
36 // senf::console::ParsedCommandOverloadBase
37
38 template <class Type>
39 prefix_ senf::console::detail::ParameterInfo<Type> &
40 senf::console::ParsedCommandOverloadBase::arg(unsigned n)
41     const
42 {
43     return dynamic_cast<detail::ParameterInfo<Type> &>(arg(n));
44 }
45
46 template <class Type>
47 prefix_ void senf::console::ParsedCommandOverloadBase::addParameter()
48 {
49     parameters_.push_back(detail::ParameterInfo<Type>::create());
50 }
51
52 ///////////////////////////////////////////////////////////////////////////
53 // senf::console::ParsedCommandOverload<FunctionTraits,n>
54
55 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY,                       \
56                                          SENF_ABSOLUTE_INCLUDE_PATH(Console/ParsedCommand.mpp),   \
57                                          2))
58 #include BOOST_PP_ITERATE()
59
60 ///////////////////////////////////////////////////////////////////////////
61 // senf::console::ParsedCommandAttributorBase
62
63 template <class Type>
64 prefix_ void senf::console::ParsedCommandAttributorBase::defaultValue(Type const & value)
65     const
66 {
67     overload().arg<Type>(index_).defaultValue = value;
68     overload().arg(index_).hasDefault = true;
69 }
70
71 ///////////////////////////////////////////////////////////////////////////
72 // senf::console::ParsedCommandAttributor<Overload>
73
74 template <class Overload>
75 prefix_ Overload & senf::console::ParsedCommandAttributor<Overload>::overload()
76     const
77 {
78     return static_cast<Overload &>(ParsedCommandAttributorBase::overload());
79 }
80
81 template <class Overload>
82 prefix_
83 senf::console::ParsedCommandAttributor<Overload>::ParsedCommandAttributor(Overload & overload,
84                                                                           unsigned index)
85     : ParsedCommandAttributorBase (overload, index)
86 {}
87
88 ///////////////////////////////////////////////////////////////////////////
89 // senf::console::ParsedAttributeAttributorBase<Overload,Self>
90
91 template <class Overload, class Self>
92 prefix_ Self
93 senf::console::ParsedAttributeAttributorBase<Overload,Self>::doc(std::string const & doc)
94     const
95 {
96     this->ParsedCommandAttributorBase::nodeDoc(doc);
97     return static_cast<Self const &>(*this);
98 }
99
100 template <class Overload, class Self>
101 prefix_ Self senf::console::ParsedAttributeAttributorBase<Overload,Self>::
102 overloadDoc(std::string const & doc)
103     const
104 {
105     this->ParsedCommandAttributorBase::overloadDoc(doc);
106     return static_cast<Self const &>(*this);
107 }
108
109 template <class Overload, class Self>
110 prefix_
111 senf::console::ParsedAttributeAttributorBase<Overload,Self>::
112 ParsedAttributeAttributorBase(Overload & overload, unsigned index)
113     : ParsedCommandAttributor<Overload> (overload, index)
114 {}
115
116 ///////////////////////////////////////////////////////////////////////////
117 // senf::console::ParsedAttributeAttributor<Overload,index,flag>
118
119 template <class Overload, unsigned index, bool flag>
120 prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
121 senf::console::ParsedAttributeAttributor<Overload,index,flag>::arg(std::string const & name,
122                                                                    std::string const & doc)
123     const
124 {
125     this->argName(name);
126     this->argDoc(doc);
127     return next();
128 }
129
130 template <class Overload, unsigned index, bool flag>
131 prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
132 senf::console::ParsedAttributeAttributor<Overload,index,flag>::arg(std::string const & name,
133                                                                    std::string const & doc,
134                                                                    value_type const & value)
135     const
136 {
137     this->argName(name);
138     this->argDoc(doc);
139     defaultValue(value);
140     return next();
141 }
142
143 template <class Overload, unsigned index, bool flag>
144 prefix_
145 senf::console::ParsedAttributeAttributor<Overload,index,flag>::
146 ParsedAttributeAttributor(Overload & overload)
147     : ParsedAttributeAttributorBase<Overload, ParsedAttributeAttributor> (overload, index)
148 {}
149
150 template <class Overload, unsigned index, bool flag>
151 prefix_ senf::console::ParsedAttributeAttributor<Overload, index+1>
152 senf::console::ParsedAttributeAttributor<Overload,index,flag>::next()
153     const
154 {
155     return ParsedAttributeAttributor<Overload, index+1>(this->overload());
156 }
157
158 template <class Overload, unsigned index, bool flag>
159 prefix_ void senf::console::ParsedAttributeAttributor<Overload,index,flag>::
160 defaultValue(value_type const & value)
161     const
162 {
163     ParsedCommandAttributorBase::defaultValue<arg_type>(value);
164 }
165
166 ///////////////////////////////////////////////////////////////////////////
167 // senf::console::ParsedAttributeAttributor<Overload, index, false>
168
169 template <class Overload, unsigned index>
170 prefix_
171 senf::console::ParsedAttributeAttributor<Overload, index, false>::
172 ParsedAttributeAttributor(Overload & overload)
173     : ParsedAttributeAttributorBase<Overload, ParsedAttributeAttributor> (overload, index)
174 {}
175
176 ///////////////////////////////////////////////////////////////////////////
177 // namespace members
178
179 namespace {
180
181     // What is THIS about ??
182
183     // Ok, here's the dope: parsed commands may optionally have an std::ostream & first argument. If
184     // this argument is given, then the function will be called with the console output stream as
185     // it's first argument.
186     //
187     // This is implemented in the following way: ParsedCommandOverload (the class responsible for
188     // calling the callback) will ALWAYS pass the stream as first argument. If the user callback
189     // expects os as it's first argument, 'ignoreOneArg' will be false and the user supplied
190     // function will be directly passed to ParsedCommandOverload.
191     //
192     // If however, it does NOT take an std::ostream first argument, 'ignoreOneArg' will be true and
193     // the create member will use boost::bind to DROP the first argument.
194     
195     template <class Traits, bool ignoreOneArg, unsigned arity=Traits::arity>
196     struct CreateParsedCommandOverload
197     {};
198
199     template <class Traits, unsigned arity>
200     struct CreateParsedCommandOverload<Traits, false, arity>
201     {
202         typedef Traits traits;
203         
204         template <class Function>
205         static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn) 
206             { return senf::console::ParsedCommandOverload<traits>::create(fn); };
207     };
208
209 #   define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY,                     \
210                                             SENF_ABSOLUTE_INCLUDE_PATH(Console/ParsedCommand.mpp), \
211                                             4))
212 #   include BOOST_PP_ITERATE()
213
214 }
215
216 template <class Function>
217 prefix_ senf::console::ParsedAttributeAttributor<
218     senf::console::ParsedCommandOverload<
219         typename senf::console::detail::ParsedCommandTraits<Function>::traits> >
220 senf::console::senf_console_add_node(DirectoryNode & node, std::string const & name,
221                                      Function fn, int)
222 {
223     OverloadedCommandNode & cmdNode (
224         node.hasChild(name) 
225         ? dynamic_cast<OverloadedCommandNode &>(node(name))
226         : node.add(name, OverloadedCommandNode::create()) );
227
228     typedef detail::ParsedCommandTraits<Function> CmdTraits;
229     typedef ParsedCommandOverload<typename CmdTraits::traits> Overload;
230     typedef ParsedAttributeAttributor<Overload> Attributor;
231
232     return Attributor(
233         cmdNode.add( CreateParsedCommandOverload<
234                          typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(fn) ) );
235 }
236
237 template <class Owner, class Function>
238 prefix_ senf::console::ParsedAttributeAttributor<
239     senf::console::ParsedCommandOverload<
240         typename senf::console::detail::ParsedCommandTraits<Function>::traits> >
241 senf::console::
242 senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
243                       Function fn, int,
244                       typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type *)
245 {
246     OverloadedCommandNode & cmdNode (
247         node.hasChild(name) 
248         ? dynamic_cast<OverloadedCommandNode &>(node(name))
249         : node.add(name, OverloadedCommandNode::create()) );
250
251     typedef detail::ParsedCommandTraits<Function> CmdTraits;
252     typedef ParsedCommandOverload<typename CmdTraits::traits> Overload;
253     typedef ParsedAttributeAttributor<Overload> Attributor;
254
255     return Attributor(
256         cmdNode.add( CreateParsedCommandOverload<
257                          typename CmdTraits::traits, ! CmdTraits::has_ostream_arg>::create(
258                              senf::membind(fn,&owner)) ) );
259 }
260
261 ///////////////////////////////cti.e///////////////////////////////////////
262 #undef prefix_
263
264 \f
265 // Local Variables:
266 // mode: c++
267 // fill-column: 100
268 // comment-column: 40
269 // c-file-style: "senf"
270 // indent-tabs-mode: nil
271 // ispell-local-dictionary: "american"
272 // compile-command: "scons -u test"
273 // End: