Apache Mesos
hashset.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_HASHSET_HPP__
14 #define __STOUT_HASHSET_HPP__
15 
16 #include <set>
17 #include <unordered_set>
18 #include <utility>
19 
20 #include <boost/get_pointer.hpp>
21 
22 #include "foreach.hpp"
23 
24 // Prior to C++14 we can't use an enum type as the key to any
25 // hash-based collection because of a defect in the standard. See
26 // www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148 for more
27 // details. The workaround for now is to use the following hash
28 // function when using an enum.
29 //
30 // TODO(benh): Remove this once we move to C++14.
32 {
33  template <typename T>
34  std::size_t operator()(T t) const
35  {
36  static_assert(
37  sizeof(typename std::underlying_type<T>::type) <= sizeof(std::size_t),
38  "Expecting enum type to be convertible to std::size_t");
39  return static_cast<std::size_t>(t);
40  }
41 };
42 
43 
44 // Provides a hash set via 'std::unordered_set'. We inherit from it to add
45 // new functions as well as to provide better naming for some of the
46 // existing functions.
47 template <typename Elem,
48  typename Hash = typename std::conditional<
49  std::is_enum<Elem>::value,
51  std::hash<Elem>>::type,
52  typename Equal = std::equal_to<Elem>>
53 class hashset : public std::unordered_set<Elem, Hash, Equal>
54 {
55 public:
57 
58  // An explicit default constructor is needed so
59  // 'const hashset<T> map;' is not an error.
60  hashset() {}
61 
62  // An implicit constructor for converting from a std::set.
63  //
64  // TODO(arojas): Allow any arbitrary type that supports 'begin()'
65  // and 'end()' passed into the specified 'emplace'?
66  hashset(const std::set<Elem>& set)
67  {
68  std::unordered_set<Elem, Hash, Equal>::reserve(set.size());
69 
70  for (auto iterator = set.begin(); iterator != set.end(); ++iterator) {
71  std::unordered_set<Elem, Hash, Equal>::emplace(*iterator);
72  }
73  }
74 
75  // An implicit constructor for converting from an r-value std::set.
76  //
77  // TODO(arojas): Allow any arbitrary type that supports 'begin()'
78  // and 'end()' passed into the specified 'insert'?
79  hashset(std::set<Elem>&& set)
80  {
81  // An implementation based on the move constructor of 'hashmap'
82  // fails to compile on all major compilers except gcc 5.1 and up.
83  // See http://stackoverflow.com/q/31051466/118750?sem=2.
84  std::unordered_set<Elem, Hash, Equal>::reserve(set.size());
85 
86  for (auto iterator = set.begin(); iterator != set.end(); ++iterator) {
87  std::unordered_set<Elem, Hash, Equal>::emplace(std::move(*iterator));
88  }
89  }
90 
91  // Allow simple construction via initializer list.
92  hashset(std::initializer_list<Elem> list)
93  {
94  std::unordered_set<Elem, Hash, Equal>::reserve(list.size());
95 
96  for (auto iterator = list.begin(); iterator != list.end(); ++iterator) {
97  std::unordered_set<Elem, Hash, Equal>::emplace(*iterator);
98  }
99  }
100 
101  // Checks whether this map contains a binding for a key.
102  bool contains(const Elem& elem) const
103  {
104  return std::unordered_set<Elem, Hash, Equal>::count(elem) > 0;
105  }
106 
107  // Checks whether there exists a value in this set that returns the
108  // a result equal to 'r' when the specified method is invoked.
109  template <typename R, typename T>
110  bool exists(R (T::*method)(), R r) const
111  {
112  foreach (const Elem& elem, *this) {
113  const T* t = boost::get_pointer(elem);
114  if (t->*method() == r) {
115  return true;
116  }
117  }
118  }
119 
120  // Checks whether there exists an element in this set whose
121  // specified member is equal to 'r'.
122  template <typename R, typename T>
123  bool exists(R (T::*member), R r) const
124  {
125  foreach (const Elem& elem, *this) {
126  const T* t = boost::get_pointer(elem);
127  if (t->*member == r) {
128  return true;
129  }
130  }
131  }
132 };
133 
134 
135 // TODO(jmlvanre): Possibly remove this reference as per MESOS-2694.
136 template <typename Elem, typename Hash, typename Equal>
139 
140 
141 // Union operator.
142 template <typename Elem, typename Hash, typename Equal>
144  const hashset<Elem, Hash, Equal>& left,
145  const hashset<Elem, Hash, Equal>& right)
146 {
147  // Note, we're not using 'set_union' since it affords us no benefit
148  // in efficiency and is more complicated to use given we have sets.
149  hashset<Elem, Hash, Equal> result = left;
150  result |= right;
151  return result;
152 }
153 
154 
155 // Union assignment operator.
156 template <typename Elem, typename Hash, typename Equal>
159  const hashset<Elem, Hash, Equal>& right)
160 {
161  left.insert(right.begin(), right.end());
162  return left;
163 }
164 
165 
166 // Difference operator.
167 template <typename Elem, typename Hash, typename Equal>
169  const hashset<Elem, Hash, Equal>& left,
170  const hashset<Elem, Hash, Equal>& right)
171 {
172  hashset<Elem, Hash, Equal> result = left;
173  result -= right;
174  return result;
175 }
176 
177 
178 // Difference assignment operator.
179 template <typename Elem, typename Hash, typename Equal>
182  const hashset<Elem, Hash, Equal>& right)
183 {
184  foreach (const Elem& elem, right) {
185  left.erase(elem);
186  }
187 
188  return left;
189 }
190 
191 #endif // __STOUT_HASHSET_HPP__
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:130
bool exists(R(T::*method)(), R r) const
Definition: hashset.hpp:110
Definition: hashset.hpp:53
hashset< Elem, Hash, Equal > & operator|=(hashset< Elem, Hash, Equal > &left, const hashset< Elem, Hash, Equal > &right)
Definition: hashset.hpp:157
hashset(std::set< Elem > &&set)
Definition: hashset.hpp:79
hashset< Elem, Hash, Equal > & operator-=(hashset< Elem, Hash, Equal > &left, const hashset< Elem, Hash, Equal > &right)
Definition: hashset.hpp:180
hashset(const std::set< Elem > &set)
Definition: hashset.hpp:66
std::size_t operator()(T t) const
Definition: hashset.hpp:34
bool contains(const Elem &elem) const
Definition: hashset.hpp:102
bool exists(R(T::*member), R r) const
Definition: hashset.hpp:123
hashset< Elem, Hash, Equal > operator-(const hashset< Elem, Hash, Equal > &left, const hashset< Elem, Hash, Equal > &right)
Definition: hashset.hpp:168
hashset()
Definition: hashset.hpp:60
hashset< Elem, Hash, Equal > operator|(const hashset< Elem, Hash, Equal > &left, const hashset< Elem, Hash, Equal > &right)
Definition: hashset.hpp:143
hashset(std::initializer_list< Elem > list)
Definition: hashset.hpp:92
static const hashset< Elem, Hash, Equal > & EMPTY
Definition: hashset.hpp:56
Try< std::vector< Entry > > list(const std::string &hierarchy, const std::string &cgroup)
Try< uint32_t > type(const std::string &path)
Definition: hashset.hpp:31