Skip to content

Commit

Permalink
enum_set: Add iterator
Browse files Browse the repository at this point in the history
Sometimes it is useful to be able to query for all the members of an
`enum_set`, rather than just add, remove, and query for membership. (The
patch following this one makes use of this in the auth. sub-system).

We use the bitset iterator in Seastar to help with the implementation.
  • Loading branch information
Jesse Haber-Kucharsky committed Feb 14, 2018
1 parent bbe09a4 commit f4fc12f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
18 changes: 18 additions & 0 deletions enum_set.hh
Expand Up @@ -21,6 +21,7 @@

#pragma once

#include <boost/iterator/transform_iterator.hpp>
#include <seastar/core/bitset-iter.hh>

#include <algorithm>
Expand Down Expand Up @@ -146,7 +147,16 @@ private:
static constexpr unsigned shift_for() {
return Enum::template sequence_for<Elem>();
}

static auto make_iterator(mask_iterator iter) {
return boost::make_transform_iterator(std::move(iter), [](typename Enum::sequence_type s) {
return enum_type(s);
});
}

public:
using iterator = std::invoke_result_t<decltype(&enum_set::make_iterator), mask_iterator>;

constexpr enum_set() : _mask(0) {}

/**
Expand Down Expand Up @@ -229,6 +239,14 @@ public:
return _mask;
}

iterator begin() const {
return make_iterator(mask_iterator(_mask));
}

iterator end() const {
return make_iterator(mask_iterator(0));
}

template<enum_type... items>
struct frozen {
template<enum_type first>
Expand Down
35 changes: 35 additions & 0 deletions tests/enum_set_test.cc
Expand Up @@ -23,10 +23,26 @@

#include "enum_set.hh"

#include <iostream>
#include <iterator>
#include <unordered_set>

#include <boost/test/unit_test.hpp>

#include "to_string.hh"

enum class fruit { apple = 3, pear = 7, banana = 8 };

static std::ostream& operator<<(std::ostream& os, fruit f) {
switch (f) {
case fruit::apple: os << "apple"; break;
case fruit::pear: os << "pear"; break;
case fruit::banana: os << "banana"; break;
}

return os;
}

using fruit_enum = super_enum<fruit, fruit::apple, fruit::pear, fruit::banana>;

//
Expand Down Expand Up @@ -91,3 +107,22 @@ BOOST_AUTO_TEST_CASE(set_remove) {
fs.remove(fruit::pear);
BOOST_REQUIRE(!fs.contains(fruit::pear));
}

BOOST_AUTO_TEST_CASE(set_iterator) {
const auto fs1 = fruit_set::of<fruit::pear, fruit::banana>();

std::unordered_set<fruit> us1;
std::copy(fs1.begin(), fs1.end(), std::inserter(us1, us1.begin()));

BOOST_REQUIRE_EQUAL(us1, (std::unordered_set<fruit>{fruit::pear, fruit::banana}));

//
// Empty set.
//

const auto fs2 = fruit_set();
std::unordered_set<fruit> us2;
std::copy(fs2.begin(), fs2.end(), std::inserter(us2, us2.begin()));

BOOST_REQUIRE(us2.empty());
}

0 comments on commit f4fc12f

Please sign in to comment.