#+INCLUDE: theme/style.org 
#+TITLE: CPP / C++ Notes - Design Patterns 
#+DESCRIPTION: cpp/c++ c++ design patterns gneric programming object oriented metaprogramming
#+STARTUP: content 

* General Design Patterns 
** General Techniques / Mechanism for Code Reuse 

 + *Inheritance*
   + Dynamic / Runtime / Subtyping Polymorphism.
   + Benefits:
     + Allow switching implementation at runtime, store
       different objects (pointers, smart pointers or references) at the
       same container, defer method calls to specific implementation and
       allow a client code work with multiple different implementations
       at runtime. Inheritance alone is not evil, the problem is deep
       inheritance hierarchies.
   + Drawbacks:
     + Loss of value semantics and intrusive.
     + Classes must inherit from the same base class which requires
       modification. 
     + Objects can only be returned from factory functions as pointers
       or pointers wrapped by smart pointers.
     + Slower speed than static polymorphism (templates and overloaded
       functions or methods.)

 + *Delegation* (a kind of OO composition)
   + Use another object for implementing some functionality and
     forward a method call to it instead of inheriting the object
     class. Examples: store items in a std::vector, instead of storing
     them directly in the class with heap-allocated arrays; store an
     heap-allocated object using smart pointers rather than storing it
     using raw pointer and freeing it on the destructor.

 + *Static Polymorphism*
   + It is templates and overloaded functions or methods.
   + Templates can eliminate virtual method call overhead by resolving
     methods at compile-time rather than at runtime.

 + *Type Erasure*
   + Combination of static and dynamic polymorphism which gets the
     best of both sides with minimal overhead.

 + *Free Functions*
   + C++ is a multiparadigm language and not everything needs to to be
     a class. So, functions can be used to extending classes without
     modifying them by taking objects as arguments and applying
     operations on them. 

 + *Higher Order Functions / Higher Order Methods / Lambda Functions*
   + Lambda function can be used to add new behaviors to an object at
     runtime, create generalized algorithms, functions, simplify event
     handling, callbacks and design patterns.  
** Singleton 
*** Overview 

Singleton is a creational design pattern where there is only a single
instance of a class and client code is forbidden from creating new
instances.

Note: Despite that there are lots of objections against this design
pattern, it is still worth knowing how it works.

Use cases:

  + Any class where just a single instance is needed.

  + Encapsulate global states  or global variables in a single global object.

  + Caches

  + File caches 

  + Logging (Logger object)

  + Runtime configuration

  + Configuration files 

  + Factory classes in factory-design pattern. A factory-object is
    used for indirect instatiation of objects from some class
    hierarchy.

  + Device Driver 

Implementation variants: 

  + Early initialized

  + Lazily initialized, initialized only when needed.

Disadvantages of singleton patterns: 

 + Testability => It is hard to isolate code that needs the singleton and
   replace it at runtime. 

 + Can hide dependency between classes.

 + Concurrency => The singleton must be made thread-safe in
   multi-threading applications. Access to global state without proper
   locking and synchronization can lead to race condition bugs.

