Skip to content

Instantly share code, notes, and snippets.

@sekia
Created January 21, 2016 20:19
Show Gist options
  • Select an option

  • Save sekia/c6b3350ea7860c9273d8 to your computer and use it in GitHub Desktop.

Select an option

Save sekia/c6b3350ea7860c9273d8 to your computer and use it in GitHub Desktop.
Flip-flop predicate like Perl and Ruby, in C++11
#ifndef FLIPFLIOP_H__
#define FLIPFLIOP_H__
#include <functional>
#include <utility>
namespace flipflop {
template <typename Value>
class FlipFlop {
private:
using Predicate = std::function<bool (const Value&)>;
enum class State { Init, KeepTrue };
public:
FlipFlop() = delete;
FlipFlop(Predicate&& begin_p, Predicate&& end_p) noexcept
: begin_p_(std::forward<Predicate>(begin_p)),
end_p_(std::forward<Predicate>(end_p)),
state_(State::Init) {}
FlipFlop(const Value& begin_v, const Value& end_v) noexcept
: FlipFlop(
[=](const Value& v){ return v == begin_v; },
[=](const Value& v){ return v == end_v; }) {}
bool operator()(const Value& v) noexcept {
switch (state_) {
case State::Init:
if (begin_p_(v)) {
state_ = State::KeepTrue;
return true;
}
return false;
case State::KeepTrue:
if (end_p_(v)) { state_ = State::Init; }
return true;
}
return false; // Not reach here.
}
private:
Predicate begin_p_;
Predicate end_p_;
State state_;
};
} // namespace flipflop
#endif // FLIPFLIOP_H__
#include <cstdio>
#include <string>
#include "flipflop.h"
int main() {
flipflop::FlipFlop<std::string> ff("bar", "baz");
const std::string strs[] = { "foo", "bar", "quux", "baz", "quux", "baz" };
for (const auto& str : strs) {
std::printf("%s: %s\n", str.c_str(), ff(str) ? "IN" : "OUT");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment