Advertisement
Guest User

Untitled

a guest
Jan 13th, 2020
397
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.13 KB | None | 0 0
  1. #include <algorithm>
  2. #include <map>
  3. #include <vector>
  4. #include <iostream>
  5. #include <stdexcept>
  6.  
  7. class FizzBuzzNoDefaultHandlerException:
  8.   public std::logic_error
  9. {
  10. public:
  11.     FizzBuzzNoDefaultHandlerException(): logic_error("defaultHandler == nullptr") { ;; }
  12.  
  13.     ~FizzBuzzNoDefaultHandlerException() = default;
  14. };
  15.  
  16. class FizzBuzz
  17. {
  18. public:
  19.     virtual int GetDivider() const { return 0; }
  20.  
  21.     virtual void Emit(std::ostream & o, const int val) = 0;
  22.  
  23.     virtual ~FizzBuzz() noexcept { ;; }
  24. };
  25.  
  26. class FizzBuzzDefault:
  27.   public FizzBuzz
  28. {
  29. public:
  30.  
  31.     virtual void Emit(std::ostream & o, const int val) { o << val; }
  32.  
  33.     virtual ~FizzBuzzDefault() noexcept { ;; }
  34. };
  35.  
  36. class FizzBuzz3:
  37.   public FizzBuzz
  38. {
  39. public:
  40.     virtual int GetDivider() const { return 3; }
  41.  
  42.     virtual void Emit(std::ostream & o, const int val) { o << "Fizz"; }
  43.  
  44.     virtual ~FizzBuzz3() noexcept { ;; }
  45. };
  46.  
  47. class FizzBuzz5:
  48.   public FizzBuzz
  49. {
  50. public:
  51.     virtual int GetDivider() const { return 5; }
  52.  
  53.     virtual void Emit(std::ostream & o, const int val) { o << "Buzz"; }
  54.  
  55.     virtual ~FizzBuzz5() noexcept { ;; }
  56. };
  57.  
  58. class FizzBuzzFactory
  59. {
  60. public:
  61.     FizzBuzzFactory(const FizzBuzzFactory&) = delete;
  62.     FizzBuzzFactory& operator=(const FizzBuzzFactory&) = delete;
  63.  
  64.     FizzBuzzFactory(FizzBuzz * _defaultHandler): defaultHandler(_defaultHandler)
  65.     {
  66.         if (defaultHandler == nullptr) { throw FizzBuzzNoDefaultHandlerException(); }
  67.     }
  68.  
  69.     bool AddHandler(FizzBuzz * action)
  70.     {
  71.         const bool res = storage.insert(FBStoragePair(action -> GetDivider(), action)).second;
  72.         if (res) { keys.push_back(action -> GetDivider()); }
  73.  
  74.     return res;
  75.     }
  76.  
  77.     const std::vector<int> & GetSupportedHandlers() const { return keys; }
  78.  
  79.     FizzBuzz * GetHandler(const int divider)
  80.     {
  81.         FBStorage::iterator it_storage = storage.find(divider);
  82.         if (it_storage != storage.end()) { return it_storage -> second; }
  83.  
  84.     return nullptr;
  85.     }
  86.  
  87.     FizzBuzz * GetDefaultHandler() { return defaultHandler; }
  88.  
  89.     ~FizzBuzzFactory() = default;
  90.  
  91. private:
  92.     FizzBuzz * defaultHandler;
  93.  
  94.     typedef std::map<int, FizzBuzz *>   FBStorage;
  95.     typedef std::pair<int, FizzBuzz *>  FBStoragePair;
  96.  
  97.     FBStorage         storage;
  98.     std::vector<int>  keys;
  99. };
  100.  
  101.  
  102. template<typename T>class FizzBuzzRunner
  103. {
  104. public:
  105.     FizzBuzzRunner(T & _factory): factory(_factory) { ;; }
  106.  
  107.     void Emit(std::ostream & o, const int value)
  108.     {
  109.         const std::vector<int> & handlers = factory.GetSupportedHandlers();
  110.  
  111.         int handlers_used = 0;
  112.  
  113.         for_each(handlers.begin(), handlers.end(), [&](const int divider)
  114.         {
  115.             if (value % divider == 0)
  116.             {
  117.                 factory.GetHandler(divider) -> Emit(o, value);
  118.                 ++handlers_used;
  119.             }
  120.         });
  121.         if (handlers_used == 0) { factory.GetDefaultHandler() -> Emit(o, value); }
  122.         o << std::endl;
  123.     }
  124.  
  125.     ~FizzBuzzRunner() = default;
  126. private:
  127.     T   & factory;
  128. };
  129.  
  130. int main()
  131. {
  132.     FizzBuzzDefault fizzbuzz_default;
  133.     FizzBuzz3 fizzbuzz_3;
  134.     FizzBuzz5 fizzbuzz_5;
  135.  
  136.     FizzBuzzFactory factory(&fizzbuzz_default);
  137.     factory.AddHandler(&fizzbuzz_3);
  138.     factory.AddHandler(&fizzbuzz_5);
  139.  
  140.     FizzBuzzRunner<FizzBuzzFactory> runner(factory);
  141.  
  142.     for(int x = 1; x <= 100; ++x) { runner.Emit(std::cout, x); }
  143. return 0;
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement