ParsedCommand.ih
Go to the documentation of this file.
1 //
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
6 //
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
11 //
12 
13 
14 /** \file
15  \brief ParsedCommand internal header */
16 
17 #ifndef IH_SENF_Scheduler_Console_ParsedCommand_
18 #define IH_SENF_Scheduler_Console_ParsedCommand_ 1
19 
20 // Custom includes
21 #include <boost/preprocessor/repetition/enum_trailing.hpp>
22 #include <boost/function.hpp>
23 #include <boost/intrusive_ptr.hpp>
24 #include "Parse.hh"
25 
26 //-/////////////////////////////////////////////////////////////////////////////////////////////////
27 
28 namespace senf {
29 namespace console {
30 
31  template < class FunctionTraits,
32  class ReturnType=typename FunctionTraits::result_type,
33  unsigned arity=FunctionTraits::arity >
34  class ParsedCommandOverload;
35 
36  template < class Overload,
37  unsigned index=0,
38  bool flag=(index < unsigned(Overload::traits::arity)) >
39  class ParsedArgumentAttributor;
40 
41 namespace detail {
42 
43  /** \brief Internal: Argument information structure
44 
45  This class is used to hold argument information for automatically parsed commands.
46 
47  \see ParsedCommandOverloadBase
48  */
49  struct ArgumentInfoBase
50  : public intrusive_refcount
51  {
52  typedef boost::intrusive_ptr<ArgumentInfoBase> ptr;
53 
54  std::string type;
55  std::string name;
56  std::string defaultDoc;
57  bool hasDefault;
58  std::string doc;
59  bool singleToken;
60 
61  explicit ArgumentInfoBase(std::string const & type, bool singleToken=false);
62  virtual ~ArgumentInfoBase();
63 
64  virtual std::string defaultValueStr() const = 0;
65  };
66 
67  /** \brief Internal: Argument information structure
68 
69  This class is used to hold argument information for automatically parsed commands.
70 
71  \see ParsedCommandOverloadBase
72  */
73  template <class ParameterType>
74  struct ArgumentInfo
75  : public ArgumentInfoBase
76  {
77  typedef boost::intrusive_ptr<ArgumentInfo> ptr;
78  typedef boost::function<void (ParseCommandInfo::TokensRange const &,
79  ParameterType &)> Parser;
80 
81  static ptr create();
82  ArgumentInfo();
83 
84  ParameterType defaultValue;
85  Parser parser;
86 
87  virtual std::string defaultValueStr() const;
88  };
89 
90 #ifndef DOXYGEN
91 
92  // FirstArgType returns void, if the function has no arguments, otherwise it returns arg1_type
93 
94  template <class Traits, bool flag=(Traits::arity>0)>
95  struct FirstArgType
96  {
97  typedef void type;
98  };
99 
100  template <class Traits>
101  struct FirstArgType<Traits,true>
102  {
103  typedef typename Traits::arg1_type type;
104  };
105 
106  template <class FnunctionP, class Function, bool isFN=boost::is_function<Function>::value>
107  struct ParsedCommandTraits_i
108  {
109  static const bool is_callable = false;
110  static const bool is_member = false;
111  static const bool is_simple = false;
112  };
113 
114  template <class FunctionP, class Function>
115  struct ParsedCommandTraits_i<FunctionP, Function, true>
116  {
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;
121 
122  static const bool has_ostream_arg = boost::is_same<first_arg_type, std::ostream &>::value;
123 
124  typedef typename boost::mpl::if_c<
125  has_ostream_arg,
126  typename function_traits_remove_arg<base_traits>::type,
127  base_traits>
128  ::type traits;
129 
130  typedef typename senf::remove_cvref<typename base_traits::result_type>::type result_type;
131 
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;
135 
136  typedef typename senf::member_class<base_type>::type class_type;
137 
138  typedef ParsedCommandOverload<traits> Overload;
139  typedef ParsedArgumentAttributor<Overload> Attributor;
140  };
141 
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>
145  {
146  static const bool is_simple = true;
147  };
148 
149  template <class FunctionP>
150  struct ParsedCommandTraits
151  : public ParsedCommandTraits_i< FunctionP,
152  typename senf::remove_any_pointer<FunctionP>::type >
153  {};
154 
155  struct ParsedCommandAddNodeAccess;
156 
157  // What is THIS about ??
158 
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.
162  //
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.
167  //
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.
170 
171  template <class Traits,
172  bool ignoreOneArg=! Traits::has_ostream_arg,
173  unsigned arity=Traits::traits::arity>
174  struct CreateParsedCommandOverload
175  {};
176 
177  template <class Traits, unsigned arity>
178  struct CreateParsedCommandOverload<Traits, false, arity>
179  {
180  typedef typename Traits::traits traits;
181 
182  template <class Function>
183  static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
184  { return senf::console::ParsedCommandOverload<traits>::create(fn); };
185  };
186 
187 # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY, \
188  SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp), \
189  4))
190 # include BOOST_PP_ITERATE()
191 
192 #endif
193 
194 }}}
195 
196 //-/////////////////////////////////////////////////////////////////////////////////////////////////
197 #endif
198 
199 
200 // Local Variables:
201 // mode: c++
202 // fill-column: 100
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"
208 // End: