All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
option_set.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Danny Y., Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_OPTPARSE_OPTION_SET_HPP
23 #define GEARS_OPTPARSE_OPTION_SET_HPP
24 
25 #include "option.hpp"
26 #include <set>
27 #include <vector>
28 #include <algorithm>
29 
30 namespace gears {
31 namespace optparse {
32 namespace detail {
33 struct option_comparison {
34  bool operator()(const option& lhs, const option& rhs) const {
35  return lhs.name < rhs.name || (lhs.name == rhs.name && lhs.alias < rhs.alias);
36  }
37 };
38 } // detail
39 
50 struct option_set {
51 private:
52  std::set<option, detail::option_comparison> cache;
53  std::vector<option> options;
54 public:
64  option_set(bool help = true) {
65  if(help) {
66  options.emplace_back("help", 'h', "shows this message and exits");
67  cache.insert(options.back());
68  }
69  }
70 
82  option_set(std::initializer_list<option> l) {
83  options.emplace_back("help", 'h', "shows this message and exits");
84  cache.insert(options.back());
85 
86  for(auto&& i : l) {
87  if(cache.count(i)) {
88  continue;
89  }
90 
91  cache.insert(i);
92  options.push_back(i);
93  }
94  }
95 
105  template<typename... Args>
106  void add(Args&&... args) {
107  // emplace it to the vector
108  options.emplace_back(std::forward<Args>(args)...);
109 
110  // check if it's in the cache and remove it if so
111  auto&& it = cache.find(options.back());
112  if(it != cache.end()) {
113  options.pop_back();
114  }
115 
116  cache.insert(options.back());
117  }
118 
129  template<typename Argument>
130  option_set& remove(const Argument& arg) {
131  auto&& it = std::find_if(options.begin(), options.end(), [&arg](const option& opt) {
132  return opt.is(arg);
133  });
134 
135  if(it != options.end()) {
136  cache.erase(*it);
137  options.erase(it);
138  }
139  return *this;
140  }
141 
153  template<typename T, typename Argument>
154  const T& get(const Argument& arg) const {
155  auto&& it = std::find_if(options.begin(), options.end(), [&arg](const option& opt) {
156  return opt.is(arg);
157  });
158 
159  if(it == options.end()) {
160  throw std::invalid_argument("option not found");
161  }
162 
163  return it->template get<T>();
164  }
165 
175  template<typename T, typename Argument>
176  const T& get_or(const Argument& arg, const typename std::remove_reference<T>::type& def) const noexcept {
177  auto&& it = std::find_if(options.begin(), options.end(), [&arg](const option& opt) {
178  return opt.is(arg);
179  });
180 
181  if(it == options.end()) {
182  return def;
183  }
184 
185  return it->template get_or<T>(def);
186  }
187 
197  template<typename Argument>
198  bool is_active(const Argument& arg) const noexcept {
199  auto&& it = std::find_if(options.begin(), options.end(), [&arg](const option& opt) {
200  return opt.is(arg);
201  });
202 
203  return it != options.end() && it->is_active();
204  }
205 
209  size_t size() const noexcept {
210  return options.size();
211  }
212 
216  bool empty() const noexcept {
217  return options.empty();
218  }
219 
221 
230  auto begin() noexcept -> decltype(options.begin()) {
231  return options.begin();
232  }
233 
234  auto begin() const noexcept -> decltype(options.begin()) {
235  return options.begin();
236  }
238 
240 
249  auto end() noexcept -> decltype(options.end()) {
250  return options.end();
251  }
252 
253  auto end() const noexcept -> decltype(options.end()) {
254  return options.end();
255  }
257 };
258 } // optparse
259 } // gears
260 
261 #endif // GEARS_OPTPARSE_OPTION_SET_HPP