2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
15 \brief ParsedCommand internal header */
17 #ifndef IH_SENF_Scheduler_Console_ParsedCommand_
18 #define IH_SENF_Scheduler_Console_ParsedCommand_ 1
21 #include <boost/preprocessor/repetition/enum_trailing.hpp>
22 #include <boost/function.hpp>
23 #include <boost/intrusive_ptr.hpp>
26 //-/////////////////////////////////////////////////////////////////////////////////////////////////
31 template < class FunctionTraits,
32 class ReturnType=typename FunctionTraits::result_type,
33 unsigned arity=FunctionTraits::arity >
34 class ParsedCommandOverload;
36 template < class Overload,
38 bool flag=(index < unsigned(Overload::traits::arity)) >
39 class ParsedArgumentAttributor;
43 /** \brief Internal: Argument information structure
45 This class is used to hold argument information for automatically parsed commands.
47 \see ParsedCommandOverloadBase
49 struct ArgumentInfoBase
50 : public intrusive_refcount
52 typedef boost::intrusive_ptr<ArgumentInfoBase> ptr;
56 std::string defaultDoc;
61 explicit ArgumentInfoBase(std::string const & type, bool singleToken=false);
62 virtual ~ArgumentInfoBase();
64 virtual std::string defaultValueStr() const = 0;
67 /** \brief Internal: Argument information structure
69 This class is used to hold argument information for automatically parsed commands.
71 \see ParsedCommandOverloadBase
73 template <class ParameterType>
75 : public ArgumentInfoBase
77 typedef boost::intrusive_ptr<ArgumentInfo> ptr;
78 typedef boost::function<void (ParseCommandInfo::TokensRange const &,
79 ParameterType &)> Parser;
84 ParameterType defaultValue;
87 virtual std::string defaultValueStr() const;
92 // FirstArgType returns void, if the function has no arguments, otherwise it returns arg1_type
94 template <class Traits, bool flag=(Traits::arity>0)>
100 template <class Traits>
101 struct FirstArgType<Traits,true>
103 typedef typename Traits::arg1_type type;
106 template <class FnunctionP, class Function, bool isFN=boost::is_function<Function>::value>
107 struct ParsedCommandTraits_i
109 static const bool is_callable = false;
110 static const bool is_member = false;
111 static const bool is_simple = false;
114 template <class FunctionP, class Function>
115 struct ParsedCommandTraits_i<FunctionP, Function, true>
117 typedef FunctionP base_type;
118 typedef typename senf::remove_any_pointer<base_type>::type function_type;
119 typedef boost::function_traits<function_type> base_traits;
120 typedef typename FirstArgType<base_traits>::type first_arg_type;
122 static const bool has_ostream_arg = boost::is_same<first_arg_type, std::ostream &>::value;
124 typedef typename boost::mpl::if_c<
126 typename function_traits_remove_arg<base_traits>::type,
130 typedef typename senf::remove_cvref<typename base_traits::result_type>::type result_type;
132 static const bool is_callable = true;
133 static const bool is_member = boost::is_member_pointer<base_type>::value;
134 static const bool is_simple = false;
136 typedef typename senf::member_class<base_type>::type class_type;
138 typedef ParsedCommandOverload<traits> Overload;
139 typedef ParsedArgumentAttributor<Overload> Attributor;
142 // Disable auto-parsing for ParseCommandInfo arg -> register manually parsed command
143 template <class FunctionP>
144 struct ParsedCommandTraits_i<FunctionP, void (std::ostream &, ParseCommandInfo const &), true>
146 static const bool is_simple = true;
149 template <class FunctionP>
150 struct ParsedCommandTraits
151 : public ParsedCommandTraits_i< FunctionP,
152 typename senf::remove_any_pointer<FunctionP>::type >
155 struct ParsedCommandAddNodeAccess;
157 // What is THIS about ??
159 // Ok, here's the dope: parsed commands may optionally have an std::ostream & first argument. If
160 // this argument is given, then the function will be called with the console output stream as
161 // it's first argument.
163 // This is implemented in the following way: ParsedCommandOverload (the class responsible for
164 // calling the callback) will ALWAYS pass the stream as first argument. If the user callback
165 // expects os as it's first argument, 'ignoreOneArg' will be false and the user supplied
166 // function will be directly passed to ParsedCommandOverload.
168 // If however, it does NOT take an std::ostream first argument, 'ignoreOneArg' will be true and
169 // the create member will use boost::bind to DROP the first argument.
171 template <class Traits,
172 bool ignoreOneArg=! Traits::has_ostream_arg,
173 unsigned arity=Traits::traits::arity>
174 struct CreateParsedCommandOverload
177 template <class Traits, unsigned arity>
178 struct CreateParsedCommandOverload<Traits, false, arity>
180 typedef typename Traits::traits traits;
182 template <class Function>
183 static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
184 { return senf::console::ParsedCommandOverload<traits>::create(fn); };
187 # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY, \
188 SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp), \
190 # include BOOST_PP_ITERATE()
196 //-/////////////////////////////////////////////////////////////////////////////////////////////////
203 // comment-column: 40
204 // c-file-style: "senf"
205 // indent-tabs-mode: nil
206 // ispell-local-dictionary: "american"
207 // compile-command: "scons -u test"