Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <map>
- #include <vector>
- #include <iostream>
- #include <stdexcept>
- class FizzBuzzNoDefaultHandlerException:
- public std::logic_error
- {
- public:
- FizzBuzzNoDefaultHandlerException(): logic_error("defaultHandler == nullptr") { ;; }
- ~FizzBuzzNoDefaultHandlerException() = default;
- };
- class FizzBuzz
- {
- public:
- virtual int GetDivider() const { return 0; }
- virtual void Emit(std::ostream & o, const int val) = 0;
- virtual ~FizzBuzz() noexcept { ;; }
- };
- class FizzBuzzDefault:
- public FizzBuzz
- {
- public:
- virtual void Emit(std::ostream & o, const int val) { o << val; }
- virtual ~FizzBuzzDefault() noexcept { ;; }
- };
- class FizzBuzz3:
- public FizzBuzz
- {
- public:
- virtual int GetDivider() const { return 3; }
- virtual void Emit(std::ostream & o, const int val) { o << "Fizz"; }
- virtual ~FizzBuzz3() noexcept { ;; }
- };
- class FizzBuzz5:
- public FizzBuzz
- {
- public:
- virtual int GetDivider() const { return 5; }
- virtual void Emit(std::ostream & o, const int val) { o << "Buzz"; }
- virtual ~FizzBuzz5() noexcept { ;; }
- };
- class FizzBuzzFactory
- {
- public:
- FizzBuzzFactory(const FizzBuzzFactory&) = delete;
- FizzBuzzFactory& operator=(const FizzBuzzFactory&) = delete;
- FizzBuzzFactory(FizzBuzz * _defaultHandler): defaultHandler(_defaultHandler)
- {
- if (defaultHandler == nullptr) { throw FizzBuzzNoDefaultHandlerException(); }
- }
- bool AddHandler(FizzBuzz * action)
- {
- const bool res = storage.insert(FBStoragePair(action -> GetDivider(), action)).second;
- if (res) { keys.push_back(action -> GetDivider()); }
- return res;
- }
- const std::vector<int> & GetSupportedHandlers() const { return keys; }
- FizzBuzz * GetHandler(const int divider)
- {
- FBStorage::iterator it_storage = storage.find(divider);
- if (it_storage != storage.end()) { return it_storage -> second; }
- return nullptr;
- }
- FizzBuzz * GetDefaultHandler() { return defaultHandler; }
- ~FizzBuzzFactory() = default;
- private:
- FizzBuzz * defaultHandler;
- typedef std::map<int, FizzBuzz *> FBStorage;
- typedef std::pair<int, FizzBuzz *> FBStoragePair;
- FBStorage storage;
- std::vector<int> keys;
- };
- template<typename T>class FizzBuzzRunner
- {
- public:
- FizzBuzzRunner(T & _factory): factory(_factory) { ;; }
- void Emit(std::ostream & o, const int value)
- {
- const std::vector<int> & handlers = factory.GetSupportedHandlers();
- int handlers_used = 0;
- for_each(handlers.begin(), handlers.end(), [&](const int divider)
- {
- if (value % divider == 0)
- {
- factory.GetHandler(divider) -> Emit(o, value);
- ++handlers_used;
- }
- });
- if (handlers_used == 0) { factory.GetDefaultHandler() -> Emit(o, value); }
- o << std::endl;
- }
- ~FizzBuzzRunner() = default;
- private:
- T & factory;
- };
- int main()
- {
- FizzBuzzDefault fizzbuzz_default;
- FizzBuzz3 fizzbuzz_3;
- FizzBuzz5 fizzbuzz_5;
- FizzBuzzFactory factory(&fizzbuzz_default);
- factory.AddHandler(&fizzbuzz_3);
- factory.AddHandler(&fizzbuzz_5);
- FizzBuzzRunner<FizzBuzzFactory> runner(factory);
- for(int x = 1; x <= 100; ++x) { runner.Emit(std::cout, x); }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement