OSVR-Core
MiniArgsHandling.h
Go to the documentation of this file.
1 
16 // Copyright 2016 Sensics, Inc.
17 //
18 // Licensed under the Apache License, Version 2.0 (the "License");
19 // you may not use this file except in compliance with the License.
20 // You may obtain a copy of the License at
21 //
22 // http://www.apache.org/licenses/LICENSE-2.0
23 //
24 // Unless required by applicable law or agreed to in writing, software
25 // distributed under the License is distributed on an "AS IS" BASIS,
26 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27 // See the License for the specific language governing permissions and
28 // limitations under the License.
29 
30 #ifndef INCLUDED_MiniArgsHandling_h_GUID_51E5C000_C9EC_438C_FF9C_2FE43886985C
31 #define INCLUDED_MiniArgsHandling_h_GUID_51E5C000_C9EC_438C_FF9C_2FE43886985C
32 
33 // Internal Includes
34 // - none
35 
36 // Library/third-party includes
37 #if defined(OSVR_HAVE_BOOST) || defined(BOOST_VERSION)
38 #include <boost/algorithm/string/predicate.hpp> // for argument handling
39 #endif
40 
41 // Standard includes
42 #include <algorithm>
43 #include <cstddef>
44 #include <initializer_list>
45 #include <iterator>
46 #include <string>
47 #include <utility>
48 #include <vector>
49 
50 namespace osvr {
51 namespace util {
52  namespace args {
53  using ArgList = std::vector<std::string>;
54 
56  inline ArgList makeArgList(int argc, char *argv[]) {
57  return std::vector<std::string>(argv + 1, argv + argc);
58  }
61  template <typename F> inline std::size_t handle_arg(ArgList &c, F &&f) {
62  auto origSize = c.size();
63  auto origEnd = end(c);
64  auto newEnd = std::remove_if(begin(c), end(c), std::forward<F>(f));
65  if (newEnd != origEnd) {
66  std::size_t newSize = std::distance(begin(c), newEnd);
67  c.resize(newSize);
68  return origSize - newSize;
69  }
70  return 0;
71  }
72  namespace detail {
74  template <typename T>
75  static bool apply(T &&a, std::string const &b) {
76  return (std::forward<T>(a) == b);
77  }
78  };
79 #ifdef OSVR_HAVE_BOOST
80  struct CaseInsensitiveComparisonPolicy {
81  template <typename T>
82  static bool apply(T &&a, std::string const &b) {
83  return boost::iequals(b, std::forward<T>(a));
84  }
85  };
86 #endif // OSVR_HAVE_BOOST
87 
88  template <typename ComparisonPolicy, typename SequenceType>
89  inline bool generic_handle_has_switch(ArgList &c,
90  SequenceType &&argSwitch) {
91  return 0 < handle_arg(c, [&argSwitch](std::string const &arg) {
92  return ComparisonPolicy::apply(arg, argSwitch);
93  });
94  }
95  } // namespace detail
96 
97 #ifdef OSVR_HAVE_BOOST
98  template <typename SequenceType>
105  inline bool handle_has_iswitch(ArgList &c, SequenceType &&argSwitch) {
106  return detail::generic_handle_has_switch<
107  detail::CaseInsensitiveComparisonPolicy>(
108  c, std::forward<SequenceType>(argSwitch));
109  }
110 #endif // OSVR_HAVE_BOOST
111 
118  template <typename SequenceType>
119  inline bool handle_has_switch(ArgList &c, SequenceType &&argSwitch) {
120  return detail::generic_handle_has_switch<
122  c, std::forward<SequenceType>(argSwitch));
123  }
129  template <typename F, typename G>
130  inline std::size_t handle_value_arg(ArgList &c, F &&predicate,
131  G &&action) {
132 
133  if (c.size() < 2) {
134  // Need at least two args for this to work.
135  return 0;
136  }
137  auto origEnd = end(c);
138  auto origSize = c.size();
139  std::vector<bool> isCandidate(origSize, false);
140  // Apply predicate
141  std::transform(begin(c), origEnd, begin(isCandidate),
142  [&](std::string const &arg) {
143  return std::forward<F>(predicate)(arg);
144  });
145 
146  ArgList remainingArgs;
147  auto beforeEnd = end(c);
148  --beforeEnd;
149 
150  std::size_t count = 0;
153  bool lastAccepted = false;
154  for (auto it = begin(c), e = end(c); it != beforeEnd && it != e;
155  ++it) {
156  if (std::forward<F>(predicate)(*it)) {
158  ++it;
159  ++count;
160  std::forward<G>(action)(*it);
161  lastAccepted = true;
162  } else {
164  remainingArgs.emplace_back(std::move(*it));
165  lastAccepted = false;
166  }
167  }
168 
172  if (!lastAccepted) {
173  remainingArgs.emplace_back(std::move(c.back()));
174  }
175 
177  c.swap(remainingArgs);
178  return count;
179  }
180 
181  namespace detail {
182  template <typename ComparisonPolicy, typename SequenceType>
183  inline bool generic_handle_has_any_switch_of(
184  ArgList &c,
185  std::initializer_list<SequenceType> const &argSwitches) {
186  return 0 <
187  handle_arg(c, [&argSwitches](std::string const &arg) {
188  for (const auto &sw : argSwitches) {
189  if (sw == arg) {
190  return true;
191  }
192  }
193  return false;
194  });
195  }
196  } // namespace detail
203  template <typename SequenceType>
205  ArgList &c,
206  std::initializer_list<SequenceType> const &argSwitches) {
207  return detail::generic_handle_has_any_switch_of<
209  }
210 
211 #ifdef OSVR_HAVE_BOOST
212  template <typename SequenceType>
221  inline bool handle_has_any_iswitch_of(
222  ArgList &c, std::initializer_list<SequenceType> argSwitches) {
223  return detail::generic_handle_has_any_switch_of<
224  detail::CaseInsensitiveComparisonPolicy>(c, argSwitches);
225  }
226 #endif // OSVR_HAVE_BOOST
227  } // namespace args
228 } // namespace util
229 } // namespace osvr
230 #endif // INCLUDED_MiniArgsHandling_h_GUID_51E5C000_C9EC_438C_FF9C_2FE43886985C
Definition: RunLoopManager.h:42
std::size_t handle_arg(ArgList &c, F &&f)
Takes a predicate to find arguments.
Definition: MiniArgsHandling.h:61
ArgList makeArgList(int argc, char *argv[])
Constructs a vector containing the arguments excluding argv[0].
Definition: MiniArgsHandling.h:56
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
typename F::template apply< Args... > apply
Apply an alias class.
Definition: Apply.h:44
Definition: newuoa.h:1888
t_< detail::transform_< List, Fun >> transform
Given a list and an alias class, apply the alias class to each element in the list and return the res...
Definition: Transform.h:54
bool handle_has_switch(ArgList &c, SequenceType &&argSwitch)
Takes a "sequence" (something with operator== with std::string) to compare (case-sensitive) with ever...
Definition: MiniArgsHandling.h:119
bool handle_has_any_switch_of(ArgList &c, std::initializer_list< SequenceType > const &argSwitches)
Takes a list of "sequences" (something with operator== with std::string) to compare (case-sensitive) ...
Definition: MiniArgsHandling.h:204
std::size_t handle_value_arg(ArgList &c, F &&predicate, G &&action)
Takes a predicate to find arguments.
Definition: MiniArgsHandling.h:130
void remove_if(GeneralizedTransform &transform, UnaryPredicate pred)
Remove levels from a generalized transform as dictated by an arbitrary predicate. ...
Definition: GeneralizedTransform.h:111