Created
January 21, 2016 20:19
-
-
Save sekia/c6b3350ea7860c9273d8 to your computer and use it in GitHub Desktop.
Flip-flop predicate like Perl and Ruby, in C++11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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