24 #ifndef GRAPHLAB_SMALL_SET_HPP
25 #define GRAPHLAB_SMALL_SET_HPP
33 #include <graphlab/serialization/iarchive.hpp>
34 #include <graphlab/serialization/oarchive.hpp>
38 #include <graphlab/macros_def.hpp>
46 template<
size_t MAX_DIM,
typename T,
typename Less = std::less<T> >
51 typedef const T& const_reference;
52 typedef ptrdiff_t difference_type;
53 typedef size_t size_type;
55 typedef const T* const_iterator;
56 enum sizes {max_dim_type = MAX_DIM };
59 template<
size_t T1,
size_t T2 >
60 struct max_type {
enum max_value { value = T1 < T2? T2 : T1 }; };
63 inline bool operator()(
const T& a,
const T& b)
const {
64 return !Less()(a,b) && !Less()(b,a);
73 small_set(
const T& elem) : nelems(1) { values[0] = elem; }
79 template<
typename OtherT>
81 ASSERT_LE(nelems, MAX_DIM);
83 foreach(
const OtherT& elem, other) values[index++] = elem;
91 template<
size_t OtherSize>
93 nelems(other.
size()) {
94 ASSERT_LE(nelems, MAX_DIM);
96 for(
const T* elem = other.
begin(); elem != other.
end(); ++elem)
97 values[index++] = *elem;
102 inline T*
begin() {
return values; }
105 inline T*
end() {
return values + nelems; }
109 inline const T*
begin()
const {
return values; }
112 inline const T*
end()
const {
return values + nelems; }
115 inline size_t size()
const {
return nelems; }
123 return std::binary_search(
begin(),
end(), elem, Less());
127 template<
size_t OtherDim>
129 return std::includes(
begin(),
end(),
130 other.
begin(), other.
end(), Less());
138 template<
size_t OtherDim>
139 bool operator<=(const small_set<OtherDim, T, Less>& other)
const {
140 return other.contains(*
this);
148 template<
size_t OtherDim>
149 bool operator<(const small_set<OtherDim, T, Less>& other)
const {
150 return other.contains(*
this) &&
size() < other.size();
153 template<
size_t OtherDim>
155 if(
size() != other.
size())
return false;
170 ASSERT_LE(begin, end);
172 const size_t other_size = end -
begin;
173 ASSERT_LE(other_size, MAX_DIM);
176 for(
size_t i = 0; i < other_size; ++i) {
179 if(i+1 < other_size) ASSERT_LT(begin[i], begin[i+1]);
187 void erase(
const T& elem) { *
this -= elem; }
192 ASSERT_LT(index, nelems);
193 return values[index];
230 return result += elem;
235 template<
size_t OtherDim>
244 safe_iterator(result.begin(),
245 result.absolute_end()),
247 result.nelems = new_end - result.begin();
248 ASSERT_LE(result.nelems, result_type::max_dim_type);
254 template<
size_t OtherDim>
256 *
this = *
this + other;
267 T* ptr(std::lower_bound(
begin(),
end(), elem, Less()));
269 if(ptr !=
end() && !(elem < *ptr) )
return *
this;
272 T tmp(elem); nelems++;
273 ASSERT_LE(nelems, MAX_DIM);
276 for(; ptr <
end(); ++ptr) std::swap(*ptr, tmp);
284 template<
size_t OtherDim>
297 *
this = *
this - other;
302 template<
size_t OtherDim>
310 safe_iterator(result.
begin(),
311 result.absolute_end()),
313 result.nelems = new_end - result.
begin();
314 ASSERT_LE(result.nelems, MAX_DIM);
319 template<
size_t OtherDim>
323 std::set_intersection(
begin(),
end(),
325 safe_iterator(result.
begin(),
326 result.absolute_end()),
328 result.nelems = new_end - result.
end();
329 ASSERT_LE(result.nelems, MAX_DIM);
334 template<
size_t OtherDim>
336 *
this = *
this * other;
343 assert(nelems <= MAX_DIM);
344 for(
size_t i = 0; i < nelems; ++i) {
346 if( i > 0 ) assert(values[i] > values[i-1]);
353 for(
size_t i = 0; i < nelems; ++i) arc << values[i];
361 inline T* absolute_end() {
return values + MAX_DIM; }
364 struct safe_iterator :
365 public std::iterator<std::input_iterator_tag, T> {
368 safe_iterator(
const safe_iterator& other) :
370 safe_iterator(T*
begin,
const T*
end) :
371 begin(begin), end(end) {
372 ASSERT_NE(begin, NULL);
373 ASSERT_NE(end, NULL);
374 ASSERT_LE(begin, end);
376 inline safe_iterator& operator++() { ++
begin;
return *
this; }
377 inline safe_iterator& operator++(
int) {
378 safe_iterator tmp(*
this); operator++();
return tmp;
380 inline bool operator==(
const safe_iterator& other) {
381 ASSERT_EQ(
end, other.end);
382 return begin == other.begin;
384 inline bool operator!=(
const safe_iterator& other) {
385 return !operator==(other);
391 template<
size_t MAX_DIM,
typename T>
393 operator<<(std::ostream& out, const graphlab::small_set<MAX_DIM, T>&
set) {
395 for(
size_t i = 0; i <
set.size(); ++i) {
397 if(i + 1 <
set.size()) out <<
", ";
407 #include <graphlab/macros_undef.hpp>