OSVR-Core
UniqueContainer.h
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 #ifndef INCLUDED_PassthruUniqueContainer_h_GUID_AD5E86CA_230D_4BBA_8DF0_F2C3811CFD00
26 #define INCLUDED_PassthruUniqueContainer_h_GUID_AD5E86CA_230D_4BBA_8DF0_F2C3811CFD00
27 
28 // Internal Includes
30 
31 // Library/third-party includes
32 // - none
33 
34 // Standard includes
35 #include <algorithm>
36 #include <functional>
37 
38 namespace osvr {
39 namespace util {
41  namespace unique_container_policies {
48  struct PushBack {
49  template <typename Container> struct Specialized {
51  using iterator = typename Container::iterator;
52  using const_iterator = typename Container::const_iterator;
53  using value_type = typename Container::value_type;
54  using reference = typename Container::reference;
55  using rv_reference = typename Container::value_type &&;
56  using const_reference = typename Container::const_reference;
58  static bool contains(Container const &c, const_reference v) {
59  return policy::find(c, v) != end(c);
60  }
61 
64  static bool remove(Container &c, const_reference v) {
65  auto it = policy::find(c, v);
66  if (end(c) != it) {
67  c.erase(it);
68  return true;
69  }
70  return false;
71  }
72 
76  static bool insert(Container &c, const_reference v) {
77  if (!policy::contains(c, v)) {
78  c.push_back(v);
79  return true;
80  }
81  return false;
82  }
83 
87  static bool insert(Container &c, rv_reference v) {
88  if (!policy::contains(c, v)) {
89  c.emplace_back(v); // move-construct
90  return true;
91  }
92  return false;
93  }
94 
96  static auto find(Container const &c, const_reference v)
97  -> decltype(std::find(begin(c), end(c), v)) {
98  return std::find(begin(c), end(c), v);
99  }
100 
102  static auto find(Container &c, const_reference v)
103  -> decltype(std::find(begin(c), end(c), v)) {
104  return std::find(begin(c), end(c), v);
105  }
106  };
107  };
108 
119  template <template <class X> class Comparison = std::less>
120  struct SortedInsert {
121  template <typename Container> struct Specialized {
123  using iterator = typename Container::iterator;
124  using const_iterator = typename Container::const_iterator;
125  using value_type = typename Container::value_type;
126  using reference = typename Container::reference;
127  using rv_reference = typename Container::value_type &&;
128  using const_reference = typename Container::const_reference;
129  using comparator = Comparison<value_type>;
130 
132  static comparator get_comparator() { return comparator{}; }
133 
139  static auto lower_bound(Container &c, const_reference v)
140  -> decltype(std::lower_bound(begin(c), end(c), v,
141  policy::get_comparator())) {
142  return std::lower_bound(begin(c), end(c), v,
143  policy::get_comparator());
144  }
145 
151  static auto lower_bound(Container const &c, const_reference v)
152  -> decltype(std::lower_bound(begin(c), end(c), v,
153  policy::get_comparator())) {
154  return std::lower_bound(begin(c), end(c), v,
155  policy::get_comparator());
156  }
157 
160  static bool contains(Container const &c, const_reference v) {
161  return std::binary_search(begin(c), end(c), v,
162  policy::get_comparator());
163  }
164 
168  static bool remove(Container &c, const_reference v) {
169  auto it = policy::find(c, v);
170  if (end(c) != it) {
171  c.erase(it);
172  return true;
173  }
174  return false;
175  }
176 
182  static bool insert(Container &c, const_reference v) {
183  auto it = policy::lower_bound(c, v);
184  if (!policy::iter_indicates_contains(c, it, v)) {
185  c.insert(it, v);
186  return true;
187  }
188  return false;
189  }
190 
196  static bool insert(Container &c, rv_reference v) {
197  auto it = policy::lower_bound(c, v);
198  if (!policy::iter_indicates_contains(c, it, v)) {
199  c.emplace(it, v); // move-construct
200  return true;
201  }
202  return false;
203  }
204 
209  static auto find(Container const &c, const_reference v)
210  -> decltype(policy::lower_bound(c, v)) {
211  auto it = policy::lower_bound(c, v);
212  return policy::iter_indicates_contains(c, it, v) ? it
213  : end(c);
214  }
215 
220  static auto find(Container &c, const_reference v)
221  -> decltype(policy::lower_bound(c, v)) {
222  auto it = policy::lower_bound(c, v);
223  return policy::iter_indicates_contains(c, it, v) ? it
224  : end(c);
225  }
226 
230  static bool check_equiv(const_reference a, const_reference b) {
231  auto comp = policy::get_comparator();
232  return !(comp(a, b)) && !(comp(b, a));
233  }
234 
238  template <typename IteratorType>
239  static bool iter_indicates_contains(Container const &c,
240  IteratorType const &it,
241  const_reference v) {
242  if (end(c) == it) {
243  return false;
244  }
245  return check_equiv(*it, v);
246  }
247 
249  static void sort(Container &c) {
250  std::sort(begin(c), end(c), policy::get_comparator());
251  }
252  };
253  };
254 #if 0
255  struct SortedInsert {
256  template <typename Container>
257  using Specialized = SortedInsertCustomCompare<
258  std::less>::template Specialized<Container>;
259  };
260 #endif
261  } // namespace unique_container_policies
262 
286  template <typename Container,
287  typename Policy = unique_container_policies::PushBack,
288  typename... WrapperArgs>
290  : public ContainerWrapper<Container, WrapperArgs...> {
291  typedef typename Policy::template Specialized<Container> policy;
292  typedef ContainerWrapper<Container, WrapperArgs...> base;
293 
294  protected:
295  using value_type = typename Container::value_type;
296  using reference = typename Container::reference;
297  using rv_reference = typename Container::value_type &&;
298  using const_reference = typename Container::const_reference;
301  bool contains(const_reference v) {
302  return policy::contains(container(), v);
303  }
304  bool insert(const_reference v) {
305  return policy::insert(container(), v);
306  }
307  bool insert(rv_reference v) { return policy::insert(container(), v); }
308  bool remove(const_reference v) {
309  return policy::remove(container(), v);
310  }
311 
313  Container const &container() const { return base::container(); }
314 
315  private:
318  Container &container() { return base::container(); }
319  };
320 
324  template <typename Container,
325  typename Policy = unique_container_policies::PushBack,
326  typename... WrapperArgs>
328  : public UniqueContainerBase<Container, Policy, WrapperArgs...> {
329  typedef UniqueContainerBase<Container, Policy, WrapperArgs...> base;
330 
331  public:
332  using rv_reference = typename Container::value_type &&;
333  using const_reference = typename Container::const_reference;
334  bool contains(const_reference v) { return base::contains(v); }
335  bool insert(const_reference v) { return base::insert(v); }
336  bool insert(rv_reference v) { return base::insert(v); }
337  bool remove(const_reference v) { return base::remove(v); }
338 
340  Container const &container() const { return base::container(); }
341  };
342 
343 } // namespace util
344 } // namespace osvr
345 #endif // INCLUDED_PassthruUniqueContainer_h_GUID_AD5E86CA_230D_4BBA_8DF0_F2C3811CFD00
static auto find(Container const &c, const_reference v) -> decltype(policy::lower_bound(c, v))
Helper function.
Definition: UniqueContainer.h:209
static bool insert(Container &c, const_reference v)
Insert from a const reference.
Definition: UniqueContainer.h:76
static bool contains(Container const &c, const_reference v)
Part of the interface expected by UniqueContainer.
Definition: UniqueContainer.h:160
Definition: RunLoopManager.h:42
apply_list< quote< or_ >, transform< Haystack, detail::is_< Needle >>> contains
Determines if type Needle is in the list Haystack - is an alias for a type that inherits std::true_ty...
Definition: Contains.h:49
static auto lower_bound(Container const &c, const_reference v) -> decltype(std::lower_bound(begin(c), end(c), v, policy::get_comparator()))
Helper function.
Definition: UniqueContainer.h:151
static void sort(Container &c)
Helper function.
Definition: UniqueContainer.h:249
static bool check_equiv(const_reference a, const_reference b)
Helper function.
Definition: UniqueContainer.h:230
Header providing a class template suitable for inheritance that wraps an arbitrary STL-like container...
A basic policy for use with a vector or similar container, where you have a comparison operator and t...
Definition: UniqueContainer.h:120
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
A basic policy for use with a vector or similar container, where you don&#39;t expect a lot of additions ...
Definition: UniqueContainer.h:48
Container const & container() const
Const access to the container is permitted.
Definition: UniqueContainer.h:313
static bool insert(Container &c, const_reference v)
Part of the interface expected by UniqueContainer.
Definition: UniqueContainer.h:182
static bool iter_indicates_contains(Container const &c, IteratorType const &it, const_reference v)
Helper function.
Definition: UniqueContainer.h:239
static auto lower_bound(Container &c, const_reference v) -> decltype(std::lower_bound(begin(c), end(c), v, policy::get_comparator()))
Helper function.
Definition: UniqueContainer.h:139
static auto find(Container &c, const_reference v) -> decltype(std::find(begin(c), end(c), v))
Time complexity: O(std::find) = O(n)
Definition: UniqueContainer.h:102
static bool insert(Container &c, rv_reference v)
Part of the interface expected by UniqueContainer.
Definition: UniqueContainer.h:196
bool contains(const_reference v)
Returns true iff the underlying container contains an instance of the given value.
Definition: UniqueContainer.h:301
static bool contains(Container const &c, const_reference v)
Time complexity: O(find) = O(n)
Definition: UniqueContainer.h:58
static comparator get_comparator()
Helper function to avoid vexing parse.
Definition: UniqueContainer.h:132
static auto find(Container &c, const_reference v) -> decltype(policy::lower_bound(c, v))
Helper function.
Definition: UniqueContainer.h:220
Container const & container() const
Const access to the container is permitted.
Definition: UniqueContainer.h:340
detail::ContainerWrapper_t< Container, Args... > ContainerWrapper
Parent class to inherit from to get a container with some functionality exposed.
Definition: ContainerWrapper.h:232
static auto find(Container const &c, const_reference v) -> decltype(std::find(begin(c), end(c), v))
Time complexity: O(std::find) = O(n)
Definition: UniqueContainer.h:96
A "Unique Container" designed for composition, not inheritance.
Definition: UniqueContainer.h:327
static bool remove(Container &c, const_reference v)
Time complexity: O(find) + O(member erase), which is O(n) (+ amortized constant time) for a std::vect...
Definition: UniqueContainer.h:64
A policy-based generic "Unique Container", that wraps ContainerWrapper (and thus an underlying contai...
Definition: UniqueContainer.h:289
static bool insert(Container &c, rv_reference v)
Insert from an rvalue-reference (move-insert).
Definition: UniqueContainer.h:87