Example where singletons are found: 

  + C++ Standard-library global IO object (Singletons):
    + std::cin  => Encapsulates console input - standard input 
    + std::cout => Encapsulates console stdout - standard output 
    + std::cerr => Encapsulates console stderr - standard error output
    + std::clog 

 *Further Reading* 

  + [[https://en.wikipedia.org/wiki/Singleton_pattern][Singleton pattern - Wikipedia]]

  + [[http://www.jot.fm/issues/issue_2007_03/column2.pdf][The Parametric Singleton Design Pattern]]

  + [[http://www.object-oriented-security.org/lets-argue/singletons][Singletons Considered Harmful]]

  + [[https://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons][design patterns - What is so bad about singletons? - Stack Overflow]]

  + [[https://stackoverflow.com/questions/228164/on-design-patterns-when-should-i-use-the-singleton][On design patterns: When should I use the singleton? - Stack Overflow]]

  + [[http://misko.hevery.com/2008/08/25/root-cause-of-singletons/][Root Cause of Singletons]]

  + [[https://dzone.com/articles/singleton-design-pattern-%E2%80%93][Singleton Design Pattern Tutorial – An Introspection w/ Best Practices - DZone Java]]

  + [[https://www.geeksforgeeks.org/singleton-design-pattern-introduction/][Singleton Design Pattern | Introduction - GeeksforGeeks]]

  + [[https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples][Java Singleton Design Pattern Example Best Practices - JournalDev]]

  + [[https://www.vojtechruzicka.com/singleton-pattern-pitfalls/][Singleton Pattern Pitfalls | Vojtech Ruzicka's Programming Blog]]

  + [[https://www.codeproject.com/Articles/307233/Singleton-Pattern-Positive-and-Negative-Aspects-2][Singleton Pattern – Positive and Negative Aspects - CodeProject]]

  + https://wiki.unity3d.com/index.php/Singleton (Games C#)
*** Example 1 - FileRepository Class


 *Example Code* 

 + File: [[file:src/design-patterns/singleton1.cpp][file:src/design-patterns/singleton1.cpp]]
 + Online Compiler: https://rextester.com/SJWB72590
 + Note: This code is not thread-safe.

Header of class FileRepository => (FileRepository.hpp)

#+BEGIN_SRC cpp
  //----- file: FileRepository.hpp ------//
  #ifndef __file_repository 
  #define __file_repository
  #include <std::string>

  class FileRepository
  {
  private:
      std::deque<std::string> _files;	
      // Forbid client code instating a new instance. 
      FileRepository(){
         std::cerr << " [LOG] File Respository Initialized." << "\n";
      }	
      // Forbid client code from creating a copy or using the
      // copy constructor.
      FileRepository(const FileRepository&){}		
  public:
      ~FileRepository();
	
      // Return a reference to not allow client code 
      // to delete object. 	
      static auto getInstance() -> FileRepository&;	

      // Use old C++ 'member function' syntax.
      void addFile(std::string fname);
      void clearFiles();
      // C++11 member function declaration looks better. 
      auto showFiles() -> void;
  };
  #endif 
#+END_SRC

Implementation of FileRepository (FileRepository.cpp)

#+BEGIN_SRC cpp
  #include <iostream>
  #include "FileRepository.hpp"

  FileRepository::~FileRepository(){
        std::cerr << " [LOG] File Respository Deleted. Ok." << "\n";
  }

  // Static method 
  auto FileRepository::getInstance() -> FileRepository& {
       static auto instance = std::unique_ptr<FileRepository>{nullptr};		
       // Initialized once - lazy initialization 
       if(!instance)
            instance.reset(new FileRepository);		
       return *instance.get();
  }

  void FileRepository::addFile(std::string fname){
       _files.push_back(std::move(fname));
  }

  void FileRepository::clearFiles(){
       _files.clear();
  }
  // C++11 Member function declaration 
  auto FileRepository::showFiles() -> void {
       for(const auto& file: _files)
          std::cout << " File = " << file << std::endl;
  }
#+END_SRC

Test in CERN ROOT/Clign REPL:

#+BEGIN_SRC cpp 
   // Load C++ code as it was a script.
   >> .L singleton1.cpp

   // Try to instantiate singleton object without reference. 
   //------------------------------------------------------
   >> FileRepository repo = FileRepository::getInstance()
   ROOT_prompt_2:1:23: error: calling a private constructor of class 'FileRepository'
   FileRepository repo = FileRepository::getInstance()
                         ^
   singleton1.cpp:21:5: note: declared private here
       FileRepository(const FileRepository&){}
       ^
   >> FileRepository& repo = FileRepository::getInstance()
   [LOG] File Respository Initialized.

   (FileRepository &) @0x2fc9640
   >> 

   >> repo.showFiles()
   >> 
   >> repo.addFile("quarterly-sales-report.dat")
   >> repo.addFile("interest-payments.txt")
   >> repo.addFile("taxes-report.xls")
   >> repo.showFiles()
    File = quarterly-sales-report.dat
    File = interest-payments.txt
    File = taxes-report.xls
   >> 
   >> 

   // Try to copy object. 
   >> FileRepository r = repo;
   ROOT_prompt_9:1:20: error: calling a private constructor of class 'FileRepository'
   FileRepository r = repo;
                      ^
   singleton1.cpp:21:5: note: declared private here
       FileRepository(const FileRepository&){}
       ^
   >> 

   // Try to create a new object 
   >> FileRepository& repo2 = FileRepository::getInstance()
   (FileRepository &) @0x2fc9640
   >> repo2.showFiles()
    File = quarterly-sales-report.dat
    File = interest-payments.txt
    File = taxes-report.xls
   >> 

   // Check whether repo and repo2 are the same object (reference equality)
   // -> They are equal under reference equality criteria if they have the same address.
   >> &repo == &repo2
   (bool) true
   >> 

   // Exit REPL.
   >> .q
  [LOG] File Respository Deleted. Ok.
#+END_SRC

Main function: 

#+BEGIN_SRC cpp
  FileRepository& repo1 = FileRepository::getInstance();
  repo1.addFile("CashFlowStatement.txt");
  repo1.addFile("Balance-Sheet.dat");
  repo1.addFile("Sales-Report.csv");

  FileRepository& repo2 = FileRepository::getInstance();

  std::cout << std::boolalpha << "Same object? (&repo == &repo1 ?) = "
            << (&repo1 == &repo2)
            << "\n";
  std::cout << "Repository files" << std::endl;
  repo2.showFiles();

  std::cout << "Add more files" << std::endl;
  repo2.addFile("fileX1.pdf");
  repo2.addFile("fileX2.pdf");
  repo2.addFile("fileX3.pdf");
  repo2.showFiles();
#+END_SRC

Compiling and running ([[file:src/design-patterns/singleton1.cpp][file:src/design-patterns/singleton1.cpp]]): 

#+BEGIN_SRC txt 
  clang++ singleton1.cpp -o singleton1.bin -g -std=c++14 -Wall -Wextra && ./singleton1.bin

   [LOG] File Respository Initialized.
  Same object? (&repo == &repo1 ?) = true
  Repository files
   File = CashFlowStatement.txt
   File = Balance-Sheet.dat
   File = Sales-Report.csv
  Add more files
   File = CashFlowStatement.txt
   File = Balance-Sheet.dat
   File = Sales-Report.csv
   File = fileX1.pdf
   File = fileX2.pdf
   File = fileX3.pdf
   [LOG] File Respository Deleted. Ok.
#+END_SRC
*** Example 2 - OpenGL GLFW Keyboard Manager 

The following singleton class allows registering multiple capturing
lambda callbacks for a given keyboard key. The purpose of the class
KeyboardManager is to provide an easier way to pass capturing C++11
lambdas to the function [[https://www.glfw.org/docs/3.3/group__input.html#ga1caf18159767e761185e49a3be019f8d][glfwSetKeyCallback()]]. Passing capturing
lambdas to glfwSetKeyCallback() directly is not possible as this
function lacks an extra void pointer for passing user data. In order
to overcome this issue, a Singleton class was used as global variable
for passing lambda to the GLFW callback.

Relevant type signatures: 

#+BEGIN_SRC cpp 
  GLFWkeyfun glfwSetKeyCallback	(  GLFWwindow * window
                                 , GLFWkeyfun 	callback 
                                );
	
  // C notation for function pointer type alias. 
  typedef void(* GLFWkeyfun) (GLFWwindow *, int, int, int, int);

  // C++ notation for function pointer type alias.  
  using GLFWkeyfun = void (*) (GLFWwindow *, int, int, int, int);
#+END_SRC


File: _glfw_kbd_singleton.cpp_ 

#+BEGIN_SRC cpp 
  // Brief: Draw curve copying data to the GPU 
  #include <iostream>
  #include <vector> 
  #include <array>
  #include <functional>
  #include <map>
  #include <cmath>
  #include <cassert>

  // -------- OpenGL headers ---------//
  #define GL_GLEXT_PROTOTYPES 1 // Necessary for OpenGL >= 3.0 functions
  #define GL3_PROTOTYPES      1 // Necessary for OpenGL >= 3.0 functions

  #include <GL/gl.h>
  #include <GLFW/glfw3.h>

  // #include <GL/glew.h>
  #include <GL/glu.h>
  #include <GL/glut.h>

  // Singleton object for registering lambda event handlers for GLFW keyboard typing events.
  class KeyboardManager
  {
  public:
      using KeyCallback = std::function<void (GLFWwindow* window)>;
      using KeyCallbackDB = std::map<int, KeyCallback>;
  private:
      KeyCallbackDB m_keydb{};
      GLFWwindow*   m_window = nullptr;
    
      // Private constructor for not allowing client code creating more 
      // than one instance.
      KeyboardManager()
      {
         std::cerr << " [TRACE] KeyboardManager - Singleton initialized." << "\n";
      }   
      // Forbid client code from creating a copy or using the
      // copy constructor.
      KeyboardManager(const KeyboardManager&){}     
  public:
      ~KeyboardManager() = default;

      // This is the unique way to get singleton instance. 
      static KeyboardManager& getInstance()
      {
          static KeyboardManager instance{};
          return instance;
      }

      KeyboardManager& 
      set_window(GLFWwindow* window)
      {
          m_window = window;

          // =>> Note: This lambda must be non-capturing. Otherwise, it will result 
          // in compile-time error. 
          // 
          // =>> Note: All this redundancy and boilerplate code is need because 
          //     the function glfwSetKeyCallback() lacks an extra void* pointer 
          //     for passing custom user data.
          ::glfwSetKeyCallback(m_window 
              ,[](GLFWwindow* window, int key, int scancode, int action, int mods)
              {
                  std::cerr << " [TRACE] glfwSetKeyCallback() key = " 
                            << key << " / char " << (char) key <<  '\n';
                  // Get singletion instance 
                  KeyboardManager& instance = KeyboardManager::getInstance();
                  auto it = instance.m_keydb.find(key);
                  if(it == instance.m_keydb.end()){ return; }
                  // Call callback functions.
                  it->second(window);
              });         
           return *this;
      }

      KeyboardManager& 
      add_keyCallback(int key, KeyCallback callback)
      {
          this->m_keydb[key] = callback;
          return *this;
      }    

  };


  int main(int argc, char** argv)
  {
      // Initialize GLFW 
      if ( !glfwInit() ){ return -1; }

      glutInit(&argc, argv);

      /* Create a windowed mode window and its OpenGL context */
      GLFWwindow* window = glfwCreateWindow(640, 480, "Simple triangle draw", NULL, NULL);
      if (!window)
      {
          glfwTerminate();
          return -1;
      }
     .... ...    .... ...    .... ...    .... ... 
     .... ...    .... ...    .... ...    .... ... 

      // Get singleton instance and set window.
      KeyBoardMager& kdb = KeyboardManager::getInstance().set_window(window);

      GLenum draw_type = GL_TRIANGLES;

      // Register events 
      kdb.add_keyCallback('A', [&draw_type](GLFWwindow* win){ draw_type = GL_TRIANGLES; });    
      kdb.add_keyCallback('B', [&draw_type](GLFWwindow* win){ draw_type = GL_LINE_LOOP; });

      kdb.add_keyCallback('C', [&draw_type](GLFWwindow* win){ draw_type = GL_LINES;      });
      kdb.add_keyCallback('D', [&draw_type](GLFWwindow* win){ draw_type = GL_LINE_STRIP; });
      kdb.add_keyCallback('F', [&draw_type](GLFWwindow* win){ draw_type = GL_LINE;       }); 


      // Positive rotatation of 10 degrees around Z axis (counter - clockwise)
      kdb.add_keyCallback(GLFW_KEY_RIGHT, [&](GLFWwindow* win)
          {  
              std::cerr << " [TRACE] Postive rotation around Z axis " << '\n';
              angle = angle + 10.0;
              glUniform1f(uniform_angle, angle);
          });   

     ...    ...    ...    ...    ...    ... 
     ...    ...    ...    ...    ...    ... 

      // ============== R E N D E R - L O O P ===========================//
      //

      /* Loop until the user closes the window */
      while (!glfwWindowShouldClose(window))
      {
         ....        ....        ....        ....        .... 
         ....        ....        ....        ....        .... 
      } 

  } // ------ End of main() ---------------------------------------------//

#+END_SRC
*** Example 3 - Generic Singleton 

This code contains a reusable-generic singleton template class, which
is applied to the previous case for calling lambdas from a C++
function that accepts function pointer and does not contain an extra
void pointer for allowing the calling code to pass state or
non-capturing lambdas. 

Generic singleton templated class: 

#+BEGIN_SRC cpp 
  template<typename Impl>
  class CRTP_Singleton
  {
  protected:
      CRTP_Singleton() = default;
  public:
    
      CRTP_Singleton(const CRTP_Singleton&) = delete;
      CRTP_Singleton& operator=(CRTP_Singleton const&) = delete;

      static Impl& getInstance()
      {  
          static Impl impl;
          return impl;  
      }

  };
#+END_SRC

Singleton class that inherits CRTP_Singleton: 

#+BEGIN_SRC cpp 
  // Singleton object for registering lambda event handlers for GLFW keyboard typing events.
  class KeyboardManager: public CRTP_Singleton<KeyboardManager>
  {
      friend KeyboardManager::CRTP_Singleton<KeyboardManager>;
  public:

      using KeyCallback = std::function<void (GLFWwindow* window)>;
      using KeyCallbackDB = std::map<int, KeyCallback>;
  protected:

      KeyCallbackDB m_keydb{};
      GLFWwindow*   m_window = nullptr;
    
      // Private constructor for not allowing client code creating more 
      // than one instance.
      KeyboardManager(){ }
  public:
      ~KeyboardManager() = default;

      KeyboardManager& 
      set_window(GLFWwindow* window)
      {
          m_window = window;
          assert( m_window != nullptr );
      
      ::glfwSetKeyCallback(m_window 
              ,[](GLFWwindow* window, int key, int scancode, int action, int mods)
              {
                  std::cerr << " [TRACE] glfwSetKeyCallback() key = " 
                            << key << " / char " << (char) key <<  '\n';
                  // Get singleton instance 
                  KeyboardManager& instance = KeyboardManager::getInstance();
                  auto it = instance.m_keydb.find(key);
                  if(it == instance.m_keydb.end()){ return; }
                  std::fprintf(stderr, " [TRACE] Execute callback function. \n");
                  // Call callback functions.
                  it->second(window);
              });         
           return *this;
      }

      KeyboardManager& 
      add_keyCallback(int key, KeyCallback callback)
      {

          std::fprintf(stderr, " [TRACE] Add callback key. \n");
          this->m_keydb[key] = callback;
          return *this;
      }    

  };

#+END_SRC

Class usage in main() function: 

#+BEGIN_SRC cpp 
      ... ... ... ... .... .... 
      ... ... ... ... .... .... 

      GLFWwindow* window = glfwCreateWindow(640, 480, "Simple triangle draw", NULL, NULL);

      if (!window)
      {
           std::fprintf(stderr, " [ERROR] Unable to open GLFW Window. \n");    
          glfwTerminate();
          return -1;
      }
      ... ... ... ... .... .... 

     // Get singleton instance and set window.
     auto& kdb = KeyboardManager::getInstance().set_window(window);

     GLenum draw_type = GL_LINE_LOOP;

     // Register events 
     kdb.add_keyCallback('A', [&draw_type](GLFWwindow* win){ draw_type = GL_TRIANGLES; });    

     // Positive rotatation of 10 degrees around Z axis (counter - clockwise)
     kdb.add_keyCallback(GLFW_KEY_RIGHT, [&](GLFWwindow* win)
         {  
             std::cerr << " [TRACE] Postive rotation around Z axis " << '\n';
             angle = angle + 10.0;
             glUniform1f(uniform_angle, angle);
         });  


      ... ... ... ... .... .... 
      ... ... ... ... .... .... 
      ... ... ... ... .... .... 
#+END_SRC
** Named constructor - static factory method

The named constructor or static factory design pattern uses static
methods instead of constructors for instantiating objects. This
approach has many advantages over constructor instantiation. Named
constructors are more readable than ordinary constructors and unlike
constructors, many named constructors static methods sharing the same
type signature can coexist. Another benefit is that this technique
allows objects to be instantiated in many different ways from several
different data representation.

Side note: It should not be confused with factory design pattern or
abstract factory design pattern.

Example:

#+BEGIN_SRC cpp   :results output pp :exports both 
  #include <iostream>
  #include <ostream>
  #include <cstdint>

  // #include <stdint>   // WARNING - It may not be available

  // Unsigned byte from 0 to 255 or 0x00 to 0xFF
  // ---> typedef uint8_t ubyte;
  using ubyte = uint8_t ; 

  class Color{
  private:
      ubyte m_r;
      ubyte m_g;
      ubyte m_b;
  public:
      Color(ubyte red, ubyte green, ubyte blue):
          m_r(red), m_g(green), m_b(blue) {}
      ubyte red(){
          return m_r;
      }
      ubyte blue(){
          return m_b;
      }
      ubyte green(){
          return m_g;
      }
      // Named constructor or static factory method which builds the object
      // From the RGB tuple data representation 
      static Color fromRGB(ubyte red, ubyte green, ubyte blue){
          return Color(red, green, blue);
      }
      // Named constructor which builds Color object 
      // from hexadecimal data representation 
      static Color fromHex(int color){
          int r = color & 0xFF;
          int g = (color >> 8 ) & 0xFF;
          int b = (color >> 16) & 0xFF;
          return Color(r, g, b);
      }
      // Named constructor which builds a specific color.
      static Color colorRED(){
          return fromRGB(255, 0, 0);
      }
      static Color colorBLUE(){
          return fromRGB(0, 255, 0);
      }
      static Color colorGREEN(){
          return fromRGB(0, 0, 255);
      }
      friend std::ostream& operator <<(std::ostream& os, const Color& c){
          os << "Color(r = "
             << static_cast<int>(c.m_r)
             << ", g = " << static_cast<int>(c.m_g)
             << ", b = " << static_cast<int>(c.m_b) << ")";
          return os;
      }      
  };

  int main(){
      std::cout << "Red    = " << Color::colorRED()   << "\n";
      std::cout << "Blue   = " << Color::colorBLUE()  << "\n";
      std::cout << "Green  = " << Color::colorGREEN() << "\n";
      std::cout << "Color1 = " << Color::fromRGB(20, 90, 200) << "\n";
      std::cout << "Color2 = " << Color::fromHex(0xFF8AB5) << "\n";
      std::cout.flush();
      return 0;
  }
#+END_SRC

#+RESULTS:
: Red    = Color(r = 255, g = 0, b = 0)
: Blue   = Color(r = 0, g = 255, b = 0)
: Green  = Color(r = 0, g = 0, b = 255)
: Color1 = Color(r = 20, g = 90, b = 200)
: Color2 = Color(r = 181, g = 138, b = 255)

See: 
 + [[https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)][Factory (object-oriented programming) - Wikipedia]]

** Factory Method 
*** Overview  

Factory method design pattern allows instatiating classes from a class
hierarchy without hardcoding the class name and knowing the class
implementation. There are many variations of this design pattern,
however the most common form is a class with method which returns an
instance of a derived class based on some input such as a number,
code, class name as string or number.

Definitions: 

 + Factory method or factory functions are any methods or functions
   which returns an instance of a class or derived class.

Note: The factory design pattern in this document is the variation
which creates an instance of a set of derived classes based on some
input. 

*** Factory Method Pattern Variations 

Some variations: 

 + _An ordinary function_ whith if-else statements which returns an
   instance of a set of derived  classes according to some
   input.
   + Disadvantage: Adding new derived classes requires code
     modification.

 + _A static method_ with if-else statements. This is mostly used on
   languages where there are not free functions or ordinary
   functions.
   + Disadvantage: Requires modifying the code when new classes are
     added to the hierarchy. 

 + _Registry-based factory_ (mostly known as Polymorphic Factory)- A
   class contains a factory method for instantiating derived classes
   based on some input and a hash table for registration of derived
   classes.
   + Disadvantage: Possibly requires manual registration during the
     program initialization.

   + Example:
     + Factory.register("sql",   SQLCreator)
     + Factory.register("mysql", MYSQLCreator)
     + DBDrivef driver = Factory.create("sqlite");

 + _Reflection-base factory_ - Some implementations uses reflection
   registration of derived classes.
   + Disadvantage: May not be possible in languages without reflection
     such as C++.

*** Sample Class Hierarchy 

Consider the following class hierarchy: 

 + Base class 

#+BEGIN_SRC cpp 
  class Base{
  public:
     Base() = default;
      // Destructor of base class must always be virtual 
      virtual ~Base() = default;   
      virtual auto getType() const -> std::string {
        return "Base";
     }	
     void showType(){
        std::cout << "Class type = " << this->getType() << "\n";
     }
  };
#+END_SRC

 + Derived class A 

#+BEGIN_SRC cpp 
class DerivedA: public Base{
public:
    DerivedA(){}
    auto getType() const  -> std::string {
       return "DerivedA";
    }
};
#+END_SRC

 + Derived class B

#+BEGIN_SRC cpp 
  class DerivedB: public Base{
  public:
     DerivedB(){}
     auto getType() const -> std::string {
        return "DerivedB";
     }
  };
#+END_SRC

*** Simple factory - if-else statement

Note: This implementation uses a factory function instead of a factory
method. The function creates an instance of Base, DerivedA or DerivedB
based on the provided name. The problem of this implementation is that
it requires modification of the code when new derived classes are
added.

#+BEGIN_SRC cpp 
  #include <memory> // smart pointers 
 
  auto simpleFactory(const std::string& name) -> std::unique<Base> {
       if(name == "Base")
           return std::make_unique<Base>();
       if(name == "DerivedA")
           return std::make_unique<DerivedA>();
       if(name == "DerivedB")
           return std::make_unique<DerivedB>();
       return nullptr;
  }

  >> auto base = simpleFactory("Base");
  >> if(base) { std::puts("Ok, then proceed."); }
  Ok, then proceed.

  >> base->getType()
  (std::string) "Base"

  >> auto da = simpleFactory("DerivedA");
  >> da->getType()
  (std::string) "DerivedA"
  >> 
#+END_SRC

*** Polymorphic Factory - registry based factory

Despite this implementation be more complex than a factory-method
pattern implementation using if-else statement, this one doesn't
require source modification if new derived classes are added to the
hierarchy. 

The class Factory is used for instantiating derived classes of Base
class based on the class name provided as a string. The factory
methods in this class are makeUnique and makeRaw.

 + File:
   + [[file:src/design-patterns/factory-pattern1.cpp][file:src/design-patterns/factory-pattern1.cpp]]
 + Online Compiler:
   + https://rextester.com/ILKI85678

#+BEGIN_SRC cpp 
  class Factory{
  private:
      using FactoryMap = std::map<std::string, Factory*>;
      // Force global variable to be initialized, thus it avoid
      // the inialization order fisaco. 
      static auto getRegister() -> FactoryMap& {
         static FactoryMap classRegister{};
         return classRegister;
      }
  public:	
      /** Register factory object of derived class */
      static
      auto registerFactory(const std::string& name, Factory* factory) -> void {
           auto& reg = Factory::getRegister();
           reg[name] = factory;
      }
      /** Show all registered classes */
      static
      auto showClasses() -> void {
           std::cout << " Registered classes. " << "\n";
           std::cout << " =================== " << "\n";
           for(const auto& pair: Factory::getRegister())
                   std::cout << " + " << pair.first << "\n";
      }		
      /**  Construct derived class returning a raw pointer */
      static
      auto makeRaw(const std::string& name) -> Base* {
           auto it = Factory::getRegister().find(name);
           if(it != Factory::getRegister().end())
                   return it->second->construct();
           return nullptr;
      }

      /** Construct derived class returning an unique ptr  */
      static
      auto makeUnique(const std::string& name) -> std::unique_ptr<Base>{
          return std::unique_ptr<Base>(Factory::makeRaw(name));
      }

      // Destructor 
      virtual
      ~Factory() = default;

      virtual
      auto construct() const -> Base* = 0;
  };
#+END_SRC
 
Concrete Factory: 

 + Template class used for creating static object which registers the
   associated derived class during the program initialization before
   the function main. 

#+BEGIN_SRC cpp 
  template<typename DerivedClass>
  class ConcreteFactory: Factory{
  public:
     // Register this global object on the Factory register 
     ConcreteFactory(const std::string& name){
        std::cerr << " [TRACE] " << " Registered Class = " << name << "\n";
        Factory::registerFactory(name, this);
     }
     auto construct() const -> Base* {
        return new DerivedClass;
     }	
  };
#+END_SRC

Manual class registration: 

#+BEGIN_SRC cpp 
  // Register Base class
  namespace {
     // Anonymous namespace is used to make the definitions here private to the current
     // compilation unit (current file). It is equivalent to the old C static keyword.
     // It could be placed at Base.cpp 
     ConcreteFactory<Base> factoryBase("Base");
  }
#+END_SRC

Class registration with macros:

#+BEGIN_SRC cpp 
  // Macro for class registration 
  #define REGISER_FACTORY(derivedClass) \
          namespace { auto registry_ ## derivedClass = ConcreteFactory<derivedClass>(#derivedClass);  }

  //  Registration with macro. 
  REGISER_FACTORY(DerivedA);
  REGISER_FACTORY(DerivedB);
#+END_SRC

Main function: 

#+BEGIN_SRC cpp 
    Factory::showClasses();
    std::cout << "\n";
    std::unique_ptr<Base> objBase = Factory::makeUnique("Base");
    std::cout << " type of objBase = " << objBase->getType() << "\n";

    std::unique_ptr<Base> objDA = Factory::makeUnique("DerivedA");
    std::cout << " type of derivedA = " << objDA->getType() << "\n";

    std::unique_ptr<Base> objDB = Factory::makeUnique("DerivedB");
    std::cout << " type of derivedA = " << objDB->getType() << "\n";

    std::unique_ptr<Base> objDC = Factory::makeUnique("Derived-error");
    if(!objDC)
       std::cout << " ==> Error: object not found in factory" << '\n';
#+END_SRC

Output:

#+BEGIN_SRC txt 
  $ clang++ factory-pattern1.cpp -o factory-pattern1.bin -g -std=c++1z -Wall -Wextra $

  $ ./factory-pattern1.bin
   [TRACE]  Registered Class = Base
   [TRACE]  Registered Class = DerivedA
   [TRACE]  Registered Class = DerivedB
   Registered classes. 
   =================== 
   + Base
   + DerivedA
   + DerivedB

   type of objBase = Base
   type of derivedA = DerivedA
   type of derivedA = DerivedB
   ==> Error: object not found in factory
#+END_SRC

*** References

 *References*

 + Bruce Eckel - *Thinking in Patterns with Java* - Page: 53
   + <http://www.cs.huji.ac.il/~noam/intro2cs2001/www/TIPatterns.pdf>

 + Bruce Eckel - *Thinking in C++, 2nd edition, Volume 2*
   + <http://www.cs.cmu.edu/~gregjor/project/eckelbook/volume2/Chap11.htm>

 + http://www.lsi.us.es/~jtorres/LibroJava/TIJ2R3-17_.html

 + [[http://www.andypatterns.com/index.php/blog/from_strategy_to_bridge/][AndyPatterns - From Strategy to Bridge]]

 + [[http://www.thedevpiece.com/cdi-polymorphism-and-the-factory-pattern/][CDI, Polymorphism and The Factory Pattern]]

 + Design patterns - OOD Lecture 6 -
   <https://www.it.uu.se/edu/course/homepage/ood/ht12/overview/patterns/Lecture6.pdf>

 + Creational Patterns for Variability
   + <http://www-st.inf.tu-dresden.de/Lehre/WS04-05/dpf/slides/2b-creational-variability-2p.pdf>

 + the Factory Design Pattern -
   <https://cs.anu.edu.au/courses/comp2500/notes/15factory.slides.pdf>

 + Design Patterns as Quality Influencing Factor in Object Oriented
   Design Approach - <https://arxiv.org/pdf/1402.2372.pdf>

 + [[https://www.journaldev.com/1392/factory-design-pattern-in-java][Factory Design Pattern in Java - JournalDev]]

 + [[https://industriallogic.com/xp/refactoring/polymorphicCreationFactory.html][Introduce Polymorphic Creation with Factory Method]]

 + Factory Method -
   <https://www.dofactory.com/net/factory-method-design-pattern> 

 *Further Reading* 

 + *Doing something on shared library initialization*
   + <http://zerohour.net/~reed/dylib_init.html>

 + *Factory Design Pattern in C++*
   + <http://blog.fourthwoods.com/2011/06/04/factory-design-pattern-in-c/>

 + *Abstract Factory Step-by-Step Implementation in C++*
   + <http://www.dorodnic.com/blog/2014/03/29/abstract-factory/>

 + *Sutter's Mill - GotW #90 Solution: Factories*
   + <https://herbsutter.com/2013/05/30/gotw-90-solution-factories/>

 + *Unforgettable Factory Registration*
   + <http://www.nirfriedman.com/2018/04/29/unforgettable-factory/>

 + *C++: Factory With Self-Registering Types*
   + <https://dzone.com/articles/factory-with-self-registering-types>

 + *Object Factories in a Static Library*
   + <http://www.sourcexr.com/articles/2014/06/21/object-factory-in-a-static-library>

 + *Automatic object factory in C++*
   + <https://blog.noctua-software.com/object-factory-c++.html>

 + *Self Registering Classes - Taking polymorphism to the limit*
   + <https://accu.org/index.php/journals/597>

** Builder (Joshua Blosh)

The purpose of the builder design pattern proposed by Joshua Bloch is
to simplify the instantiation of objects with many constructor
parameters or many optional parameters. Note: it should not be
confused with the GOF (Gang of Four) builder pattern.

Example: 

 - File: builder.cpp 

#+BEGIN_SRC cpp 
  // Joshua Bloch's Builder Pattern for simplifying the instantiation
  // of objects with many constructor parameters. It is not the
  // GOF (Gang of Four) builder pattern. 
  #include <iostream>
  #include <string>

  // Function meta object 
  class UserData{
  public:
          using ulong = unsigned long;
  private:
          ulong          _userID = 0;
          std::string    _name;
          std::string    _lastName;
          std::string    _email;
          UserData() = default;
  public:
          // Explicit is better than implicit 
          ~UserData() = default;
	
          auto show() -> void
          {
              std::cout << "\nUser{"
                        << "\n" << "  id        = " << _userID
                        << "\n" << "  name      = " << _name
                        << "\n" << "  last name = " << _lastName
                        << "\n" << "  email     = " << _email
                        << "\n" << "}"
                        << "\n";
          }
	
          // Allow builder class access UserData's private data
          friend class UserBuilder;
  }; //--- EoF class UserData --- //

  class UserBuilder{
  private:
          //class UserData;
          UserData _data{};
  public:
          UserBuilder(){
                  // _data = UserData();
          }		
          auto setID(ulong userID ) -> UserBuilder& {
             _data._userID = userID;
             return *this;
          }
          auto setName(const std::string& name) -> UserBuilder& {
              _data._name = name;
              return *this;
          }
          auto setLastName(const std::string& name) -> UserBuilder& {
              _data._lastName = name;
              return *this;
          }
          auto setEmail(const std::string& email) -> UserBuilder& {
             _data._email = email;
             return *this;
          }
          auto build() -> UserData {
             return this->_data;
          }
  }; //--- EoF class UserData::builder --- //

  int main(){
      auto user0 =
              UserBuilder()
              .setID(2065)
              .setName("John")
              .setLastName("Von Neumman")
              .setEmail("nx098774a@sknmap.co")
              .build();
      auto user1 =
              UserBuilder()
              .setID(1065)
              .setName("Blaise")
              .setLastName("Pascal")
              .setEmail("dummyEmail@service1.co.uk")
              .build();
      auto user2 =
              UserBuilder()
              .setID(2001)
              .setName("Nikola")
              .setLastName("Tesla")
              .setEmail("wsx752@couk.com.sk")
              .build();
      user0.show();
      user1.show();		
      user2.show();
      return EXIT_SUCCESS;
  }
#+END_SRC

Running: 

#+BEGIN_SRC sh 
   $ g++ builder.cpp -o builder.bin -g -std=c++1z -Wall -Wextra && ./builder.bin
   User{
     id        = 2065
     name      = John
     last name = Von Neumman
     email     = nx098774a@sknmap.co
   }

   User{
     id        = 1065
     name      = Blaise
     last name = Pascal
     email     = dummyEmail@service1.co.uk
   }

   User{
     id        = 2001
     name      = Nikola
     last name = Tesla
     email     = wsx752@couk.com.sk
   }
#+END_SRC
** Decorator 
*** Overview 

Structural design pattern which allows to extend a funcitonality of an
object dynamically without deep inheritance or deep class
hierarchies. 

 + Decorators are also known as wrappers due to it wrap itself around
   anohter object.

 + The wrapping/enclosing object is called "decorator".

GOF: "Attach additional resposibilities to an object
dynamically. Decorators provide a flexible alternative 
to subclassing for extending functionality."

Diagra built with: [[http://stable.ascii-flow.appspot.com][ascii flow]]

#+BEGIN_SRC text 
            +-------------------------------------+
            | <<Interface>> IComponent            |
            |-------------------------------------|
            |  +Operation()                       |
            +------------^----------------^-------+
                         |                |
                  +------+                +
                  |                       +-------+
                  |                               |
       +----------+-----------+      +-----------------------------+
       |  Component           |      | Decorator                   |
       |----------------------|      |-----------------------------|
       |  +Operation()        |      | Variable: IComponen comp    |
       |                      |      |                             |
       +----------------------+      | +Decorator(IComopent comp)  |
                                     |                             |
                                     | +Operation(){               |
                                     |   newBehavior();            |
                                     |   comp.Operation();         |
                                     |  }                          |
                                     +-----------------------------+
#+END_SRC
*** Example 

In this demonstration, it is presented a 2D stateful graphical API
similar to OpenGL or Windows' GDI which draws shapes on the
screen. There are two shapes Square and Triangle and two
decorators. ColorDecorator which sets the current context color saving
the current color and restoring it later and PositionDecorator which
changes the current coordinate in the transformation matrix, draws the
wrapped object and then restore the matrix to its previous state. The
use of decorators allows the functionality of some shape to be
extended without modifying or inheriting it. Another benefit is that
decorators can be combined with each other without inheritance.

 + File: [[file:src/design-patterns/decorator1.cpp][file:src/design-patterns/decorator1.cpp]]
 + Online Compiler: https://rextester.com/GSF96195

Interface IShape:

#+BEGIN_SRC cpp 
  // Interface IShape (IComponent) 
  struct IShape
  {
    virtual auto draw() -> void = 0;
    virtual auto description() -> std::string = 0;
    virtual ~IShape() = default;
  };
#+END_SRC

Concrete shape: Square 

#+BEGIN_SRC cpp 
    // Component class
    class Square: public IShape
    {
    public:
       auto draw() -> void
       {
          std::cout << " => Draw square" << std::endl;
       }
       auto description() -> std::string 
       {
          return "square";
       }
    };
#+END_SRC

Concrete shape: Triangle

#+BEGIN_SRC cpp 
  // Component class 
  class Triangle: public IShape
  {
  public:
      auto draw() -> void
      {
         std::cout << " => Draw tringle" << std::endl; 
      }
      auto description() -> std::string
      {
         return "triangle";
      }
  };
#+END_SRC

Decorator class for drawing a shape with some color. 

#+BEGIN_SRC cpp 
  // Decorator 1 => Draw shape with color
  class ColorDecorator: public IShape {
  public:
      ColorDecorator(std::shared_ptr<IShape> shape)
         : m_shape(shape) { }
      auto draw() -> void
      {
          // Save color:   push() 
          std::cout << " => [ColorDecorator] Draw object with color blue" << std::endl;
          m_shape->draw();
          // Restore color: pop()
      }
      auto description() -> std::string
      {
          return  m_shape->description() + " ; color = " + m_color;
      }
      // Return a reference to itself (ColorDecorator&)
      auto setColor(const std::string& color) -> decltype(*this)& {
          m_color = color;
          return *this;
      }
  private:
      // The decorator owns the decorated object 
      std::shared_ptr<IShape>  m_shape;
      std::string   m_color = "blue";
  };
#+END_SRC

Decorator class for drawing a shape at some position by saving,
changing and restoring the transformation matrix. 

#+BEGIN_SRC cpp 
  class PositionDecorator: public IShape {
  public:
       PositionDecorator(std::shared_ptr<IShape> shape)
        : m_shape(shape){ }

       auto draw() -> void
       {
          // Save transformation matrix:   pushMatrix() 
          std::cout << " =>  [PositionDecorator] Draw object at x = "
                   << m_x << " ; y = " << m_y << std::endl;
          m_shape->draw();
          // Restore transformation matrix: popMatrix()
       }
       auto description() -> std::string
       {
          return  m_shape->description() + " ; position x  = "
                  + std::to_string(m_x) +  " , y = " + std::to_string(m_y);
       }
       auto setPosition(double x, double y) -> PositionDecorator& {
          m_x = x, m_y = y;
          return *this;
       }	
  private:	
       // The decorator owns the decorated object 
       std::shared_ptr<IShape> m_shape;
       int m_x = 0, m_y = 0;
  };
#+END_SRC

 *Building* 

#+BEGIN_SRC sh 
  $ clang++ decorator1.cpp -o decorator1.bin -g -std=c++14 -Wall -Wextra
  $ ./decorator1.bin
#+END_SRC

 *Experiment 1* 

#+BEGIN_SRC cpp 
   std::puts("\n ======>> Experiment 1 <<===========");
   auto shape = std::make_shared<ColorDecorator>(std::make_shared<Square>());
   shape->setColor("yellow");
   shape->draw();
#+END_SRC

Output: 

#+BEGIN_SRC sh 
   ======>> Experiment 1 <<===========
   => [ColorDecorator] Draw object with color blue
   => Draw square
   DESCRIPTION = square ; color = yellow
#+END_SRC

 *Experiment 2* 

#+BEGIN_SRC cpp 
    std::puts("\n ======>> Experiment 2 <<===========");
    auto observerd = std::shared_ptr<IShape>{nullptr};

    auto shapeWithColorAndPosition =
        [&observerd]{
            auto shape        = std::make_shared<Triangle>();
            observerd         = shape;
            auto shapeColored = std::make_shared<ColorDecorator>(shape);
            shapeColored->setColor("white");
            auto shapePos     = std::make_shared<PositionDecorator>(shapeColored);			
            return  shapePos;
        }();

    shapeWithColorAndPosition->setPosition(100, 20);
    shapeWithColorAndPosition->draw();
    std::cout << " DESCRIPTION = "
                      << shapeWithColorAndPosition->description() << std::endl;

    std::cout << " [INFO] observed shape = " << observerd->description() << std::endl;
#+END_SRC

Output: 

#+BEGIN_SRC sh 
   ======>> Experiment 2 <<===========
   =>  [PositionDecorator] Draw object at x = 100 ; y = 20
   => [ColorDecorator] Draw object with color blue
   => Draw tringle
   DESCRIPTION = triangle ; color = white ; position x  = 100 , y = 20
   [INFO] observed shape = triangle
#+END_SRC

*** Other implementations 

 + [[http://miuliano.me/blog/2016/02/22/design-patterns-cpp-14/][Design Patterns & C++14]]
   + C++11: YES 
   + Note: Uses smart pointer (std::unique_ptr). 

 + [[https://www.badprog.com/c-design-pattern-decorator][C++ - Design pattern - Decorator | BadproG.com]]
   + C++11: YES 
   + Note: It uses smart pointer (std:unique_ptr) for the wrapped
     object. All objects in the main functions are allocated on the
     heap using std::make_unique (C++14).

 + [[https://sourcemaking.com/design_patterns/decorator/cpp/1][Decorator Design Pattern in C++: Before and after]]
   + C++11: NO 
   + Note: It uses raw pointer for accessing heap-allocated
     wrapped objects. All member objects are allocated on the heap and
     deleted manually. All objects in the main function are allocated
     on the hep (free-store).
   + Note: It doesn't follow modern C++ best practices which advise to
     manage dynamic memory with smart pointers.

 + [[https://www.geeksforgeeks.org/decorator-pattern-set-3-coding-the-design/][Decorator Pattern | Set 3 (Coding the Design) - GeeksforGeeks]]
   + C++11: NO
   + Note: Uses raw pointers, heap-allocated objects and manual
     delete. 

 + [[https://stackoverflow.com/questions/2988066/decorator-pattern-in-c][Decorator pattern in C++ - Stack Overflow]]
   + C++11: NO
   + Note: All objects allocated on the heap.

 + [[https://en.wikipedia.org/wiki/Decorator_pattern][Decorator pattern - Wikipedia]] 
   + C++11: NO
   + The decorator class uses a raw pointer to the wrapped object. All
     objects in the main functions are allocated on the stack. In this
     example, there is any problem over using raw pointers since they
     don't own memory.
   + Note: Also shows the decorator _implemented with Mixins_.

 + [[https://www.bogotobogo.com/DesignPatterns/decorator.php][Design Patterns: Decorator Pattern - 2018]]
   + Uses raw pointer for wrapped object. All objects in main
     functions are allocated on the heap.

 + [[http://www.sourcetricks.com/2013/03/decorator-pattern.html#.XAgr3B6YXMU][C++ Decorator Pattern ~ Programming Tutorials by SourceTricks]]
** Strategy
*** Overview  

Intent: A behavioral design pattern from GOF which allows the client
code to select and change an algorithm encapsulated as an object at
runtime.

Note: this design pattern is similar to a callback and can be
simplified with functional programming. 

 *Parts:*

 + _Context_:
   + Object that has a reference to an strategy objects and sets the
     strategy at runtime.
   + Resposibilities:
     + Set strategy
     + Change strategy
     + Invoke strategy

 + _IStrategy_: (Algorithm interface)
   + Strategt interface define the algorithm operations.

 + _Concrete strategy_.
   + Strategies objects or implementation of IStrategy class.
*** Example 

Code: 
 + File: [[file:src/design-patterns/strategy-pattern1.cpp][file:src/design-patterns/strategy-pattern1.cpp]]
 + Online Compiler: https://rextester.com/WQO93455

Strategy interface: 

#+BEGIN_SRC cpp 
  // Strategy interface 
  struct IStrategy{
    virtual ~IStrategy(){}
    // Essential: Algorithm encapsulated by strategy object 
    virtual auto compute(double x, double y) const -> double = 0;  
    // Optional: Provides strategy metadata 
    virtual auto name() const -> const std::string = 0;
    // Clone this object (Note: This is a virtual constructor)
    virtual auto clone() const -> IStrategy* = 0;
  };
#+END_SRC

Context Class: 
 - Selects and switch the strategy (aka algorithm).

#+BEGIN_SRC cpp 
  class Context{
  private: 
    std::unique_ptr<IStrategy> _strategy;
  public:
    Context()
      : _strategy{nullptr} { }
    Context(IStrategy* s)
      : _strategy{s} { }
    Context(const IStrategy& s)
      : _strategy{s.clone()} { }
    auto setStrategy(IStrategy* s){
      _strategy.reset(s);
    }
    auto setStrategy(const IStrategy& s){
      _strategy.reset(s.clone());
    }  
    auto compute(double x, double y) -> void {
      if(_strategy == nullptr)
        std::runtime_error("Error: strategy not set");
      double result = _strategy->compute(x, y);
      std::cout << " strategy = " << _strategy->name() << " "
                << "( x = " << x << " ; "
                << "y = " << y << " )"
                << "\n" ;
      std::cout << "Result = " << result << "\n";
    }
  };
#+END_SRC

Concrete strategies: 

 - add => algorithm which adds two numbers.

#+BEGIN_SRC cpp 
  class AddStrategy: public IStrategy {
  public:
    auto name() const -> const std::string{
      return "add";
    }
    auto compute(double x, double y) const -> double {
      return x + y;
    }
    auto clone() const -> IStrategy* {
      std::cerr << " [TRACE] AddStrategy => I was cloned" << "\n";
      return new AddStrategy(*this);
    }
  };
#+END_SRC

 + Multiplication 

#+BEGIN_SRC cpp 
  struct MulStrategy: public IStrategy {
  public:
    auto name() const -> const std::string{
      return "mul";
    }  
    double compute(double x, double y) const {
      return x + y;
    }
    auto clone() const -> IStrategy* {
      std::cerr << " [TRACE] MulStrategy => I was cloned" << "\n";
      return new MulStrategy(*this);
    }  
  };
#+END_SRC

 + Linear Combination: 

#+BEGIN_SRC cpp 
  struct LinearCombStrategy: public IStrategy {
    double a, b, c;
    LinearCombStrategy(double a, double b, double c)
      : a(a), b(b), c(c)
    {
    }
    auto name() const -> const std::string{
      return "Linear combination a * x + b * y + c";
    }    
    auto compute(double x, double y) const -> double{
      return a * x + b * y + c;
    }
    auto clone() const -> IStrategy* {
      std::cerr << " [TRACE] LinearCombStrategy => I was cloned" << "\n";
      return new LinearCombStrategy(*this);
    }  
  };
#+END_SRC

Main function: 

#+BEGIN_SRC cpp 
  Context ctx;
  std::cout << "==== Strategy = add ====" << "\n";
  ctx.setStrategy(new AddStrategy);
  ctx.compute(3.0, 4.0);

  std::cout << "==== Strategy = mul ====" << "\n";
  ctx.setStrategy(new MulStrategy);
  ctx.compute(3.0, 4.0);

  std::cout << "==== Strategy = Linear combination ====" << "\n";
  ctx.setStrategy(new LinearCombStrategy(5, 3, 4));
  ctx.compute(3.0, 4.0);

  std::cout << "==== Strategy = Linear combination [2] ====" << "\n";
  auto comb1 = LinearCombStrategy(6.0, 5.0, 10.0);
  // Copy stack-allocated object comb1 using the virtual constructor
  ctx.setStrategy(comb1);
  ctx.compute(5.0, 3.0);  

  std::cout << "==== Strategy = Linear combination [2] ====" << "\n";  
  // Copy stack-allocated temporary object comb1 using the virtual constructor
  // clone
  ctx.setStrategy(LinearCombStrategy{6.0, 5.0, 10.0});
  ctx.compute(2.0, 6.0);  
#+END_SRC

Output: 

#+BEGIN_SRC txt 
  $ clang++ strategy-pattern1.cpp -o strategy-pattern1.bin -g -std=c++1z -Wall -Wextra 
  $ ./strategy-pattern1.bin
  ==== Strategy = add ====
   strategy = add ( x = 3 ; y = 4 )
  Result = 7
  ==== Strategy = mul ====
   strategy = mul ( x = 3 ; y = 4 )
  Result = 7
  ==== Strategy = Linear combination ====
   strategy = Linear combination a * x + b * y + c ( x = 3 ; y = 4 )
  Result = 31
  ==== Strategy = Linear combination [2] ====
   [TRACE] LinearCombStrategy => I was cloned
   strategy = Linear combination a * x + b * y + c ( x = 5 ; y = 3 )
  Result = 55
  ==== Strategy = Linear combination [2] ====
   [TRACE] LinearCombStrategy => I was cloned
   strategy = Linear combination a * x + b * y + c ( x = 2 ; y = 6 )
  Result = 52

#+END_SRC
** Method Chaining - Fluent API

#+BEGIN_SRC cpp 
  class CharacterSuperMutant{
  private:
      double m_x;
      double m_y;
      double m_z;
  public:
      CharacterSuperMutant& setX(double x){
          m_x = x;
          return *this;
      }
      CharacterSuperMutant& setPosition(double x, double y, double z);

      auto setColor(COLOR color) -> decltype(this*)& {
          ... ....
          return *this;
      }
      // C++ 11 
      auto setForce(double force) -> CharacterSuperMutant& {
          ... ... 
          return *this;
      }   
     
      // Method / member function declaration, the implemention is in a different file.
      CharacterSuperMutant& CharacterSuperMutant::setPosition(double x, double y, double z);

      // C++11 
      auto CharacterSuperMutant::setStamina(double x, double y, double z) -> CharacterSuperMutant&;
  };

  // Example: Method implemented separated from class declaration in .cpp file.
  CharacterSuperMutant& CharacterSuperMutant::setPosition(double x, double y, double z){
      m_x = x; m_y = y; m_z  = z;
      return *this;
  }

  // C++11 auto syntax 
  auto CharacterSuperMutant::setStamina(double x, double y, double z) -> CharacterSuperMutant& {
      // ... ... ... 
      return *this;
  }

#+END_SRC

Usage: 

#+BEGIN_SRC cpp 
  CharacterSuperMutant mutant1;
  mutant1.setForce(1000).setColor(BLUE).setPosition(x).show();

  // Set methods at initialization 
  auto superMonster = CharacterSuperMutant().setForce(100).setPosition(4300).;

  // Instead of:
  mutant1.setForce(1000);
  mutant1.setColor(BLUE);
  mutant1.setPosition(x);
#+END_SRC

** GOF - Template Pattern 

It is stated by GOF as: "Defines the skeleton of an algorithm in a
method, deferring some steps to subclasses. Template Method lets
subclasses redefine certain steps of an algorithm without changing the
algorithms structure."

 + Intent: Create an algorithm template that allows redefine some
   steps without changing its structure.

The parent abstract class has four different types of methods:
 + _Concrete methods_: Methods implemented in the abstract class.

 + _Abstract methods_: Methods without implementation that must be
   implemented by subclasses.

 + _Hook methods_: Methods with default implementation that can be
   overriden by subclasses.

 + _Template methods_: Method that calls concrete methods, abstract
   methods or hook methods.

Participants: 
 + _Base Class_: Defines an algorithm which calls primitive methods (aka
   hook methods) that will be defined by the derived classes.
 + _Derived Class_: Implements primitive methods (virtual methods or
   methods that can be overriden) defined in the _base class_.

Features: 
 + The base class defines an algorithm stub, however some steps are
   required to be implemented by the derived class.
 + This pattern provides an _inverse control structure_, the algorithm
   defined in the base class which calls the primitive methods which
   are algorithm steps declared in the base class.
 + This pattern can be the base of an framework. 

Example: 

#+BEGIN_SRC cpp 
  class IntervalSummation{
  public:
   // Algorithm or entry point which calls the derived class method.
   // This is the template method 
   double summation(int lower, int upper) const{
           double sum = 0;
           for(int i = lower; i <= upper; i++)
                   sum += this->stepFn(i);
           return sum; 
   }
  protected:
      // Hook method or to be defined by the derived class
      virtual double stepFn(double x) const = 0 ;
  };

  class SumOfSquares: public IntervalSummation{
  private:
      double stepFn(double x) const { return x * x; }
  };

  class SumOfCubes: public IntervalSummation{
  private:
      double stepFn(double x) const { return x * x * x; }
  };

  void clientCode(const IntervalSummation& obj){
      std::cout << "Summation at [0, 15] = " << obj.summation(0, 15) << std::endl;
  }

#+END_SRC

Running in CERN's ROOT REPL:

#+BEGIN_SRC sh 
  >> sq.summation(0, 10)
  (double) 385.00000

  >> sc.summation(0, 10)
  (double) 3025.0000

  >> clientCode(sq)
  Summation at [0, 15] = 1240

  >> clientCode(sc)
  Summation at [0, 15] = 14400
  >> 
#+END_SRC

References: 

 + Template Method, Factory Method, and Composite. -
   <http://condor.depaul.edu/cjones1/depaul/se455/notes/lecture07.pdf>
 + Template Method - <http://cs.unb.ca/~wdu/cs4015/ch5k.pdf>
 + Encapsulating Algorithms with the Template Method Design Pattern -
   <https://redlich.net/pdf/publications/jupitermedia/template.pdf>
 + Template Method Design Pattern in Java -
   <https://www.journaldev.com/1763/template-method-design-pattern-in-java>

** Null-Object Pattern 

An object, called nulll object, which doesn't do anything and has
empty methods implementing a required interface by the client code is
used to convey the absense of an ordinary object instead of null or
null pointer.

Example: in a database system, instead of returning null, null
reference or null pointer for an not found employee object, an empty
object, called null object, with an empty mehtods is returned. It has
the advantage of avoiding null exception that can crash unexpectdely a
program. Another problem of null or null pointers is that null bugs
cannot be caught at compile-time and are also known to be hard to
debug and trace.

Alternatives: 
 + Throw an exception when there is the absense of an object. For
   instance, std::runtime_error("Error: record not found.").
 + Use optional type (Haskell's maybe) or C++17 Optional.
 + Return a pointer that is set to null for denoting the absence of an
   object. This pattern is widely used by many C and C++
   codes. However it is prone for the infamous null pointer exception
   problems. 

#+BEGIN_QUOTE
  A Null Object provides a surrogate for another object that shares
  the same interface but does nothing. Thus, the Null Object
  encapsulates the implementation decisions of how to do nothing and
  hides those details from its collaborators.
    -- Bobby Woolf in [PLoP3]
#+END_QUOTE

Code Example:

#+BEGIN_SRC cpp
  // Interface 
  class ICompany{
          virtual unsigned    getID() const       = 0;	
          virtual std::string getName() const     = 0;
          virtual void        showCompany() const = 0;
          virtual ~ICompany() = default;
  };

  class Company: public ICompany{
  public:
          Company(unsigned id, const std::string& name):
                  _name(name),
                  _id(id){
          }
          unsigned getID()      const { return _id; }
          std::string getName() const { return _name; }
          void showCompany() const {
                  std::cout << "Company is = " << _name << "\n";
          }	
          ~Company() = default;
  private:
          std::string _name;
          unsigned    _id;	
  };

  // Null object 
  // Returns this null object instead of returning a null pointer
  // when a givne company is not found in the database system.
  class NullCompany: public ICompany{
  public:
          unsigned getID()      const { return 0; }
          std::string getName() const { return ""; }
          void showCompany()    const {}		
  };
#+END_SRC

** Composite 

The composite pattern is a structural design pattern intruduced by GOF
which allows clients to deal with tree collection of objects in the
same way as a primitive objects. 

Features and applications: 

 + Allow client code to ignore differences between individual objects
   and collection (composite objects) and treat them uniformly.

 + Known cases:
   + GUI Widgets - Java Swing GUI library allows to build a complex
     GUI out of individual UI elements such as buttons, menu, text box
     and panels which can have many UI child objects and other panels.
   + AST - Abstract Syntax Trees 
   + XML - Nodes 

 + Participants of Composite
   * _Component_:
     + Overview: Interface or abstract class which defines common
       operations shared by the primitive objects and composite objects.

   * _Leaf_
     + Overview:
       + Represents a primitive object which doesn't contain any child
         object. 

   * _Composite_
     * Overview 
       * As the name implies, the composite object contains leaf
         children objects.
       * Implements child operations in the component interface.
       * Can add or remove leaf objects or composite object as
         children.
       * The composite object forwards the messages related to child
         operations to the children elements.
     * Methods:
       - .Add(Component)   
       - .Remove(Component)
       - .Clear()

 *Example:*

File: 
 + [[file:src/design-patterns/composite1.cpp][file:src/design-patterns/composite1.cpp]]
 
Online Compiler: 
 + https://rextester.com/DYIE1548


Component interface: 
 + Defines primitive elements operations.

#+BEGIN_SRC cpp 
  class IGraphic{
  public:
       virtual auto type() const -> const std::string  = 0;
       virtual auto draw() -> void = 0;
       virtual auto rotate(double) -> void = 0;
       virtual ~IGraphic() = default;
  };
#+END_SRC

Convenient type aliases: 

#+BEGIN_SRC cpp 
  using cstring = const char*;
  using GNode = std::shared_ptr<IGraphic>;
#+END_SRC

Leaf, group aka composite object: 
 + Allows to performing an operation, which would be performed on a
   single primitive element, on all elements stored in the composite
   object.

#+BEGIN_SRC cpp 
  class Group: public IGraphic{
  private:
      std::vector<GNode> _nodes;
      const std::string _id;
      static constexpr cstring _type = "Group";
  public:
      Group(const std::string& id): _id(id) {
          std::cout << " [TRACE] Create group = " << id << "\n";
      }
      ~Group(){
          std::cout << " [TRACE] Destroy group - id = << " << _id << "\n";
      }

      auto begin() const -> decltype(_nodes.begin()) {
          return _nodes.begin();
      }
      auto end() const -> decltype(_nodes.end()) {
          return _nodes.end();
      }

      auto clear() -> void {
          _nodes.clear();
      }
      auto size() -> size_t {
          return _nodes.size();
      }
      auto add(GNode n) -> void {
          std::cout << " [TRACE] id = " << _id
                    << "; Add object = " << n->type() << "\n";
         _nodes.push_back(n);
      }
      auto add(IGraphic* n) -> void {
          std::cout << " [TRACE] id = " << _id
                    << " ; Add object = " << n->type() << "\n";
          _nodes.push_back(std::shared_ptr<IGraphic>(n));
      }
      // Add stack-allocated object 
      auto addFromStack(IGraphic* n) -> void {
          std::cout << " [TRACE] id = " << _id
                    << " ; Add object = " << n->type() << "\n";
          // Dummy deleter to avoid core dump by avoiding deleting
          // stack-allocated object or non-owned pointer.
          auto s = std::shared_ptr<IGraphic>(n, [](IGraphic*){ return ; });
          _nodes.push_back(s);
      }	

      // Note: Template methods should always be in the header files
      template<class Node>
      auto addNew(const std::string& id) -> void {
          auto n = std::make_unique<Node>(id);
          std::cout << " [TRACE] id = " << _id
                            << " ; Add object = " << n->type() << "\n";    
          _nodes.push_back(std::move(n));
      }

      // ======> Interface IGraphic <<=========//

      auto type() const -> const std::string override {
          return _type;
      }    
      auto draw() -> void override {
          std::cout << " [TRACE] Draw group - id =  " << _id << "\n";
          for(const auto& obj: _nodes)
              obj->draw();
      }
      auto rotate(double angle) -> void override {
          std::cout << " [TRACE] Rotate group - id = " << _id << "\n";
          for(const auto& obj: _nodes)
              obj->rotate(angle);
      }    
  };
#+END_SRC

Primitive element or node: Line  

#+BEGIN_SRC cpp 
  class Line: public IGraphic {
  private:
      static constexpr cstring _type = "Line";
      std::string _id;
  public:
      Line(const std::string& id): _id{id} { }
      auto type() const -> const std::string override {
           return _type;
      } 
      auto draw() -> void override {
           std::cout << " [TRACE] Draw line - id = " << _id << "\n";
      } 
      auto rotate(double angle) -> void override {
           std::cout << " [TRACE] Rotate line ; id = " << _id 
                     << "; angle = " << angle << "\n";
      }  
  };
#+END_SRC


Primitive element or node: Triangle 

#+BEGIN_SRC cpp 
  class Triangle: public IGraphic {
  private:
      static constexpr cstring _type = "Triangle";
      std::string _id;
  public:
      Triangle(const std::string& id): _id{id} { }
      auto type() const -> const std::string override {
         return _type;
      } 
      auto draw() -> void override {
          std::cout << " [TRACE] Draw triangle - id = " << _id << "\n";
      } 
      auto rotate(double angle) -> void override {
           std::cout << " [TRACE] Rotate triangle"
                     << " id = " << _id
                     << " angle = " << angle << "\n";
      }  
  };
#+END_SRC

Sample client code: 

#+BEGIN_SRC cpp 
  // Count total number of elements 
  auto countElements(const Group& group) -> size_t {
      size_t n = 0;
      for(const auto& g: group){
         if(g->type() == "Group"){
                 auto p = static_cast<Group*>(g.get());
                 n += countElements(*p);			
         } else{ ++n; }
      }
      return n;
  }

#+END_SRC

Main function: 

#+BEGIN_SRC cpp 
   const char nl = '\n';

   std::cout << "=== Objects construction === " << nl;

   auto groupA = Group("groupA");
   groupA.add(new Triangle("triangleA1"));
   groupA.add(new Line("lineA1"));
   groupA.addNew<Line>("LineA2");

   auto groupB = std::make_shared<Group>("GroupB");
   groupB->add(new Triangle("triangleB1"));
   groupB->addNew<Triangle>("triangleB2");
   groupB->addNew<Line>("LineB1");
   groupB->addNew<Line>("LineB2");
   auto triangleB3 = Triangle("triangleB3");
   groupB->addFromStack(&triangleB3);
   groupA.add(groupB);

   std::cout << nl << "=== End of object construction === " << nl;
   std::cout << "Total of elements of groupA = " << countElements(groupA) << "\n";
   std::cout << "Total of elements of groupB = " << countElements(*groupB) << "\n";

   std::cout << nl << " [*] ==> Draw group B" << "\n";
   groupB->draw();

   std::cout << nl << " [*] ==> Rotate group B" << "\n";
   groupB->rotate(90);

   std::cout << nl << " [*] ==> Draw group A" << "\n";
   groupA.draw();

   std::cout << nl << " [*] ==> Rotate group A" << "\n";
   groupA.rotate(15);

   std::cout << nl << " [*] ==> Remove objects from group B" << "\n";
   groupB->clear();
   groupA.draw();

   std::cout << "=== End of Program ====" << "\n";

#+END_SRC

Running:  ([[file:src/design-patterns/composite1.cpp][file:src/design-patterns/composite1.cpp]])

#+BEGIN_SRC sh 
   $ g++ composite1.cpp -o composite1.bin -g -std=c++1z -Wall -Wextra 
   $ ./composite1.bin

   === Objects construction === 
    [TRACE] Create group = groupA
    [TRACE] id = groupA ; Add object = Triangle
    [TRACE] id = groupA ; Add object = Line
    [TRACE] id = groupA ; Add object = Line
    [TRACE] Create group = GroupB
    [TRACE] id = GroupB ; Add object = Triangle
    [TRACE] id = GroupB ; Add object = Triangle
    [TRACE] id = GroupB ; Add object = Line
    [TRACE] id = GroupB ; Add object = Line
    [TRACE] id = GroupB ; Add object = Triangle
    [TRACE] id = groupA; Add object = Group

   === End of object construction === 
   Total of elements of groupA = 8
   Total of elements of groupB = 5

    [*] ==> Draw group B
    [TRACE] Draw group - id =  GroupB
    [TRACE] Draw triangle - id = triangleB1
    [TRACE] Draw triangle - id = triangleB2
    [TRACE] Draw line - id = LineB1
    [TRACE] Draw line - id = LineB2
    [TRACE] Draw triangle - id = triangleB3

    [*] ==> Rotate group B
    [TRACE] Rotate group - id = GroupB
    [TRACE] Rotate triangle id = triangleB1 angle = 90
    [TRACE] Rotate triangle id = triangleB2 angle = 90
    [TRACE] Rotate line ; id = LineB1; angle = 90
    [TRACE] Rotate line ; id = LineB2; angle = 90
    [TRACE] Rotate triangle id = triangleB3 angle = 90

    [*] ==> Draw group A
    [TRACE] Draw group - id =  groupA
    [TRACE] Draw triangle - id = triangleA1
    [TRACE] Draw line - id = lineA1
    [TRACE] Draw line - id = LineA2
    [TRACE] Draw group - id =  GroupB
    [TRACE] Draw triangle - id = triangleB1
    [TRACE] Draw triangle - id = triangleB2
    [TRACE] Draw line - id = LineB1
    [TRACE] Draw line - id = LineB2
    [TRACE] Draw triangle - id = triangleB3

    [*] ==> Rotate group A
    [TRACE] Rotate group - id = groupA
    [TRACE] Rotate triangle id = triangleA1 angle = 15
    [TRACE] Rotate line ; id = lineA1; angle = 15
    [TRACE] Rotate line ; id = LineA2; angle = 15
    [TRACE] Rotate group - id = GroupB
    [TRACE] Rotate triangle id = triangleB1 angle = 15
    [TRACE] Rotate triangle id = triangleB2 angle = 15
    [TRACE] Rotate line ; id = LineB1; angle = 15
    [TRACE] Rotate line ; id = LineB2; angle = 15
    [TRACE] Rotate triangle id = triangleB3 angle = 15

    [*] ==> Remove objects from group B
    [TRACE] Draw group - id =  groupA
    [TRACE] Draw triangle - id = triangleA1
    [TRACE] Draw line - id = lineA1
    [TRACE] Draw line - id = LineA2
    [TRACE] Draw group - id =  GroupB
   === End of Program ====
    [TRACE] Destroy group - id = << groupA
    [TRACE] Destroy group - id = << GroupB
#+END_SRC
** Observer-Observable 
*** Overview 

The observer design pattern is a behavioral design pattern introduced
by GOF(Gang-of-Four book), which defines a one-to-many dependency
between a subject (a.k.a observable) and observers that are notified
by the subject object whenever its state change. 

This pattern is widely used in GUI graphical user interfaces for
decoupling the application state and business logic from the graphical
user interface. For instance, many GUI applications that provide
Comboboxes, Listboxes or selection boxes widgets does not allow adding 
elements to those widgets directly. Instead, they provide observable
objects, such as ListModel which notifies the subscribed, or attached
widgets, about its changes. When any new element is added to a
hypothetical ListModel object, it notifies the dependent widgets such as
ListBoxes, Comboboxes and tables which update themselves. The benefit
of this approach is that it allows changing the user interface widgets
without modifying the application logic. 

Also known as: 

  * observer design pattern 
  * publisher/subscriber
  * subject/observer 

Use-cases and potential applications: 

  * GUI - Graphical User Interfaces
  * Chart Applications 
  * CAD - Computer Aided Design Software
  * Spreadsheets 
  * Object-oriented callbacks
  * Event-driven systems
  * "Reactive programming" buzzword (ReactiveX)

Other Variants: 

  + MVC - Model View Controller design pattern for GUIs
  + MVP - Model View Presenter design pattern for GUIs 
  + "Reactive programming"
  + Two-way data bindings from .NET WPF (Windows Presentation Foundation)
  + Observable property from .NET
  + Observable variables from Java and Android
  + Signals and slots from Qt Framework 

Known uses: 

  * Java: java.util.Observer
  * .NET (C#): System.IObservable and System.IObserver  
  * Java Swing
  * QT GUI C++ Framework 
 
Parts: 

  + _Subject_ (aka Observable) - Keeps references to all _observer_
    objects and notifies them whenever its state changes.

    + Typical Methods:
      + Subject.subscribe(Observer) => Register observer for further notifications.
      + Subject.register(Observer) => Register observer for further notifications.
      + Subject.attach(Observer) => Register observer for further notifications.
      + Subject.detach(Observer) => Remove observer, unsubscribe from notifications.
      + Subject.notify() => Notify all observers by calling the method .notify()

  + _Observer_ - Object that subscribes to the _subject_ notifications and
    are called by the subject whenever there is a state change.

    + Typical methods:
      + .update()
      + .notify() 

Potential problems: 

  + When notified, an observer object should complete its computation
    as fast as possible, otherwise it will block the remaining
    observers from being notified.

  + If the computation performed by any observer, when a notification
    arrives, blocks the current thread, all other remaining observers
    will not be able to receive notifications from the subject object.

  + Possible callback hell. Every observer is just a object-oriented callback. 

Mechanisms to send data to observers:

 + Pull model. Observer executes Subject.getData() to get data from subject.

 + Push model. The subject pass its data as argument of observers'
   update method. =for o in observers do o.update(subject.data)=

 *See also* 

General: 

  + [[https://en.wikipedia.org/wiki/Observer_pattern][Observer pattern - Wikipedia]]

  + [[https://stackoverflow.com/questions/15594905/difference-between-observer-pub-sub-and-data-binding][model view controller - Difference between Observer, Pub/Sub, and Data Binding - Stack Overflow]]

  + [[http://www.cs.williams.edu/~freund/cs326/cs326-dependencies.pdf][CS 326 - Dependency and Decoupling]]

  + [[https://www.cs.mcgill.ca/~hv/classes/CS400/01.hchen/doc/observer/observer.html][McGill - Observer Design Pattern]]

  + [[https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee817669(v=pandp.10)?redirectedfrom=MSDN][Exploring the Observer Design Pattern | Microsoft Docs]]

  + [[https://docs.microsoft.com/en-us/dotnet/standard/events/observer-design-pattern][Microsft - Observer Design Pattern]]

  + http://ima.udg.edu/~sellares/EINF-ES1/ObserverToni.pdf

  + [[http://se.inf.ethz.ch/old/teaching/ss2007/0050/slides/07_softarch_patterns_observer_6up.pdf][Software Architecture - Lecture 7: Patterns, Observer, MVC]] - Betrand Meyer

  + [[https://www.codeproject.com/Articles/888/Applying-Observer-Pattern-in-C-Applications][Applying Observer Pattern in C++ Applications - CodeProject]]

  + [[https://www.codeproject.com/Articles/38108/Propagator-in-C-An-Alternative-to-the-Observer-Des][Propagator in C# - An Alternative to the Observer Design Pattern - CodeProject]]

  + [[http://archive.www6.in.tum.de/www6/pub/Main/TeachingWs2013MSE/2_OderskyDeprecatingObservers.pdf][Deprecating the Observer Pattern]] - EPFL Report (Paper)

Observer Pattern Variants. 

  + [[https://mvc.givan.se/papers/MVP_Model-View-Presenter_The_Taligent_Programming_Model_for_C++_and_Java.pdf][MVP: Model-View-Presenter - The Taligent Programming Model for C++ and Java]]

  + [[https://signalslot.readthedocs.io/en/latest/pattern.html][Signal/Slot design pattern — signalslot 0.1.1 documentation]]

  + [[https://doc.qt.io/qt-5/signalsandslots.html][Signals & Slots | Qt Core 5.15.0]]

  + [[https://www.boost.org/doc/libs/1_74_0/doc/html/signals2.html][Chapter 35. Boost.Signals2 - 1.74.0]] (Boost library)

  + [[http://reactivex.io/][ReactiveX]] - "The Observer pattern done right. ReactiveX is a
    combination of the best ideas from the Observer pattern, the
    Iterator pattern, and functional programming"

  + [[https://ayende.com/blog/4107/an-easier-way-to-manage-inotifypropertychanged][An easier way to manage INotifyPropertyChanged - Ayende @ Rahien]]

  + [[https://www.codeproject.com/Articles/796075/Implement-Observer-Pattern-in-NET-3-Techniques][Implement Observer Pattern in .NET (3 Techniques) - CodeProject]]

  + [[https://www.codeproject.com/Articles/166530/A-Chained-Property-Observer][A Chained Property Observer - CodeProject]]

  + [[https://docs.microsoft.com/en-us/archive/msdn-magazine/2001/april/net-an-introduction-to-delegates][.NET: An Introduction to Delegates | Microsoft Docs]] 

  + [[https://docs.microsoft.com/en-us/dotnet/api/system.iobservable-1][.NET - System.IObserver<T>]]

  + [[https://docs.microsoft.com/en-us/dotnet/api/system.iobservable-1][.NET - System.IObservable<T>]]

  + [[https://docs.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=netcore-3.1][ObservableCollection<T> Class (System.Collections.ObjectModel) | Microsoft Docs]]

  + [[https://developer.android.com/reference/android/databinding/ObservableList][ObservableList  |  Android Developers]]

  + [[https://developer.android.com/topic/libraries/data-binding/observability][Work with observable data objects  |  Android Developers]]

  + [[https://developer.android.com/reference/android/databinding/Observable.OnPropertyChangedCallback][Observable.OnPropertyChangedCallback  |  Android Developers]]

  + [[https://www.developer.com/java/data/understanding-java-observable-and-javafx-observable.html][Understanding Java Observable and JavaFX Observable - Developer.com]]

  + [[https://dzone.com/articles/javafx-collections-observablelist-and-observablema][JavaFX Collection's ObservableList and ObservableMap - DZone]]
*** Implementation 1 - Classical Implementation 

This implementation is based on classical observer-design pattern and
defines two interfaces IObservable, which all observable objects
inherit from, and IObserver, which all observer objects inherit
from. This sample application defines a counter observable object that
notifies all observers when its state changes. The application also
provides three observers, a console observer which prints the console
(terminal) and two Qt5 Gui observers which displays that counter
value. 

 + All Sources: https://gist.github.com/9331193ae1f9b05e4949160a4e024e84

File: _CMakeLists.txt_ 

#+BEGIN_SRC cmake 
   cmake_minimum_required(VERSION 3.9)
   project(observer-design-pattern1)

   #====== Global Configurations ==================#

   set(CMAKE_CXX_STANDARD 17)
   set(CMAKE_VERBOSE_MAKEFILE ON)
   set(CMAKE_INCLUDE_CURRENT_DIR ON)
   set(CMAKE_AUTOUIC ON)
   set(CMAKE_AUTOMOC ON)
   set(CMAKE_AUTORCC ON)
   set(CMAKE_CXX_STANDARD_REQUIRED ON)

   find_package(Qt5 COMPONENTS Core Widgets REQUIRED)

   #=============== Target Configurations ============#

          add_executable( observer1 observer-pattern1.cpp )
   target_link_libraries( observer1 Qt5::Core Qt5::Gui Qt5::Widgets)
#+END_SRC

File: _observer-pattern1.cpp_ 

#+BEGIN_SRC cpp 
   #include <iostream>
   #include <iomanip>

   #include <QtWidgets>
   #include <QApplication>
   #include <QSysInfo>

   struct IObserver;

   struct IObservable 
   {
       /** Subscribe to observable notifications */
       virtual void addObserver(IObserver* obs) = 0;

       /** Notify all observers */
       virtual void notify() = 0; 
       virtual     ~IObservable() = default;
   };

   struct IObserver 
   {
       virtual void update(IObservable* sender) = 0;
       virtual     ~IObserver() = default;
   };

   class BasicObservable: public IObservable 
   {
       std::vector<IObserver*> m_observers{};
   public:

       void addObserver(IObserver* obs) override 
       {
           m_observers.push_back(obs);
           obs->update(this);
       }

       /** Notify all observers */
       void notify() override  
       {
           for(const auto obs: m_observers){ obs->update(this); }
       }    
   };

   class CounterModel: public BasicObservable
   {
       int m_counter = 0;
   public: 

       void increment() 
       { 
           m_counter += 1;
           this->notify();
       }
       void decrement() 
       {
           m_counter -= 1;
           this->notify();
       }
       void reset()
       { 
           m_counter = 0;  
           this->notify();
       }

       void set(int n)
       {
           m_counter = n;
           this->notify();
       }

       int get() const { return m_counter; }
   };

   /** Concrete observer that prints the subject state in the console (terminal) */
   class ConsoleView: public IObserver 
   {
       /* override: IObserver::update() */
       void update(IObservable* sender) override 
       {
           /* Note: It can result in undefined behavior. */
           int cnt = static_cast<CounterModel*>(sender)->get();
           std::cout << " [CONSOLE] Counter state changed to = " << cnt << '\n';
       }
   };


   class FormView: public IObserver {
       QWidget      m_win{};
       QFormLayout* m_form;
       QPushButton* m_btn_increment;
       QPushButton* m_btn_decrement;
       QLabel*      m_label;

       CounterModel& m_model;
   public:

       FormView(CounterModel& model): m_model(model)
       {
           m_win.setWindowTitle("Form View");
           m_form = new QFormLayout(&m_win);
           m_btn_increment = new QPushButton("[+]");
           m_btn_decrement = new QPushButton("[-]");
           m_label         = new QLabel("0");

           m_form->addRow("Increment",     m_btn_increment);
           m_form->addRow("Decrement",     m_btn_decrement);
           m_form->addRow("Counter value", m_label);

           m_win.show(); 

           /** ------ Setup event handlers ------------------- **/

           QObject::connect(m_btn_decrement, &QPushButton::clicked, 
               [self = this]{ 
                   self->m_model.decrement();
               });

           QObject::connect(m_btn_increment, &QPushButton::clicked, 
               [this](){ 
                   m_model.increment(); 
               });
       }

       /* override: IObserver::update() */
       void update(IObservable* sender) override 
       {
           int cnt = static_cast<CounterModel*>(sender)->get();
           m_label->setText(QString::number(cnt)); 
           std::cout << " [QT GUI] Counter state changed to = " << cnt << '\n';
       }
   };

   class LabelView: public IObserver
   {
       QLabel m_label;
   public:
       LabelView() 
       {   
           m_label.setWindowTitle("Label View");
           m_label.resize(400, 300);
           m_label.show();
       }

       /* override: IObserver::update() */
       void update(IObservable* sender) override 
       {
           int cnt = static_cast<CounterModel*>(sender)->get();
           m_label.setText(" [LABEL Observer] Counter value = " + QString::number(cnt));
       }

   };


   int main(int argc, char** argv)
   {
       // Useful for debugging
       std::cout << " [INFO] QTVersion = " << ::qVersion() << std::endl;


       QApplication app(argc, argv);

       CounterModel model;     
       ConsoleView  observerA{};
       FormView     observerB{model};
       LabelView    observerC{};

       model.addObserver(&observerA);
       model.addObserver(&observerB);
       model.addObserver(&observerC);

       return app.exec();
   }
#+END_SRC

Building and running: 

#+BEGIN_SRC sh 
  # Get sources 
  $ git clone https://gist.github.com/9331193ae1f9b05e4949160a4e024e84 observer1 && cd observer1

  # Build  
  $ cmake -H. -B_build -DCMAKE_BUILD_TYPE=Debug && cmake --build _build --target 
 
  # Run: 
  $ _build/observer1b 
#+END_SRC

GUI Screenshot: 

[[file:images/observer-desing-pattern1.png][file:images/observer-desing-pattern1.png]]
*** Implementation 2 - Using Callbacks 

In this implementation, the observer object is replaced by a
std::function<> callback which makes the code more loose coupled as
any objects from any class and lambdas can be used as observers. 

GIST: 

 + https://gist.github.com/ff0cb5ac26bba23fc4c17c8bb8df070d

File: _CMakeLists.txt_ 

#+BEGIN_SRC cmake 
     cmake_minimum_required(VERSION 3.9)
     project(observer-design-pattern2)

     #====== Global Configurations ==================#

     set(CMAKE_CXX_STANDARD 17)
     set(CMAKE_VERBOSE_MAKEFILE ON)
     set(CMAKE_INCLUDE_CURRENT_DIR ON)
     set(CMAKE_AUTOUIC ON)
     set(CMAKE_AUTOMOC ON)
     set(CMAKE_AUTORCC ON)
     set(CMAKE_CXX_STANDARD_REQUIRED ON)

     find_package(Qt5 COMPONENTS Core Widgets REQUIRED)

     #=============== Target Configurations ============#

     add_executable( observer2 observer-pattern2.cpp )
     target_link_libraries( observer2 Qt5::Core Qt5::Gui Qt5::Widgets)
#+END_SRC

File: _observer-pattern2.cpp_ 

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <iomanip>
  #include <functional> 

  #include <QtWidgets>
  #include <QApplication>
  #include <QSysInfo>

  using ObserverCallback = std::function<void (void* sender)>;

  struct IObservable 
  {
      /** Subscribe to observable notifications */
      virtual void addObserver(ObserverCallback obs) = 0;

      /** Notify all observers */
      virtual void notify() = 0; 
      virtual     ~IObservable() = default;
  };

  class Observable: public IObservable 
  {
      void* m_sender = nullptr;
      std::vector<ObserverCallback> m_observers{};
    
  public:

      Observable(){ }
      Observable(void* sender): m_sender(sender){ }
    
      void addObserver(ObserverCallback callback) override 
      {
          m_observers.push_back(callback);
          callback(m_sender);
      }

      /** Notify all observers */
      void notify() override  
      {
          for(const auto callback: m_observers){ callback(m_sender); }
      }    
  };

  class CounterModel
  {
      int m_counter{0};
      Observable m_obs{this};
  public: 
      void increment() { m_counter += 1; m_obs.notify(); }
      void decrement() { m_counter -= 1; m_obs.notify(); }
      int  get() const { return m_counter; }

      void onCounterChanged(ObserverCallback callback)
      {
          m_obs.addObserver(callback);
      }
  };

  class FormView {
      QWidget      m_win{};
      QFormLayout* m_form;
      QPushButton* m_btn_increment;
      QPushButton* m_btn_decrement;
      QLabel*      m_label;

      CounterModel& m_model;
  public:

      FormView(CounterModel& model): m_model(model)
      {
          m_win.setWindowTitle("Form View");
          m_form = new QFormLayout(&m_win);
          m_btn_increment = new QPushButton("[+]");
          m_btn_decrement = new QPushButton("[-]");
          m_label         = new QLabel("0");

          m_form->addRow("Increment",     m_btn_increment);
          m_form->addRow("Decrement",     m_btn_decrement);
          m_form->addRow("Counter value", m_label);

          m_win.show(); 

          /** ------ Setup event handlers ------------------- **/

          QObject::connect(m_btn_decrement, &QPushButton::clicked, 
              [self = this]{ 
                  self->m_model.decrement();
              });
        
          QObject::connect(m_btn_increment, &QPushButton::clicked, 
              [this](){ 
                  m_model.increment(); 
              });
      }

      void update(void* sender)  
      {
          int cnt = reinterpret_cast<CounterModel*>(sender)->get();
          m_label->setText(QString::number(cnt)); 
          std::cout << " [QT GUI] Counter state changed to = " << cnt << '\n';
      }
  };

  class LabelView
  {
      QLabel m_label;
  public:
      LabelView() 
      {   
          m_label.setWindowTitle("Label View");
          m_label.resize(400, 300);
          m_label.show();
      }

      void notify(void* sender)
      {
          int cnt = reinterpret_cast<CounterModel*>(sender)->get();
          m_label.setText(" [LABEL Observer] Counter value = " + QString::number(cnt));
      }

  };


  int main(int argc, char** argv)
  {
      QApplication app(argc, argv);

      CounterModel model;     
    
      model.onCounterChanged([](void* sender){
          int cnt = static_cast<CounterModel*>(sender)->get();
          std::cout << " [CONSOLE VIEW] Counter state changed to = " << cnt << '\n';
      });

      FormView   observerB{model};
      LabelView  observerC{};

      model.onCounterChanged([&](void* sender){
          observerB.update(sender);
      });
    
      model.onCounterChanged([&](void* sender){ 
          observerC.notify(sender); 
      });

      return app.exec();
  }
#+END_SRC
** Chain of Responsibility 
*** Overview 

The Chain-of-responsibility design pattern is a behavioral design
pattern, introduced by the GOF book, which allows decoupling the
sender of a request object from the objects that handle the
request. In this pattern, _request_ objects, also called _commands_ or
_events_, are passed through a chain of _handler objects_ that process a
request or forward it to the next handler in the chain without the
sender know which handler will process the request. 

 + Note: GOF means (Gang-of-Four Book) - _Elements of Reusable_
   _Object-Oriented Software_ - Eric Gamma et al.

 + Note: The _request_ is also referred by some sources as _command_ or
   _event_. 


Possible use-cases: 

  + Request processing

  + Event handling

  + Error handling 

  + Data validation

  + Replace nested if-else statements allowing this piece code to be
    extended without modifying it. (Open-close - OOP -
    Object-Oriented-Programming principle from SOLID).

Intent, according to GOF book - Elements of Reusable Object-Oriented
Software:

#+BEGIN_QUOTE
  Avoid coupling the sender of a request to its receiver by giving
  more than one object a chance to handle the request. Chain the
  receiving objects and pass the request along the chain until an
  object handles it. 
#+END_QUOTE

Further Reading: 

  + [[https://en.m.wikipedia.org/wiki/Chain-of-responsibility_pattern][Chain of responsiblity design pattern - Wikipedia]]

  + [[https://codenuclear.com/chain-of-responsibility-design-pattern-in-java/][Chain of responsiblity design pattern in Java - Code Nuclear]]

  + [[https://sii.pl/blog/chain-of-responsibility-an-elegant-way-to-handle-complex-validation/][Chain of responsiblity - An Elegant Way ot handle complex validation]]

  + [[https://blog.ploeh.dk/2019/07/22/chain-of-responsibility-as-catamorphisms/][Chain of Responsility as catamorphisms]] (Mark Seemann)

  + [[https://blogs.sap.com/2020/02/26/abap-with-coffee-and-chain-of-responsibilitycor-oo-pattern/][ABAP with Coffee and Chain of Responsibility(CoR) OO Pattern]] - SAP
    company (Sreejith Ramachandran)

  + [[https://www.codeproject.com/Articles/1047753/Using-Chain-Of-Responsibility-Instead-of-if-else-S][Using Chain Of Responsibility Instead of if/else Statement]] (Fitim Skenderi)

*** Http Request handling - Implementation 1 

The following code simulates a http server that receives a http
requests and sends a response which depends on the http request. This
hypothetical http server has the following routes: 
 
  + '/' or '' for ~http://www.mysite.com/~ (GET http method)

  + '/download' for ~http://www.mysite.com/download~ (GET http method)

  + '/upload' for  ~http://www.mysite.com/upload~ (POST http method)

  + Any other path (aka resource) that does not exist.  For
    ~http://www.mysite.com/do-not-exist~ (GET http method) => Returns
    404 not found http response.


All this code is available at GIST: 

  + GIST: https://gist.github.com/b915ecb586be56802bf221a24936a654

File: _chain-of-responsibility1.cpp_ 

#+BEGIN_SRC cpp 
   #include <iostream>
   #include <string> 

   enum class HttpMethod {
       GET, POST, DELETE, PUT, HEAD, PATCH, UKNOWN_METHOD
   };

   struct HttpRequest {
        std::string  path    = "/";
        HttpMethod   method  = HttpMethod::GET;
        std::string  payload = "";
        // Missing - http headers ---- //

        bool isGET()    const { return method == HttpMethod::GET;    }
        bool isPOST()   const { return method == HttpMethod::POST;   }
        bool isDELETE() const { return method == HttpMethod::DELETE; }
   };

   /** Process server Http GET request and returns a response. */
   void dispatch_request(HttpRequest const& req)
   {
      // Http route:  http://www.mysite.com/
      if(req.isGET() && ( req.path == "/" || req.path == ""))
      {
          std::printf(" => Serve index page, web site homepage \n");

      // Http route:  http://www.mysite.com/download 
      } else if( req.isGET() && req.path == "/download" ) 
      {
           std::printf(" => Serve http://www.mysite.com/dowload page. ");

       // Http route:  http://www.mysite.com/upload 
       } else if( req.isPOST() && req.path == "/upload") 
       {
          std::printf(" => Upload document to web server \n");

        // Http route:  http://www.mysite.com/<error-failure>
        } else {
            std::printf(" => Error: 404 - Not Found resource: '%s' \n", req.path.c_str());
        }
   }


   int main(int argc, char** argv)
   {
       auto req1 = HttpRequest{ "/", HttpMethod::GET, "" };
       dispatch_request(req1);

       auto req2 = HttpRequest{ "/error/resource", HttpMethod::GET, "" };
       dispatch_request(req2); 

       auto req3 = HttpRequest{ "/upload", HttpMethod::POST, "file data" };
       dispatch_request(req3);


       return 0;
   }
#+END_SRC

Compiling: 

#+BEGIN_SRC sh 
  $ g++ chain-of-responsibility1.cpp -o cor1 -std=c++1z -Wall -Wextra

  $ ./cor1 
   => Serve index page, web site homepage 
   => Error: 404 - Not Found resource: '/error/resource' 
   => Upload document to web server   
#+END_SRC

Some drawbacks of the previous code are: adding new http routes or resources,
requires modification of the _dispatch_request()_ function which
violates the _open-close_ principle of object-oriented programming which
states that the code should be open for extension but closed to
modification. 
*** Http Request handling - Implementation 2 (old c++ style) 

This implementation of the chain-of-responsibility design pattern is
similar to the one presented by the GOF book. A handler object checks
whether the request can be handled, otherwise the handler forwards the
request to next handler in the chain. In this particular case, the
request is a _http request_ and the handler is an object that checks if
it can serve the http request by sending a _http response_ back to the
client side (request sender). Otherwise, the current handler forwards the
request to the next http handler in the chain until the last handler
is reached. 

The advantage of this implementation using the chain-of-responsibility
design pattern over the previous one using nested if else is that new
http handlers (http routes or http resources) can be added without
changing the server code. 

Note: This implementation was designed in old C++ style (C++98)
without using smart pointers. 

File: _chain-of-responbility2.cpp_ 

#+BEGIN_SRC cpp 
   #include <iostream>
   #include <string> 

   enum class HttpMethod {
      GET, POST, DELETE, PUT, HEAD
   };

   /** Request object - encapsulates a http request */
   struct HttpRequest {
       std::string  path    = "/";
       HttpMethod   method  = HttpMethod::GET;
       std::string  payload = "";
       // Missing - http headers implementation ---- //

       bool isGET()    const { return method == HttpMethod::GET;    }
       bool isPOST()   const { return method == HttpMethod::POST;   }
       bool isDELETE() const { return method == HttpMethod::DELETE; }
   };

   /** Interface class for generic node of chain of responsibility */
   class IHttpHandler {
   public:
       virtual void handle(const HttpRequest& req) = 0;
       virtual void set_next(IHttpHandler* next) = 0;
       virtual ~IHttpHandler() = default; 
   };

   class BasicHttpHandler: public IHttpHandler {
   protected:
      /** Note: the keyword 'protected' allows derived classes
       *  (aka subclasses) to access the 'm_next' pointer. But 
       *  this keyword forbids any external code from accessing 
       *  the pointer m_next.
       */
      IHttpHandler* m_next = nullptr;

   public:
       BasicHttpHandler(IHttpHandler* next = nullptr)
        : m_next(next){ }


       virtual ~BasicHttpHandler() {
          delete m_next;
          m_next = nullptr;
       }

       /** Set next request in the chain */
       void set_next(IHttpHandler* next)
       {
          m_next = next;
       }

   };

   class HttpGetHandler: public BasicHttpHandler {
      std::string m_path; 
   public:

       HttpGetHandler(std::string path): m_path(path){ }

       void handle(const HttpRequest& req) override
       {
           // Checks whether this handler object can process the request. 
           if(req.method == HttpMethod::GET && m_path == req.path) {
                   std::printf( " [RESPONSE] <HttpGetHandler> Return Html and http response with " 
                                "status code 200 for resource: %s \n", m_path.c_str());
           } else {
                   // If the request cannot be handle, this hanlder forwards the request to 
                   // the next handler in the chain. 
                   m_next->handle(req); 
           }
       }

   };

   class HttpUploadHandler: public BasicHttpHandler {

       void handle(const HttpRequest& req) override
       {
          if( req.method == HttpMethod::POST && req.path == "/upload" ) 
               std::printf( " [RESPONSE] <HttpUploadHandler> Uploading data: '%s' \n"
                            , req.payload.c_str());
          else 
               m_next->handle(req); 
       }

   };

   class HttpError404Handler: public BasicHttpHandler {	
       void handle(const HttpRequest& req) override
       {
           std::printf(" [RESPONSE] <HttpError404Handler>" 
                       " Error 404 Not found resource: %s \n", req.path.c_str());
       }

   };

   struct HttpServer 
   {
       // First handler in the chain 
       IHttpHandler* m_hnd; 

       HttpServer() {
           IHttpHandler* hnd_index =  new HttpGetHandler("/");

           IHttpHandler* hnd_download = new HttpGetHandler("/download");
           hnd_index->set_next(hnd_download);

           IHttpHandler* hnd_upload = new HttpUploadHandler();
           hnd_download->set_next(hnd_upload);

           IHttpHandler* hnd_error = new HttpError404Handler(); 
           hnd_upload->set_next(hnd_error);

           m_hnd = hnd_index;		
       }

       ~HttpServer() {
            delete m_hnd; 
            m_hnd = nullptr;
       }

       void dispatch_request(const HttpRequest& req)
       {
            std::printf("\n [TRACE] Process request => path = %s \n", req.path.c_str());
            m_hnd->handle(req);
            std::printf(" ---------------------------------------\n");
       }
   };


   int main(int argc, char** argv)
   {
       HttpServer server;

       auto req1 = HttpRequest{ "/", HttpMethod::GET, "" };
       server.dispatch_request(req1); 

       auto req2 = HttpRequest{ "/error/resource", HttpMethod::GET, "" };
       server.dispatch_request(req2); 	

       auto req3 = HttpRequest{ "/upload", HttpMethod::POST, "file data" };
       server.dispatch_request(req3); 	


       return 0;
   }

#+END_SRC

Build and running: 

#+BEGIN_SRC sh 
  $ g++  chain-of-responsibility2.cpp -o cor2 -std=c++1z -Wall -Wextra
  
  $ ./cor2 

   [TRACE] Process request => path = / 
   [RESPONSE] <HttpGetHandler> Return Html and http response with status code 200 for resource: / 
   ---------------------------------------

   [TRACE] Process request => path = /error/resource 
   [RESPONSE] <HttpError404Handler> Error 404 Not found resource: /error/resource 
   ---------------------------------------

   [TRACE] Process request => path = /upload 
   [RESPONSE] <HttpUploadHandler> Uploading data: 'file data' 
   ---------------------------------------  
#+END_SRC

*** Http Request handling - Implementation 3 (modern c++ style) 

This implementation is similar to the implementation 2, but the
advantage of the current approach is the usage of smart pointers and
less code repetition. 

File: _chain-of-responsibility3.cpp_ 

#+BEGIN_SRC cpp 
   #include <iostream>
   #include <string> 
   #include <memory>

   enum class HttpMethod {
      GET, POST, DELETE, PUT, HEAD
   };

   /** Request object - encapsulates a http request */
   struct HttpRequest {
       std::string  path    = "/";
       HttpMethod   method  = HttpMethod::GET;
       std::string  payload = "";
       // Missing - http headers implementation ---- //

       bool isGET()    const { return method == HttpMethod::GET;    }
       bool isPOST()   const { return method == HttpMethod::POST;   }
       bool isDELETE() const { return method == HttpMethod::DELETE; }
   };

   /** Interface class for generic node of chain of responsibility */
   class IHttpHandler {
   public:
       /** Predicate that checks whether request can be handled */
       virtual bool can_handle(const HttpRequest& req) = 0;

       /** Process (aka handle) request */
       virtual void do_handle(const HttpRequest& req) = 0;

       virtual void handle(const HttpRequest& req) = 0;

       ~IHttpHandler() = default; 
   };

   class BasicHttpHandler: public IHttpHandler {
         std::shared_ptr<IHttpHandler> m_next;

   public:
       BasicHttpHandler(std::shared_ptr<IHttpHandler> next = nullptr)
          : m_next(next){ }

       virtual ~BasicHttpHandler() = default;

       void set_next(std::shared_ptr<IHttpHandler> next)
       {
           m_next = next;
       }

       /** Note: The keyword 'final' causes compile-time error if this 
        * method is overriden by any class derived from this one. 
        */
       void handle(const HttpRequest& req) final 
       {
           if(this->can_handle(req)) 
             this->do_handle(req);
           else if(m_next != nullptr)
              m_next->handle(req);
           else 
              throw std::runtime_error(" There is no handle for this request.");
       }
   };

   class HttpGetHandler: public BasicHttpHandler {
        std::string m_path; 
   public:
       HttpGetHandler(std::string path): m_path(path){ }

       bool can_handle(const HttpRequest& req) override
       {
            return req.method == HttpMethod::GET && m_path == req.path;
       }

       void do_handle(const HttpRequest& req) override
       {

           std::printf( " [RESPONSE] <HttpGetHandler> Return Html and http response with " 
                                    "status code 200 for resource: %s \n", m_path.c_str());
       }

   };

   class HttpUploadHandler: public BasicHttpHandler {

        bool can_handle(const HttpRequest& req) override
        {
             return req.method == HttpMethod::POST && req.path == "/upload";
        }

        void do_handle(const HttpRequest& req) override
        {
              std::printf( " [RESPONSE] <HttpUploadHandler> Uploading data: '%s' \n"
                          , req.payload.c_str());
        }
   };

   class HttpError404Handler: public BasicHttpHandler {
       bool can_handle(const HttpRequest& req) override
       {
           return true; 
       }

       void do_handle(const HttpRequest& req) override
       {
           std::printf(" [RESPONSE] <HttpError404Handler>" 
                      " Error 404 Not found resource: %s \n", req.path.c_str());
       }

   };

   struct HttpServer 
   {
       std::shared_ptr<IHttpHandler> m_hnd; 

       HttpServer() {
              auto hnd_index = std::make_shared<HttpGetHandler>("/");

              auto hnd_download = std::make_shared<HttpGetHandler>("/download");
              hnd_index->set_next(hnd_download);

              auto hnd_upload = std::make_shared<HttpUploadHandler>();
              hnd_download->set_next(hnd_upload);

              auto hnd_error = std::make_shared<HttpError404Handler>(); 
              hnd_upload->set_next(hnd_error);

              m_hnd = hnd_index;		
      }

       void dispatch_request(const HttpRequest& req)
       {
            std::printf("\n [TRACE] Process request => path = %s \n", req.path.c_str());
            m_hnd->handle(req);
            std::printf(" ---------------------------------------\n");
       }
   };


   int main(int argc, char** argv)
   {
        HttpServer server;

        auto req1 = HttpRequest{ "/", HttpMethod::GET, "" };
        server.dispatch_request(req1); 

        auto req2 = HttpRequest{ "/error/resource", HttpMethod::GET, "" };
        server.dispatch_request(req2); 	

        auto req3 = HttpRequest{ "/upload", HttpMethod::POST, "file data" };
        server.dispatch_request(req3); 	


        return 0;
   }

#+END_SRC

Compiling and running: 

#+BEGIN_SRC sh 
   $ g++  chain-of-responsibility3.cpp -o cor3 -std=c++1z -Wall -Wextra
 
   $ ./cor3

    [TRACE] Process request => path = / 
    [RESPONSE] <HttpGetHandler> Return Html and http response with status code 200 for resource: / 
    ---------------------------------------

    [TRACE] Process request => path = /error/resource 
    [RESPONSE] <HttpError404Handler> Error 404 Not found resource: /error/resource 
    ---------------------------------------

    [TRACE] Process request => path = /upload 
    [RESPONSE] <HttpUploadHandler> Uploading data: 'file data' 
    ---------------------------------------
#+END_SRC

*** Http Request handling - Implementation 4 (modern c++ style + functional) 

This implementation of chain-of-responsibility design pattern replaces
the linked list of http handlers by an array of handlers. Another
modification is the introduction of the class AdapterHandler which
allows creating http handlers (http routes) using C++ lambdas which
makes possible to create new http handlers without creating new
classes. Thus, the class AdapterHandler makes this code more
functional-programming friendly. 

File: _chain-of-responsibility4.cpp_. 

#+BEGIN_SRC cpp 
    #include <iostream>
    #include <string>
    #include <vector>  
    #include <memory>

    enum class HttpMethod {
       GET, POST, DELETE, PUT, HEAD
    };

    /** Request object - encapsulates a http request */
    struct HttpRequest {
         std::string  path    = "/";
         HttpMethod   method  = HttpMethod::GET;
         std::string  payload = "";
         // Missing - http headers implementation ---- //

         bool isGET()    const { return method == HttpMethod::GET;    }
         bool isPOST()   const { return method == HttpMethod::POST;   }
         bool isDELETE() const { return method == HttpMethod::DELETE; }
    };

    /** Interface class for generic node of chain of responsibility */
    class IHttpHandler {
    public:
        /** Predicate that checks whether request can be handled */
        virtual bool can_handle(const HttpRequest& req) = 0;

        /** Process (aka handle) http request and returns http response. */
        virtual void handle(const HttpRequest& req) = 0;

        ~IHttpHandler() = default; 
    };

    class HttpGetHandler: public IHttpHandler {
        std::string m_path; 
    public:
        HttpGetHandler(std::string path): m_path(path){ }

        bool can_handle(const HttpRequest& req) override
        {
            return req.method == HttpMethod::GET && m_path == req.path;
        }

        void handle(const HttpRequest& req) override
        {
            std::printf( " [RESPONSE] <HttpGetHandler> Return Html and http response with " 
                         "status code 200 for resource: %s \n", m_path.c_str());
        }

    };

    /* This class allows creating http handlers (transaction handlers)
     * using C++ lambdas. 
     */
    template<typename predicate_t, typename action_t>
    class AdapterHandler: public IHttpHandler 
    {
      predicate_t m_predicate; 
      action_t    m_action;
      public:

      AdapterHandler(predicate_t predicate, action_t action)
        :  m_predicate(predicate), m_action(action) { }

      bool can_handle(const HttpRequest& req) override
      {
          return m_predicate(req);
      }

      void handle(const HttpRequest& req) override
      {
         return m_action(req);
      }

    };


    struct HttpServer 
    {
          std::vector<std::shared_ptr<IHttpHandler>> m_handlers; 

          HttpServer() {
                 addHandler(std::make_shared<HttpGetHandler>("/"));
                 addHandler(std::make_shared<HttpGetHandler>("/download"));

                 addLambdaHandler(
                   [](const HttpRequest& req)
                   { 
                       return req.method == HttpMethod::POST && req.path == "/upload";     
                   }
                  ,[](const HttpRequest& req)
                   { 
                           std::printf( " [RESPONSE] <HttpUploadHandler> Uploading data: '%s' \n"
                                       , req.payload.c_str());        
                    }
                 );

                addLambdaHandler(
                    [](const HttpRequest& req){ return true; }
                   ,[](const HttpRequest& req){ 
                                   std::printf(" [RESPONSE] <HttpError404Handler>" 
                                               " Error 404 Not found resource: %s \n", req.path.c_str());
                   }
                );
        }

        void addHandler(std::shared_ptr<IHttpHandler> hnd)
        {
            m_handlers.push_back(hnd);
        }

       template<typename predicate_t, typename action_t>
       void addLambdaHandler(predicate_t pred, action_t action)
       {
         using T = AdapterHandler<predicate_t, action_t>;
         auto hnd = std::make_shared<T>(pred, action);
         m_handlers.push_back( hnd );
       }

       void dispatch_request(const HttpRequest& req)
       {
          std::printf("\n [TRACE] Process request => path = %s \n", req.path.c_str());
          for(const auto& hnd: m_handlers) 
            if(hnd->can_handle(req)) {
                hnd->handle(req); 
                return;
            }

         std::printf(" ---------------------------------------\n");
      }
    };


    int main(int argc, char** argv)
    {
        HttpServer server;

        auto req1 = HttpRequest{ "/", HttpMethod::GET, "" };
        server.dispatch_request(req1); 

        auto req2 = HttpRequest{ "/error/resource", HttpMethod::GET, "" };
        server.dispatch_request(req2); 	

        auto req3 = HttpRequest{ "/upload", HttpMethod::POST, "file data" };
        server.dispatch_request(req3); 	

        return 0;
    }
#+END_SRC 

Build and running: 

#+BEGIN_SRC sh 
   $ g++ chain-of-responsibility4.cpp -o cor4 -std=c++1z -Wall -Wextra

   $ ./cor4

    [TRACE] Process request => path = / 
    [RESPONSE] <HttpGetHandler> Return Html and http response with status code 200 for resource: / 

    [TRACE] Process request => path = /error/resource 
    [RESPONSE] <HttpError404Handler> Error 404 Not found resource: /error/resource 

    [TRACE] Process request => path = /upload 
    [RESPONSE] <HttpUploadHandler> Uploading data: 'file data'
#+END_SRC
** Visitor 
*** Overview 

The visitor design pattern is a behavioral design pattern which allows
to add new operations to a class hierarchy without modifying classes
or adding new methods to derived classes. While the visitor makes
easier to add new operators, it makes harder to add new derived
classes.

Intent: (GOF):

 + "Represent an operation to be performed on the elements of an
    object structure. Visitor lets you define a new operation without 
    changing the classes of the elements on which it operates."

Features: 

 + Define operations to be performed on tree data structures without
   modifying them or adding new virtual methods.
 + Decouple data structure and algorithms.
 + Decouple two class hierarchies.
 + The code to perform the operation is centralized in the visitor
   object. If the operation were implemented as methods, the code
   would be scattered through all derived classes.

Drawbacks: 
 + The class hierarchy must be stable as adding a new derived class
   requires modifying all visitors implementations.

Application Domains: 

 + Process tree-like recursive data structures such as:
   + File systems: directories + files
   + AST - Abstract Syntax Tree
   + XML

 + Process a collection of heterogenous derived classes. 

 + Emulate *double dispatching* (aka dual dispatching or multi-methods)
   which is a feature available at Common Lisp (CLOS) and Perl6.

 + Process/ evaluate or interpret an AST - Abstract Syntax Tree in
   many different ways, for instance, evaluate expression, serialize
   to string, compile, get string representation and so on.

 + Serialization

 + Game colisions

 + Shape intersections 

Variations: 
   + Cyclic Visitor 
   + Acyclic Visitor
   + Decorator
   + Extension Object

Alternatives to Visitor Design Pattern: 

 + If-else statements + RTTI (Runtime Type Identification)

 + *Boost.Variant* or C++17 *std::variant* 

 + Multi methods - not possible in C++.
   + Possible in Common Lisp, Clojure and so on.

 + Pattern Matching + Algebraic Data Types or Classes.
   + Possible in functinal laguages such as F# (F Sharp), Scala,
     Haskell and so on.

Parts:

   + Interface: _Element_ 
     + The element is an element of the class hirarchy which contains
       the method _.accept(Visitor v)_ which takes a visitor as
       argument.
     + Method: _.accept(Visitor v)_ => Takes a visitor (operation) as
       argument. 

   + Interface: _Visitor_ - 
     + Perform the operations the class hierarchy. Every operation is
       an implementation of the visitor interface.
     + Methods: The visitor interface requires a method visit for
       derived class of the interface Element. Note: Element1,
       Element2 and Element3 are derived classes of interface Element. 
       + _.visit(Element1 e)_  => Specific version of the operation for class Element1.
       + _.visit(Element2 e1)_ => Specific version of the operation for Element2.
       + _.visit(Element3 e)_  => ... 

   + ConcreteElement -> Implementation of interface Element.

   + ConcreteVisitor -> Operation for the class hierarchy.

Papers: 

  + *Open Pattern Matching for C++*
    + <http://www.stroustrup.com/OpenPatternMatching.pdf>

  + *Design and evaluation of C++ open multi-methods*
     <https://parasol.tamu.edu/~yuriys/papers/OMM10.pdf>
    + Note: Shows many use cases for double-dispatch and 

  + *XVF: C++ Introspection by Extensible Visitation*
    + <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.578.2090&rep=rep1&type=pdf>

  + *Design Patterns for Dealing with Dual Inheritance Hierarchies in C++*
    + <https://pdfs.semanticscholar.org/f403/361d9ef3dac96463787b852b605a918bc4fe.pdf>

  + *Generic Visitors in C++*
    + <https://www.lrde.epita.fr/dload/20030528-Seminar/tisser_n0503_visitors.pdf>

  + *Acyclic Visitor*
    + <https://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf>

  + *Using Template Metaprogramming to Enhance Reuse in Visitor-based Model Interpreters*
    + <http://www.dre.vanderbilt.edu/~gokhale/WWW/papers/ECBS12_Templates.pdf>

Other implementation examples: 

 + [[https://eli.thegreenplace.net/2016/a-polyglots-guide-to-multiple-dispatch/][A polyglot's guide to multiple dispatch - Eli Bendersky's website]]

 + [[http://www.sourcetricks.com/2011/06/visitor-pattern.html#.W-CKfh6YW00][Visitor Pattern ~ Programming Tutorials by SourceTricks]]

 + [[https://codereview.stackexchange.com/questions/153786/modular-visitor-pattern][c++ - Modular Visitor Pattern - Code Review Stack Exchange]]

 + [[https://www.codeproject.com/Articles/588882/TheplusVisitorplusPatternplusExplained][The Visitor Pattern Explained - CodeProject]]

 + [[https://foonathan.net/blog/2017/12/21/visitors.html][foonathan::blog() - Implementation Challenge: Revisiting the visitor pattern]]

 + [[http://alblue.bandlem.com/2009/07/why-i-don-like-visitor-pattern.html][Why I don't like the visitor pattern - AlBlue’s Blog]]

 + [[https://accu.org/index.php/articles/2021][ACCU - Defining Visitors Inline in Modern C++]]

 + [[http://softwareengisneering.blogspot.com/2009/03/c-visitors-basic-implementation.html][Software EngiSneering: C++ Visitors: Basic Implementation]]

 + [[http://blog.aaronballman.com/2011/11/visitor/][The Amazing Visitor Pattern | Ruminations]]

Visitor with C++17 - std::variant 

 + [[https://www.boost.org/doc/libs/1_68_0/doc/html/variant.html][Chapter 45. Boost.Variant - 1.68.0]] (Boost Variant Documentation)

 + [[https://www.heise.de/developer/artikel/C-17-hat-einen-Visitor-3700274.html][C++17   hat einen Visitor | heise Developer]] (In German)

Generic Visitor 

 + [[https://stackoverflow.com/questions/11796121/implementing-the-visitor-pattern-using-c-templates][Implementing the visitor pattern using C++ Templates - Stack Overflow]]

 + [[https://www.artima.com/cppsource/cooperative_visitor.html][Cooperative Visitor: A Template Technique for Visitor Creation]]

 + [[https://www.etlcpp.com/blog/2017/11/12/templated-implementation-of-the-visitor-pattern/][Templated implementation of the Visitor Pattern – Blog – John  Wellbelove]]

Reflection based visitor: 

 + [[https://www.oodesign.com/visitor-pattern.html][Visitor Pattern | Object Oriented Design]]

*** Example: Basic Cyclic Visitor 

File:
 + [[file:src/design-patterns/visitor1.cpp][file:src/design-patterns/visitor1.cpp]]
Online Compiler: 
 + https://repl.it/repls/LinearVioletredRatio

 + _IVisitor interace_ - The visitor interface encapsulates the
   operation performed on the class hierarchy. It should define a
   specific version operation (method visit) for each derived class.

#+BEGIN_SRC cpp
  // Forward reference
  class Circle;
  class Square;
  class Blob;

  class IVisitor{
  public:
      virtual ~IVisitor() = default;
      virtual void visit(Circle& sh) = 0;
      virtual void visit(Square& sh) = 0;
      virtual void visit(Blob& sh) = 0;
  };
#+END_SRC

Class hierarchy: 

 + Interface IShape.
 
#+BEGIN_SRC cpp 
  // Shape interface - The base class must define the method accept
  class IShape{
  public:
      virtual ~IShape() = default;	
      virtual void accept(IVisitor& v) = 0;
  };
#+END_SRC

 + Implementations of the interface class IShape. 

#+BEGIN_SRC cpp 
  class Circle: public IShape{
  public:
       double radius;
       Circle(double radius): radius(radius) { }
       void accept(IVisitor& v) override {
               v.visit(*this);
       }
  };

  class Square: public IShape{
  public:
      double side;
      Square(double side): side(side) { }
      void accept(IVisitor& v) override {
          v.visit(*this);
      }
  };

  class Blob: public IShape{
  public:
      Blob(){}
      void accept(IVisitor& v) override {
          v.visit(*this);
      }
  };
#+END_SRC
 
 + PrintNameVisitor - Visitor Interface Implementation - This visitor
   encapsulates an operation which prints the name of each object in
   the class hierarchy.

#+BEGIN_SRC cpp 
  // Operation which prints name of the class hierarchy
  class PrintNameVisitor: public IVisitor{
  public:
      void visit(Circle& sh) override
      {
        std::cout << " => Shape is a circle of radius = "
                  << sh.radius
                  << "\n";
      }
      void visit(Square& sh) override
      {
         std::cout << " => Shape is a square of side = "
                   << sh.side
                   << "\n";		
      }
      void visit(Blob& ) override
      {
         std::cout << " => Shape is a blob with an undefined shape"
                   << "\n";
      }
  };
#+END_SRC
 

 + ComputeAreaVisitor - This stateful visitor encapsulate an operation
   which computes the area of each element.

#+BEGIN_SRC cpp 
  class ComputeAreaVisitor: public IVisitor{
  private:
      double _area = 0.0;
  public:
      ComputeAreaVisitor() = default;
      double getArea(){
        return _area;
      }
      void visit(Circle& sh) override
      {
         // CircleArea =  PI * radius^2
         _area = 3.1415 * sh.radius * sh.radius;
      }
      void visit(Square& sh) override
      {
         _area = sh.side * sh.side;
      }
      void visit(Blob& ) override
      {
         _area = 100.0;
      }
  };
#+END_SRC

 + FunctionAdapater - Turns lambda function into a visitor object
   reducing the code boilerplate.

#+BEGIN_SRC cpp 
  // Lambda function are used for adding new behavior to the object.
  template<class Result>
  class FunctionAdapter: public IVisitor{
      template<typename T> using Func = std::function<Result (T& sh)>;
      Result       _res;
      Func<Circle> _fn_circle;
      Func<Square> _fn_square;
      Func<Blob>   _fn_blob;
  public:
      Result get(){
              return _res;
      }
      FunctionAdapter(Func<Circle> fnCircle, Func<Square> fnSquare, Func<Blob> fnBlob)
         : _res{}
         , _fn_circle{fnCircle}
         , _fn_square{fnSquare}
         , _fn_blob{fnBlob}
      {		
      }		
      void visit(Circle& sh) override { _res = _fn_circle(sh); }
      void visit(Square& sh) override { _res = _fn_square(sh);}
      void visit(Blob& sh)   override { _res = _fn_blob(sh); }
  };
#+END_SRC


 + Compiling and Running:

#+BEGIN_SRC sh 
  $ clang++ visitor1.cpp -o visitor1.bin -g -std=c++14 -Wall -Wextra && ./visitor1.bin
#+END_SRC

 + Experiment 1: 

#+BEGIN_SRC cpp 
  // Sample shapes 
  auto s1 = Circle(3.0);
  auto s2 = Square(4.0);
  auto s3 = Blob();

  std::cout << "===> Experiment 1: PrintNameVisitor " << "\n";
  auto visitor1 = PrintNameVisitor();
  s1.accept(visitor1);
  s2.accept(visitor1);
  s3.accept(visitor1);	
#+END_SRC

Output: 

#+BEGIN_SRC txt 
  ===> Experiment 1: PrintNameVisitor 
   => Shape is a circle of radius = 3
   => Shape is a square of side = 4
   => Shape is a blob with an undefined shape

#+END_SRC

 + Experiment 2: 

#+BEGIN_SRC cpp 
    std::cout << "===> Experiment 2: ComputeAreaVisitor " << "\n";
    auto visitor2 = ComputeAreaVisitor();
    s1.accept(visitor2);
    std::cout << "Area of shape 1 = " << visitor2.getArea() << "\n";
    s2.accept(visitor2);
    std::cout << "Area of shape 2 = " << visitor2.getArea() << "\n";
    s3.accept(visitor2);
    std::cout << "Area of shape 3 = " << visitor2.getArea() << "\n";
#+END_SRC

Output: 

#+BEGIN_SRC txt 
  ===> Experiment 2: ComputeAreaVisitor 
  Area of shape 1 = 28.2735
  Area of shape 2 = 16
  Area of shape 3 = 100
#+END_SRC

 + Experiment 3:

#+BEGIN_SRC cpp 
  auto visitor3 = FunctionAdapter<std::string>{
      [](Circle& ){ return "circle"; },
      [](Square& ){ return "square"; },
      [](Blob&   ){ return "blob";   },
   };
  s1.accept(visitor3);
  std::cout << "Type of shape 1 = " << visitor3.get() << "\n";
  s2.accept(visitor3);
  std::cout << "Type of shape 2 = " << visitor3.get() << "\n";
  s3.accept(visitor3);
  std::cout << "Type of shape 3 = " << visitor3.get() << "\n";
#+END_SRC

Output: 

#+BEGIN_SRC txt 
  ===> Experiment 3: FunctionAdapter 
  Type of shape 1 = circle
  Type of shape 2 = square
  Type of shape 3 = blob
#+END_SRC

 + Experiment 4: 

#+BEGIN_SRC cpp 
    std::cout << "===> Experiment 4: FunctionAdapter " << "\n";
    // Creates operation to compute shape perimiter
    auto visitor4 = FunctionAdapter<double>{
            [](Circle& s){ return 2 * 3.1415 * s.radius * s.radius ; },
            [](Square& s){ return 4.0 * s.side; },
            [](Blob&    ){ return -100.0;   },
     };	
    s1.accept(visitor4);
    std::cout << "Perimeter of shape 1 = " << visitor4.get() << "\n";
    s2.accept(visitor4);
    std::cout << "Perimeter of shape 2 = " << visitor4.get() << "\n";
    s3.accept(visitor4);
    std::cout << "Perimeter of shape 3 = " << visitor4.get() << "\n";
#+END_SRC

Output: 

#+BEGIN_SRC txt 
  ===> Experiment 4: FunctionAdapter 
  Perimeter of shape 1 = 56.547
  Perimeter of shape 2 = 16
  Perimeter of shape 3 = -100
#+END_SRC

*** Example: Generic Acyclic Visitor 

File:
 + [[file:src/design-patterns/visitor2.cpp][file:src/design-patterns/visitor2.cpp]]

Online Compiler: 
 + https://rextester.com/TXVI24042

Description: Simple generic acyclic implementation of visitor pattern
in C++11. Note: acyclic means that it doesn't have cyclic
dependencies. 

Template class visitable used the CRTP (Curious Recurring Template
Pattern) for making derived classes visitable without virtual
methods. 


Shape interface class: 

#+BEGIN_SRC cpp 
  // Shape interface - The base class must define the method accept
  class IShape{
  public:
      virtual ~IShape() = default;
  };
#+END_SRC

Visitable CRTP Template class 

#+BEGIN_SRC cpp 
  template<typename Implementation>
  class VisitableShape: public IShape{
  public:
      /** Accept any visitor class which implements
        ,* the method:
        ,* void Visitor::visit(Implementation& impl);
        ,*********************************************/
        template<typename Visitor>
        void accept(Visitor&& v) {
           v.visit(static_cast<Implementation&>(*this));
        }
  };

#+END_SRC

Visitable class hierarchy: 

#+BEGIN_SRC cpp 
  class Circle: public VisitableShape<Circle> {
  public:
      double radius;
      Circle(double radius): radius(radius) { }
  };

  class Square: public VisitableShape<Square> {
  public:
      double side;
      Square(double side): side(side) { }
  };

  class Blob: public VisitableShape<Blob> {
  public:
      Blob(){}
  };
#+END_SRC


The following template class turns a list of lambda function
parameters into a visitor object. 

#+BEGIN_SRC cpp 
  template<class Result>
  class FunctionAdapter{	
      // Lambda function are used for adding new behavior to the object.
       template<typename T> using Func = std::function<Result (T& sh)>;
       Result       _res;
       Func<Circle> _fn_circle;
       Func<Square> _fn_square;
       Func<Blob>   _fn_blob;
  public:
       Result get(){ return _res; }
       FunctionAdapter(Func<Circle> fnCircle, Func<Square> fnSquare, Func<Blob> fnBlob)
               : _res{}
               , _fn_circle{fnCircle}
               , _fn_square{fnSquare}
               , _fn_blob{fnBlob}
       {
       }
       void visit(Circle& sh)  { _res = _fn_circle(sh); }
       void visit(Square& sh)  { _res = _fn_square(sh);}
       void visit(Blob& sh)    { _res = _fn_blob(sh); }

       template<class Visitable>
       Result operator()(Visitable& visitable){
               this->visit(visitable);
               return this->get();
       }
  };
#+END_SRC

Some visitors implementation: 

#+BEGIN_SRC cpp 
  auto visitorGetName = FunctionAdapter<std::string>{
       [](Circle& ){ return "circle"; },
       [](Square& ){ return "square"; },
       [](Blob&   ){ return "blob";   },
  };

  // Creates operation to compute shape perimeter
  auto visitorGetArea = FunctionAdapter<double>{
       [](Circle& s){ return 2 * 3.1415 * s.radius * s.radius ; },
       [](Square& s){ return 4.0 * s.side; },
       [](Blob&    ){ return -100.0;   },
  };
#+END_SRC

Running in REPL: 

#+BEGIN_SRC cpp 
  >> .L visitor2.cpp

  >> auto s1 = Circle(3.0);
  >> auto s2 = Square(4.0);
  >> auto s3 = Blob();

  >> s1.accept(visitorGetName)
  >> visitorGetName.get()
  "circle"

  >> s2.accept(visitorGetName)
  >> visitorGetName.get()
  "square"

  >> visitorGetName(s1)
  "circle"

  >> visitorGetName(s2)
  "square"

  >> visitorGetArea(s1)
  (double) 56.547000

  >> s1.accept(visitorGetArea)
  >> visitorGetArea.get()
  (double) 56.547000

  >> visitorGetArea(s2)
  (double) 16.000000

  >> s2.accept(visitorGetArea)
  >> visitorGetArea.get()
  (double) 16.000000

  >> visitorGetArea(s2)
  (double) 16.000000

  >> visitorGetArea(s3)
  (double) -100.00000
  >> 
#+END_SRC
*** Example: Visitor implemented with C++17 std::variant 

The type std::variant and the function std::visit from C++17 standard
can simplify the implementation of visitor design pattern decreasing
the amount of boilerplate code and the coupling between classes. In
fact, by using std::visit, no class modification is required to
implement this pattern.

 + Note: If the current compiler doesn't support C++17 ISO Standard, a
   workaround is to use [[https://www.boost.org/doc/libs/1_68_0/doc/html/variant.html][Boost.Variant]] library, which is the
   predecessor of C++17's std::variant.

File:
 + [[file:src/design-patterns/visitor1-cpp17.cpp][file:src/design-patterns/visitor1-cpp17.cpp]]

Online Compiler:
 + [[https://coliru.stacked-crooked.com/a/7130e9b6494370d5][visitor1-cpp17.cpp]] 

Headers used: 

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <cstdio>
  #include <string>
  #include <memory>
  #include <functional>
  #include<type_traits>
  // C++17 Variant std::variant and std::visit 
  #include <variant> 
#+END_SRC

Classes: 

#+BEGIN_SRC cpp 
  class Circle{
  public:
      double radius;
      Circle(double radius): radius(radius) { }
  };

  class Square{
  public:
      double side;
      Square(double side): side(side) { }
  };

  class Blob{
  public:
      Blob(){}
  };
#+END_SRC

Simple visitor: 
 + Implements operation which prints the description of an element in
   the class "hierarchy".

#+BEGIN_SRC cpp 
  struct PrintNameVisitor{
      void operator()(const Circle& sh){
           std::cout << " SHAPE = Circle of radius " << sh.radius << std::endl;
      }
      void operator()(const Square& sh){
           std::cout << " SHAPE = Square of radius " << sh.side << std::endl;
      }
      void operator()(const Blob&){
           std::cout << " SHAPE = Blob - no one knows how it looks like. " << std::endl;
      }	
  };
#+END_SRC

Generic Visitor: 
 + Turns 3 lambda functions ,which processes each element, into a
   visitor object. 

#+BEGIN_SRC cpp 
  /** Visitor which adpts a function */
  template<typename Result>
  class FunctionVisitor{
  private:	
       template<typename Input> using FN = std::function<Result (const Input&)>;
       FN<Circle> fn_circle;
       FN<Square> fn_square;
       FN<Blob>   fn_blob;
  public:
      FunctionVisitor(FN<Circle> fnCircle, FN<Square> fnSquare, FN<Blob> fnBlob)
       : fn_circle(fnCircle)
        ,fn_square(fnSquare)
        ,fn_blob(fnBlob){ }
      //Result get() const { return result; }
      Result operator()(const Circle& sh){ return fn_circle(sh); }
      Result operator()(const Square& sh){ return fn_square(sh); }
      Result operator()(const Blob& sh){  return fn_blob(sh);   }
  };
#+END_SRC

 + Higher order function makeVisitor, turn 3 lambda functions into a
   single visitor lambda function. 

#+BEGIN_SRC cpp 
  template<typename Input, typename Result>
  using FnVisit = std::function<Result (const Input&)>;

  /** Make a visitor using a functional-programming way 
   ,* Visitor with lambdas look like "pattern matching"  
   ,* from functional languages.
   ,*/
  template<typename Result = void>
  auto makeVisitor(FnVisit<Circle, Result> fnCircle,
                   FnVisit<Square, Result> fnSquare,
                   FnVisit<Blob, Result>   fnBlob ){
          return [=](auto&& a){
                     using C = std::decay_t<decltype(a)>;
                     if constexpr(std::is_same_v<C, Circle>){               
                          return fnCircle(a);
                     }
                     if constexpr(std::is_same_v<C, Square>){
                          return fnSquare(a);
                     }
                     if constexpr(std::is_same_v<C, Blob>){               
                         return fnBlob(a);
                     }
                     std::cerr << "WARNING - Not returned valid result";
                     return Result{};
               };
  } //-- EoF makeVisitor ----// 
#+END_SRC

Variant type Shape: 
 + An instance of this type can be a Circle, Square or Blob.

#+BEGIN_SRC cpp 
   using Shape = std::variant<Circle, Square, Blob>;	
#+END_SRC

Sample shapes: 

#+BEGIN_SRC cpp 
  // Sample shapes
  Shape s1 = Circle(3.0);
  Shape s2 = Square(4.0);
  Shape s3 = Blob();
#+END_SRC


 + *Experiment Code 1*

#+BEGIN_SRC cpp 
   std::puts("\n === EXPERIMENT 1 =================");
   std::visit(printVisitor, s1);
   std::visit(printVisitor, s2);
   std::visit(printVisitor, s3);
#+END_SRC

Output: 

#+BEGIN_SRC text 
   === EXPERIMENT 1 =================
   SHAPE = Circle of radius 3
   SHAPE = Square of radius 4
   SHAPE = Blob - no one knows how it looks like. 
#+END_SRC

 + *Experiment Code 2*

#+BEGIN_SRC cpp 
    std::puts("\n === EXPERIMENT 2 =================");
    auto visitorGetName = FunctionVisitor<std::string>{
        [](const Circle& ) { return "circle"; },
        [](const Square& ) { return "square"; },
        [](const  Blob&  ) { return "blob";   }
    };

    std::cout << "Type of shape 1 = " << std::visit(visitorGetName, s1) << "\n";
    std::cout << "Type of shape 2 = " << std::visit(visitorGetName, s2) << "\n";
    std::cout << "Type of shape 3 = " << std::visit(visitorGetName, s3) << "\n";
#+END_SRC

Output: 

#+BEGIN_SRC text 
   === EXPERIMENT 2 =================
  Type of shape 1 = circle
  Type of shape 2 = square
  Type of shape 3 = blob
#+END_SRC

 + *Experiment Code 3*

#+BEGIN_SRC cpp 
   std::puts("\n === EXPERIMENT 3 =================");

   // Creates operation to compute shape perimeter
   auto visitorGetArea = FunctionVisitor<double>{
       [](const Circle& s){ return 3.1415 * s.radius * s.radius ; },
       [](const Square& s){ return s.side * s.side; },
       [](const Blob&    ){ return 0.0 / 0.0; /* NAN Not a number */   },
   };

   std::cout << "Area of shape 1 = " << std::visit(visitorGetArea, s1) << "\n";
   std::cout << "Area of shape 2 = " << std::visit(visitorGetArea, s2) << "\n";
   std::cout << "Area of shape 3 = " << std::visit(visitorGetArea, s3) << "\n";
#+END_SRC

Output: 

#+BEGIN_SRC text 
   === EXPERIMENT 3 =================
  Area of shape 1 = 28.2735
  Area of shape 2 = 16
  Area of shape 3 = nan
#+END_SRC

 + *Experiment Code 4*

#+BEGIN_SRC cpp 
    std::puts("\n === EXPERIMENT 4 =================");

    auto fnVisitorArea = makeVisitor<double>(
        [](const Circle& s){ return 3.1415 * s.radius * s.radius ; }
       ,[](const Square& s){ return s.side * s.side; }
       ,[](const Blob&    ){ return 0.0 / 0.0; /* NAN Not a number */   }
     );

    std::cout << "Area of shape 1 = " << std::visit(fnVisitorArea, s1) << "\n";
    std::cout << "Area of shape 2 = " << std::visit(fnVisitorArea, s2) << "\n";
    std::cout << "Area of shape 3 = " << std::visit(fnVisitorArea, s3) << "\n";
#+END_SRC

Output:

#+BEGIN_SRC text 
   === EXPERIMENT 4 =================
  Area of shape 1 = 28.2735
  Area of shape 2 = 16
  Area of shape 3 = nan
#+END_SRC
* C++ Specific Design Pattern and Idioms
** Erase-Remove Idiom 

The algorithms [[http://www.cplusplus.com/reference/algorithm/remove/][std::remove]] and [[http://www.cplusplus.com/reference/algorithm/remove_if/][std::remove_if]] don't remove anythign
from a container, they just move the elements supposed to be removed
to the end of the container. The erase/remove idiom is a just a simple
technique for really removing the elements from the container.

Example: 

 + The following session in CERN's ROOT REPL shows that std::remove
   does not remove elements of deque zs equal to 1. In order to
   really remove them, it is necessary to use COTAINER.erase method. 

#+BEGIN_SRC cpp 
        // =======>>> BEFORE <<<============//

  >> auto zs = std::deque<int> {1, 10, 1, 2, 2, 5, 10, 1, 1, 1, 5, 2};
  >> zs
  { 1, 10, 1, 2, 2, 5, 10, 1, 1, 1, 5, 2 }

        // =======>>> std::remove <<<============//

  // Remove all elements equal to 1 
  >> auto it = std::remove(zs.begin(), zs.end(), 1);

  // Elements are not removed 
  >> zs
  { 10, 2, 2, 5, 10, 5, 2, 1, 1, 1, 5, 2 }

  // Iterator 
  >> it
  (std::_Deque_iterator<int, int &, int *> &) @0x7f1eb9a99060

  // Now elements are removed. 
  >> zs.erase(it, zs.end())
  (std::deque<int, std::allocator<int> >::iterator) @0x3b50df0

  // ==========>>> AFETER <<<===================
  >> zs
  (std::deque<int, std::allocator<int> > &) { 10, 2, 2, 5, 10, 5, 2 }
#+END_SRC

For short 

 + Note: It not only works for deque, it works for all STL iterators. 

#+BEGIN_SRC cpp 
  >>  auto elems = std::deque<int> {1, 10, 1, 2, 2, 1, 1, 5, 10, 1, 1, 1, 5, 2};
   
  // Before removing 
  >> elems
  { 1, 10, 1, 2, 2, 1, 1, 5, 10, 1, 1, 1, 5, 2 }
  >> 

  // Really remove all elements equal to 1. 
  >> elems.erase(std::remove(elems.begin(), elems.end(), 1), elems.end())
  (std::deque<int, std::allocator<int> >::iterator) @0x3bc3e80

  // After removing 
  >> elems
  { 10, 2, 2, 5, 10, 5, 2 }
  >> 
#+END_SRC

The boilerplate code can be reduced by defining generic functions 
(templated functions) which operates on any container, namely
_erase_equal_ and _erase_if_. 

 *Function: erase_equal*

Remove all elements equal to some value. 

#+BEGIN_SRC cpp 
  // Erase all elements of a container equal to a given value 
  template< class T
           ,template<class>        class Allocator
           ,template<class, class> class Container
           >
  void erase_equal(Container<T, Allocator<T>>& container, const T& value){
       auto it = std::remove(container.begin(), container.end(), value);
       container.erase(it, container.end());
  }
#+END_SRC

Usage example for deque: 

#+BEGIN_SRC cpp 
  >> std::deque<int> elems1 = {1, 10, 1, 2, 2, 1, 1, 5, 10, 1, 1, 1, 5, 2};

  >> elems1
  { 1, 10, 1, 2, 2, 1, 1, 5, 10, 1, 1, 1, 5, 2 }

  >> erase_equal(elems1, 1)
  >> elems1
  (std::deque<int> &) { 10, 2, 2, 5, 10, 5, 2 }

  >> erase_equal(elems1, 10)
  >> elems1
  { 2, 2, 5, 5, 2 }
  >> 
#+END_SRC

Usage example for vector: 

#+BEGIN_SRC cpp 
  //========= VECTOR ======================
   auto words = std::vector<std::string>{ "c++", "breakthrough", "c++", "RUST", "asm", "ARM", 
      "RISC", "CISC", "asm", "forth", "forth", "c++", "low level", "RUST", "asm"
    };

   >> words
   { "c++", "breakthrough", "c++", "RUST", "asm", "ARM", "RISC", "CISC", "asm", 
     "forth", "forth", "c++", "low level", "RUST", "asm" }
   >> 

  // Error: Cannot infer type of of parameter T
  //-------------------------------------------
  >> erase_equal(words, "c++")
  ROOT_prompt_6:1:1: error: no matching function for call to 'erase_equal'
  erase_equal(words, "c++")
  ^~~~~~~~~~~
  input_line_15:6:8: note: candidate template ignored: deduced conflicting types for parameter 'T'
        ('std::__cxx11::basic_string<char>' vs. 'char [4]')
    void erase_equal(Container<T, Allocator<T>>& container, const T& value){

  // Now it works 
  >> erase_equal(words, std::string("c++"))

  // Other possibility 
  >> erase_equal<std::string>(words, "c++")

  >> words
  { "breakthrough", "RUST", "asm", "ARM", "RISC", "CISC", "asm", "forth", "forth", "low level", "RUST", "asm" }
  >> 

  >> erase_equal<std::string>(words, "asm")
  >> words
  { "breakthrough", "RUST", "ARM", "RISC", "CISC", "forth", "forth", "low level", "RUST" }
  >> 
#+END_SRC

 *Function: erase_if*

Remove all elements matching a predicate function: 

#+BEGIN_SRC cpp 
  // Erase all elements of a container equal to a given value 
  template< class T
           ,class Predicate  /* Some predicate function */
           ,template<class>        class Allocator
           ,template<class, class> class Container
           >
  void erase_if(Container<T, Allocator<T>>& container, Predicate predicate){
       auto it = std::remove_if(container.begin(), container.end(), predicate);
       container.erase(it, container.end());
  }
#+END_SRC


#+BEGIN_SRC cpp 
  >> std::deque<int> adeque = {6, 10, 6, 7, 5, 1, 4, 2, 1, 6, 10, 2, 9, 8, 1, 1, 5, 2};
  >> adeque
  { 6, 10, 6, 7, 5, 1, 4, 2, 1, 6, 10, 2, 9, 8, 1, 1, 5, 2 }
  >> 

  // Remove all elemets less than 5
  >> erase_if(adeque, [](int x){ return x < 5; })
  >> adeque
  (std::deque<int> &) { 6, 10, 6, 7, 5, 6, 10, 9, 8, 5 }
  >> 
#+END_SRC


References: 

 + [[https://www.codeproject.com/Articles/1227392/Erase-remove-Idiom-Revisited][Erase-remove Idiom Revisited - CodeProject]]
 + [[https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove][More C++ Idioms/Erase-Remove - Wikibooks, open books for an open world]]
 + [[https://www.geeksforgeeks.org/difference-between-stdremove-and-vectorerase-for-vectors/][Difference between std::remove and vector::erase for vectors - GeeksforGeeks]]

Further Reading:

 + [[https://www.fluentcpp.com/2018/09/18/how-to-remove-pointers-from-a-vector-in-cpp/][How to Remove Pointers from a Vector in C++ - Fluent C++]]
 + [[http://amse.ru/courses/cpp2/2011_03_14.html][C++. STL algorithms]] (in Russian)
** Virtual Friend Function Idiom 

A C++ friend function is a free function with access to a class
protected and private member variables and member functions. Unlike
virtual member functions (aka virtual methods), which are resolved at
runtime and can be overridden by each derived class, friend functions
cannot be declared as virtual and be overridden by each derived class
for customizing the function behavior for each different
implementation.  The virtual friend function idiom emulates the
virtual member function by forwarding the method call to a member
function.

This technique can be used for implementing stream insertion (<<) and
extraction operator for reading and writing derived classes from
streams. 

In the following code, the idiom is used for printing a class
hierarchy and customizing the behavior of the stream insertion
operator (<<), which is a friend function, for each derived class. 

File: _virtual-friend-function.cpp_ 

#+BEGIN_SRC cpp 
  #include <iostream> 
  #include <string> 

  // Shape interface 
  class IShape
  {
  // Protected =>> Means that only derived classes 
  // can access this function.     
  protected:
         // Print object to the stream object 
         virtual void print_me(std::ostream& os) const = 0;
  public:
      virtual void draw() const = 0;
      virtual ~IShape() = default;
    
      // Friend function => (Just a free function)
      friend std::ostream& operator<<(std::ostream& os, const IShape& shape)
      {
           shape.print_me(os);
           return os;
      }
  };

  class Circle: public IShape
  {
  private:
      double radius = 0.0;
    
      void print_me(std::ostream& os) const override 
      {
          os << " IShape(Cicle) with radius = " << radius;
      }
    
  public:  
      Circle(double radius): radius(radius){ }
    
      void draw() const override {
          // Implementation here ....
      }
  };


  class Square: public IShape
  {
  private:
      double length = 0.0;
    
      void print_me(std::ostream& os) const override 
      {
          os << " IShape(Square) with length = " << length;
      }
    
  public:  
      Square(double length): length(length){ }
    
      void draw() const override {
          // Implementation here ....
      }
  };


  int main(int argc, char** argv)
  {
      Square shapeA{5};
      Circle shapeB{10}; 
    
      /* 
       ,*  virtual-friend-function.cpp: In function ‘int main(int, char**)’:
       ,* virtual-friend-function.cpp:67:30: error: 
       ,*    ‘virtual void Square::print_me(std::ostream&) const’ is private *      within this context
       |     shapeA.print_me(std::cout);
       ,*/
          // shapeA.print_me(std::cout);  // Compile-time error.
    
      std::cout << " [INFO] shape A = " << shapeA << '\n';
      std::cout << " [INFO] shape B = " << shapeB << '\n';
    
      return 0;
  }
#+END_SRC


Building: 

#+BEGIN_SRC sh 
  $ g++ virtual-friend-function.cpp -o out.bin -std=c++1z -Wall -Wextra -g
#+END_SRC

Running: 

#+BEGIN_SRC sh 
  $ ./out.bin
   [INFO] shape A =  IShape(Square) with length = 5
   [INFO] shape B =  IShape(Cicle) with radius = 10
#+END_SRC

** RAII idiom - Resource Aquisition Is Initialization
*** Overview 

Comes from book: _C++ Programming with Design Patterns Revealed_ 

RAII is a design pattern which takes advantage of C++'s deterministic
destructor feature for deallocating resources such as pointers to
objects allocated on the heap memory, database handlers, socket
handlers and etc. The RAAI technique uses an object allocated on the
stack which acquires the resource as a constructor argument and
performs the resource cleanup in the destructor method which is called
when when the wrapper object goes out scope or an exception happens.

 + Note: This pattern is specific for C++, for Java and Scala use _try_
   _finally_ statements. Python has the _with_ statement and C# has the
   _using_ statement. In addition, this pattern needs the
   *deterministic destructor* feature which is unique to C++.

Alternative or more descriptive names: 

 + CADRE => Constructor Acquires, Destructor Releases
 + SBRM  => Scope-Bound Resource Management. 

Note: It is no longer necessary to design any class for RAII since
C++11 has smart pointers which already implements this
pattern. However, it is important to understand how this idiom works
and the problem that it solves.
 + In C++ >= C++ 11, it is better to use ~unique_ptr~ for handling
   resources as shown at [[https://msdn.microsoft.com/en-us/library/hh438480.aspx][Objects Own Resources (RAII)]] 

RAII is the process of: 
 + Acquiring a resouce and wrapping it as an object's state.
 + Using the resource 
 + Releasing the resource in the object's destructor member function
   which is executed when the object goes out of escope.

Problems solved by this technique.
 + Avoid [[https://en.wikipedia.org/wiki/Memory_leak][memory leak]] 
 + Avoid [[https://en.wikipedia.org/wiki/Resource_leak][resource leak]]
 + Save and restore context. => An object allocated on the stack could
   be used to set the current directory and restore saved directory
   when the destructor is invoked when the object goes out scope. The
   same technique could be used to save and restore std::cout or
   std::cerr flags. 

Known uses: 
 + C++11 _shared_ptr_ (Smart pointer)
 + C++11 _unique_ptr_ (Smart pointer)
 + Almost all STL containers/collections which manages heap-memory
   behind the scene, namely, std::vector, std::list, std::map, ... and
   so on.

 *Example:* 

Naive code - If an exception happens, the resource will not be
released and the code will be vulnerable to memory leak or resource
leak.

#+BEGIN_SRC cpp 
  Handler* handle  = getDatabaseHandler(); 
  // Throw exception => Resource leak 
  performInvalidOperation(handle);  
  ...
  // Forget to release resource!
  deleteResource(handle); 
#+END_SRC

Or: 

#+BEGIN_SRC cpp 
   Object* heapObject = new Object(param0, param1, ....);
   peformOperation(heapObject); 
   heapObject->method1; 

   // Throw exception!! ==> Memory Leak!

   // If the user forget this statement, 
   // a memory leak will happen. 
   delete heapObject; 
#+END_SRC
 
 *Solution - RAAI idiom*

 - An object is used to control the lifetime of a resource ensuring
   that is released when the object goes out of scope or an exception
   happens. The resource is aquired by the constructor and realeased
   by the destructor.

#+BEGIN_SRC cpp 
  template<class Resource>
  class RaaiHandler {
  public:  
     // Consructor: Acquire resource on the constructor 
     RaaiHandler(Resource* rawHandle_) : (rawHandle_) {};

     // Destructor: Releases resource 
     // The destructor is always called when the object goes out of scope 
     // or an exception happens.
     ~RaiiHandler() {
        delete _handler; 
      }      
  private:
     RaiiHandler* _handler;
  };

  // Object created without new keyword is allocated in the stack, not in the heap.
  RaiiHandler hnd(createNewResource());
  // .. . Peform operation 
  Operation(hnd);
  // Once the escope is gone, the resource is released.
#+END_SRC
*** Example - Heap-allocated memory

 Another more specific RAAI Example: 

 + In this example, the resource acquired in the constructor, a
   heap-allocated array of type T, is released at the destructor when
   a HeapArray object goes out of scope. All STL containers such as
   std::vector, std::map, std::deque and so on uses RAII technique for
   avoiding memory leak by deleting the heap-allocated objects when
   no longer needed. 

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <string>
  #include <ostream>

  template<typename T>
  class HeapArray{
    private:
    size_t m_size;
    T*     m_resource;  
  public:  
    // Resource is acquired at constructor 
    HeapArray(size_t size, T init)
      : m_size(size),
        m_resource(new (std::nothrow) T[size])
    {
      std::cout << " [LOG] Intialize array with size = " << size
                << " and init = " << init << std::endl;
      if(m_resource != nullptr)
        for(size_t i = 0; i < size; i++)
          m_resource[i] = init;
    }
    // Delegated constructor on the right size 
    HeapArray(size_t size): HeapArray(size, T{}){ }
   
    // Resource is released at destructor 
    ~HeapArray()
    {
      std::cout << " [LOG] Destructor -> Delete array" << std::endl;
      // Always safe to delete 
      delete [] m_resource;
      m_resource = nullptr;
    }

    // Forbid copy constructor
    HeapArray(const HeapArray&) = delete;
    // Forbid copy-assignment operator 
    HeapArray& operator= (const HeapArray&) = delete;
    // Move constructor 
    HeapArray(HeapArray&& rhs)
    {
      std::cout << " [LOG] Move constructor " << std::endl;
      std::swap(this->m_resource, rhs.m_resource);
    }
    // Move assignment operator 
    HeapArray& operator= (HeapArray&& rhs)
    {
      std::cout << " [LOG] Move assignment operator " << std::endl;
      std::swap(this->m_resource, rhs.m_resource);
      return *this;
    }
    size_t size() const {
      return m_size;
    }    
    T& operator[](size_t n){
      return m_resource[n];
    }
  
    friend auto operator<< (std::ostream& os, const HeapArray<T>& rhs) -> std::ostream&
    {
     os << "[" << rhs.m_size << "]( ";
     for(size_t i = 0; i < rhs.m_size; i++)
       os << rhs.m_resource[i] << " ";  
     os << ")";
     return os;
    }  
  };

#+END_SRC

Usage example: 

#+BEGIN_SRC cpp 
  >> .L raai1.cpp

  >> auto vb = HeapArray<double>(4, 3.5);
   [LOG] Intialize array with size = 4 and init = 3.5
  >> std::cout << "vb = " << vb << std::endl;
  vb = [4]( 3.5 3.5 3.5 3.5 )

  >> vb[0] = 10.0;
  >> vb[1] = 20.0;
  >> vb[2] = -10.2;

  >> std::cout << "vb = " << vb << std::endl;
  vb = [4]( 10 20 -10.2 3.5 )
#+END_SRC


 *References*

 + [[https://www.codeproject.com/Articles/580077/ResourceplusAcquisitionplusisplusInitializationplu][Resource Acquisition is Initialization (RAII) - CodeProject]]
 + [[https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii][c++ - What is meant by Resource Acquisition is Initialization (RAII)? - Stack Overflow]]
 + [[https://www.codeproject.com/Articles/122129/RAII-Resource-Acquisition-Is-Initialization-C-Help][RAII (Resource Acquisition Is Initialization) C# Helper Classes - CodeProject]]
 + [[http://jrdodds.blogs.com/blog/2004/08/raii_in_c.html/][RAII in C++ (constructive nonconformist)]]
  
*** Example - Managing Resource with custom wrapper

Resource is everything that needs to be released or cleaned up after
no longer needed. Some examples of resource are file descriptors,
handlers, socket handlers, data base handlers and heap allocated
memory. The RAAI technique can help managing resources since it
ensures that a resource cleanup always will happen after the wrapper
object goes out of scope. 

 *Example:*

In the C-file API, the resource is the FILE* file pointer. The API
requies the client code to call fclose after the pointer is no longer
needed. Despite that this case is applied to the C-file API, it can
applied to any other type of resource. 

Note: It is better to use the C++ file API since it is more C++
friendly and already has RAII. The C-file API was used in this section
for simulating a generic resource.

API: 

#+BEGIN_SRC cpp 
   #include <cstdio> // <stdio.h> in C.
   // Open file getting the resource FILE*
   FILE* fopen(const char *pathname, const char *mode);
   // Release resource. 
   int   fclose(FILE* stream);

   int   fputs(const char* s, FILE* stream);
   int   putc(int c, FILE* stream);
#+END_SRC

Solution 1: Use a custom RAAI wrapper object. 

#+BEGIN_SRC cpp 
   #include <iostream>
   #include <cstdio>

   template<class Resource>
   class RAIIWrapper{
      public:
      using Cleanup_fn = std::function<void (Resource*)>;

      // Constructor: Acquire resource 
      // Parameter res      => Wrapped Resource 
      // Parameter cleanup  => Clenup function which releases resources. 
      RAIIWrapper(Resource* res, Cleanup_fn cleanup)
       :m_res(res), m_cleanup(cleanup) { }

      // Forbid copy-constructor 
      RAIIWrapper(const RAIIWrapper& rhs) = delete;
      // Forbid copy-assignment operator 
      RAIIWrapper& operator= (const RAIIWrapper& rhs) = delete;

      // Move constructor => Transfer resource ownership 
      //  from teporary object rhs (R-value) to new object (this).
      RAIIWrapper(RAIIWrapper&& rhs){
        this->m_res = rhs.m_res;
        rhs.m_res = nullptr;
      }
      // Move assignment operator - move resource ownership 
      // from temporary object (rhs) in the right hand-size of (=)
      // to this object. 
      RAIIWrapper& operator= (RAIIWrapper&& rhs){
         std::swap(this->m_res, rhs.m_res);
         return *this;
      }    

      void close(){
        if(m_res != nullptr) m_cleanup(m_res);
        m_res = nullptr;
        std::cerr << "LOG cleanup resource.";
      }
      // Destructor => Release resource 
      ~RAIIWrapper(){
         this->close();
       }
      Resource* get() const { return m_res; }
      // Conversion operator to check whether wrapped pointer is null. 
      operator bool() const {
        return m_res != nullptr;
      }

      private:
      Resource* m_res;
      Cleanup_fn m_cleanup;      
   };
#+END_SRC

Sample client code: 

#+BEGIN_SRC cpp 
  void writeFile(const char* file){
       // The wrapper automatically release the wrapped resource when out of scope
       RAIIWrapper<FILE> fptr(::fopen(file, "w"), &fclose);
       if(!fptr){
          ::fputs(" [ERROR] Failed to create file\n", stderr);
          return;
       }
       ::fputs("Testing line 1\n", fptr.get());
       ::fputs("Testing line 2\n", fptr.get());
       ::fputs("C++17 is AWESOME! AMAZING!\n", fptr.get());
  }
#+END_SRC

Test: 

#+BEGIN_SRC cpp 
  >> writeFile("/tmp/raii-resource.txt")
  LOG cleanup resource.>> 

  >> writeFile("/etc/raii-resource.txt")
   [ERROR] Failed to create file
  LOG cleanup resource.>> 
  >> 
  // Check created file. 
  >> .! cat /tmp/raii-resource.txt
  Testing line 1
  Testing line 2
  C++17 is AWESOME! AMAZING!
  >> 
#+END_SRC

*** Example - Managing Resource with smart pointer 

The smart pointer std::unique_ptr is not only suitable for managing
heap-allocated objects, it is also useful for managing resources.

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <memory>     // Smart pointers 
  #include <functional> // std::function 

  // Used for simulating a generic resource. 
  // FILE*, fopen, fclose .... 
  #include <cstdio> 

  // Type alias for smart pointer with custom deleter 
  template<typename T>
  using Resource = std::unique_ptr<T, std::function<void (T*)>>;

  void writeFile(const char* file)
  {
       // The wrapper automatically release the resource when out of scope
       Resource<FILE> fptr(::fopen(file, "w"),
                           // Custom-deleter function 
                           [](FILE* hnd){
                             std::cerr << " [TRACE] File closed OK." << std::endl;
                             if(hnd != nullptr) ::fclose(hnd);
                           });
       if(!fptr){
          ::fputs(" [ERROR] Failed to create file\n", stderr);
          return;
       }
       ::fputs("Testing line 1\n", fptr.get());
       ::fputs("Testing line 2\n", fptr.get());
       ::fputs("C++17 is AWESOME! AMAZING!\n", fptr.get());
  }

  >> writeFile("/tmp/resource1.txt");
   [TRACE] File closed OK.
 
  >> .! cat /tmp/resource1.txt
  Testing line 1
  Testing line 2
  C++17 is AWESOME! AMAZING!

  >> writeFile("/boot/resource1.txt");
   [ERROR] Failed to create file
  >> 
 
#+END_SRC
** PIMPL idiom - Pointer to Implementation

The PIMPL - Pointer to Implementation idiom, also known as compiler
firewall, is a widely used technique  in C++ for completly hiding class
private members in the public header file. This technique uses an
opaque pointer to an internal non declared class in the current header
file encapsulating all fields of the outer class.

Also known as: 
 + PIMPL - Pointer to Implementation
 + Compiler firewall idiom
 + Cheshire Cat

Motivation and Benefits: 

 + Reduce compilation time as the number of #include headers in the
   class header is not changed.

 + Makes the class data member in the public header really private and
   obfuscated.

 + Changing of private members of the class which are encapsulated in
   the opaque pointer class does not require recompilation of client
   code. This feature is very important for library development as it
   avoid client code recompilation as the public headers are not
   changed.

 + Less likely to breaking binary compatibility - ABI Application
   Binary Interface.

 + Note: Changing class member variables or member functions (methods)
   breaks the ABI and requires the recompilation of client code. The
   pimpl maintains the binary compatibility by not changing class'
   private members.

 + TL;DR
   + PIMPL: Allow changes to implementation without the
     need to recompile client code.

Drawbacks: 

 + More complexity and work for API implementators.
 + Not convenient when there are protected members which needs to be
   accessed by subclasses. 
 + Runtime performance overhead due to the pointer indirection. 

Example: All private members of class CashFlow are conained in the
opaque type Impl which is not defined in the header file.

 - file: _CashFlow.h_  -> Class public interface.

#+BEGIN_SRC cpp 
  #ifndef _CashFlow_H_
  #define _CashFlow_H_

  // C++ 11's smart pointers
  #include <memory>

  class CashFlow{
  private:
      // Forward declaration of incomplete type (Implementation).
      struct Impl;
      // This opaque type encapsulate the outer class' private member 
      // Pointer to implementation (PIMPL)
      std::unique_ptr<Impl> m_pimpl;
      // Explicit Default ctor 
      ~CashFlow = default;
  public:
      // Default ctor 
      CashFlow();
      void show();
      void add(double x);
      int  size();
      // Net Present Value - NPV of cash flow for a given rate of return 
      double npv(double rate); 
      // Compute IRR - Internal rate of return 
      double irr(); 
  };

  #endif // --- EOF ---- // 
#+END_SRC

 - file: _CashFlow.cpp_  -> Class implementation.

#+BEGIN_SRC cpp 
  // C++ 11's smart pointers
  #include <memory>
  #include "CashFlow.h"

  // Struct is just class with all members
  // public by default 
  struct CashFlow::Impl{
      // cash flow vector 
      std::vector<double> m_clf;
      // Default ctor 
      Impl(){}
      // Default dtor 
      ~Impl() = default;  
  };

  // Ctor 
  CashFlow::CashFlow(): m_pimpl(new Impl()) {}

  void CashFlow::add(double x){
      m_pimpl->m_clf.push_back(x);
  }

  double CashFlow::get(int i){
      return m_pimpl->m_clf[i];
  }
     ... ... ... .... 
#+END_SRC  

References and further: 

 + *Pimpl Idiom* - <>
 
 + *Best Friends: C++11 Move Semantics and Pimpl* -
   <https://www.embeddeduse.com/2016/05/30/best-friends-cpp11-move-semantics-and-pimpl/>

 + *Improving C++ Encapsulation with the Pimpl Idiom* -
   <https://visualstudiomagazine.com/articles/2012/11/29/the-pimpl-idiom-in-c-plus-plus.aspx> 

 + *Why every C++ developer should know about the pimpl idiom pattern* -
   <https://tonka2013.wordpress.com/2013/08/31/why-every-c-developer-should-know-about-the-pimpl-idiom-pattern/> 

 + *Passing Containing Parent to pimpl idiom implementation class* -
   http://www.sharprobotica.com/2010/04/passing-containing-parent-to-pimpl-idiom-implementation-class/

 + *Dive in to C++ and survive* -
   <https://www.embedded.com/print/4008235> 
 
 + *Modern and Lucid C++ Advanced for Professional Programmers* -
   <https://wiki.ifs.hsr.ch/CppAdvanced/files/lecture_12_advanced_library_design.pdf> 
** Non-copiable class idiom

Classes where copying doesn't make sense such as classes managing
resources or singletons should have the copy constructor and copy
assignment operator no accessible to any external code. It can be done
by making the both member functions private or by annotating them as
deleted (C++11).

 + Note: resource means anything that needs to be disposed when no
   longer needed such as heap memory, database handlers, socket
   handlers, file descriptors and etc.

 *Prior to C++11*

Notes: 

 + The copy-constructor and copy-assignment operators should be
   declared private, even if they are not declared the copiler will
   generate both by default what can lead to unexpected bugs.

 + If the following class used the default copy constructor and
   copy-assignment operator, the socket handler would be copied, but
   the initial class and the copy would still use the same resource,
   in this case connection. Then, if one of the classes went out of
   scope, the destructor would be invoked disposing the
   resource. Therefore, it would close the connection and make the
   socket unavailable to the remaining class and any attempt to use
   the disposed resource would result in a runtime error hard to
   debug. 

#+BEGIN_SRC cpp 
  //=========>> file: socket.hpp - Header <<===========;
  class SocketWrapper{
  public:
      // Constructor 
      SocketWrapper();
      // Destructor 
      ~SocketWrapper();			
    
      // Move consttructor [OPTIONAL]
      SocketWrapper(SocketWrapper&& rhs);
      // Move-assignment operator  [OPTIONAL]
      SocketWrapper& operator=(SocketWrapper&& rhs);
  private:
      // Copy constructor 
      SocketWrapper(const SocketWrapper&);
      // Copy assignment operator
      SocketWrapper& operator=(const SocketWrapper&);
	
      // Resource - socket file descriptor 
      int m_sockfd;   
  };

  //====>>> file: socket.cpp - Implementation <<<==========
  SocketWrapper::SocketWrapper(){
      m_sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
  }

  SocketWrapper::~SocketWrapper(){
     ::close(m_sockfd);
  }
 
  // Forbidden copy constructor 
  SocketWrapper::SocketWrapper(const SocketWrapper&)
  {	
  }

  // Forbidden copy-assignemnt operator 
  SocketWrapper& operator=(const SocketWrapper&)
  {
  }

  // Move constructor 
  SocketWrapper::SocketWrapper(SocketWrapper&& rhs){
      std::swap(this.m_sockfd, rhs.m_sockfd);
  }

  // Move assignment-operator 
  SocketWrapper& SocketWrapper::operator=(SocketWrapper&& rhs){
      std::swap(this.m_sockfd, rhs.m_sockfd);
      return *this;
  }

#+END_SRC

 *C++ >= C++11* 

 + In C++11, it is just necessary to annotate both copy constructor
   and assignment operator with delete to make them non
   accessible. Any attempt to copy a class with those member functions
   annotated as deleted will result in a compile-time error. 

#+BEGIN_SRC cpp 
  //=========>> file: socket.hpp - Header  <<===========;
  class SocketWrapper{
  public:
      // Constructor
      SocketWrapper();
      // Destructor 
      ~SocketWrapper();

      // Copy constructor 
      SocketWrapper(const SocketWrapper&) = delete;
      // Copy assignment operator
      SocketWrapper& operator=(const SocketWrapper&) = delete;	

      // Move consttructor [OPTIONAL]
      SocketWrapper(SocketWrapper&& rhs);
      // Move-assignment operator  [OPTIONAL]
      SocketWrapper& operator=(SocketWrapper&& rhs);

  private:
      // Resource - socket file descriptor 
      int m_sockfd;   
  };

  //====>>> file: socket.cpp - Implementation <<<==========
  SocketWrapper::SocketWrapper(){
      m_sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
  }
  SocketWrapper::~SocketWrapper(){
     ::close(m_sockfd);
  }
  // Move constructor 
  SocketWrapper::SocketWrapper(SocketWrapper&& rhs){
      std::swap(this.m_sockfd, rhs.m_sockfd);
  }
  // Move assignment-operator 
  SocketWrapper& SocketWrapper::operator=(SocketWrapper&& rhs){
      std::swap(this.m_sockfd, rhs.m_sockfd);
      return *this;
  }
#+END_SRC


  *Non-copiable parent class trick* 

The class could also be made non-copiable using the following trick
used by boost::noncopyable [[https://github.com/inducer/boost-python-ublas-subset/blob/master/boost_subset/boost/noncopyable.hpp][noncopyable]]: 

 + NonCopyable base class: Any class inheriting this class (private
   inheritance) will be non-copiable. 

#+BEGIN_SRC cpp 
  class NonCopyable
  {
  protected:
      NonCopyable()  = default;
      ~NonCopyable() = default;

      // Disable default copy-constructor
      NonCopyable(const NonCopyable&) = delete;
      // Disable default copy assignment operator
      const NonCopyable& operator=(const NonCopyable&) = delete;
  };
#+END_SRC

 + Derived class. (Note: private inheritance). Any attempt to perform
   copy operations with copy constructor or copy assignment operator,
   results in compile-time error.

#+BEGIN_SRC cpp 
  //=========>> file: socket.hpp - Header  <<===========;
  class SocketWrapper: private NonCopyable
  {
  public:
      // Constructor
      SocketWrapper();
      // Destructor 
      ~SocketWrapper();

      // Move consttructor [OPTIONAL]
      SocketWrapper(SocketWrapper&& rhs);
      // Move-assignment operator  [OPTIONAL]
      SocketWrapper& operator=(SocketWrapper&& rhs);

  private:
      // Resource - socket file descriptor 
      int m_sockfd;   
  };
#+END_SRC




** Copy and swap idiom 

The copy-and-swap idiom is a widely used technique for implementing
the _rule-of-three_ by defining the copy-assignment operator with a
custom _swap function_. In C++11, the idiom can also be used for
implementing the rule-of-five by defining the move constructor and
move assignment operator with a swap function.

Notes: 

 + The _copy-assignment operator_ is needed by the _rule-of-three_
   (pre-C++11) which states that a class managing a resouce, which
   implements copy constructor, copy assignment operator and a
   destructor, should all of them.

 + The _move-assignment operator_ is needed by the _rule-of-five_ (C++11)
   which states that a class, which wraps some resource implementing a
   copy constructor, copy assignment operator, move constructor, move
   assignment operator and a destructor, should implement all of them.

 + Note: This idiom is only applicable to _copiable classes_ which
   manages some resource. 

Benefits: 

 + Less code duplication.

 + Just a swap to rule them all for implementing the copy-assignment
   operator, move assignment operator and move constructor in C++11.

The following member functions are necessary to implement this idiom:

 + Copy-constructor
 + Destructor
 + _Swap function_ which can swap the data of two objects of same
   class. This function all member variables of both objects. 
   + DO NOT use std::swap as this function.
   + This functions must be non-throwing. 

 *Example*

The following redundant class String manages a resource, a
heap-allocated array of characters. 

 + File: [[file:src/design-patterns/copy-swap1.cpp][file:src/design-patterns/copy-swap1.cpp]]
 + Gist: [[https://gist.github.com/caiorss/899d8fcb09dd29b920aa0069e5b9b4ab][copy-swap1.cpp]]
 + Online Compiler: https://rextester.com/XWJA10133

#+BEGIN_SRC cpp 
  class String
  {
  public:
      // Default constructor 
      String();
      String(size_t size, char ch);
      String(const char* text);
      // Copy-constructor (rule-of-three and rule-of-five)
      String(const String& rhs);
      // Move-constructor (rule-of-three and rule-of-five)
      String(String&& rhs);
      // Destructor (rule-of-three and rule-of-five)
      ~String();

      // Copy-assignment operator (rule-of-three and rule-of-five)
      String& operator= (const String& rhs);
      // Move-assignment operator (rule-of-five)
      String& operator= (String&& rhs);

      String operator+(const char* text);

      // Swap function (std::swap overload) 
      // needed by the copy-and-swap idiom.
      friend void swap(String& lhs, String& rhs);

      // Make class printable - note this operator is a member
      // function of class ostream, no from this class.
      friend std::ostream& operator<<(std::ostream& os, const String& rhs);

      size_t      size();
      const char* data();
  private:	
      // String size 
      size_t m_size;
      // Resource: Pointer to first string character 
      char*  m_data;	
  };
#+END_SRC

The idiom needs the following functions: 

 + *Copy constructor*

#+BEGIN_SRC cpp 
  String::String(const String& rhs){
     this->m_size = rhs.m_size;
     this->m_data = new (std::nothrow) char [rhs.m_size + 1];
     std::copy(rhs.m_data, rhs.m_data + rhs.m_size + 1, this->m_data);
  }
#+END_SRC

 + *Destructor* 

#+BEGIN_SRC cpp 
  String::~String()
  {
     // Check for null to avoid dangling pointer.
     if(m_data != nullptr)
             delete [] m_data;
     m_data = nullptr;
     m_size = 0;	
  }
#+END_SRC

 + *Swap function* which can be a member function or a friend function
   overload of std::swap. In this case, it was used the friend
   std::swap version. 

#+BEGIN_SRC cpp 
   // std::swap overload - Implementation of
   // => friend void swap(String& lhs, String& rhs)
   void swap(String& lhs, String& rhs){
        std::swap(lhs.m_data, rhs.m_data);
        std::swap(lhs.m_size, rhs.m_size);
   }
#+END_SRC

The copy-assignment operator, move-assignment operator and move
constructor are implemented with the custom _std::swap_ overload. 

 + _Copy-assignment operator_:

   + The temporary copy is used for disposing the current's object
     data which is transferred to the temporary object and deleted
     when the object goes out of scope.

#+BEGIN_SRC cpp 
  // Copy-assignment operator (rule-of-three and rule-of-five)
  // Copy-and-swap implementation 
  String& String::operator= (const String& rhs)
  {
      // Temporary copy 
      String temp(rhs);
      swap(*this, temp);
      return *this;
  }
#+END_SRC

 + _Move constructor_ (C++11, Rule of five)

#+BEGIN_SRC cpp 
  // Move-constructor
  String::String(String&& rhs)
   : String() // Delegated constructor 
  {
     swap(*this, rhs);
  }
#+END_SRC

 + _Move assignment operator_ (C++11, Rule of five)

#+BEGIN_SRC cpp 
   // Move-assignment operator (rule-of-five)
   // Transfer resource ownership from right hand-side object
   // to this object being instantiated. 
   String& String::operator= (String&& rhs){
       swap(*this, rhs);	
       return *this;
   }
#+END_SRC


 *Useful C++ Documentation*

 + [[https://en.cppreference.com/w/cpp/language/copy_assignment][Copy assignment operator - cppreference.com]]

 + [[https://en.cppreference.com/w/cpp/algorithm/swap][std::swap - cppreference.com]] (Header <utility>)

 + [[http://www.cplusplus.com/reference/algorithm/swap/][swap - C++ Reference]]

 *Reference and further reading*

 + [[http://web.archive.org/web/20140113221447/http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/][Want Speed? Pass by Value. « C++Next]]

 + [[http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0208r1.pdf][Copy-swap transaction]] 

 + [[https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap][More C++ Idioms/Copy-and-swap - Wikibooks, open books for an open world]]

 + [[https://www.heise.de/developer/artikel/C-Vor-und-Nachteile-des-d-Zeiger-Idioms-Teil-1-1097781.html?seite=all][C++: Vor- und Nachteile des d-Zeiger-Idioms, Teil 1 | heise Developer]]
   + Note: In German. 

 + [[https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-throwing_swap][More C++ Idioms/Non-throwing swap - Wikibooks, open books for an open world]]

 + [[https://cpppatterns.com/patterns/copy-and-swap.html][Copy-and-swap - C++ Patterns]] 

 + [[https://www.geeksforgeeks.org/copy-swap-idiom-c/][Copy-and-Swap Idiom in C++ - GeeksforGeeks]]

 + [[https://gist.github.com/ZenLulz/34e3ea73893cad952c904b7e9387a847][C/C++ - The perfect Copy-And-Swap idiom usage · GitHub]]

 + [[https://codereview.stackexchange.com/questions/85539/applying-the-copy-swap-idiom-to-humans-and-employees][c++ - Applying the copy-swap idiom to humans and employees - Code Review Stack Exchange]]

 + [[http://www.vollmann.ch/en/blog/implementing-move-assignment-variations-in-c++.html][C++: More on Implementing Move Assignment]]

 + [[https://stackoverflow.com/questions/19841626/move-assignment-incompatible-with-standard-copy-and-swap][c++ - Move Assignment incompatible with Standard Copy and Swap - Stack Overflow]]

** Interface Class idiom
*** Overview  

Unlike C# and Java, C++ doesn't have any keyword for implementing
interface, however it can be implemented by creating a class with only
pure virtual functions, in other words, only abstract methods or
methods without implementation. 

The interface class has a runtime overhead due to the virtual methods
that are resolved at runtime. An alternative solution when the virtual
methods calls performance overhead is not acceptable, is to use
generic programming or templates which doesn't have runtime cost since
the methods to be called are resolved at compile-time.

An interface class should: 
 + be on the header file, for instance, _IStack.hpp_ or any other header
   file. It does not need any implementation .cpp file.
 + not contain any member variable
 + any concrete methods (non pure virtual member functions)
 + contain only virtual member function, aka abstract methods or
   methods without implementation.
 + Always define a default *virtual destructor member function
   function*. Otherwise, memory leaks may happen as the destructors of
   derived classes will not be called.

Applications: 

 + _Use multiple implementations_
   + An interface class allows a client code, depending on the
     interface and no concrete implementation, to be able use multiple
     implementations and swap or replace them at runtime.

 + _Parallell development and team working_
   + If the interface is kept the same and is stable, the  client code
     and multiple implementations can be developed in parallel by
     different people and teams. 

 + _Avoid the diamond-of-death problem_
   + Most programming languages avoid the infamous diamond-of-death
     problem caused by multiple inheritance by allowing a class
     to inherit from multiple interfaces and only a single parent
     concrete class or abstract class.
   + See
     + [[https://blogs.mathworks.com/developer/2015/06/08/diamond-of-death/][The Diamond of Breadth]]
     + [[https://franzejr.wordpress.com/2011/01/18/deadly-diamond-of-death/][Deadly Diamond of Death - Java]]
     + [[https://www.quora.com/What-is-a-diamond-problem-a-diamond-dead-problem-or-a-deadly-diamond-of-death-in-Java][What is a diamond problem, a diamond dead problem, or deadly diamond of death in Java?]]

 + _Mock objec for testing_
   + If the client code depends only on the interface, an object used
     by the client code, for instance, a database object (class
     RealDatabase) implemeting the interface IDatabase which connects
     to a real database can be replaced by a mock or dummy object
     (class DummyDatabase) that simulates a database and is not
     connect to any real database.

 + _Plugin systems_
   + For instance an application could load the classes implementing a
     common interfaces class called IIinterface, class ClassA from the
     shared library (file: pluginA.dll on Windows or pluginA.so on an
     Unix-like OS) and the class ClassB from the plugin file
     pluginB.so. Those plugins or shared libraries containing the
     classes implementing the common interface can be loaded and
     unloaded at runtime using the operating system APIs, _LoadLibrary_
     on Windows and _dlopen_ on UNix-like operating systems (Linux,
     MacOSX, BSD...). The benefits of a plugin system are:
     extensibility of functionality at runtime, reload classes at
     runtime, user extensions, faster compile-time and easier update.

   + Potential ABI problem: If the application and its plugins are
     built with different C++ compilers, the application may not be
     able to load the classes provided by the plugins due to the C++
     lack of standard ABI - Application Binary Interface. The
     application its plugins only will be binary compatible if the
     interface class uses oly C-compatible types in its member
     functions (methods) signatures. It means that the interface class
     cannot use C++ types in its member functions such as STL
     containers, std::string, references, tuples and so on. A binary
     compatible interface can only int, double, pointer to void void*,
     pointer to clases, function pointers and so on.


Alternative: 

 + Interfaces have a runtime overhead due to the runtime resolution of
   virtual member functions. In cases where this performance penalty
   is not acceptable, an alternative to the interface approach
   (dynamic polymorphism) is to use template metaprogramming and
   templated functions since they can work with any class satisfying
   the type requirements regardless if they inherit from the same base
   class. Another alternative is to use CRTP - Curious Recurring
   Template Pattern which can emulate inheritance (dynamic
   polymorphism) with static polymorphism. The drawback of the
   template metaprogramming approaches is the lack of runtime
   polymorphism, since classes not inheriting from a common base class
   cannot be stored in the STL container or be referred with the same
   pointer.

 *Interface Class Declaration:*

#+BEGIN_SRC cpp 
  class IStack{
  public:
      virtual ~IStack() = default;
      virtual int    size()         const = 0;
      virtual void   push(double x)       = 0;
      virtual double pop()                = 0;
      virtual double peek()         const = 0;
  };
#+END_SRC

Note: 

 + The annotation *virtual* - means that the method (member function)
   can be overriden by the derived class. Methods in the base class
   not annotated as virtual cannot be overriden in the derived
   classes. Unlike Java, C++ methods are not virtual by default. 

 + The annotation (=0) - means a pure virtual member function, aka
   pure virtual function which is an _abstract method_, method without
   implementation. 

Or: 

#+BEGIN_SRC cpp 
  struct IStack{
      virtual ~IStack() = default;
      virtual int    size()         const = 0;
      virtual void   push(double x)       = 0;
      virtual double pop()                = 0;
      virtual double peek()         const = 0;
  };
#+END_SRC

Or using C++ auto keyword for functions: 

#+BEGIN_SRC cpp 
  struct IStack{
      virtual ~IStack() = default;
      virtual auto size() const   -> int    = 0;
      virtual auto push(double x) -> void   = 0;
      virtual auto pop()          -> double = 0;
      virtual auto peek() const   -> double = 0;
  };
#+END_SRC

*** Known Uses 

In Windows *COM (Component Object Model)* architechture, a client code
can load classes at runtime without knowing anything about their
implementations. All COM classes and COM intefaces are required to
implement the interface IUnknown which allows a client code to query
at runtime the interfaces implemented by the class and get pointers to
those interfaces. 

The COM Architechture has a plugin-system design, In-process COM
servers which provides COM one or more COM-compatible classes are DLL
shared libraries providing a set of standard functions. A client-code
instantiates COM classes using the Windows API function
[[https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-cogetclassobject][CoGetClassObject]] that locates the shared libraries using the unique
class ID (CLSDI) and IID (Interface Identifier) in the Windows
registry. The CLSID is used for locating the shared library file
(*.dll) containing COM classes and the IID is used to set the
interface pointer returned by the function CoGetClassObject. The C++
ABIs issues are circunvented because all COM interfaces uses only
C-compatible types in their member functions.

 *Windows API COM Interfaces*: 

Interface IUnknown

 + Base interface required to be implemented by all interfaces and
   concrete COM classes.
 + IID (Interface ID): {00000000-0000-0000-C000-000000000046}

#+BEGIN_SRC cpp 
  struct IUnknown {
    virtual HRESULT __stdcall QueryInterface (REFIID riid, void **ppvObject) = 0;
    virtual ULONG   AddRef () = 0;
    virtual ULONG   Release () = 0;
  };
#+END_SRC

Interface IDispatch

 + Allows querying which methods a class implements and calling
   class methods at runtime without knowing them at compile-time.
 + IID (Interface ID): {00020400-0000-0000-C000-000000000046} 

#+BEGIN_SRC cpp 
  class IDispatch : public IUnknown {
    public:

    /** Checks whether if the object can provide a type library. */
    virtual HRESULT GetTypeInfoCount(/* [OUT] */ unsigned int * pctinfo) = 0;

    /** Get the type library */
    virtual HRESULT GetTypeInfo( /* [IN] */  unsigned int  iTInfo,
                                 /* [OUT] */ LCID          lcid,
                                 /* [IN] */  ITypeInfo**  ppTInfo
                                ) = 0;
    /** Find the numeric ID of some object's method or property */                            
    virtual HRESULT GetIDsOfNames( /* [IN] */  REFIID        riid,
                                   /* [IN] */  OLECHAR**     rgszNames,
                                   /* [IN] */  unsigned int  cNames,
                                   /* [IN] */  LCID          lcid,
                                   /* [OUT] */ DISPID*       rgDispId
                                 ) = 0;

    /** Call a property or method. */
    virtual HRESULT Invoke(            DISPID          dispIdMember,
                           /* [IN] */  REFIID          riid,
                           /* [IN] */  LCID            lcid,
                           /* [IN] */  WORD            wFlags,
                           /* [IN] */  DISPPARAMS *    pDispParams,
                           /* [IN] */  VARIANT *       pVarResult,
                           /* [IN] */  EXCEPINFO *     pExcepInfo,
                           /* [OUT] */ unsigned int *  puArgErr
                          ) = 0;
  };
#+END_SRC

*** Example 

 *Complete Code Example*
 - File:  [[file:src/design-patterns/interface-class.cpp][file:src/design-patterns/interface-class.cpp]]

Interface class declaration:

#+BEGIN_SRC cpp 
  // Interface Stack. (Should be placed in the header file.) 
  class IStack{
  public:
          virtual ~IStack() = default;
          virtual int    size()         const = 0;
          virtual void   push(double x)       = 0;
          virtual double pop()                = 0;
          virtual double peek()         const = 0;
  };
#+END_SRC

Example: Interface implementations. 

 - Implementation of interface IStack using vector as internal
   representation.

#+BEGIN_SRC cpp 
  class StackVector: public IStack{
  public:
          StackVector(){}
          StackVector(const std::initializer_list<double>& xs){
                  _stack.insert(_stack.begin(), xs.begin(), xs.end());
          }
          int size() const {
                  return _stack.size();
          }	
          void push(double x){
                  _stack.push_back(x);
          }   
          double pop(){
                  if(this->size() == 0)
                          throw std::runtime_error("Error: stack is empty");
                  double top = _stack.back();
                  _stack.pop_back();
                  return top;
          }
          double peek() const {
                  if(this->size() == 0)
                          throw std::runtime_error("Error: stack is empty");		
                  return _stack.back();
          }
  private:
          std::vector<double> _stack{};
  };
#+END_SRC

 - Implementation using deque as internal representation:

#+BEGIN_SRC cpp 
  class StackDeque: public IStack{
  public:
          StackDeque(){}
          StackDeque(const std::initializer_list<double>& xs){
                  _stack.insert(_stack.begin(), xs.begin(), xs.end());
          }	
          int size() const {
                  return _stack.size();
          }	
          void push(double x){
                  _stack.push_back(x);
          }   
          double pop(){
                  if(this->size() == 0)
                          throw std::runtime_error("Error: stack is empty");
                  double top = _stack.back();
                  _stack.pop_back();
                  return top;
          }
          double peek() const {
                  if(this->size() == 0)
                          throw std::runtime_error("Error: stack is empty");		
                  return _stack.back();
          }
  private:
          std::deque<double> _stack{};
  };
#+END_SRC

 - Sample client code: 

#+BEGIN_SRC cpp 

  auto stack_sum(IStack& s) -> double{
          //std::cerr << " ==> stack_sum for references" << std::endl;
          double sum = 0.0;
          if(s.size() == 0)
                  return sum;
          while(s.size() != 0)
                  sum += s.pop();
          return sum;
  }

  auto stack_sum(IStack* s) -> double{
          // std::cerr << " ==> stack_sum for pointers" << std::endl;
          double sum = 0.0;
          if(s->size() == 0)
                  return sum;
          while(s->size() != 0)
                  sum += s->pop();
          return sum;
  }
#+END_SRC

Function main: 

#+BEGIN_SRC cpp 
   StackVector sv = {1.0, 2.0, 3.0, 5.0, 6.0};
   StackDeque  sd = {1.0, 2.0, 3.0, 5.0, 6.0};
   // The same client code works with any implementation of the interface. 
   std::cout << "stack_sum(sv) = " << stack_sum(sv) << std::endl;
   std::cout << "stack_sum(sd) = " << stack_sum(sd) << std::endl;

   IStack* spointer = nullptr;
   StackVector sv2 = {1.0, 2.0, 3.0, 5.0, 6.0};
   StackDeque  sd2 = {1.0, 2.0, 3.0, 5.0, 6.0};
   spointer = &sv2;
   std::cout << "stack_sum(spointer) = " << stack_sum(spointer) << std::endl;
   spointer = &sd2;
   std::cout << "stack_sum(spointer) = " << stack_sum(spointer) << std::endl;

   auto sptr = std::unique_ptr<IStack, std::function<void (IStack*)>>{
           nullptr,
           // Custom deleter 
           [](IStack* p){
                   std::cerr << " ==== Stack deleted OK" << std::endl ;
                   delete p;
           }
   };
   sptr.reset(new StackVector());
   sptr->push(10);
   sptr->push(25.0);
   sptr->push(20.0);
   std::cout << "stack_sum(sptr) = " << stack_sum(*sptr) << std::endl;
   sptr.reset(new StackDeque());
   sptr->push(10);
   sptr->push(25.0);
   sptr->push(20.0);
   std::cout << "stack_sum(sptr) = " << stack_sum(*sptr) << std::endl;
#+END_SRC

Compiling Running: 

#+BEGIN_SRC txt 
   $ clang++ interface-class.cpp -o interface-class.bin -g -std=c++1z -Wall -Wextra 
   $ ./interface-class.bin
   stack_sum(sv) = 17
   stack_sum(sd) = 17
   stack_sum(spointer) = 17
   stack_sum(spointer) = 17
   stack_sum(sptr) = 55
    ==== Stack deleted OK
   stack_sum(sptr) = 55
    ==== Stack deleted OK
#+END_SRC

References and further reading: 
 + [[https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Interface_Class][More C++ Idioms/Interface Class - Wikibooks, open books for an open world]]
 + [[https://accu.org/index.php/journals/269][ACCU - Separating Interface and Implementation in C++]]
 + [[https://www.boost.org/doc/libs/1_63_0/libs/smart_ptr/sp_techniques.html][Smart Pointer Programming Techniques - 1.63.0]]
** CRTP - Curious Recurring Template Pattern
*** Overview 

It is a variation of GOF template design pattern where an algorithm
defined by the base class is customized or specified by the derived 
class. However, unlike the GOF one, this version uses C++ template
metaprogramming for emulating dynamic polymorphism or inheritance
at compile time. So it makes the code faster by eliminating virtual
function-calls.

Features: 
 + Coined by James Coplien - 1995
 + Static polymorphism technique based on template metaprogramming for
   speeding up the code eliminating virtual functions.

Use cases:
 + Reduce virtual function call overhead - by simulating dynamic
   polymorphism through static polymorphism. 
 + Implement state machines.
 + Implement high performance numerical libraries.
 + Code injection.

Libraries using this pattern:
 + Boost.Iterator
 + Boost.Python
 + Boost.Serialization 

Also known as: 
 + Code injection
 + Barton‐Nackman Trick
 + Mixin - Name used outside C++ community 

*** Eliminating Virtual Member Function 

 *Approach 1 - GOF - OOP template pattern* 

 - Code 1: GOF Template method design pattern using virtual functions.

 #+BEGIN_SRC cpp 
   class IntervalSummation{
   public:
           // Algorithm or entry point which calls the derived class method.
           // This is the template method 
           double summation(int lower, int upper) const{
                   double sum = 0;
                   for(int i = lower; i <= upper; i++)
                           sum += this->stepFn(i);
                   return sum; 
           }
   protected:
           // Hook method or to be defined by the derived class
           virtual double stepFn(double x) const = 0 ;
   };

   class SumOfSquares: public IntervalSummation{
   private:
           double stepFn(double x) const { return x * x; }
   };

   class SumOfCubes: public IntervalSummation{
   private:
           double stepFn(double x) const { return x * x * x; }
   };

   void clientCode(const IntervalSummation& obj){
           std::cout << "Summation at [0, 15] = " << obj.summation(0, 15) << std::endl;
   }
#+END_SRC

  *Approach 2 - CRTP generic programming pattern* 

 + Code 2: Code rewritten using CRTP for eliminating virtual function
   calls. The advantage is that this code can run faster than the
   previous one, however the cost is the higher complexity, loss of
   readability and runtime polymorphism. For instance, now is not
   possible to store multiple implementations of IntervalSummation in
   a data structure or refer to them with the same pointer.

 + File: [[file:src/design-patterns/crtp1.cpp][file:src/design-patterns/crtp1.cpp]]
 + Online Compiler: https://rextester.com/ZLZH2040

#+BEGIN_SRC cpp 
  template<class Implementation>
  class IntervalSummation{
  public:
          // Get reference to implementation 
          Implementation& self(){
                  return *static_cast<Implementation*>(this);
          }
          // Overload method 
          const Implementation& self() const {
                  return *static_cast<Implementation const * const>(this);
          } 	
          double summation(int lower, int upper) const {
          double sum = 0;
          for(int i = lower; i <= upper; i++)
                sum += self().stepFn(i);
          return sum; 
          }
  };

  class SumOfSquares: public IntervalSummation<SumOfSquares>{
  public:
          double stepFn(double x) const { return x * x; }
  };

  class SumOfCubes: public IntervalSummation<SumOfCubes>{
  public:
          double stepFn(double x) const { return x * x * x; }
  };

  template<class T>
  void clientCode(const IntervalSummation<T>& obj){
          std::cout << "Summation at [0, 15] = " << obj.summation(0, 15) << std::endl;
  }

#+END_SRC

Running: 

#+BEGIN_SRC sh 
  $ clang++ crtp.cpp -o crtp.bin -std=c++1z -Wall -Wextra  && ./crtp.bin
  Sum of squares in [0, 10] = 385
  Sum of cubes   in [0, 10] = 3025
  Summation at [0, 15] = 1240
  Summation at [0, 15] = 14400
#+END_SRC

References: 

 + [[https://www.codeproject.com/Tips/537606/Cplusplus-Prefer-Curiously-Recurring-Template-Patt][C++: Prefer Curiously Recurring Template Pattern (CRTP) to Template Pattern - CodeProject]]
 + [[https://mklimenko.github.io/english/2018/07/02/platform-dependent-crtp/][CRTP-based platform-dependent optimizations | GNSS C++ solutions]]
 + http://stevedewhurst.com/once_weakly/once-weakly20170328/once-weakly20170328.pdf
 + [[http://enki-tech.blogspot.com/2012/08/c11-generic-singleton.html][Enki :: Technical Blog: C++11: A generic Singleton]]
 + IDENTIFYING PROGRAMMING IDIOMS IN C++ GENERIC LIBRARIES -
   <https://etd.ohiolink.edu/rws_etd/document/get/kent1259116053/inline>
 + [[http://www.masaers.com/2014/01/22/CRTP-operator-hijacking.html][Using CRTP to easily hijack operators in c++11 | masaers’ blog]]
 + https://github.com/nojhan/crtp_functor_ttp
 + [[https://web.archive.org/web/20060211034709/http://devnet.developerpipeline.com/documents/s=9843/cuj0601diggins/][Developer::Pipelines | Building More Flexible Types with Mixins]]
 + [[https://accu.org/index.php/journals/296][ACCU :: Better Encapsulation for the Curiously Recurring Template Pattern]]
 + [[http://www.di.unipi.it/~nids/docs/templates_vs_inheritance.html][Replacing Virtual Methods with Templates]]
 + http://gsd.web.elte.hu/lectures/bolyai/2018/mixin_crtp/mixin_crtp.pdf
 + https://faithandbrave.hateblo.jp/entry/20071206/1196934096
 + [[https://nativecoding.wordpress.com/2015/06/05/virtual-methods-vs-crtp-benchmark-2/][Virtual Methods vs CRTP Benchmark – Native Coding]]
 + https://nativecoding.wordpress.com/2015/01/11/important-c-idioms/
 + http://barngoggles.com/visitor-with-crtp/

Best Links: 

 + https://nativecoding.wordpress.com/2015/01/11/important-c-idioms/
 + https://marcoarena.wordpress.com/2012/04/29/use-crtp-for-polymorphic-chaining/
 + http://thothonegan.tumblr.com/post/157363120503/crtp-curiously-recurring-template-pattern

Videos: 

 + Curiously Recurring Template Pattern (CRTP) -
   <https://www.youtube.com/watch?v=C3Pi5GlIfjs>

 + 

 + 
*** Generating operator overloading free functions 

The CRTP design pattern can be used for generating operator free
functions and  avoiding code repetition when implementing them. 

 + File:  [[file:src/design-patterns/crtp-operators.cpp][file:src/design-patterns/crtp-operators.cpp]]
 + Online Compiler: https://rextester.com/PBI36673


 *Example:*

Class EqualityOperator: 
  + Requirement: the _Impl_ class must implement the member function:
    + _bool T::equal(T const& rhs) const_

#+BEGIN_SRC cpp 
  template<typename Impl>
  class EqualityOperator
  {
  public:

      friend bool operator==(Impl const& lhs, Impl const& rhs)
      {
          return lhs.equal(rhs);
      }

      friend bool operator!=(Impl const& lhs, Impl const& rhs)
      {
          return lhs.equal(rhs);
      }

  };
#+END_SRC

Class AddOperator: 

  + Imlements the operator (+) free functions. 
  + Requirement => The class _Impl_ must implement the member function:
    + Impl Impl::add(T const& T) const

#+BEGIN_SRC cpp 
  template<typename Impl, typename T>
  struct AddOperator
  {
  public:

      friend Impl operator+(Impl const& lhs, T const& rhs)
      {
          return lhs.add(rhs);
      }

      friend Impl operator+(T const& lhs, Impl const& rhs)
      {
          return rhs.add(lhs);
      }
  };
#+END_SRC

Class StreamInsertionOperator:

  + Implements the operator (<<) stream-insertion operator for the
    class Impl.

  + Requirement: The class Impl must implement the following member function:
    + void printme(std::ostream& os) const 

#+BEGIN_SRC cpp 
  template<typename Impl>
  struct StreamInsertionOperator
  {
  public:

      friend std::ostream& operator<<(std::ostream& os, Impl const& rhs)
      {
          rhs.printme(os);
          return os;
      }

  };
#+END_SRC

Class Point2D: 
  + Inherits and all previous CRTP classes and implements their
    requirements (implicit interface).

#+BEGIN_SRC cpp 
  class Point2D: public EqualityOperator<Point2D>
               , public AddOperator<Point2D, int>
               , public StreamInsertionOperator<Point2D>
  {
  public:
      int x;
      int y;
      Point2D(int x, int y): x(x), y(y) { }


      // Required by:
      void printme(std::ostream& os) const
      {
          os << "Point2D[ x = " << x << " ; y = " << y << " ] " << std::endl;
      }

  private:
      // Allows class EqualityOperator<Point2D> to access private
      // members of this class.
      friend class EqualityOperator<Point2D>;
      friend struct AddOperator<Point2D, int>;

      // Required by: EqualityOperator<Point2D>
      bool equal(Point2D const& rhs) const
      {
          return x == rhs.x && y == rhs.y;
      }

      // Required by: AddOperator<Point2D, int>
      Point2D add(int rhs) const
      {
          return Point2D(this->x + rhs, this->y + rhs);
      }

  };
#+END_SRC

Function: main()

#+BEGIN_SRC cpp 
  Point2D p1(10, 20);
  Point2D p2(25, 30);
  Point2D p3(10, 20);

  std::cout << std::boolalpha;

  std::cout << " p1 === p2 ? => " << (p1 == p2) << std::endl;
  std::cout << " p1 === p3 ? => " << (p1 == p3) << std::endl;

  std::cout <<" p1 + 10 = " << p1 + 10 << std::endl;
  std::cout <<" 10 + p1 = " << 10 + p1 << std::endl;
#+END_SRC

Output of main():

#+BEGIN_SRC sh 
 $ ./crtp-operators.bin 

 p1 === p2 ? => false
 p1 === p3 ? => true
 p1 + 10 = Point2D[ x = 20 ; y = 30 ] 

 10 + p1 = Point2D[ x = 20 ; y = 30 ] 
#+END_SRC

*** CRTP with more concise notation 

The following code uses the convenience templated function rcast<>
provide a more concise notation for expressing the code intent and
takes care of const qualifiers. 

File: _crtp.cpp_

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <string>
  #include <iomanip> 

  // Convenience function for CRTP pattern.
  template<typename Dest, typename Src>
  inline Dest& rcast(Src* td){ return *reinterpret_cast<Dest*>(td); }

  // Convenience templated function for CRTP pattern. This overload can be 
  // called from member functions functions with const annotation. Such as: 
  //   ReturType MyClass::someMemberFunc(arg0, ...) const 
  template<typename Dest, typename Src>
  inline const Dest& rcast(const Src* td){ return *reinterpret_cast<const Dest*>(td); }

  template<typename Impl>
  struct CurvePlotter
  {
      // Version 1 => Using convenience function rcast<T>(), which 
      // saves typing and expresses the intent in a more explicit way.
      //
      void tabulate_1(double start, double stop, double step) const 
      {
          std::cout << " ======== Version 1 =========" << '\n';
          rcast<Impl>(this).show_function_name();
        
          for(double x = start; x < stop; x += step)
          {
              double y = rcast<Impl>(this).eval(x);
              std::cout << std::setw(10) << x << std::setw(10) << y << '\n';
          }
      }
    

     // Version 2 => Implementation 2 => Without using convenience function.     
      void tabulate_2(double start, double stop, double step) const 
      {
          std::cout << " ======== Version 2 =========" << '\n';
        
          reinterpret_cast<Impl const*>(this)->show_function_name();
        
          for(double x = start; x < stop; x += step)
          {
              double y = reinterpret_cast<const Impl*>(this)->eval(x);
              std::cout << std::setw(10) << x << std::setw(10) << y << '\n';
          }        
      }
  };

  class LinearPlotter: public CurvePlotter<LinearPlotter>
  {
    double m_a, m_b;
  public:
      LinearPlotter(double a, double b): m_a(a), m_b(b) { }
      void show_function_name() const { std::cout << " Curver name = linear " << '\n';  }
      double eval(double x) const { return m_a * x + m_b; }    
  };


  class QuadraticPlotter: public CurvePlotter<QuadraticPlotter>
  {
      double m_a, m_b, m_c;
  public:
      QuadraticPlotter(double a, double b, double c): m_a(a), m_b(b), m_c(c){ }
    
      void show_function_name() const { std::cout << " Curver name = quadratic " << '\n';  }
      double eval(double x) const { return m_a * x * x + m_b * x + m_c; }
  };

  int main()
  {
      auto plt_lin = LinearPlotter(3.0, 5.0);
      plt_lin.tabulate_1(-5.0, 6.0, 1.0);
      plt_lin.tabulate_2(-5.0, 6.0, 1.0);
    
      auto plt_quad = QuadraticPlotter(2.0, -10.0, 25.0);
      plt_quad.tabulate_1(-5.0, 6.0, 1.0);
      plt_quad.tabulate_2(-5.0, 6.0, 1.0);
  }
#+END_SRC

Building and running: 

#+BEGIN_SRC sh 
   $ clang++ crtp.cpp -o out.bin -std=c++1z -g -Wall -Wextra

  $ ./out.bin                                                                                                                                                                                                                             
   ======== Version 1 =========                                                                                                                                                                                                           
   Curver name = linear                                                                                                                                                                                                                   
          -5       -10                                                                                                                                                                                                                    
          -4        -7                                                                                                                                                                                                                    
          -3        -4                                                                                                                                                                                                                    
          -2        -1                                                                                                                                                                                                                    
          -1         2                                                                                                                                                                                                                    
           0         5                                                                                                                                                                                                                    
           1         8                                                                                                                                                                                                                    
           2        11                                                                                                                                                                                                                    
           3        14                                                                                                                                                                                                                    
           4        17                                                                                                                                                                                                                    
           5        20                                                                                                                                                                                                                    
   ======== Version 2 =========                                                                                                                                                                                                           
   Curver name = linear                                                                                                                                                                                                                   
          -5       -10                                                                                                                                                                                                                    
          -4        -7                                                                                                                                                                                                                    
          -3        -4                                                                                                                                                                                                                    
          -2        -1                                                                                                                                                                                                                    
          -1         2                                                                                                                                                                                                                    
           0         5                                                                                                                                                                                                                    
           1         8                                                                                                                                                                                                                    
           2        11                                                                                                                                                                                                                    
           3        14                                                                                                                                                                                                                    
           4        17                                                                                                                                                                                                                    
           5        20                                                                                                                                                                                                                    
   ======== Version 1 =========                                                                                                                                                                                                           
   Curver name = quadratic                                                                                                                                                                                                                
          -5       125                                                                                                                                                                                                                    
          -4        97                                                                                                                                                                                                                    
          -3        73                                                                                                                                                                                                                    
          -2        53                                                                                                                                                                                                                    
          -1        37                                                                                                                                                                                                                    
           0        25                                                                                                                                                                                                                    
           1        17                                                                                                                                                                                                                    
           2        13                                                                                                                                                                                                                    
           3        13                                                                                                                                                                                                                    
           4        17                                                                                                                                                                                                                    
           5        25                                                                                                                                                                                                                    
   ======== Version 2 =========                                                                                                                                                                                                           
   Curver name = quadratic                                                                                                                                                                                                                
          -5       125                                                                                                                                                                                                                    
          -4        97                                                                                                                                                                                                                    
          -3        73                                                                                                                                                                                                                    
          -2        53                                                                                                                                                                                                                    
          -1        37                                                                                                                                                                                                                    
           0        25
           1        17
           2        13
           3        13
           4        17
           5        25                                                                              
#+END_SRC
** Type Erasure Pattern 
*** Overview  

Type erasure is a set of techniques for providing an uniform interface
for many different types by hiding the type information from the
client code. In C++ type erasure can be implemented with a combination
of object oriented programming and generic programming, in other
words, inheritance and templates. The fundamental building blocks of
this pattern are a base class, called _concept_, which provides the
uniform interface to the wrapped types and a derived templatized
class, called _model_, inherting the concept class which adapts the
wrapped type to the concept class. The inheritance allows any template
instantation of the model to be treated as it was the base class, thus
this approach hides the type information which can be later recovered
by downcasting the base class to the derived class.

 - Definition by Dave Abrahams and Aleksey Curtovoy in, *C++ Template*
   *Metaprogramming.*

#+BEGIN_QUOTE
  In its fullest expression, type erasure is the process of turning a
  wide variety of types with a common interface into one type with that
  same interface
#+END_QUOTE

Parts: 

 + *Concept class*
   - base class - definines the interface being enforced. 
 + *Model class*
   - templatized class inherting the concept class adpating the
     wrapped type to the concept class and holding an instance of the
     wrapped type. 
 + *Type Erasure class* (outter class)
   - Both the concept and model classes are private inner classes of
     the type erasure class.
   - The type erasure class takes an instance of the model class in the
     constructor.
   - This class stores a pointer variable to the concept class, but
     storing a pointer to the model class (dynamic polymorphism).
 + *Wrapped Type* or Objects 
   + Types wrapped by the model class wich will be erased. 

Use-cases: 

 + Create a common interface for many different types. 
 + Store wrapped types without a common base class in STL containers.
 + Store templatized classes in STL containers.
 + Implement dynamic or runtime polymorphism with value semantics.
 + Take advantage of the commonality of many unrelated classes without
   a common base class without modifying their source code. 

Known uses in C++ standard library: 

 + std::function (C++11, formber Boost.Function)

 + std::any (C++17, former Boost.Any)
   + A container which can store anything and the type of the stored
     object is not known at runtime. 

 + std::variant (C++17, former Boost.Variant)
   + Provides an interface for sum types or disjoint union or _visitor_ OO
     design pattern which is useful for manipulating abstract syntax
     tree, creating interpreters, tree data structures and fixed class
     hierarchies. 

 + void* - Void pointer in many C-APIs. 


References and further reading:
 + Nevin Liber, *Type Erasure*  <http://files.meetup.com/1455470/Type%20Erasure.pdf>
 + [[https://stackoverflow.com/questions/46041683/type-erasure-retrieving-value-type-check-at-compile-time][c++ - Type erasure: Retrieving value - type check at compile time - Stack Overflow]]
 + [[http://talesofcpp.fusionfenix.com/post-16/episode-nine-erasing-the-concrete][Episode Nine: Erasing the Concrete]]
 + [[https://codereview.stackexchange.com/questions/41879/concept-based-polymorphism][c++ - Concept based polymorphism - Code Review Stack Exchange]]
 + [[https://github.com/andyprowl/virtual-concepts/blob/master/draft/Dynamic%2520Generic%2520Programming%2520with%2520Virtual%2520Concepts.pdf][Dynamic Programming with Virtual Concepts]]
 + [[https://www.reddit.com/r/cpp/comments/5epngi/type_erased_concepts/][Type erased concepts : cpp]]
 + [[http://www.cplusplus.com/articles/oz18T05o/][C++ type erasure - C++ Articles]]
 + [[https://blog.tartanllama.xyz/type-erasure-unified-call/][Type erasure with unified call syntax]]
 + [[http://www.sgh1.net/posts/cpp-type-erasure.md][My Internet Weblog - Type Erasure in C++]]
 + [[https://accu.org/index.php/journals/2424][ACCU - Polymorphism in C++ – A Type Compatibility View]]

*** Example 1 - Simple type erasure.

_Problem:_ Handle the classes A, B and C which don't have a common base
class using dynamic (aka runtime) polymorphism taking advantage of
their commonality, the method .getName(). Note: the source code of A,
B and C aren't allowed to be modified

 - Complete source code:
   + File: [[file:src/design-patterns/type-erasure1.cpp][file:src/design-patterns/type-erasure1.cpp]]
   + Online Compiler: https://rextester.com/XFH16030

#+BEGIN_SRC cpp 
  class A{
  public:
      std::string getName() const {
          return "class A";
      }
      void sayA(){
          std::cout << "I am the class A" << "\n";
      }
  };

  class B{
  public:
      std::string getName() const  {
          return "class B";
      }
      void sayB(){
          std::cout << "I am the class B" << "\n";
      }	
  };

  class C{
  public:
      std::string getName() const  {
          return "class C";
      }
      void sayC() const {
          std::cout << "I am the class C" << "\n";
      }
  };
#+END_SRC

Solution: Type erasure design pattern. 

#+BEGIN_SRC cpp 
  class TypeErasure{
  private:
      //  --- Forward declarations ----
      class Concept;
      template<class T> class Model;

      // --- Member Variables ----- // 
      std::shared_ptr<Concept> _concept_ptr;
      // Optional: 
      // RTTI (runtime type information) for recovering wrapped type
      // by downcasting 
      const std::type_info& _tinfo;
  public:
      template<typename T> 
      TypeErasure(const T& obj)
      : _concept_ptr(std::make_shared<Model<T>>(obj))
      ,_tinfo(typeid(T)) 
      {		
      }

      auto getName() const -> std::string {
              return _concept_ptr->getName();
      }

      // Recover reference to wrapped type 
      template<typename T>
      auto recover() -> T {		
          if(typeid(T) != _tinfo)
                  throw std::runtime_error("Error: cannot cast to this type");
          // Note: static_cast downcasting to wrong type has undefined behavior,
          // use with care!
          return static_cast<Model<T>*>(_concept_ptr.get())->_obj;
      }

      template<typename T>
      auto hasType() -> bool {
              return _tinfo == typeid(T);
      }
  private:
     // Concept class defines the interface to be enforced
     // In general, it is an interface class, a class with only pure virtual
     // methods (abstract methods), in other words methods without implementation.
     class Concept{
     public:
             virtual auto getName() const -> std::string = 0;
             virtual ~Concept() = default;
     };

     // Adapt the wrapped type (T) to the concept
     template<typename T>
     class Model: public Concept {
     public:
             // Instance of the wrapped type 
             T _obj;
             // Initialize _opj by copying the parameter 
             Model(const T& obj): _obj(obj){}
             auto getName() const -> std::string {
                     return _obj.getName();
             }
     };
  };

#+END_SRC

Testing in Cling REPL: 

#+BEGIN_SRC cpp 
  >> .L type-erasure1.cpp 
  >> 
  >> A()
  (A) @0x1fc2970
  >> A().getName()
  (std::string) "class A"
  >> B().getName()
  (std::string) "class B"
  >> 
  >> B().sayB()
  I am the class B
  >> 

  auto tlist = std::deque<TypeErasure>();
  tlist.emplace_back(A())
  tlist.emplace_back(B())
  tlist.emplace_back(C())
 
  >> for(const auto& t: tlist) { std::cout << "Class type = " << t.getName() << "\n"; }
  Class type = class A
  Class type = class B
  Class type = class C
  >> 

  >> tlist.at(0).recover<A>()
  (A) @0x20cc590
  >> tlist.at(0).recover<A>().sayA()
  I am the class A
  >> tlist.at(0).recover<A>().getName()
  (std::string) "class A"
  >> 

  >> tlist.at(1).recover<B>().getName()
  (std::string) "class B"
  >> 

  >> tlist.at(1).recover<C>()
  Error in <TRint::HandleTermInput()>: std::runtime_error caught: Error: cannot cast to this type
  >> 
#+END_SRC

Main function: 

#+BEGIN_SRC cpp 
   auto tlist = std::deque<TypeErasure>();
   tlist.emplace_back(A());
   tlist.emplace_back(B());
   tlist.emplace_back(C());

   std::cout << "\n" << "EXPERIMENT 1 ============" << "\n";	
   for(const auto& t: tlist) {
           std::cout << "Class type = " << t.getName() << "\n";
   }

    // Note: It is a copy!
    A objA = tlist.at(0).recover<A>();
    objA.sayA();

    std::cout << "\n" << "EXPERIMENT 2 ============" << "\n";

    // Simulate downcasting failure 
    try {
       B objB = tlist.at(0).recover<B>();
       objB.sayB();
    } catch(const std::runtime_error& ex){
       std::cout << " [FAILURE]" << ex.what() << "\n";
    }

    B objB = tlist.at(1).recover<B>();
    objB.sayB();

    auto objC = tlist.at(2).recover<C>();
    objC.sayC();
#+END_SRC

Compiling and running: (File: [[file:src/design-patterns/type-erasure1.cpp][file:src/design-patterns/type-erasure1.cpp]])

#+BEGIN_SRC cpp 
  $ clang++ type-erasure1.cpp -o type-erasure1.bin -g -std=c++1z -Wall -Wextra 
  $ ./type-erasure1.bin

  EXPERIMENT 1 ============
  Class type = class A
  Class type = class B
  Class type = class C
  I am the class A

  EXPERIMENT 2 ============
   [FAILURE]Error: cannot cast to this type
  I am the class B
  I am the class C
#+END_SRC
*** Example 2 - Template type erasure - property system 

 *Problem:* 

In the following code the templated class TProperty<T> encapsulates
Get/Set properties. The problem is to put multiple properties with
different types such as TProperty<int>, TProperty<double> and
TProperty<std::string> in the same container, std::vector, std::map
and so on. 

 + File:  [[file:src/design-patterns/property-type-erasure1.cpp][file:src/design-patterns/property-type-erasure1.cpp]]

#+CAPTION: Property class encapsulating get/set class member variables. 
#+BEGIN_SRC cpp 
  /** Class that encapsulate get/set properties 
   ,*  @tparam - Type default constructible, copiable and equality-comparable 
   ,*/
  template <typename T>
  class TProperty
  {
      std::string    m_name;	
      T              m_value;
      std::type_info const& m_tinfo;
  public:
     TProperty(std::string name, T const& init = T{})
         : m_name(std::move(name))
         , m_value(init)
         , m_tinfo(typeid(T))
     { }

     std::string Name() const 
     {
             return m_name;
     }

     const std::type_info& Type()
     {
             return m_tinfo;
     }
     TProperty<T> Get() const
     {
             return m_value;
     }
     TProperty<T>& Set(T const& value)
     {
             std::cerr << " [TRACE] Property [" << m_name << "] set to value = "
                       << value << std::endl;
             m_value = value;
     }

     friend std::ostream& operator<<(std::ostream& os, TProperty<T> const& rhs)
     {
         return os << " Property{ Name = " << std::quoted(rhs.m_name)
                   << " ; Value = " << rhs.m_value << " }";
     }
  };
#+END_SRC

Sample usage: (function main)

#+CAPTION: Sample usage 
#+BEGIN_SRC cpp 
  TProperty<int>         p1("count", 100);
  TProperty<double>      p2("range", 5.6);
  TProperty<std::string> p3("name", "Box");

  std::cout << "Before setting" << std::endl;
  std::cout << "p1 = " << p1 << "\n";
  std::cout << "p2 = " << p2 << "\n";
  std::cout << "p3 = " << p3 << "\n";

  std::cout << "\n After setting" << std::endl;
  p1.Set(20);
  p2.Set(80.50);
  p3.Set("Square");
  std::cout << "p1 = " << p1 << "\n";
  std::cout << "p2 = " << p2 << "\n";
  std::cout << "p3 = " << p3 << "\n";
#+END_SRC

 *Solution:* 

The solution for the requirement of referring to multiple properties
using the same pointer or "storing" properties with different types in
the same container is to use type erasure through inheritance, or make
the template class inherit from some base class or base interface
class.

 + File: [[file:src/design-patterns/property-type-erasure2.cpp][file:src/design-patterns/property-type-erasure2.cpp]]
 + Online Compiler: https://rextester.com/JTC56116

Interface class IProperty: 

#+CAPTION: Property base class (interface)
#+BEGIN_SRC cpp 
  template <typename T>
  class TProperty;

  class IProperty
  {		
  public:	
    virtual std::string           Name() const = 0;
    virtual std::type_info const& Type() const = 0 ;
    virtual void                  Print(std::ostream& os) const = 0;

    virtual ~IProperty() = default;

    // Note: Adding Non virtual methods does not causes break the base class ABI
    // or binary compatibility with derived classes (fragile-base class problem).
    template<typename T>
    T Get() const {
         if(this->Type() != typeid(T)) throw std::bad_cast();
         return static_cast<TProperty<T> const*>(this)->Get();
    }

    template<typename T>
    void Set(T const& value) {
         if(this->Type() != typeid(T)) throw std::bad_cast();
         static_cast<TProperty<T>*>(this)->Set(value);
    }

    template<typename T>
    TProperty<T>& As()
    {
         if(this->Type() != typeid(T)) throw std::bad_cast();
         return *static_cast<TProperty<T>*>(this);
    }

    template<typename T, typename Visitor>
    void Visit(Visitor& visitor)
    {
        if(this->Type() != typeid(T)) throw std::bad_cast();
        static_cast<TProperty<T>*>(this)->Visit(visitor);
    }

    // Make class printable 
    friend std::ostream& operator<<(std::ostream& os, IProperty const& rhs)
    {
        rhs.Print(os);
        return os;
    }
  };
#+END_SRC

Class template TProperty: 
  + As the class TProperty inherits the base class IProperty, all
    template instances TProperty<int>, TProperty<double> and so on can
    be referred by the same pointer and "stored" in the same
    container. 

#+CAPTION: Class TProperty inheriting IProperty
#+BEGIN_SRC cpp 
  /** Class that encapsulate get/set properties 
   ,*  @tparam - Type default constructible, copiable and equality-comparable 
   ,*/
  template <typename T>
  class TProperty: public IProperty
  {
       std::string     m_name;	
      T               m_value;
      std::type_info const* m_tinfo;
  public:
    TProperty(std::string name, T const& init = T{})
            : m_name(std::move(name))
            , m_value(init)
            , m_tinfo(&typeid(T))
    { }

    ~TProperty() = default;

    std::string Name() const 
    {
         return m_name;
    }

    const std::type_info& Type() const
    {
         return *m_tinfo;
    }

    T Get() const
    {
         return m_value;
    }

    TProperty<T>& Set(T const& value)
    {
         std::cerr << " [TRACE] Property [" << m_name << "] set to value = "
                   << value << std::endl;
         m_value = value;
         return *this;
    }

    void Print(std::ostream& os) const
    {
         os << " Property{ Name = " << std::quoted(m_name)
            << " ; Value = " << m_value << " }";		
    }

    void PrintValue(std::ostream& os) const
    {
         os << m_value;
    }

    template<typename Visitor>
    void Visit(Visitor& visitor)
    {
         visitor.visit(m_value);
    }
  };

#+END_SRC

Function makeProperty: 
  + Creates some property with type specified by calling code (client code).
  + Any property created TProperty<T> will be seen by the calling code
    as the same object IProperty. 

#+BEGIN_SRC cpp 
  template<typename T>
  std::shared_ptr<IProperty>
  make_property(std::string const& name, T const& init = T{})
  {
      return std::make_shared<TProperty<T>>(name, init);
  }
#+END_SRC

Usage (main function): 

#+BEGIN_SRC cpp 
  std::vector<std::shared_ptr<IProperty>> plist;

  plist.push_back(make_property<int>("basis-points", 100));
  plist.push_back(make_property<double>("price", 5.6));
  plist.push_back(make_property<std::string>("product", ""));

  std::cout <<"\n ======= Experiment 1 =======" << std::endl;
  int i = 0; 
  for(const auto& p: plist)
          std::cout << " => p[" << i++ << "] = " << *p << "\n";

  std::cout <<"\n ======= Experiment 2 =======" << std::endl;
  TProperty<int>& p0 = plist[0]->As<int>();
  p0.Set(200);
  std::cout << " => p0.Name() = " << p0.Name() << " ; Value = " << p0.Get() << "\n";

  plist[0]->Set(80);

  std::cout << " => plist[0]->Name() = "  << plist[0]->Name()
            <<  " plist[0]->Get<int>() = " << plist[0]->Get<int>()
            << std::endl;
#+END_SRC

Compilation Output: 

#+BEGIN_SRC sh 
  $ clang++ property-type-erasure2.cpp -o property-type-erasure2.bin -std=c++1z -g -O0 -Wall 
  $ ./property-type-erasure2.bin

   ======= Experiment 1 =======
   => p[0] =  Property{ Name = "basis-points" ; Value = 100 }
   => p[1] =  Property{ Name = "price" ; Value = 5.6 }
   => p[2] =  Property{ Name = "product" ; Value =  }

   ======= Experiment 2 =======
   [TRACE] Property [basis-points] set to value = 200
   => p0.Name() = basis-points ; Value = 200
   [TRACE] Property [basis-points] set to value = 80
   => plist[0]->Name() = basis-points plist[0]->Get<int>() = 80
#+END_SRC
** Virtual Copy Constructor Idiom - Prototype Pattern 
*** Overview 

The virtual copy constructor idiom is a workround for allowing a
client to clone or performing deep copy at runtime of C++ instances
of derived classes from a given base class without knowing the type of
those of those instances. In other words, this idioms makes possible
to a client to clone instances of derived classes given as pointers to
base class (the type of pointers is Base*).

Note: this idiom is quite similar tot the [[https://www.programering.com/a/MjN5ADMwATA.html][prototype design pattern.]]

*** Example: Simple Virtual Copy Constructor 

File: [[file:src/design-patterns/virtual-constructor1.cpp][file:src/design-patterns/virtual-constructor1.cpp]]

Note: This example can be improved using smart pointers.

 + Interface class: 

#+BEGIN_SRC cpp 
  class IBase{
  public:
      // Destructor always virtual to avoid memory leak,
      virtual ~IBase() = default;	
      // "virtual copy constructor"
      virtual auto clone() const -> IBase* = 0;
      // "virtual default constructor"
      virtual auto create() const        -> IBase*      = 0;	
      virtual auto getID() const         -> std::string = 0;
      virtual auto setID(std::string id) -> void	= 0;
      virtual auto show() const          -> void        = 0;
  };
#+END_SRC

 + Concrete class DerivedA: 

#+BEGIN_SRC cpp 
  class DerivedA: public IBase{
  private: 
          std::string _id;
  public:
      DerivedA()
       : _id("unnamed-A"){ }

      DerivedA(std::string id)
       : _id{std::move(id)}{  }

      auto clone() const -> IBase* {
        // Invoke copy constructor 
        return new DerivedA(*this);
      }
      auto create() const -> IBase* {
        // Invoke default constructor 
        return new DerivedA();
      }
      auto getID() const -> std::string {
        return _id;
      }
      auto setID(std::string id) -> void {
        _id = id;
      }   
      auto show() const -> void  {
        std::cout << " => Class DerivedA - id = " << _id << "\n";
      }  
  };
#+END_SRC

 + Concrete clas DerivedB: 

#+BEGIN_SRC cpp 
  class DerivedB: public IBase{
  private:
       std::string _id;
  public:
       DerivedB()
        : _id("unnamed-B"){ }

       DerivedB(std::string id)
        : _id{std::move(id)}{  }

       auto clone() const -> IBase* {
         // Invoke copy constructor 
         return new DerivedB(*this);
       }
       auto create() const -> IBase* {
         // Invoke default constructor 
         return new DerivedB();
       }  
       auto getID() const -> std::string {
         return _id;
       }
       auto setID(std::string id) -> void {
          _id = std::move(id);
       }     
       auto show() const -> void  {
          std::cout << " => Class DerivedB - id = " << _id << "\n";
       }  
  };
#+END_SRC

Testing in ROOT REPL:

 + Create test objects: 

#+BEGIN_SRC cpp
// Load file as a script 
>> .L virtual-constructor1.cpp 

>> DerivedA da("objectA");

>> DerivedB db("objectB");
 
>> da.show()
 => Class DerivedA - id = objectA
>>  

>> db.show()
 => Class DerivedB - id = objectB
>> 

>> IBase* ptr = nullptr;

>> ptr->getID()
(std::string) "objectA"

>> ptr->show()
 => Class DerivedA - id = objectA
>> 
#+END_SRC

Clone object DerivedA: 

#+BEGIN_SRC cpp 
  >> IBase* clone1 = ptr->clone();

  >> clone1->getID()
  (std::string) "objectA"
  >> clone1->show()
   => Class DerivedA - id = objectA

  >> if(clone1 != ptr) std::puts("Objects are not the same. OK.");
  Objects are not the same. OK.

  >> clone1->setID("object-A-Clone");

  >> clone1->getID()
  (std::string) "object-A-Clone"

  >> ptr->getID()
  (std::string) "objectA"
  >> 

  // Delete cloned object 
  >> delete clone1;
  >> clone1 = nullptr;
#+END_SRC

Invoke default constructor of class DerivedB through the object
DerivedB:

#+BEGIN_SRC cpp 
  >> ptr = &db;

  >> ptr = &db;
  >> ptr->show()
   => Class DerivedB - id = objectB

  >> IBase* clone2 = ptr->create();

  >> clone2->show()
   => Class DerivedB - id = unnamed-B
  >> 
#+END_SRC


Further Reading: 

 + [[https://isocpp.org/wiki/faq/virtual-functions#virtual-ctors][ISO C++ - FAQ - Inheritance — What is a virtual constructor]]

 + [[http://www.cs.technion.ac.il/users/yechiel/c++-faq/virtual-ctors.html][What is a "virtual constructor"?, C++ FAQ]]

 + [[https://isocpp.org/wiki/faq/virtual-functions#virtual-ctor-rationale][Inheritance — <code>virtual</code> functions, C++ FAQ]]

 + [[https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Covariant_Return_Types][More C++ Idioms/Covariant Return Types - Wikibooks, open books for an open world]]

 + [[https://nerdland.net/2009/06/covariant-templatized-virtual-copy-constructors/][Covariant, Templatized Virtual Copy Constructors – Nerdland]]

 + [[http://icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html][The Anatomy of the Assignment Operator]]

Codes using "virtual copy constructor":

 + [[https://people.math.ethz.ch/~concepts/doxygen/html/classconcepts_1_1FrmE__TangentialVector.html#a9da3ec4c6f5b2b0d8f3eff38602c624b][Home – Concepts | Numerical C++ Library Concepts | ETH Zurich]]

 + [[http://www.java2s.com/Tutorial/Cpp/0180__Class/Virtualcopyconstructor.htm][Virtual   copy constructor : constructor « Class « C++ Tutorial]] 
*** Example: Virtual Copy Constructor with CRTP 

This alternative implementation uses CRTP (Curious Recurring Template)
for eliminating the boilerplate code and smart pointers.

File: [[file:src/design-patterns/virtual-constructor2.cpp][file:src/design-patterns/virtual-constructor2.cpp]]

 + IBase interface class:

#+BEGIN_SRC cpp 
  class IBase{
  public:
     // Destructor always virtual to avoid memory leak,
     virtual ~IBase() = default;	
     // "virtual copy constructor"
     virtual auto clone() const -> std::unique_ptr<IBase> = 0;
     // "virtual default constructor"
     virtual auto create() const        -> std::unique_ptr<IBase> = 0;	
     virtual auto getID() const         -> std::string  = 0;
     virtual auto setID(std::string id) -> void	        = 0;
     virtual auto show() const          -> void	        = 0;
  };
#+END_SRC

 + CRTP base class:

#+BEGIN_SRC cpp 
  /** Remember: Template always in header files. */
  template<typename Base, typename Derived>
  class Copyable: public Base{
  private:
       inline auto self() const -> const Derived& {
          return *static_cast<const Derived* const>(this);
       }
  public:
      virtual ~Copyable() = default;
      auto clone() const -> std::unique_ptr<Base> {
         // Invoke copy constructor 
         return std::make_unique<Derived>(this->self());
      }
      auto create() const -> std::unique_ptr<Base> {
         // Invoke default constructor 
         return std::make_unique<Derived>();
      }
  };

#+END_SRC

 + Class DerivedA. The class DerivedB is similar to this one. 

#+BEGIN_SRC cpp 
  class DerivedA: public Copyable<IBase, DerivedA>{
  private: 
       std::string _id;
  public:
       DerivedA()
         : _id("unnamed-A"){ }
       DerivedA(std::string id)
         : _id{std::move(id)}{  }
       auto getID() const -> std::string {
          return _id;
       }
       auto setID(std::string id) -> void {
          _id = id;
       }   
       auto show() const -> void  {
          std::cout << " => Class DerivedA - id = " << _id << "\n";
       }
  };
#+END_SRC

Testign in ROOT REPL: 

#+BEGIN_SRC cpp 
  >> .L virtual-constructor2.cpp

  >> DerivedA da("objA");
  >> DerivedB db("objB");
  >> 
  >> IBase* ptr = &da;

  >> ptr->getID()
  (std::string) "objA"

  >> ptr->show()
   => Class DerivedA - id = objA
  >>

  >> auto clone1 = ptr->clone()
  (std::unique_ptr<IBase, std::default_delete<IBase> > &) @0x7fdf62fa5068
  >> 

  >> clone1->setID("objA-clone");

  >> clone1->getID()
  (std::string) "objA-clone"
  >> 

  >> ptr->getID()
  (std::string) "objA"
  >> 

#+END_SRC
** QT Parent-child memory management 

QT does not uses smart pointers for widgets memory management, instead
it uses raw pointers and parent-child relationship for organizing
widgets as tree data structure. In the parent-child relationship
memory management technique, every child object (heap-allocated) is
owned by a single parent and every parent is responsible for releasing
the memory allocated for its children object. When a parent object is
destroyed, all its children are also destroyed. The root widget
object, which is often stack allocated, calls the destructor of its
children objects, and each of its children objects also call the
destructors of its offspring. 

Note: This is similar to the composite design pattern.  

References: 

  + [[https://doc.qt.io/qt-5/objecttrees.html][Qt5 - Object Trees & Ownership]]

  + [[https://stackoverflow.com/questions/2491707/memory-management-in-qt][Stackoverflow - Memory management in Qt?]] 

  *Sample Code* 

File: _parent-child.cpp_

#+BEGIN_SRC cpp 
  #include <iostream> 
  #include <string> 
  #include <vector>

  class Widget 
  {
  public:
      virtual  ~Widget() = default;
      Widget() = default;

      // Make class non-copiable. 
      Widget(const Widget&)          = delete;
      Widget& operator=(const Widget&) = delete;
    
      virtual const char* name() const = 0;
      virtual void display()     const = 0;
  };

  // Convenience function for CRTP pattern.
  template<typename Dest, typename Src>
  inline Dest& rcast(Src* td){ return *reinterpret_cast<Dest*>(td); }

  // Convenience templated function for CRTP pattern. This overload can be 
  // called from member functions functions with const annotation. Such as: 
  //   ReturType MyClass::someMemberFunc(arg0, ...) const 
  template<typename Dest, typename Src>
  inline const Dest& rcast(const Src* td){ return *reinterpret_cast<const Dest*>(td); }

  template<typename Impl>
  class Container: public Widget 
  {
      std::vector<Widget*> m_children{};
  public:    
      Container() = default;

      void addChild(Widget* child)
      {
          m_children.push_back(child);
      }
    
      void display() const override
      {
          std::fprintf(  stdout, " [TRACE] Display container (id = %d) / type = '%s' \n"
                       , rcast<Impl>(this).getid() , name());
          for(auto ch: m_children){ ch->display(); }
      }
    
      // Delete all child widget;
      ~Container() 
      {
          for(auto ch: m_children){ delete ch; }
        
          // CRTP is used because it is not possible to call 
          // virtual method from destructor.
          std::printf(  " [TRACE] Delete container (id = %d) (type = %s) \n"
                      , reinterpret_cast<Impl*>(this)->getid()
                      , rcast<Impl>(this).type() 
                     );       
      }
  };


  class VerticalContainer: public Container<VerticalContainer> 
  {
      int m_id = 0;
  public:
      VerticalContainer() = default;
      VerticalContainer(int id) { m_id = id; }
      int getid() const { return m_id; }    
      const char* name() const { return "vcontainer"; } 
      const char* type() const { return "vcontainer"; } 
  };

  class HorizontalContainer: public Container<HorizontalContainer>
  {
      int m_id = 0;
  public:
      HorizontalContainer() = default;
      HorizontalContainer(int id) { m_id = id; }
      int getid() const { return m_id; }
      const char* name() const { return "hcontainer"; } 
      const char* type() const { return "hcontainer"; } 
  };


  class Label: public Widget
  {
      int m_id = -1;
  public:
      Label(int id){ m_id = id; }
      const char* name() const { return "label"; }
      int getid() const { return m_id; }
      void display() const 
      {
          std::printf(" [TRACE] Display label (n = %d) \n", m_id);
      }
    
       ~Label(){ std::printf(" [TRACE] Label deleted (n = %d) \n", m_id); }
  };


  class Button: public Widget
  {
      int m_id = -1;
  public:
      Button(){ m_id = 0; }
      Button(int id){ m_id = id; }
      const char* name() const { return "button"; }    
    
      void display() const 
      {
          printf(" [TRACE] Display button (id = %d) \n", m_id);
      }
    
      ~Button(){ printf(" [TRACE] Button deleted  (n = %d) \n", m_id); }
  };

  int main()
  {
      // Root object (allocated on stack)
      // will own all sub-objects. 
      VerticalContainer vbox{0};
    
      vbox.addChild( new Label(15) );
    
      auto hbox = new HorizontalContainer{0};
      hbox->addChild( new Button(0) );
      hbox->addChild( new Button(1) );    
    
      // vbox2 will own the label objects with IDs (100 and 200).
      auto vbox2 = new VerticalContainer{1};
      vbox2->addChild( new Label(100));
      vbox2->addChild( new Label(200));
      hbox->addChild(vbox2);
      vbox.addChild( hbox );
    
      vbox.addChild( new Button(2) );    
      vbox.addChild( new Label(17) );
    
      vbox.display();
      printf("\n =========== [TERMINATED] ================\n");
      return 0;
  }
#+END_SRC

Building and running: 

#+BEGIN_SRC sh 
  $ clang++ parent-child.cpp -o out.bin -std=c++1z -Wall -Wextra -g   

  $ ./out.bin                                                                                        
   [TRACE] Display container (id = 0) / type = 'vcontainer'                                          
   [TRACE] Display label (n = 15)                                                                    
   [TRACE] Display container (id = 0) / type = 'hcontainer'                                          
   [TRACE] Display button (id = 0)                                                                   
   [TRACE] Display button (id = 1)                                                                   
   [TRACE] Display container (id = 1) / type = 'vcontainer'                                          
   [TRACE] Display label (n = 100)                                                                   
   [TRACE] Display label (n = 200)                                                                   
   [TRACE] Display button (id = 2)                                                                   
   [TRACE] Display label (n = 17) 

   =========== [TERMINATED] ================
   [TRACE] Label deleted (n = 15) 
   [TRACE] Button deleted  (n = 0) 
   [TRACE] Button deleted  (n = 1) 
   [TRACE] Label deleted (n = 100) 
   [TRACE] Label deleted (n = 200) 
   [TRACE] Delete container (id = 1) (type = vcontainer) 
   [TRACE] Delete container (id = 0) (type = hcontainer) 
   [TRACE] Button deleted  (n = 2) 
   [TRACE] Label deleted (n = 17) 
   [TRACE] Delete container (id = 0) (type = vcontainer) 
#+END_SRC

** Cross platform code with conditional compilation

Note: It is not a design pattern, but a methodology for developing
cross platform applications in C++. 

   1. Avoid relying on platform-specific features as much as
      possible.

   2. Isolate platform-specific code from non-platform specific code
      using _macros, conditional compilation_ or separate classes.

   3. Before creating a cross-platform wrapper, check whether there is
      already some available library that wraps the APIs of the target
      platforms. For instance, QT framework or WxWidgets GUI library
      already wraps the UI user interface APIs of many operating
      systems, including Windows' Win32 API, MacOSX's Cocoa and Linux's
      Xorg/X11 X Windows Systems. Those libraries save users from
      reinventing the wheel and ensure cross-platform portability.

   4. Avoid using platform-specific building systems such as GNU Make,
      BSD Make, Windows' MSBuild and so on. Instead, it is better to use
      building systems such as CMake that are widely supported on
      several operating systems and IDEs.

   5. Use _fixed width integers_ <csdtint> header: std::int8_t,
      std::uint8_t, std::int32_t, std::int64_t ... for code related to
      _serialization_, _network protocols_ and _device drivers_ or _embedded_
      _systems_. The byte sizes of the types int, short, long long long
      are not guaranteed to be the same accross all platforms,
      operating systems and processor architectures. For instance, a C
      or C++ application, built on Windows 64 bits machine, that
      attempts to read a value with type _long_ from a file created on a
      Linux machine will read the data in incorrect way and may even
      corrupting the data, if the application attempts to update the
      value.
      * Note: Another issue that should be taken into consideration in
        serialization and network-related code is the _platform_
        _endianess_ which is the order which the bytes of numeric types
        are placed in the memory.

   6. [[https://jenkins.io/][Jenkins]] CI for simultaneous and automate cross-platform compilation
      * Continuous Integration server can be used for
        cross-platform compilation and integration testing. Jenkins has
        the master-slave(agent) architecture where the master
        coordinates and agents executes the builds in different machines
        or platforms. This approach allows automatic simultaneous
        buildings of an application for multiple operating systems, such
        as Windows, Linux and OSX by running a Jenkins *slave/agent* node
        in each operating system where the software will be built.
      * Summary:
        + Jenkins can be used for building native code artifacts for
          many platforms at the same time. A jenkins node (agent)
          running Linux can build Linux ELF executables; a jenkins
          node running on Windows, can build Windows *.exe, and *.dll
          artifacts and another node on MacOSX can build artifacts for
          MacOSX, such as *.dylib and Mach-O executables.
      * See:
        + [[https://www.emidee.net/ue4/2018/03/30/Build-a-UE4-multi-platforms-game-on-jenkins.html][Multi-platforms UE4 game on Jenkins | MICHAEL DELVA]]
        + [[https://wiki.jenkins.io/plugins/servlet/mobile?contentId=753710#content/view/753710][Confluence Mobile - Jenkins Wiki]]
        + [[https://embeddedartistry.com/blog/2018/01/11/jenkins-configuring-a-linux-slave-node/][Jenkins: Configuring a Linux Slave Node – Embedded Artistry]]
        + [[https://wiki.jenkins.io/display/JENKINS/Distributed+builds][Distributed builds - Jenkins - Jenkins Wiki]]
        + [[https://www.bugsee.com/blog/automating-cross-platform-building-continuous-testing-jenkins/][Automating cross platform building and continuous testing with Jenkins - Bugsee]]
        + [[https://blogs.sap.com/2019/07/22/jenkins-configuration-windows-as-master-and-linux-as-slave/][Jenkins Configuration- Windows as Master and Linux as Slave | SAP Blogs]]
        + [[https://stackoverflow.com/questions/20086664/how-do-we-do-releases-involving-multiple-platforms-using-jenkins][build - How do we do releases involving multiple platforms using Jenkins? - Stack Overflow]]

 *Use macros for isolating platform-specific code* 

Macros are useful for writing cross-platform code by hiding and
isolating platform-specific details, such as specific hardware
registers address, compiler extensions, APIs and system calls. This
example shows how to use conditional compilation to write code which
can be compiled on an Unix-like operating system, such as Linux or OSX
and Windows.

Example: 

  + Include operating-system specific headers: 

#+BEGIN_SRC cpp 
  #if  defined(__unix__)
      // Unix: Linux, BSD, OSX ... 
     #include <unistd.h>
     #include <dlfcn.h>
     #include <elf.h>
  #elif defined(_WIN32)
     // Windows 
     #include <windows.h>
  #else 
     #error "Error: Operating system not supported."
  #endif 
#+END_SRC


  + Scoped enum is used to identify the operating system the code was
    compiled. 

#+BEGIN_SRC cpp 
  enum class SystemType{
      WindowsNT,
      Linux,
      MacOSX,
      FreeBSD,
      Unknown
  };
#+END_SRC

 + Functions returns operating system that the library was compiled
   against.  

#+BEGIN_SRC cpp 
  auto getSystemType() -> SystemType {
       #ifdef __apple__
          return SystemType::MacOSX;
       #elif defined __linux__
          return SystemType::Linux;
       #elif defined _WIN32 || defined _WIN64
         return SystemType::WindowsNT;
       #else
         return SystemType::Unknown;
       #endif
  }
#+END_SRC

 + Function that turns Enum into string: 

#+BEGIN_SRC cpp 
  auto getOperatingSystem() -> std::string {
       SystemType type = getSystemType();
       if (type == SystemType::Linux)
          return "Linux";
       if(type == SystemType::MacOSX)
          return "MacOSX";
       if(type == SystemType::WindowsNT)
          return "Windows NT";
       if(type == SystemType::FreeBSD)
          return "FreeBSD";       
       return "Unknown operating system";
  }
#+END_SRC

 + Predicate functions for detecting current OS:

#+BEGIN_SRC cpp 
  auto isWindows() -> bool {
      return getSystemType() == SystemType::WindowsNT;
  }

  // Check whether is U-N-I-X like 
  auto isNixLike() -> bool {
       auto t = getSystemType();
       return t == SystemType::Linux
               || t == SystemType::FreeBSD
               || t == SystemType::MacOSX;
  }
#+END_SRC

 + Operating-system specific APIs are isolated using macros. mkdir =>
   Unix only and CreateDirectory is a Windows API (Win32 API).

#+BEGIN_SRC cpp 
  /** Cross platform code for creating directory */
  void makeDirectory(std::string path){
       #if defined __linux__ || defined __apple__
      /** ==== U-NIX Specific code ==== */
          mkdir(path.c_str(), 0777);
       #elif _WIN32
      /** ==== Windows Specific Code ==== */
          CreateDirectoryA(path.c_str(), NULL);
       #endif
  }
#+END_SRC

 + Get home or user directory:

#+BEGIN_SRC cpp 
  /** Get home directory, ~/ or $HOME on Unix or %USERPROFILE% 
   ,* environment variable on Windows 
   ,*/
  std::string getHomeDir(){
      if (getSystemType() == SystemType::WindowsNT)
         return getEnv("USERPROFILE");
       else
        return getEnv("HOME");
  }
#+END_SRC

* Misc Techniques 
** Polymorphic IO 

This technique allows to design input or output functions which can
read from any type of input stream or print to any type of output
stream. Besides C++, this design approach can also be used with any
object oriented language with an IO class hierarchy where there are an
root abstract input class (in C++ std::istream C++) and a root abstract
output class (std::ostream in C++).

File: [[file:src/design-patterns/polymorphic-io1.cpp][file:src/design-patterns/polymorphic-io1.cpp]]

 *Polymorphic IO Functions:*

 + The class std::ostream is the base class of all C++'s output streams. By
   passing the object std::cout to std::ostream, the function
   _writeVector_ writes the vector to standard output. If the parameter passed is
   std::sstringstream, the function writes the vector to the string
   stream.

 + The function readVector can read a vector of doubles from any input
   stream since the class std::istream is the base class of all input
   streams, as a result, it can read vector from std::cin (console or
   stdin), file stream std::ifstream, string stream and so on.

 + Note: This approach can also be used for binary IO and
   serialization. 

 + Summary:
   + In order to design an output agnostic function, write to the
     abstract output _std::ostream_, instead of writing to concrete
     outputs such as std::cout, std::cerr and etc.
   + To design an input agnostic function, use std::istream instead of
     a concrete input stream.

 + Documentation:
   + [[https://en.cppreference.com/w/cpp/io][Input/output library - cppreference.com]]
   + [[http://www.cplusplus.com/reference/ostream/ostream/][ostream - C++ Reference]]
   + [[http://www.cplusplus.com/reference/istream/istream/][istream - C++ Reference]]
   + [[http://www.cplusplus.com/reference/fstream/ifstream/][ifstream - C++ Reference]]

#+BEGIN_SRC cpp 
  namespace VectorIO{
     auto writeVector(std::ostream& os, const std::vector<double>& xs) -> void
     {
         os << "VECTOR";
         os << " ";
         for(auto x: xs)
                 os << x << " ";
         os << "\n";
         os.flush();
     }
     auto writeVector(std::ostream&& os, const std::vector<double>& xs) -> void
     {
         std::cerr << " [LOG] (writeVector) R-value reference" << "\n";
         writeVector(os, xs);
     }
     auto readVector(std::istream& is) -> std::vector<double>
     {
         std::vector<double> xlist;
         std::string label;
         is >> label;
         if(label != "VECTOR")
                 throw std::runtime_error("Error: wrong file layout.");
         double x;
         while(is.good() && !is.eof()){
                 is >> x;
                 xlist.push_back(x);
         }
         return xlist;
     }
     auto readVector(std::istream&& is) -> std::vector<double>
    {
         std::cerr << " [LOG] (readVector) R-value reference" << "\n";
         return readVector(is);
     }
  }
#+END_SRC

Main function: 

#+BEGIN_SRC cpp 
     using VectorIO::writeVector;
     using VectorIO::readVector;

     std::vector<double> vtest = {2.0, 4.0, 5.0, 10.0, 3.45, 9.5};

     std::cout << "\n TEST1 Writing to stdout (Standard output stream) " << "\n";
     writeVector(std::cout, vtest);

     std::cout << "\n TEST2 Writing to stderr (Standard error stream) " << "\n";
     writeVector(std::cerr, vtest);

     std::cout << "\n TEST3 Writing to std::stringstream " << "\n";
     std::stringstream fakeFile;
     writeVector(fakeFile, vtest);	
     std::cout << "fakeFile = " << fakeFile.str() << "\n";

     std::cout << "\n TEST4 Reading from std::stringstream " << "\n";
     auto out1 = readVector(fakeFile);
     writeVector(std::cout, out1);

     std::cout << "\n TEST5 Write to a file" << "\n";
     // Note: It is not possible without R-value reference.
     writeVector(std::ofstream("vector.txt"), vtest);

     std::cout << "\n TEST6 Read from file - Version 1" << "\n";
     // Call R-value reference version 
     auto out2 = readVector(std::ifstream("vector.txt"));
     writeVector(std::cout, out2);

     std::cout << "\n TEST7 Read from file - Version 2" << "\n";
     std::ifstream fd{"vector.txt"};
     // Call L-value reference version of readVector 
     auto out3 = readVector(fd);
     writeVector(std::cout, out3);
#+END_SRC

Output: 

#+BEGIN_SRC txt 
  $ clang++ polymorphic-io1.cpp -o polymorphic-io1.bin -g -std=c++11 -Wall -Wextra 
  $ ./polymorphic-io1.bin

   TEST1 Writing to stdout (Standard output stream) 
  VECTOR 2 4 5 10 3.45 9.5 

   TEST2 Writing to stderr (Standard error stream) 
  VECTOR 2 4 5 10 3.45 9.5 

   TEST3 Writing to std::stringstream 
  fakeFile = VECTOR 2 4 5 10 3.45 9.5 


   TEST4 Reading from std::stringstream 
  VECTOR 2 4 5 10 3.45 9.5 9.5 

   TEST5 Write to a file
   [LOG] (writeVector) R-value reference

   TEST6 Read from file - Version 1
   [LOG] (readVector) R-value reference
  VECTOR 2 4 5 10 3.45 9.5 9.5 

   TEST7 Read from file - Version 2
  VECTOR 2 4 5 10 3.45 9.5 9.5 
#+END_SRC

** Multiple booleans encoded as a single bitmask value 

 Note: It is not a design pattern, but a technique for encoding
 multiple booleans or flags inside a single value, passing multiple
 booleans as function parameters or returning multiple booleans as a
 single value.

 Example: 

  - File:  [[file:src/design-patterns/boolean-bitmask.C][file:src/design-patterns/boolean-bitmask.C]]  (CLING script)

 #+BEGIN_SRC cpp 
   #include <iostream>
   #include <vector>
   #include <ostream> // Operator: (<<)
   #include <string>

   enum class Permissions: unsigned {
       executable = 0x01,  // decimal = 1 or (1 << 0)
       writeable  = 0x02,  // decimal = 2 or (1 << 1)
       readable   = 0x04   // decimal = 4 or (1 << 2)
   };

   Permissions operator | (Permissions lhs, Permissions rhs){
       return static_cast<Permissions>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
   }
   bool operator & (Permissions lhs, Permissions rhs){
       return static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs);
   }
   // Make permissions enum printable. 
   std::ostream& operator<<(std::ostream& os, const Permissions& p){
       os << std::boolalpha; // Make bool printable as 'true' or 'false' instead of 0 or 1
       os << "readable = "   << (p & Permissions::readable)   << "; "
          << "writeable = "  << (p & Permissions::writeable)  << "; "
          << "executable = " << (p & Permissions::executable);
       return os;
   }
 #+END_SRC

 Running: 

 #+BEGIN_SRC cpp 
   // Load script 
   >> .L boolean-bitmask.C 

   >> std::cout << Permissions::readable << std::endl;
   readable = true; writeable = false; executable = false

   >> std::cout << Permissions::readable << "\n";
   readable = true; writeable = false; executable = false

   >> std::cout << Permissions::writeable << "\n";
   readable = false; writeable = true; executable = false

   >> std::cout << Permissions::executable << "\n";
   readable = false; writeable = false; executable = true

   >> auto p1 = Permissions::executable | Permissions::readable ;
   >> std::cout << "p1 => " << p1 << "\n";
   p1 => readable = true; writeable = false; executable = true
   >> 

   >> auto p2 = Permissions::executable | Permissions::readable | Permissions::writeable ;
   >> std::cout << "p2 => " << p2 << "\n";
   p2 => readable = true; writeable = true; executable = true
   >> 

   >> if(p1 & Permissions::readable) { std::cout << "File is readable" << "\n"; }
   File is readable
   >> 

 #+END_SRC

 Shows all flags or all bits that are set: 

 #+BEGIN_SRC cpp 
   void showPermissions(Permissions p){
           std::cout << "Is readable?     : " << (p & Permissions::readable)   << '\n';
           std::cout << "Is writeable?    : " << (p & Permissions::writeable)  << '\n';
           std::cout << "Is executable?   : " << (p & Permissions::executable) << '\n';
   }

   >> showPermissions(p1)
   Is readable?     : true
   Is writeable?    : false
   Is executable?   : true
   >> 
   >> showPermissions(p2)
   Is readable?     : true
   Is writeable?    : true
   Is executable?   : true
   >> 
 #+END_SRC

 Design 1: Function uses multiple bools creating a file with some
 permissions. 

 #+BEGIN_SRC cpp 
   using FilePerms = std::tuple<bool, bool, bool>;

   // Design 1:
   FilePerms createFileDD1(
        std::string name,
        bool readable,
        bool writeable,
        bool executable ){
        std::cout << std::boolalpha
                  << "Create file = " << name << "\n"
                  << " with the following permissions" << "\n"
                  << "  + readable   = " << readable   << "\n"
                  << "  + writeable  = " << writeable  << "\n"
                  << "  + executable = " << executable << "\n"
                  << "\n";
        return FilePerms {readable, writeable, executable};	
   }

   >> auto pd1 = createFileDD1("dataset.txt", true, false, false)
   Create file = dataset.txt
    with the following permissions
     + readable   = true
     + writeable  = false
     + executable = false

   >> pd1
   (std::tuple<bool, bool, bool> &) { true, false, false }
   >> 

   >> std::cout << "R = " << std::get<0>(pd1) << "\n";
   R = true
   >> std::cout << "W = " << std::get<1>(pd1) << "\n";
   W = false
   >> std::cout << "X = " << std::get<2>(pd1) << "\n";
   X = false
   >> 
 #+END_SRC

 Design 2: Use bitmask flags instead of bools. The advantage is more
 readability and less functions parameters. 

 #+BEGIN_SRC cpp 
   // Design 1:
   Permissions createFileDD2(std::string name, Permissions p){
        std::cout << std::boolalpha
                  << "Create file = " << name << "\n"
                  << " with the following permissions" << "\n"
                  << "  + readable   = " << (p & Permissions::readable)   << "\n"
                  << "  + writeable  = " << (p & Permissions::writeable)  << "\n"
                  << "  + executable = " << (p & Permissions::executable) << "\n"
                  << "\n";
        return p;
   }

   >> auto pd2 = createFileDD2("Sales-report.xls", Permissions::readable | Permissions::writeable)
   Create file = Sales-report.xls
    with the following permissions
     + readable   = true
     + writeable  = true
     + executable = false

   (Permissions)  : (unsigned int) 6
   >> 

   >> createFileDD2("parser.exe", Permissions::readable | Permissions::writeable | Create file = parser.exe
    with the following permissions
     + readable   = true
     + writeable  = true
     + executable = true

   (Permissions)  : (unsigned int) 7
   >> 

   >> std::cout << "R = " << (pd2 & Permissions::readable) << "\n";
   R = true
   >> std::cout << "W = " << (pd2 & Permissions::writeable) << "\n";
   W = true
   >> std::cout << "X = " << (pd2 & Permissions::executable) << "\n";
   X = false
 #+END_SRC

** Universal Polymorphic Factory 

This customized implementation of the polymorphic factory can
instantiate objects of any type, even if they don't have the same base
class. Another feature is that the factory class doesn't need to have
any knowledge about any base class. The trick used were templates;
void* pointers for type erasure of heap-objects; static objects for
registering classes in the factory and RTTI - for generating better
error messages and making the conversion from void* to the particular
class being instantiated safer.

 + File: [[file:src/design-patterns/factory-universal1.cpp][file:src/design-patterns/factory-universal1.cpp]]
 + Online Compiler: https://rextester.com/GKEBF89553

The class ~runtime_error_location~ class is used for providing exception
with better context information with the line and the file the
exception was generated.

#+BEGIN_SRC cpp 
  #define RUNTIME_ERROR_LOCATION(message)  \
          runtime_error_location(__LINE__, __FILE__, message)

  struct runtime_error_location: public std::exception {
      std::string  message;
      runtime_error_location(const std::string& text)
                  : message{text}
      {
      }
      runtime_error_location(
                  unsigned int line,
                  const std::string& file,
                  const std::string& text
                  )
          {
            message = file + ":" + std::to_string(line) + ": " + "Error: " + text;
          }
      auto what() const noexcept -> const char* {
          return message.c_str();
      }
  };
#+END_SRC

The UniversalFactory contains the static factory methods make and makeSafe
which returns an unique_ptr to an object instantiated on the heap. If
the factory method make fails it returns a nullptr without throwing an
exception and makeSafe returns an ~runtime_error_location~ exception if
there is a failure to instantiate.

Once the classes are registered, objects can be instantiated with: 

 + std::unique_ptr<BaseA> objectD = UniversalFactory::make<BaseClass>("DerivedClassD");
 + std::unique_ptr<BaseX> object1 = UniversalFactory::make<BaseClass>("DerivedClassY");

#+BEGIN_SRC cpp 
  class UniversalFactory{
  private:
        using FactoryMap = std::map<std::string, UniversalFactory*>;
        // Force global variable to be initialized, thus it avoid the
        // inialization order fisaco.
        static auto getRegister() -> FactoryMap& {
           static FactoryMap classRegister{};
           return classRegister;
        }
  public:
      // ========== Instance Methods ========//

      // Destructor
      virtual
      ~UniversalFactory() = default;

      // Encapsulates class constructor.
      // The type void* performs pointer type erasure
      virtual
      auto create() const -> void* = 0;

      // Encapsulates destructor 
      virtual
      auto destroy(void* object) const -> void = 0;

      virtual
      auto size() const -> size_t = 0;

      virtual
      auto typeinfo() const -> const std::type_info& = 0;

      // ========== Static Methods ========//

      /** Register factory object of derived class */
      static
      auto registerFactory(const std::string& name, UniversalFactory* factory) -> void {
           auto& reg = UniversalFactory::getRegister();
           reg[name] = factory;
      }
      /** Show all registered classes printing their name to stdout. */
      static
      auto showClasses() -> void {
          std::cout << " Registered classes. " << "\n";
          std::cout << " =================== " << "\n";
          for(const auto& pair: UniversalFactory::getRegister())
               std::cout << " + " << pair.first
                         << " ; RTTI name = "
                         << pair.second->typeinfo().name()
                         << " ; size (bytes) = "
                         << pair.second->size()
                         << "\n";
      }

      /** Attemp to instantiate a class, if it is not possible, returns nullptr */
      template<class BaseClass>
      static
      auto make(const std::string& name) -> std::unique_ptr<BaseClass> {
              FactoryMap& reg = UniversalFactory::getRegister();
              auto it = reg.find(name);
              if(it == reg.end())
                      return nullptr;
              // Avoid core dump if the conversion is not possible.
              if(it->second->typeinfo() != typeid(BaseClass))
                      return nullptr;
              void* ptr = it->second->create();
              return std::unique_ptr<BaseClass>(reinterpret_cast<BaseClass*>(ptr));
      }

      /** Attempt to instantiate class, if it is not possible throws an exception. */
      template<class BaseClass>
      static
      auto makeSafe(const std::string& name) -> std::unique_ptr<BaseClass> {
         // Throw exception for providing better context information and avoid
         // Core dump due to dangerous reinterpret_cast<>.
         auto object = UniversalFactory::make<BaseClass>(name);
         if(object == nullptr)
            throw RUNTIME_ERROR_LOCATION(
                 std::string("Cannot create type. Failed to cast void* to: ") + name);
         return object;
      }
  };  // -------- End Of class UniversalFactory() ------//

#+END_SRC

The class FactoryImpl is used for creating static objects (global
objects) for registering classes in the factory during the program
initialization. This class also performs type erasure of the
constructor and destructor by using void* for allowing it to work with
any type. 

#+BEGIN_SRC cpp 
  template<typename DerivedClass, typename BaseClass = DerivedClass>
  class FactoryImpl: UniversalFactory{
  private:
       const std::type_info& _tinfo;
  public:
       // Register this global object on the Factory register
       FactoryImpl(const std::string& name)
               : _tinfo(typeid(BaseClass))
       {
           std::cerr << " [TRACE] " << " Registered Class = " << name << "\n";
           UniversalFactory::registerFactory(name, this);
       }
       // Capture class default constructor => constructor type erasure 
       auto create() const -> void* override {
               return new DerivedClass;
       }
       // Capture destructor => Destructor type erasure 
       auto destroy(void* object) const -> void override {
               delete reinterpret_cast<BaseClass*>(object);
       }	
       auto typeinfo() const -> const std::type_info& override {
               return _tinfo;
       }
       auto size() const -> size_t override {
               return sizeof(DerivedClass);
       }
  };

#+END_SRC

 *Class Registration with static objects.*

Classes can be registered in the factory by creating an static
instance (static object) of the class FactoryImpl, which registers the
class or type passed as template parameter, during the object
initialization. 


 + The first template parameter is the class to be registered and the
   second one is its base class. If the class to be registered, doesn't
   have base class, it can omitted. The constructor argument is the name
   of the class to be registered as string.

 + The anonymous namespace in this example is used for defining
   internal linkage and making the static objects private or only
   visible in the current compilation unit or file for avoiding name
   clashes.

 + Note: The registered classes doesn't need to have a common base
   class, thus it is possible to register any class as the class
   NonDerived in the code below. 

#+BEGIN_SRC cpp 
  namespace {
     
     auto register_Base       = FactoryImpl<Base, Base>("Base");
     auto register_DerivedA   = FactoryImpl<DerivedA, Base>("DerivedA");
     auto register_DerivedB   = FactoryImpl<DerivedB, Base>("DerivedB");

     // Classes without a base class doesn't need the second template paramter 
     auto register_NonDerived = FactoryImpl<NonDerived>("NonDerived");
  }
#+END_SRC

The registration boilerplate can be eliminated by using macros:

#+BEGIN_SRC cpp 
  // Register a non-polymorphic class -> It means a class without base class 
  #define REGISTER_CLASS_TO_FACTORY1(aclass) \
          namespace {  auto register_ ## derived = FactoryImpl<aclass, aclass>( #aclass ); }

  // Register a polymorphic class to the factory.
  #define REGISTER_CLASS_TO_FACTORY2(derivedClass, baseClass) \
          namespace {  auto register_ ## derivedClass = FactoryImpl<derivedClass, baseClass>( #derivedClass ); }

  REGISTER_CLASS_TO_FACTORY2(Base, Base);
  REGISTER_CLASS_TO_FACTORY2(DerivedA, Base);
  REGISTER_CLASS_TO_FACTORY2(DerivedB, Base);
  REGISTER_CLASS_TO_FACTORY1(NonDerived);
#+END_SRC

 *Usage example in CERN's ROOT/Cling REPL:*

Load the proof-of-concept file

#+BEGIN_SRC cpp  
  >> .L factory-universal1.cpp 
   [TRACE]  Registered Class = Base
   [TRACE]  Registered Class = DerivedA
   [TRACE]  Registered Class = DerivedB
   [TRACE]  Registered Class = NonDerived
  >> 
  >> 
#+END_SRC

Instantiate some classes: 

#+BEGIN_SRC cpp 
  >> auto base = UniversalFactory::make<Base>("Base")
  (std::unique_ptr<Base, std::default_delete<Base> > &) @0x7f768c558088
  >> 

  >> base->getType()
  (std::string) "Base"
  >> 

  >> auto derivA = UniversalFactory::make<Base>("DerivedA")
  (std::unique_ptr<Base, std::default_delete<Base> > &) @0x7f768c5581f8

  >> derivA->showType()
  Class type = DerivedA

  >> auto derivB = UniversalFactory::make<Base>("DerivedB")
  (std::unique_ptr<Base, std::default_delete<Base> > &) @0x7f768c558238

  >> derivB->showType()
  Class type = DerivedB
  >> 

  for(const auto& cls : {"Base", "DerivedA", "DerivedB"} ){
      auto obj = UniversalFactory::makeSafe<Base>(cls);
      std::cout << "Class [" << cls << " ] = " << obj->getType() << " \n";
  }
  // Output: 
  Class [Base ] = Base 
  Class [DerivedA ] = DerivedA 
  Class [DerivedB ] = DerivedB 
  >> 

#+END_SRC

Show all registered classes 

#+BEGIN_SRC cpp  
  >> UniversalFactory::showClasses()
   Registered classes. 
   =================== 
   + Base ; RTTI name = 4Base ; size (bytes) = 8
   + DerivedA ; RTTI name = 4Base ; size (bytes) = 8
   + DerivedB ; RTTI name = 4Base ; size (bytes) = 8
   + NonDerived ; RTTI name = 10NonDerived ; size (bytes) = 1
  >> 
#+END_SRC

Instantiate a non-derived class: 

#+BEGIN_SRC cpp 
  // Instantiate a non derived class of Base 
  >> auto ndc = UniversalFactory::make<NonDerived>("NonDerived")
  (std::unique_ptr<NonDerived, std::default_delete<NonDerived> > &) @0x7f768c558138
  >> 

  >> ndc->printMessage();
   ==> I am a non derived class
  >> 
#+END_SRC

Try creating a class which is not registered

#+BEGIN_SRC cpp 
  // Returns a null pointer if there is a failure. 
  >> UniversalFactory::make<Base>("Error") == nullptr
  (bool) true

  >> UniversalFactory::make<DerivedA>("Error") == nullptr
  (bool) true
  >> 

  // makeSafe throws an exception 
  >> auto dummy = UniversalFactory::makeSafe<Base>("NonDerived");
  Error in <TRint::HandleTermInput()>: runtime_error_location caught: 
  factory-universal1.cpp:123: Error: Cannot create type. Failed to cast void* to: NonDerived
  >> 
#+END_SRC
** Visitor Design Pattern for class introspection and serialization

This variation of visitor design pattern presented in this section
allows to introspect a class instance, which makes possible to
transverse class fields; generate automated human-readable output of
member variables and other metadata and also serialize to many different
binary or human-readable text formats. Other significant features of
this technique is that the classes which performs serialization do
not need to know anything about the serializable classes and vice-versa.

File: 
  + [[file:src/design-patterns/visitor-instrospection.cpp][file:src/design-patterns/visitor-instrospection.cpp]]

Online Compiler:
  + https://rextester.com/VLHSG7293

Features: 
 + Transverse class fields.
 + Generate automated human-readable class description as string.
 + An instrospectable class can be serialized to many different
   formats such as XML, Jon, csv, binary and so on. 
 + Serialization code is independent from any instrospectable class
   and can be reused with any other class.

 *Description*

 + An instropectable class defines a member function describe which
   takes a visitor object and describe its fields and metadata to the
   visitor by calling the visitor methods .name, .id, .description and
   .field. Note that the class doesn't need to known anything about
   the visitor.
 + Summary: The method _describe_ describes class fields and additional
   metadata to an visitor object. 

#+BEGIN_SRC cpp 
  struct AClass{
        std::string name;
        int    n;
        double k;
        long   x;

        AClass(std::string name, int n, double k, long x)
          : name(name), n(n), k(k), x(x)  { }

        // Delegated constructor
        AClass(): AClass("unnamed", 10, 25.0, 1000) { }

        // Note: This method should be in the header file.
        // Every serializable class implements
        // a templated member function "describe"
        // which describe the class structure to
        // an visitor object.
        template<class Visitor>
        void describe(Visitor& v){
           v.name("AClass");   
           v.field(n, "n");
           v.field(k, "k");
           v.field(x, "x");
           v.field(name, "name");		
        }
  };
#+END_SRC

  + The visitor class DescriptionVisitor generates and print an
    automated human-readable description of class member variables.

#+BEGIN_SRC cpp 
  /** Print class information such as name and fields to stdout. */
  struct DescriptionVisitor{
       using cstring = const char*;

       template<class Described>
       void visit(Described& desc){
             desc.describe(*this);
       }
       void name(const std::string& className){
            std::cout << "Class name = " << className << "\n";
       }
       void field(int& value, cstring name){
            std::cout << " Field { name = " << name
                      << " ; type = int "
                      << " ; value = " << value << " }\n";
       }
       void field(long& value, cstring name){
            std::cout << " Field { name = " << name
                      << " ; type = long "
                      << " ; value = " << value << " }\n";	
       }
       void field(double& value, cstring name){
            std::cout << " Field { name = " << name
                      << " ; type = double "
                      << " ; value = " << value << " }\n";
       }
       void field(std::string& value, cstring name){
            std::cout << " Field { name = " << name
                      << " ; type = std::string "
                      << " ; value = " << value << " }\n";	
       }
  };
#+END_SRC

 + The visitor _WriterVisitor_ serializes to a stream any
   instrospectable class to human-readable text format.

#+BEGIN_SRC cpp 
  /** Serialize class data to stream in text format. */
  struct WriterVisitor{
      using cstring = const char*;
      std::ostream& _os;
      WriterVisitor(std::ostream& os): _os(os) { }

      template<class Described>
      void visit(Described& desc){
           desc.describe(*this);
      }
      void name(const std::string& className){		
      }
      template<class T>
      void field(T& x, cstring name){
           _os << x << " ";
      }
  };

#+END_SRC

  + The visitor _ReadVisitor_ deserializes any instrospectable class
    from stream. 

#+BEGIN_SRC cpp
  struct ReadVisitor{
      using cstring = const char*;
      std::istream& _is;

      ReadVisitor(std::istream& is): _is(is) { }

      template<class Described>
      void visit(Described& desc){
           desc.describe(*this);
      }
      void name(const std::string& className){		
      }
      template<class T>
      void field(T& value, cstring name){
           _is >> value;
      }
  };
#+END_SRC

  + The visitor _SerializeVisitor_ serializes any instrospectable class to a
    stream in binary format. 

#+BEGIN_SRC cpp 
  /** Serialize class data to stream in binary format. */
  struct SerializeVisitor{
      using cstring = const char*;
      std::ostream& _os;

      SerializeVisitor(std::ostream& os): _os(os) { }

      template<class Described>
      void visit(Described& desc){
            desc.describe(*this);
      }
      void name(const std::string& className){		
      }
      template<class T>
      void field(T& value, cstring name){
           _os.write((char*) &value, sizeof(T));
      }	
      void field(std::string& x, cstring name){
          //std::cerr << " [LOG] String serializer" << "\n";
          auto n = x.size();
          _os.write((char*) &n , sizeof(size_t));
          _os.write((char*) x.data(), n * sizeof(char));
      }
  };

#+END_SRC

 + The visitor _DeserializeVisitor_ performs the inverse operation of
   the visitor _SerializeVisitor_ by deserializing any instrospectable
   class from a stream. 

#+BEGIN_SRC cpp 
  struct DeserializeVisitor{
      using cstring = const char*;
      std::istream& _is;

      DeserializeVisitor(std::istream& is): _is(is) { }

      template<class Described>
      void visit(Described& desc){
           desc.describe(*this);
      }
      void name(const std::string& className){ }

      template<class T>
      void field(T& value, cstring name){
           _is.read((char*) &value, sizeof(T));
      }

      void field(std::string& x, cstring name){
           size_t n = 0;
           _is.read((char*) &n, sizeof(size_t));
           std::cerr << " [LOG] N = " << n << std::endl;
           x.resize(n);
           _is.read((char*) &x[0], n * sizeof(char));
      }
  };
#+END_SRC

 *Testing Code:*

Compiling and Running: 

#+BEGIN_SRC sh 
  $ clang++ visitor-instrospection.cpp -o visitor-instrospection.bin -g -std=c++1z -Wall 
  $ ./visitor-instrospection.bin
#+END_SRC

Testing object:

#+BEGIN_SRC cpp 
   AClass cls1("objectA", 200, -2.34, 900);
#+END_SRC


 + _Experiment_: Print automated human-readable class description to stdout.

#+BEGIN_SRC cpp 
   std::cout << "\n===== EXPERIMENT 1 ===========" << std::endl;
   descVisitor.visit(cls1);
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ===== EXPERIMENT 1 ===========
   Class name = AClass
    Field { name = n ; type = int  ; value = 200 }
    Field { name = k ; type = double  ; value = -2.34 }
    Field { name = x ; type = long  ; value = 900 }
    Field { name = name ; type = std::string  ; value = objectA }
#+END_SRC

 + _Experiment_:  Text Serialization/Deserialization
   + Note: In addition to stringstream, the writer visitor can be used
     with any type of stream, including, file stream or output stream
     std::cout. The std::stringstream was used here for simulating as
     a file mock object. 

#+BEGIN_SRC cpp 
    auto pseudoFile = std::stringstream{};
    auto writer     = WriterVisitor(pseudoFile);
    writer.visit(cls1);

    auto reader = ReadVisitor(pseudoFile);
    AClass clsb;
    reader.visit(clsb);
    descVisitor.visit(clsb);
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ==> pseudoFile = 200 -2.34 900 objectA 

  Class name = AClass
   Field { name = n ; type = int  ; value = 200 }
   Field { name = k ; type = double  ; value = -2.34 }
   Field { name = x ; type = long  ; value = 900 }
   Field { name = name ; type = std::string  ; value = objectA }
#+END_SRC

 + _Experiment_: Serialize class in binary format to a pseudo-file
   (std::stringstream)

#+BEGIN_SRC cpp 
   std::cout << "\n===== EXPERIMENT 5 == Serialize to file ===========" << std::endl;
   auto mockFile = std::stringstream{};
   auto serializer = SerializeVisitor(mockFile);
   serializer.visit(cls1);

   std::cout << "Stream = " << stringToHex(mockFile.str()) << std::endl;
#+END_SRC

Output: 

#+BEGIN_SRC text 
   Stream = \xc8\x00\x00\x00\xb8\x1e\x85\xebQ \xb8\x02\xc0\x84\x03\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00o b j e c t A 
#+END_SRC

 + _Experiment_: Deserialize class from stream. 

#+BEGIN_SRC cpp 
   auto deserializer = DeserializeVisitor(mockFile);
   AClass cls2;
   deserializer.visit(cls2);
   descVisitor.visit(cls2);
#+END_SRC

Output:

#+BEGIN_SRC text 
   ===== EXPERIMENT 6 == Deserialize from file ===========
    [LOG] N = 7
   Class name = AClass
    Field { name = n ; type = int  ; value = 200 }
    Field { name = k ; type = double  ; value = -2.34 }
    Field { name = x ; type = long  ; value = 900 }
    Field { name = name ; type = std::string  ; value = objectA }
#+END_SRC

Remarks and considerations: 

 + The size of types integers types, namely, int, short and long are
   platform dependent which can make any serialization code relying on
   them not portable across different platforms. In order to overcome this
   problem, it is necessary to use fixed size integers available at
   header [[https://en.cppreference.com/w/cpp/header/cstdint][<cstdint>]].

 + The visitor code request other metadata such as class unique ID,
   GUID (Global Unique Identifier), field long description and so on.

 + It is also possible to define visitor for XML, csv and json
   serialization. 

 *Inspired by:*

 + [[http://4thmouse.com/mystuff/articles/TemplateVisitor.html][Templatized Visitor Pattern]]
 + [[http://cbloomrants.blogspot.com/2013/02/02-16-13-reflection-visitor-pattern.html][cbloom rants: 02-16-13 - The Reflection Visitor Pattern]]
 + [[https://gamedevcoder.wordpress.com/2013/02/16/c-plus-plus-rtti-for-games/][Practical C++ RTTI for games | Gamedev Coder Diary]]
 + [[https://medium.com/@swortelbernux/libraryless-reflection-in-c-288d7873e3a6][Static Visitor Reflection in C++ – Swort Elbernux – Medium]]
 + [[https://stackoverflow.com/questions/2072838/is-there-a-better-design-pattern-method-to-use][c++ - Is there a better design pattern/method to use? - Stack Overflow]]
 + [[https://stackoverflow.com/questions/2555712/c-visitor-pattern-handling-templated-string-types][C++ visitor pattern handling templated string types? - Stack Overflow]]
 + [[https://www.gamedev.net/forums/topic/553884-crtp-and-dynamic-dispatch/][CRTP and dynamic dispatch - General and Gameplay Programming - GameDev.net]]


