#+INCLUDE: theme/style.org
#+TITLE: CPP / C++ Notes 
#+DESCRIPTION: cpp c++ code examples, demonstrations, design pattern and integration.
#+STARTUP: content 

* Understanding C++ 
** Features 
*** C++ Benefits and Costs 

 Some C++ compelling features which sets it apart from most
 programming languages are: 

  *Advatanges*:

  + Compilation to native code - makes the code faster as it does not
    need to be interpreted and easier to deploye as the number of
    dependencies are minimized. Another advantage of native code is the
    obfuscation for free what makes it hard and more costly to reverse
    engineer. 

  + High Performance and zero-cost abstractions. 

  + Hardware portability and compiler availability for many processor
    and hardware architechtures. C++ has the widest range of processor
    support, so it can run on mainstream x86, desktop processors;
    mobile phone ARM-based CPUs; GPUs; embedded processors and
    microcontrollers.

  + Direct access to the operating system C-API and system calls. 

  + Interoperability with C libraries.

  + Direct Access to Memory which is important on embedded systems for
    accessing memory-mapped IO devices.

  + *Perfomance-oriented language:* C++ has many features which can help
    get the maximum performance as possible from the hardware:
    + Native Code Compilation
    + Strong static typing
    + Compiler optimizations
    + Inline functions
    + Templates
    + Pointers 
    + Lack of garbage collector 
    + Custom-allocators 
    + Lots of optimized standard data structures (STL containers)
    + Inline-assembly -> The inline-assembly support is compiler
      specific and not required by the standard. Assembly is also
      processor-specific and not portable.
    + Insider knowledge of compiler makers about the operating system
      and the processor architechture.

  *Disadvantages:*

  + Language complexity

  + Tooling
    + Due to the C++ complexity, it is hard to parse C++ code and
      consequently build code assintance tools such as refactoring
      tools, IDEs, linters, code generators and so on. This shortcoming
      is being addressed by Clang/LLVM tools that provide libraries for
      parsing C++ code. 

  + Slow compile-time

  + Compiler's cryptic error messages.

  + Lack of garbage collector. While the lack of this feature can help
    to achieve better performance and efficiency, it requires manual
    memory management which can be error prone and lead to memory
    leaks. However, smart pointers and the RAAI technique can help to
    solve this issue.

  + Lack of a comprehensive standard library.
    + The standard library still lacks lots of libraries that other
      programming languages take for granted such as CSV parsers, XML
      parsers, database drivers, graphical user interfaces and so on. 

  + ABI - Application Binary Interface Issues - due the
    non-standardized ABI, it is almost impossible to link object-code
    (aka compiled code) compiled with different compilers. This is why,
    unlike Java and C#,  there is almost no pre-compiled libraries for
    C++ what makes the binary reuse hard.

  + Lack of agreed package manager.
    + While there are many C++ package, there still no standard one
      yet. Due to ABI issues, C++ package managers only provide
      packages in source format andd don't provide precompiled packages
      as shared libraries or static libraries as Java package manager
      do.

*** C++ Language features

 C++ Supported Paradigms: 

  + _Imperative / Procedural_ as C and Pascal

  + _Object Oriented_

  + _Functional Programmign_ since C++11 with the introduction type
    deduction (auto keyword) and lambda functions.

  + _Generic Programming_ - Template metaprogramming, a combination of
    statically typed duck-typing and lisp-like metaprogramming that
    allows efficient code generation at compile-time.

 Other Features: 

  + Automatic memory management.
  + No garbage collector.
  + Low level access to system and operating system services or API in
    a similar way to C.

*** C++ New Features and Standards

  + *C++98* - *ISO/IEC 14882:1998*
    + Old C++ standard.


  + *C++03* - *ISO/IEC 14882:2003*


  + *C++11* - *ISO/IEC 14882:2011*
    + C++11 Working Draft  http://wg21.link/n3242
    + See:
      + [[https://isocpp.org/wiki/faq/cpp11-language#auto][C++11 Language Extensions — General Features, C++ FAQ]]
      + http://www.windowscpp.com/CPP11FAQ.htm
    + Features which supports Functional Programming
      + auto keyworkd for type deduction (aka type inference)
        + Which relieves the developer from writing all types and
          simplifies the code.
      + Lambda functions and std::function
        - Introduces the functional programming paradigm in C++ allowing
          users to write higher-order functions and reusable algorithms.
      + Tuples
        + allows returning multiple values
      + Move Semantics:
        - Transfer resource ownership from temporary objects. This
          feature removes the runtime overhead of temporary objects and
          also allows to return containers such as vectors, string and
          etc from functions without runtime overhed or deep copy.
    + Library Support
      + Smart Pointers => ~unique_ptr~ and ~shared_ptr~
        - Provides memory and resource management making the programs
          less prone to memory or resource leaks. Those pointers
          implments the RAII (Resource Acquisition is Initialization)
          idiom which takes advantage of C++ deterministic destructor for
          releasing resources no longer needed.
      + Regex
      + Cross-platform concurrency features.
        + Example: threads, monitors and locks which works on all
          supported platforms and operating systems.
    + Misc
      + nullpr - type-safe null pointer
      + Ranged-based loop
    + Compile-time metaprogramming features
      + Variadic Templates
      + Contexpr
        - Allows compile-time computations such as computing
          random numbers, encrypting string at runtime or generating
          look-up tables.
      + Static assert
      + String literals
      + User-defined literals


  + *C++14* - *ISO/IEC 14882:2014*
    + C++14 Working Draft - http://wg21.link/n4296
    + See: [[https://isocpp.org/wiki/faq/cpp14-language][C++14 Language Extensions, C++ FAQ]]
    + _Binary Literals_: int x = 0b1001001 -> This feature is useful for
      embedded systems and dealing with bitmasks and hardware
      registers.
    + _Digit Separators_ - allows to write the number pi = 3.1415927 as pi = 3.141'592'7
    + _Generalized return type deduction_.
    + decltype(auto)
    + Genric Lambda - Now it is possible to use the keyword auto for
      deducing or infering the type of lambda arguments.
    + Variable Templates
    + _Extended Constexpr_ - contexpr functions can have loops, mutating
      variables and don't need to be recursive as it was before,
      consequently constexpr is able to peform more complex
      compile-time computations.
    + [ [ deprecated ] ] attribute -> enables annotating an entity as
      deprecated and prints a compilation warn if a deprecated entity
      is used.


  + *C++17* - *ISO/IEC 14882:2017*
    + C++17 Working Draft - http://wg21.link/n4659
    + See:
      + http://www.cppstd17.com/
      + https://isocpp.org/wiki/faq/cpp17-language
      + [[https://www.infoworld.com/article/3044727/application-development/qa-bjarne-stroustrup-previews-c-17.html][Q&A: Bjarne Stroustrup previews C++ 17 | InfoWorld]]
    + std::any
    + std::variant
    + std::optional
    + std::string_view - Paper: [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3921.html][ISO/IEC JTC1 SC22 WG21 N3921]]
    + std::file_system - Paper: [[https://isocpp.org/files/papers/P0218r1.html][P0218R1]]
    + Structured bindings - key, value decomposition - Paper: [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0217r3.html][P0217R3]]
    + Constexpr if - Paper: [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r2.html][P0292R2]]
    + Init statements for if and switch - Paper: [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html][P0305R1]]
    + Folding Expressions - Paper: [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4295.html][N4295]]
    + Parallel algorithms
    + Nested namespaces - Paper: [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4230.html][N4230]]
    + Inline Variables - Paper: [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0386r2.pdf][P0386R]]
    + ... and much more ...!!

  + *C++20* - Coming soon.

 Compiler Support:

  + [[https://en.cppreference.com/w/cpp/compiler_support][C++ compiler support - cppreference.com]]
  + [[https://www.gnu.org/software/gcc/projects/cxx-status.html][C++ Standards Support in GCC - GNU Project - Free Software Foundation (FSF)]]
  + [[https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler][C++17 Features Supported by Intel® C++ Compiler | Intel® Software]]
  + [[https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance?view=vs-2017][Visual C++ Language Conformance | Microsoft Docs]]

** C++ Comparison and Alternatives
*** C++ Comparison with Java and C#

 General overview: Unlike most object oriented languages such as Java
 and C#, C++ doesn't have a class hierarchy, single inheritance,
 garbage collection and a comprehensive standard library. However in
 some situations, C++ benefits such as direct access to the operating
 system, memory, system calls and low level; interoperability with C
 libraries; and above all, high performance computing may offset the
 language complexity costs.

 This table shows a comparison between C++ and mainstreams object
 oriented programming languages like Java and C#.

 #+CAPTION: Comparison C++ X Mainstream high level programming languages (C#, Java, Python ...)
 | Feature                                | C++                                   | Java                | C# - .NET           |
 |----------------------------------------+---------------------------------------+---------------------+---------------------|
 | Native Code                            | Yes                                   | No                  | No                  |
 | JIT - Just-In-Time Compilation         | No  - No needed, since C++ is native. | Yes                 | Yes                 |
 | Virtual Machine                        | No                                    | Yes                 | Yes                 |
 | Garbage Collection                     | No                                    | Yes                 | Yes                 |
 | Memory Management                      | semi-automatic                        | auto                | auto                |
 |                                        |                                       |                     |                     |
 | *Object Oriented Features*               |                                       |                     |                     |
 | OOP - Object Oriented                  | Yes                                   | Yes                 | Yes                 |
 | Class Hierarchy                        | No                                    | Yes                 | Yes                 |
 | Reflection                             | No                                    | Yes                 | Yes                 |
 | Single Inheritance                     | No                                    | Yes                 | Yes                 |
 | Multiple Inheritance                   | Yes                                   | No                  | No                  |
 | Properties                             | No                                    | No                  | Yes                 |
 | Inner classes, aka nested classes      | Yes                                   | Yes                 | Yes                 |
 | Anonymous classes                      | No                                    | Yes                 | No                  |
 | Operator Overloading                   | Yes                                   | Not                 | Yes                 |
 | Marshalling                            |                                       |                     |                     |
 | Conditional Compilation - preprocessor | Yes                                   | No                  | Yes                 |
 | Lambda functions                       | Yes  - since C++11                    | Yes - since Java 8  | Yes                 |
 | Generics                               | Yes                                   | Yes                 | Yes                 |
 | *Template metaprogramming              | Yes                                   | No                  | No                  |
 | Dependency, package manager            | No                                    | Yes                 | Yes                 |
 |                                        |                                       |                     |                     |
 | *Standard Library Features*              |                                       |                     |                     |
 | Broad Cross Platform Support           | No - Provided by boost library.       | Yes                 | No                  |
 | GUI toolkit in standard library        | No                                    | Yes - Swing, JavaFX | Yes - WinForms, WPF |
 | Collection Library                     | Yes - STL.                            | Yes                 | Yes                 |
 | Sockets                                | No - Provided Boost library.          | No                  | No                  |
 | Threads                                | Yes. Since, C++11                     | Yes                 | Yes                 |
 | File System                            | C++ 11 -> No, C++17 -> Yes.           | Yes                 | Yes                 |
 |                                        |                                       |                     |                     |
 |                                        |                                       |                     |                     |

  *Notes and observations:*

  + _Class Hierarchy_ => In Java, every object inherits from the root
    class java.lang.Object. Objects can be cased from its Class or to
    'Object'. It also allows put multiple unrelated java objects in the
    same container. C# too has a root class System.Object from which
    all classes inherits:
    * [[https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html][Object (Java Platform SE 7 )]]
    * [[https://docs.microsoft.com/en-us/dotnet/api/system.object.-ctor?view=netframework-4.7.2#System_Object__ctor][Object Constructor (System) | Microsoft Docs]]
    * [[https://en.wikibooks.org/wiki/Java_Programming/Generics][Generics - Wikibooks, open books for an open world]]

  + _Virtual Machine_ => The [[https://en.wikipedia.org/wiki/C%252B%252B/CLI][C++/CLI]] implementation, also known as
    Managed C++ runs in the .NET virtual machine and has garbarge
    collector. But this implementation is only supported on Windows.

  + _C++ DO have package managers_ such as [[https://conan.io/][Conan]], [[http://www.buckaroo.pm/][Buckaroo]] and [[https://docs.microsoft.com/en-us/cpp/vcpkg?view=vs-2017][Vcpkg]]. But
    they are not standard and not widely adopted. In addition, C++
    package managers generally don't provide pre-compiled packages as
    Java and C# / .NET. Actually, due to non standard ABI - Application
    Binary Interface issues, they only provide source packages that are
    compiled locally. As far it is known, the C++ package managers also
    don't provide a way to install C-shared libraries dependencies
    locally such as GNU-scientific library, Opengl, OpenCV, Gtk,
    Blas-Lapack shared libraries and so on.


  *Main Differences between C++ and other languages*

  + _Value Semantics_
    + Classes are trated as primitive types by default.

  + _Stack or Heap Allocation_
    + Objects can be allocated on the stack and on the heap.

  + _No Garbage Collection_
    + Although, there is no garbage collection, the memory management
      can be performed in semi-automatic way by using smart pointers
      from C++11 unique_ptr or shared_ptr. The shared_ptr can emulate
      garbage collectors as it uses an internal reference counter. 

  + _Deterministic Destructor_
    + The destructor method is always called when an object goes out of
      scope or an exception happens.

  + _Many types of constructors_
    + C++ has the default constructor, copy constructor and move
      constructor.

  + _Many types of inheritance_
    + public, protected, private and virtual inheritance.

  + _Template Metaprogramming / Generic Programming_
    + Which allows generics and type-safe code generation with zero
      rutime overhead.

  + _Pointers_
    + Most languages doesn't provide access to pointers and calling C-libraries directly. 

  + _Minimal standard library_
    + Lacks many things other languages have for granted such as
      database drivers, sockets, SSL/TSL, file system, user interfaces
      and so on. Note: only on C++17 that C++ has file system access
      derived from Boost.FileSystem the standard library.

 *C++ Terminology* 

 C++ has a different terminology from mainstream programming languages
 which is shown in the following table.

 #+CAPTION: C++ terminology simplification 
 | C++                    | Other OOP Languages                             | Comment                                                                                   |
 |                        | i.e: Java, Python, ...                          |                                                                                           |
 |------------------------+-------------------------------------------------+-------------------------------------------------------------------------------------------|
 | Class                  | Class                                           | C++ class' fields and methods are private by default.                                     |
 | Struct                 | Class                                           | A C++ is the same as a Class, but fields and methods are public by default.               |
 | Class or Struct        | Abstract Class                                  | A C++ abstract class have at least one _virtual function_.                                  |
 | Class or Struct        | Interface                                       | A C++ interface is a class signature with only pure virtual functions (abstract methods.) |
 |                        |                                                 |                                                                                           |
 | Member Function        | Instance methods                                |                                                                                           |
 | Static Member Function | Static method                                   |                                                                                           |
 | Virtual Functions      | -                                               | Only methods annoted with virtual  can overriden by subclasses                            |
 | Non Virtual Functions  | -                                               | Methods without _virtual_ annotation cannot be overriden by subclasses.                     |
 | Pure Virtual Function  | Abstract method (method without implementation) |                                                                                           |
 | STL Containers         | Collection library - Lists, Maps, Tuples ...    | C++ name its collections as containters                                                   |
 |                        |                                                 |                                                                                           |


 *Java X C++ Collections Comparison*


 | Java                 | C++                |
 |----------------------+--------------------|
 | java.util.ArrayList  | std::vector        |
 | java.util.LinkedList | std::list          |
 | java.util.Stack      | std::stack         |
 | java.util.Queue      | std::queue         |
 | java.util.Deque      | std::deque         |
 | java.util.TreeSet    | std::set           |
 | java.util.HashSet    | std::unordered_set |
 | java.util.TreeMap    | std::map           |
 | java.util.HashMap    | std::unordered_map |
 |                      |                    |
  
                     
 See: 
   + [[wiki-asset-sys:C++ - CPP Programming;CppFor Java Programmers - Hans Dulimatra.pdf][CppFor Java Programmers - Hans Dulimatra.pdf]]
   + [[https://en.wikiversity.org/wiki/Java_Collections_Overview][Java Collections Overview - Wikiversity]]

*** Comparison C X C++(CPP)

 One of the most compelling advantages of C++ is the compatibility with
 C programming language and the ability to interoperate with C code and
 C shared libraries. The interoperability with C is necessary as it is
 the fundamental language of system programming which most operating
 systems, programming languages and domain-specific shared libraries
 such as GSL (GNU Scientific Library) or OpengGL are implemented. In
 addition, most operating system APIs and services are available or
 exposed in C.

 While previous knowledge of C is not required for learning C++, it is
 still necessary to know at least how to read C code in order to access
 it from C++ or to create high level C++ wrappers to it. 

 Note: C++ is not C with classes, it is complete different language,
 however it inherits many concepts from C and supports a subset from C
 and it is even possible to compile many C code with a C++ compiler.

 Some applications implemented in C:

  + Linux Kernel 
  + Free BSD operating system 
  + Windows API - Win32
  + U-nix sockets API. 
  + OpenGL
  + Gtk GUI Toolkit
  + X-Windows System
  + Python Programming Language (CPython Interpreter)
  + Ruby Programming Language
  + Lua Programming Language 


 | Feature                         | C++ / CPP - C Plus Plus                                                 | C                                                          |
 |---------------------------------+-------------------------------------------------------------------------+------------------------------------------------------------|
 | Creator                         | Bjarne Stroustrup                                                       | Dennis Ritchie                                             |
 | Paradigms                       | Imperative, Object Orientated, Gneric / Meta programming and Functional | Procedural / Imperative                                    |
 | Some use cases                  | High Performance Computing, Embedded Systems, Games, ...                | System programming and embedded systems ...                |
 | Standard ABI                    | No                                                                      | Yes                                                        |
 | Collection Library (Containers) | Yes - STL (standard) and others.                                        | No                                                         |
 | Garbage Collector               | No                                                                      | No                                                         |
 | Memory Management               | Manual and Semi automatic (provided by smart pointers.)                 | Manual                                                     |
 | Error Handling Mechanism        | Function return values, global flags and exceptions.                    | Function return values and  global flags such as errno     |
 | Exceptions                      | Yes                                                                     | No                                                         |
 | Namespaces                      | Yes                                                                     | No                                                         |
 | File Extensions                 | .cpp (c++ source code) and .hpp (c++ header file).                      | .c (C-source code) and .h (header file)                    |
 | Metaprogramming facilities      | Macros + Templates + Inline Functions + Contexptr                       | Macros                                                     |
 | String Manipulation             | std::string                                                             | C doesn't have string types, just array of characters.     |
 | Direct Access to Memory         | yes - using ~reinterpret_cast~ or C-style casting.                        | yes - using C-style casting.                               |
 | Run barebones without OS        | yes                                                                     | yes - C has more compillers for embedded devices than C++. |
 | Threads in standard library     | Yes - since C++11                                                       | No - It is platform dependent.                             |
 |---------------------------------+-------------------------------------------------------------------------+------------------------------------------------------------|

   + Direct Access to Memory:
     + Note: It means direct access to a memory location given by its
       address. This feature is used for accessing [[https://en.wikipedia.org/wiki/Memory-mapped_I/O][memory mapped IO]] in
       embedded systems and low level system programming.

 *File Extensions*

    + Source Files
      + *.cpp - C++ source files.
      + *.hpp - C++ header files.
      + *.o   - Object Code

    + Windows
      - *.exe - PE32 - Windows Executable
      - *.dll - Windows Shared Library

    + Unix (Linux, BSD ...)
      - (No extension or *.bin) - ELF - Unix Executable
      - *.so - Unix Shared Library

 *Primitive Data Types*

 | Type           | stdint.h type | Size (Bytes) | Size (Bits) | Range       | Description                                          |
 |----------------+---------------+--------------+-------------+-------------+------------------------------------------------------|
 | bool           |               |            1 |           8 |             | Boolean 0 (false) or 1 (true)                        |
 | char           |               |            1 |           8 |             | Ascii character                                      |
 | unsigned char  | uint8_t       |            1 |           8 | 0 to 255    | 1 byte integer                                       |
 | signed char    | int8_t        |            1 |           8 | -128 to 127 |                                                      |
 |                |               |              |             |             |                                                      |
 | short          | int16_t       |            2 |          16 |             | 16 bits signed integer                               |
 | unsigned short | uint16_t      |            2 |          16 |             |                                                      |
 |                |               |              |             |             |                                                      |
 | int            | int32_t       |            4 |          32 |             | 32 bits signed integer                               |
 | unsigned int   | uint32_t      |            4 |          32 |             | 32 bits unsigned integer                             |
 |                |               |              |             |             |                                                      |
 |                |               |              |             |             |                                                      |
 | float          |               |            4 |          32 |             | 32 bits IEEE 754 single-precision float point number |
 | double         |               |            8 |          64 |             | 64 bits IEEE 754 double-precision float point Number |
 | long double    |               |           10 |          80 |             | Extended precision non-IEEE float point number       |
 |                |               |              |             |             |                                                      |


  - Note: The type char can be understood as an 8-bits integer. 

** Minimal C++ Programs
*** Simple minimal C++ program 

 + File: [[file:src/minimal-program1.cpp][file:src/minimal-program1.cpp]]

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

  int main(){
      std::cout << "Hello world user" << "\n";
      std::cout << "Enter your name: ";
      std::string name;
      std::getline(std::cin, name);
      std::cout << "Be welcome to C++ land: " << name << "\n";

      // Wait user type a single character
      std::cout << "\n" << "Type RETURN to exit";
      // Read a character from standard input (console)
      std::cin.get();

      // Status code
      return 0;
  }

#+END_SRC

Note: The following code is necessary to allow inspecting the program
output on Windows after the user click at it. This code prevents the
program from exiting immediately by asking the user to type Return key
to proceed. It is not necessary on Linux or any other U*nix-like
operating system such as Mac OSX or BSD.

#+BEGIN_SRC cpp 
   std::cout << "\n" << "Type RETURN to exit";
   // Read a character from standard input (console)
   std::cin.get();
#+END_SRC

The main() function returns 0 (zero) as _status code_ for indicating
that the program was terminated gracefully or any value other than
zero indicate that program was terminated with failure.

#+BEGIN_SRC cpp 
  return 0;
#+END_SRC

The main function could aso return: 

 + To indicate success. Same as returning (0). 
 
#+BEGIN_SRC cpp 
 // Same as 0 
 return EXIT_SUCCESS; 
#+END_SRC

 + To indicate failure. Same as returning (1) 

#+BEGIN_SRC cpp 
 return EXIT_FAILURE;
#+END_SRC


 *Compiling and running:*

 + Compilation flags: 
   * -o <filename>
     + => Sets the name of the executable generated by the
       compiler. If executable name is not set, the compiler will
       generate the file a.out on *Nix like systems (Linux, MacOSX,
       FreeBSD and etc.) or a.exe on Windows.
   * -std=c++14
     + => Enable C++14 Features. It could also be -std=c++11 (for
       C++11 features), -std=c++1z (for C++17 features)
   * -g
     + => Generate debug symbols
   * -Wall
     + Increase verbosity level.

 + Compiling with Clang
   + => Clang compiler provides better error diagnosing and more
     user friendly debug messages than other compilers.

#+BEGIN_SRC cpp 
 $ clang++ minimal-program1.cpp -o minimal-program1.bin -g -std=c++14 -Wall 
#+END_SRC
 
 + Compiling with GCC

#+BEGIN_SRC cpp 
 $ g++ minimal-program1.cpp -o minimal-program1.bin -g -std=c++14 -Wall  
#+END_SRC

 + Compiling on Windows with Mingw (GCC for Windows) 
   + On Windows, the executable can be run by just clicking on it.

#+BEGIN_SRC cpp 
 $ g++ minimal-program1.cpp -o minimal-program1.exe -g -std=c++14 -Wall 
 // On Console (cmd.exe)
 $ minimal-program1.exe 
 // Or 
#+END_SRC

The compilation produces a *native executable* with: 

 + Specific _binary format_ required by operating system. On Linux,
   Android and BSD variants this format is _ELF_ (Executable Linkable
   Format); on Windows, this binary format is _PE32_ or _PE64_ (Portable
   Executable) and on MacOSX this format is _MachO_.

 + _Specifc machine code_ (Instruction set) for the processor
   architecture the program was compiled. The most common processor
   architecture used in servers and desktop computers are Intel-x86
   and Amd-x86-x64. For consumer mobile devices, the most common
   processors are the _ARM-based processors_ that are used in many
   Android-based phones, IPhone, IPad and etc.

 + Specific _system-calls_ and library calls for the operating system the
   program was compiled for.

 + Additional Notes:

   + A compiled C++ program generally cannot be run in other operating
     because different operating systems have different binary
     executable formats, different systems calls and core libraries.

   + The Wine project allows running programs compiled on Windows on
     U-nix like operating systems, including Linux, BSD and MacOSX by
     translating the PE32 binary format and the Windows system-calls
     to the host OS system call.

   + C++ programs can also be compiled to run [[https://en.wikipedia.org/wiki/Bare_machine][bare metal]], it means
     without any operating system. This type of compilation is widely
     used for embedded systems, microcontrollers, firmwares, BIOs,
     operating systems and so on.

 *Running:*

#+BEGIN_SRC cpp 
  $ ./minimal-program1.bin 
  Hello world user
  Enter your name: Somebody else
  Be welcome to C++ land: Somebody else

  Type RETURN to exit
#+END_SRC
*** Variations of main function 
**** Overview 

The main function can have the following variations: 

 + Simple main function.

#+BEGIN_SRC cpp 
   int main();
#+END_SRC

 + Main function with command line arguments

#+BEGIN_SRC cpp 
   int main(int argc, char **argv);
#+END_SRC

 + Main function with command line arguments and environment
   variables. 

#+BEGIN_SRC cpp 
  int main(int argc, char **argv, char **environ);
#+END_SRC
**** Example: Minimal program with command line arguments

Exmaple: Command line arguments. 

 + File: [[file:src/minimal-program2.cpp][file:src/minimal-program2.cpp]]

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

  int main(int argc, char **argv, char **environ){
      if(argc < 2){
         std::cerr << "Error: invalid command line argument. Expected -args or -env "
                   << "\n";
         // Exit  immediately (return 1)
         return EXIT_FAILURE; 
      }

      if(std::string(argv[1]) == "-args"){
         std::cout << "Number of command line arguments = " << argc << "\n";
         std::cout << "argv[0] = " << argv[0] << "\n";
         std::cout << "\n";
         std::cout << "Showing command line arguments:" << "\n";
         std::cout << "+-----------------------------+" << "\n";
         for(int i = 0; i < argc; i++)
                 std::cout << "argv[" << i << "] = " << argv[i] << "\n";		
         return EXIT_SUCCESS;
      }

      if(std::string(argv[1]) == "-env"){
         std::cout << "Show environment variables" << "\n";
         char** env = environ;
         while(*(env++) != nullptr)
                 std::cout << " => env = " << *env << "\n";
         return EXIT_SUCCESS;

      }
      std::cerr << "Error: invalid argument <" <<  argv[1] << "> " <<"\n";     
      // return 1
      return EXIT_FAILURE;
  };
#+END_SRC

Compiling: 

#+BEGIN_SRC sh
  $ clang++ minimal-program2.cpp -o minimal-program2.bin -g -std=c++1z -Wall
#+END_SRC

Running: 

#+BEGIN_SRC text 
  $ ./minimal-program2.bin 
  Error: invalid command line argument. Expected -args or -env 

  $ ./minimal-program2.bin -args opt1 opt2 key=value
  Number of command line arguments = 5
  argv[0] = ./minimal-program2.bin

  Showing command line arguments:
  +-----------------------------+
  argv[0] = ./minimal-program2.bin
  argv[1] = -args
  argv[2] = opt1
  argv[3] = opt2
  argv[4] = key=value

  $ ./minimal-program2.bin sadsad
  Error: invalid argument <sadsad> 

  $ ./minimal-program2.bin -env
  Show environment variables
   => env = LD_LIBRARY_PATH=:/home/archbox/opt/root/lib:/home/archbox/opt...
   => env = XDG_MENU_PREFIX=gnome-
   => env = MODULES_RUN_QUARANTINE=LD_LIBRARY_PATH
   => env = LANG=en_CA.UTF-8
   => env = GDM_LANG=en_CA.UTF-8
   => env = HISTCONTROL=ignoredups
   => env = DISPLAY=:0
   => env = HOSTNAME=localhost.localdomain
   => env = OLDPWD=/home/archbox/Documents/projects/learn.cpp
   => env = GNOME_SHELL_SESSION_MODE=classic
   ... ... ... 
   => env = MODULES_CMD=/usr/share/Modules/libexec/modulecmd.tcl
   => env = USER=archbox
   => env = ENV=/usr/share/Modules/init/profile.sh
   => env = PAGER=cat
   => env = DESKTOP_SESSION=gnome-classic
   ... ... ... 
#+END_SRC
** Simple Variable Definition and Initialization

Simple variable definition: 

#+BEGIN_SRC cpp 
  >> int i;
  >> int ix = 200;

  >> i
  (int) 0

  >> ix
  (int) 200
  >> 

  >> const char * s1  = " refresh memory about C++" ;
  >> s1
  (const char *) " refresh memory about C++"

  >> char s2 []  = " refresh memory about C++" ;
  >> s2
  (char [26]) " refresh memory about C++"
  >> 
#+END_SRC

Multiple variable default initialization in same line: 

#+BEGIN_SRC cpp 
  double x, y, z;

  >> x
  (double) 0.0000000
  >> y
  (double) 0.0000000
  >> z
  (double) 0.0000000
#+END_SRC

Multiple variables initialization at same line: 

#+BEGIN_SRC cpp
  double xx = 3.1515, yy = 3 * xx + 3.0, zz = xx * 2 + yy;
 
  >> xx
  (double) 3.1515000
  >> yy
  (double) 12.454500
  >> zz
  (double) 18.757500
  >> 

  double xa{3.1515}, ya{3 * xa + 3.0}, za{xa * 2 + ya};

  >> xa
  (double) 3.1515000
  >> ya
  (double) 12.454500
  >> za
  (double) 18.757500
  >> 
#+END_SRC

Multiple initialization with assignment: 

#+BEGIN_SRC cpp 
  double x, y, z;
  >> x = y = z = 3.0;
  >> x
  (double) 3.0000000
  >> y
  (double) 3.0000000
  >> z
  (double) 3.0000000
  >> 

  std::string s1, s2, s3;

  >> s1 = s2 = s3 = "remember c++";
  >> s1
  (std::string &) "remember c++"
  >> s2
  (std::string &) "remember c++"
  >> s2
  (std::string &) "remember c++"
  >> 
#+END_SRC

** Literals and C++14 Literals 

|----------------------------------------------------------+--------------------+-------|
| Literal Description                                      | Example            | Since |
|----------------------------------------------------------+--------------------+-------|
| Integer                                                  | 12905134           |       |
| Integer separated by single quote                        | 1'290'5134         | C++14 |
|                                                          |                    |       |
| Unsigned integer 10                                      | 12905134U          |       |
| Unsigned integer separated by single quote               | 1'290'5134U        | C++14 |
|                                                          |                    |       |
| Integer in hexadecimal base (base 16)                    | 0xFF4A5A           |       |
| Integer in hexadecimal base separate by single quote (') | 0xFF'4A'5A         | C++14 |
|                                                          |                    |       |
| Integer in binary (base 2) format (0xF1 = 241)           | 0b11110001         | C++14 |
| Integer in binary format separated by single quote       | 0b1111'0001        | C++14 |
|                                                          |                    |       |
| Float point double precision (double)                    | 15'55'100.91'51'61 | C++14 |
| Float point double precision (double)                    | 1555'100.915161    | C++14 |
|                                                          |                    |       |
| Character literal                                        | 'X'                |       |
| Non printable character literal (LF Line Feed 0x0D)      | '~\x0D'~             |       |
|                                                          |                    |       |
|----------------------------------------------------------+--------------------+-------|

Literal Formats added in C++14 

  + Binary Literals => More convenient for low level, device drivers,
    embedded systems and so on. 

    + 0b11110001 = 0xF1 = 241  

  + Numeric Literals separated by single quote:

    + 1000'000,000 => 1 billion 
    + 0b1111'0001 =  0b11110001
    + 0xF'FAA'BBAC

Examples: 

 + Character (char)

#+BEGIN_SRC cpp 

  // Character literal
  char ch1 = 'X';

  // Non printable character literal - hexadecimal value 0xD which is the
  // same as new line character  Unix LF Line Feed
  char ch2 = '\x0D';
#+END_SRC

 + Signed Integer (trivial)

#+BEGIN_SRC cpp 
  int n = 200;
#+END_SRC

 + Integer hexadecimal literal (0xFF = 255 decimal)

#+BEGIN_SRC cpp 
  int x = 0xFF;
#+END_SRC

 + Unsigned Integer Literals (suffix U) - always positive literals.

#+BEGIN_SRC cpp 
    unsigned int ux1 = 1000U;
    unsigned int ux2 = 0xFFABU;
#+END_SRC

 + Unsigned long literals (suffix UL) - always positive literals. 

#+BEGIN_SRC cpp 
   unsigned long ux3 = 0xFFABUL;
   auto ux4 = 0xFFABUL;
   assert(typeid (decltype(ux4)) == typeid(unsigned long) && "Types should be equal");
#+END_SRC

 + Integer separated by single quote: 

#+BEGIN_SRC cpp 
    // Since C++14
    uint32_t register_config = 0xF'AAB'987A;

    // Binary literal (Number in base 2) - Since C++14
    // 0b10001001 = 0x89 = 8 * 16 + 9 * 16^0 = 137
    uint8_t gpioA_config = 0b10001001;
    std::cout << " gpioA_config = " << static_cast<int>(gpioA_config) << std::endl;

    // Binary literal with single quote separator
    int gpioB_config = 0b1000'1001;
    std::cout << " gpioB_config = " << static_cast<int>(gpioB_config) << std::endl;

    // Number literal with single quote separator (')
    long quantity = 100'000'000;
#+END_SRC

  + IEEE754 Single Precision Literals - 32 bits (suffix .f)

#+BEGIN_SRC cpp 
    float flt32A = 100.23f;

    float flt32B = 100.23E5f; // 100.23 * 10^5

    float flt32C = .001114465111f; 

    float flt32D = 0.001114465111E6f; 

    // Separated by single quote (C++14)
    float flt32E = 1555'100.9151f;
    
    // Separated by single quote (C++14)
    float flt32F = 15'55'100.91'51'61f;
#+END_SRC

 + IEEE754 Double Precision Literals - 64 bits (default float point literal)

#+BEGIN_SRC cpp 
    double flt64A = -1120.4;

    double flt64A = -20.4E3;

    // Separated by single quote 
    // Separated by single quote (C++14)
    double flt32F = 15'55'100.91'51'61;
#+END_SRC

 + String Literal 

#+BEGIN_SRC cpp 
   const char* str1 = "Hello world C++";
   const char* str2 = "Hello \n \xFD \xF7 world C++";

   /* Represents: C:\\User\Dummy\Path  */
   const char* windows_path = "C:\\\\User\\Dummy\\Path";
#+END_SRC

 + Raw String Literal R"( ... )"
   + Supports multiline and characters that are used for escaping
     sequence such as backward slash (\) that needs to be escaped and
     written as (\\).

#+BEGIN_SRC cpp 
     const char* windows_path = R"(C:\Uses\Dummy\Path)";

     const char* regex = R"(^\d+\w+)";

     const char* script_source = R"(
      for(i = 0 to 10) do {
        println(i * 3)
      }

      list_files(C:\Users\data\path)
  )";
#+END_SRC

 + Multi-Line Strings and literal string concatenation 
   + Note: It is also can be used in C language.

#+BEGIN_SRC cpp 
     // Single line string 
     const char* str1 =
             " => C++98 programming language ; "
             " => Rust programming language ; "
             " => Forth programming language ; "
             " => ADA programming language ; "
             ;

     std::cout << str1 << "\n\n";

     // Multi line string 
     const char* str2 =
             "  => Product Name: Super CFD (Computational Fluid Dynamic) Simulator \n"
             "  => Aerospace SBC - Single Board Computer \n"
             "  => State Space Model Matrix \n"
             "  => Low Pass Filter \n"
             "  => SOC - System-On-Chip \n";
     std::cout << str2 << "\n\n";
#+END_SRC

Output: 

#+BEGIN_SRC sh 
  => C++98 programming language ;  => Rust programming language ;  => Forth programming language ;  => ADA programming language ; 

   => Product Name: Super CFD (Computational Fluid Dynamic) Simulator 
   => Aerospace SBC - Single Board Computer 
   => State Space Model Matrix 
   => Low Pass Filter 
   => SOC - System-On-Chip 
#+END_SRC

** Control Structures
*** ternary operator - question mark (?)

Unlike the if-else statement, the ternary operator (?) or question
mark operator, can solve return a value, although it cannot have
complex statements like if-else. In functional languages like Lisp,
Scala or Haskell, the if-else operator always is evaluated and returns

Limitation: The ternary operator cannot have complex statements like
if-else.

Syntax:

#+BEGIN_SRC cpp
 {VARIABLE} = {CONDITION} ? {RETURN-IF-TRUE} : {RETURN-IF-FASLE};
#+END_SRC

Example:

#+BEGIN_SRC cpp
  >> true ? "true" : "false"
  (const char *) "true"
  >> false ? "true" : "false"
  (const char *) "false"

  >> int x;
  >> x = true ? 10 : 25
  (int) 10
  >> x
  (int) 10

  >> x = false ? 10 : 25
  (int) 25
  >>
  >>

  >> std::string s;
  >> x = 10;
  >> s = (x < 15) ? "true" : "false"
  "true"

  >> x = 100;
  >> s = (x < 15) ? "true" : "false"
  "false"
  >>
#+END_SRC
*** if-else
**** True and false 

In C++, everything equal to zero is false and everything other than
zero is true.

 + Booleans

#+BEGIN_SRC cpp
  >> bool flag;

  // Size - 1 byte
  >> sizeof(bool)
  (unsigned long) 1

  >> flag = false;
  // Booleans are actually numbers
  >> std::cout << "flag = " << flag << "\n";
  flag = 0

  >> std::cout << "flag = " << std::boolalpha << flag << "\n";
  flag = false
  >>

  >> flag = true;

  // True
  >> std::cout << "flag = " << static_cast<int>(flag) << "\n";
  flag = 1
  >>

#+END_SRC

 + Booleans - If-else

#+BEGIN_SRC cpp
  >> bool flag;

  >> flag = false;
  >> if(flag) { std::puts(" => True"); } else { std::puts(" => False"); }
   => False

  >> flag  = true;
  >> if(flag) { std::puts(" => True"); } else { std::puts(" => False"); }
   => True
  >>
#+END_SRC

 + Char 

#+BEGIN_SRC cpp 
  char x;

  >> x = '\0'; // Null character
  >>  if(x) { std::puts(" => True"); } else { std::puts(" => False"); }
   => False

  >> x = 0x00; // Ascii code of null character
  >>  if(x) { std::puts(" => True"); } else { std::puts(" => False"); }
   => False

  >> x = 'a'
  (char) 'a'
  >>  if(x) { std::puts(" => True"); } else { std::puts(" => False"); }
   => True
  >> 
#+END_SRC

 + Integers:

#+BEGIN_SRC cpp
   int n = 10;

   >> if(n) { std::puts(" => True"); } else { std::puts(" => False"); }
    => True
   >>

   >> n = 0;
   >> if(n) { std::puts(" => True"); } else { std::puts(" => False"); }
    => False
   >>
#+END_SRC

 + Double:
   + Note: Float pointers should never be tested by comparison. 

#+BEGIN_SRC cpp
  >> double num;

  >> num = 12.3;
  >> if(num) { std::puts(" => True"); } else { std::puts(" => False"); }
   => True

  >> num = 0.0;
  >> if(num) { std::puts(" => True"); } else { std::puts(" => False"); }
   => False
#+END_SRC

 + Pointers:

#+BEGIN_SRC cpp
  >> double* ptr;

  >> ptr = nullptr;
  >> if(ptr) { std::puts(" => True"); } else { std::puts(" => False"); }
   => False

  >> double m;
  >> ptr = &m
  (double *) 0x7f14ccfce020

  >> if(ptr) { std::puts(" => True"); } else { std::puts(" => False"); }
   => True
  >>

  >> if(nullptr) { std::puts(" => True"); } else { std::puts(" => False"); }
   => False

  >> if(NULL) { std::puts(" => True"); } else { std::puts(" => False"); }
   => False
#+END_SRC

**** If-else statement with assignment 

 *IF-else statement with assignment* 

This type of assignment within the if predicate is still widely used
in C.

#+BEGIN_SRC cpp 
  // Note: nullptr should not be used instead of NULL.
  FILE* fp = NULL; 

  if( (fp  = fopen("/tmp/file2.dat", "w")) != NULL ) {
      fprintf(fp, "File content 2");
      fclose(fp);
  }
#+END_SRC

The previous code is equivalent to: 

#+BEGIN_SRC cpp 
  FILE* fp = fopen("/tmp/file1.dat", "w");

  if(fp != NULL) {
      fprintf(fp, "File content 1");
      fclose(fp);
  }
#+END_SRC

See also: 

 + [[https://stackoverflow.com/questions/47823882/auto-assignment-in-if-clause][c++ - auto assignment in if clause - Stack Overflow]]

 + [[https://stackoverflow.com/questions/17681535/variable-assignment-in-if-condition][c++ - Variable assignment in "if" condition - Stack Overflow]]

**** IF-else statement with initializers (C++17)

C++17 Allows defining variables in  IF-else statements which is useful
for writing more concise code.

Example 1: 

#+BEGIN_SRC cpp 
  if(FILE* fp = fopen("/tmp/file4.dat", "w"); fp != nullptr) {
      fprintf(fp, "File content 2");
      fclose(fp);
   }
#+END_SRC

Example 2: 

#+BEGIN_SRC cpp 
  if(auto fp = fopen("/tmp/file4.dat", "w"); fp != nullptr) {
      fprintf(fp, "File content 2");
      fclose(fp);
  }

   // Could alos be written as 
  if(auto fp = fopen("/tmp/file4.dat", "w")
      ; fp != nullptr) 
   {
      fprintf(fp, "File content 2");
      fclose(fp);
   }
#+END_SRC

Example 3:

#+BEGIN_SRC cpp 
  std::vector<int> xs {1, 20, 50, 77, 100,  25};

  if(auto it = std::find_if( xs.begin(), xs.end(), [](int x){ return x % 11 == 0; })
          ; it != xs.end() )
  {   // This branch is executed if the expression "it != xs.end()" evaluates to true. 
      std::cout << " Found element it = " << *it << std::endl;
  }

  /* Output: 
     Found element it = 77
     [INFO] Finished OK.
  */
#+END_SRC

Example 4:

#+BEGIN_SRC cpp    
  if( std::vector<int> xs {1, 20, 50, 77, 100,  25}
     ; auto it = std::find_if( xs.begin(), xs.end(), [](int x){ return x % 11 == 0; })
     ; it != xs.end() )
  {
      std::cout << " Found element it = " << *it << std::endl;
  }

  /* Output: 
     Found element it = 77
     [INFO] Finished OK.
  */
#+END_SRC

See: 

 + [[https://en.cppreference.com/w/cpp/language/if][if statement - cppreference.com]] 

 + [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r0.html][If statement with initializer]] - C++ Standard Proposal 
**** Returning value from if-else statements (C++11)

The C++ if-else statement cannot return a value or be evaluated to a
value as the if-else statement in Lisp, Scheme, Scala, Haskell and
other functional languages. Despite that the ternary operator (?) can
be evaluated to some value, it cannot contain complex expressions as
if-else statements.

 *if-else in Scala*

#+BEGIN_SRC scala 

  // ========>>> EXPERIMENT 1 ==============//
  var x: Double = 0.0;
  var n = 10;

  scala> x = if(n > 100) 256.0 else 300.0
  x: Double = 300.0

  scala> n = 200
  n: Int = 200

  scala> x = if(n > 100) 256.0 else 300.0
  x: Double = 256.0


  // ========>>> EXPERIMENT 2 ==============//

  n = 50
  scala> x =  400 + (if(n > 100) { println("Return 256.0"); 256  } else { println("Return 300.0"); 300.0})
  Return 300.0
  x: Double = 700.0

  scala> x =  400 + (if(n > 100) { println("Return 256.0"); 256  } else { println("Return 300.0"); 300.0})
  Return 256.0
  x: Double = 656.0

#+END_SRC

 *if-else in C++*

Desired functionality, however the following code doesn't work.

#+BEGIN_SRC cpp 
  >> double x;
  >> int n;
  >> 
  >> n = 10;

  // Compilation error! It doesn't work in C++ 
  >> x = if(n > 100) { 
           std::puts("Return 256");  
           return 256.0;} 
        else { 
           std::puts("Return 300.0"); 
           return 300.0; 
        }

  ROOT_prompt_4:1:5: error: expected expression
  x = if(n > 100) {std::puts("Return 256");  return 256.0;} else { std::pu...
      ^
  >> 
#+END_SRC

It could also be as shown in the following code, however, it requires
modifying the variable x in more than one place. 

#+BEGIN_SRC cpp 
  double x;
  int n; 

  n = 200;

  if(n > 100){
    std::puts("Return 256");
    x = 256.0;
  } else {
    std::puts("Return 300");
    x = 300.0 
  }
#+END_SRC

Solution: Wrap the if-else statement into a self-executing lambda
expression. 

#+BEGIN_SRC cpp 
  T result;

  result = [&](){
                if(CONDITION){
                   <COMPTATIONS...FALSE>;
                   return VALUE-TRUE;
                } else {
                   <COMPTATIONS...ELSE>;
                   return VALUE-FALSE;
                }			 
            }();
#+END_SRC

An alternative way is to wrap the if-else statement into a
function. The advantage of this solution is that the computation can
be reused in multiple different places in the code.

#+BEGIN_SRC cpp 
  T1 input1;
  T2 input2;

  // The computation is wrapped into a lambda function (thunk)
  // ,depends on inputs input1, input2, ... as inputs.
  auto computation = [&](){
                 if(CONDITION(input1, input2 ...)){
                     <COMPTATIONS...FALSE>;
                     return VALUE-TRUE;
                  } else {
                     <COMPTATIONS...ELSE>;
                      return VALUE-FALSE;
                  }			 
             };

  input1 = value1A;
  input2 = value1B;
  Result result1 = computation();

  input1 = value1B;
  input2 = value1B;
  Result result2 = computation();
#+END_SRC

Example: 

#+BEGIN_SRC cpp 
  double x;
  int n;

  n = 50;

  >> x = [&](){ if(n > 100)  {
                 std::puts(" [LOG] Return 256");
                 return 256.0;
          } else { 
                 std::puts(" [LOG] Return 300.0");
                 return 300.0;
          }}();
   [LOG] Return 300.0

  >> x
  (double) 300.00000
  >> 

  n = 400;

  >> x = [&](){ if(n > 100)  {
                  std::puts(" [LOG] Return 256");
                  return 256.0;
          } else { 
                  std::puts(" [LOG] Return 300.0");
                  return 300.0;
          }}();
   [LOG] Return 256

#+END_SRC

Further Reading: 

 + [[https://herbsutter.com/2013/04/05/complex-initialization-for-a-const-variable/][Complex initialization for a const variable | Sutter’s Mill]]
 + [[https://www.reddit.com/r/cpp/comments/62k8b0/lambda_initialization_trick_add_syntactic_sugar/][Lambda initialization trick, add syntactic sugar? : cpp]]
 + [[https://stackoverflow.com/questions/15581662/is-it-possible-to-initialize-static-variable-with-lambda][c++ - is it possible to initialize static variable with lambda? - Stack Overflow]]

*** switch case

Swich case statements can only be used with numbers, characters or
Enums. They cannot be used for processing strings or classes.

 *Example 1*: Print month based on its number.

#+BEGIN_SRC cpp 
  void printMonth1(int n){
      const char nl = '\n';
       switch(n){
          case 1:  std::cout << "JAN" << nl; break;
          case 2:  std::cout << "FEB" << nl; break;
          case 3:  std::cout << "MAR" << nl; break;
          case 4:  std::cout << "APR" << nl; break;			
          case 5:  std::cout << "MAY" << nl; break;
          case 6:  std::cout << "JUN" << nl; break;
          case 7:  std::cout << "JUL" << nl; break;
          case 8:  std::cout << "AUG" << nl; break;
          case 9:  std::cout << "SEP" << nl; break;
          case 10: std::cout << "OCT" << nl; break;
          case 11: std::cout << "NOV" << nl; break;
          case 12: std::cout << "DEC" << nl; break;
          default: std::cout << "Error: invalid month." << nl; break;
       }
  }

  >> printMonth1(1)
  JAN
  >> printMonth1(2)
  FEB
  >> printMonth1(12)
  DEC
  >> printMonth1(100)
  Error: invalid month.
  >> printMonth1(-1)
  Error: invalid month.
  >> 
#+END_SRC

or 

#+BEGIN_SRC cpp 
  void printMonth2(int n){
      const char nl = '\n';
       switch(n){
          case 1:  std::cout << "JAN" << nl; break;
          case 2:  std::cout << "FEB" << nl; break;
          case 3:  std::cout << "MAR" << nl; break;
          case 4:  std::cout << "APR" << nl; break;			
          case 5:  std::cout << "MAY" << nl; break;
          case 6:  std::cout << "JUN" << nl; break;
          case 7:  std::cout << "JUL" << nl; break;
          case 8:  std::cout << "AUG" << nl; break;
          case 9:  std::cout << "SEP" << nl; break;
          case 10: std::cout << "OCT" << nl; break;
          case 11: std::cout << "NOV" << nl; break;
          case 12: std::cout << "DEC" << nl; break;
       }
       std::cout << "Error: invalid month." << nl; break;
  }
#+END_SRC

 *Example 2* : Return month name as a string based on month number.

#+BEGIN_SRC cpp 
  #include <std::string>
  std::string getMonth(int n){
       switch(n){
           case 1:  return "JAN";
           case 2:  return "FEB";
           case 3:  return "MAR";
           case 4:  return "APR";
           case 5:  return "MAY";
           case 6:  return "JUN";
           case 7:  return "JUL";
           case 8:  return "AUG";
           case 9:  return "SEP";
           case 10: return "OCT";
           case 11: return "NOV";
           case 12: return "DEC";
           default:
                   throw std::domain_error("Error: invalid month");
       }
  }
#+END_SRC

Test code: 

 - Online compiler: https://rextester.com/TKA23321

#+BEGIN_SRC cpp
    std::string month;    
    month = getMonth(1);
    std::cout << "Month = " << month << "\n";     
    month = getMonth(4);
    std::cout << "Month = " << month << "\n";    

    try{
        month = getMonth(100);
        std::cout << "Month = " << month << "\n";    
    } catch(const std::domain_error& ex){
        std::cout << "An error has happened = " << ex.what() << "\n";
    }
#+END_SRC

Output: 

#+BEGIN_SRC text 
  Month = JAN
  Month = APR
  An error has happened = Error: invalid month
#+END_SRC

 *Example 3*: Switch-case for string input. 

As switch-case control structure cannot be used with std::string
input, the best approach is to use if-else statements, if-statements
with early return or hash tables.

 - Solution 1: If statements with early return. 

#+BEGIN_SRC cpp 
  #include <string>

  int getDayOfWeekNum(const std::string& weekDay){
      if(weekDay == "Sun") return 1;
      if(weekDay == "Mon") return 2;
      if(weekDay == "Tue") return 3;
      if(weekDay == "Wed") return 4;
      if(weekDay == "Thu") return 5;
      if(weekDay == "Fri") return 6;
      if(weekDay == "Sat") return 7;
      return -1;
  }

  >> getDayOfWeekNum("Sun")
  (int) 1
  >> getDayOfWeekNum("Tue")
  (int) 3
  >> getDayOfWeekNum("Fri")
  (int) 6
  >> getDayOfWeekNum("")
  (int) -1
  >> getDayOfWeekNum("Error")
  (int) -1
  >> 
#+END_SRC

 - Solution 2: A hash table or dictionary.

Note: /Static variables inside functions are initialized only once and
retains their current state/ between function calls. They are similar
to global variables, but static variables are only visible inside the
function they are defined.

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

  int getDayOfWeekNum2(const std::string& weekDay){
      static auto week_table = std::map<std::string, int> {
         {"Sun", 1}, {"Mon", 2}, {"Tue", 3}, {"Wed", 4},
         {"Thu", 5}, {"Fri", 6}, {"Sat", 7}
      };
      if(week_table.find(weekDay) != week_table.end())
         return week_table[weekDay];	
      return -1;
  }

  >> getDayOfWeekNum2("Sun")
  (int) 1
  >> getDayOfWeekNum2("Mon")
  (int) 2
  >> getDayOfWeekNum2("Monasd")
  (int) -1
  >> 
#+END_SRC

*** for loop

 + Basic for-loop

#+BEGIN_SRC cpp
  #include <iostream>

  >> for(int x = 0; x < 5; x++) {
         std::cout << " x = " << x << "\n";
     }
   x = 0
   x = 1
   x = 2
   x = 3
   x = 4

  >> for(double x = -10.0; x <= 10.0; x += 2.5) {
          std::cout << " x = " << x << "\n";
     }
   x = -10
   x = -7.5
   x = -5
   x = -2.5
   x = 0
   x = 2.5
   x = 5
   x = 7.5
   x = 10
  >>

#+END_SRC

 + Infinity loop

#+BEGIN_SRC cpp
  >> for(;;){ std::puts(" It is an infinity loop"); }
   It is an infinity loop
   It is an infinity loop
   It is an infinity loop
   It is an infinity loop
   .,.. ... ... ...
#+END_SRC

*** while loop
    
#+BEGIN_SRC cpp
  #include <iostream>
  #include <cstdio>

  >> n = 0
  (int) 0

  >> while(n < 5){  std::cout << "n = " << n++ << "\n"; }
  n = 0
  n = 1
  n = 2
  n = 3
  n = 4

  >> int j = 0;
  >> while(j++ < 5){  std::cout << "j = " << j << "\n"; }
  j = 1
  j = 2
  j = 3
  j = 4
  j = 5
  >> j = 0
  (int) 0

  >> while(++j < 5){  std::cout << "j = " << j << "\n"; }
  j = 1
  j = 2
  j = 3
  j = 4
  >>
#+END_SRC

Infinity lop:

#+BEGIN_SRC cpp
  >> while(true){ std::cout << " It is an infinity loop" << "\n";}
  It is an infinity loop
  It is an infinity loop
  It is an infinity loop
  ... ... ... ..
#+END_SRC

*** do - while loop

#+BEGIN_SRC cpp
  int z = -10;

  // Single line
  >> do{ std::cout << " z = " << z << "\n"; z++; } while(z < 0)
   z = -10
   z = -9
   z = -8
   z = -7
   z = -6
   z = -5
   z = -4
   z = -3
   z = -2
   z = -1
  >>

  // Multiple Lines
  do{
      std::cout << " z = " << z << "\n";
      z++;
  } while(z < 0)
#+END_SRC
** Basic Console IO 
*** Overview 

C++ input/output system is object oriented which means that it is
possible to write input-agnostic or output-agnostic code which can be
reused without any rewritten for reading data from console, file,
string and other end-points.

C++ Has the following global objects for performing IO. 

 + *std::cout* 
   + (stdout) Standard output stream used for displaying program output. 

 + *std::cerr* 
   + (stderr) Stadnard error output stream used for displaying program
     error and logging output. It prints by default to the
     console. The output of the stream std::cerr (stderr) can be separated from
     std::cout (stdout) output by redirecting the stederr output to a
     log file or discarding it.

 + *std::clog*
   + (stderr) => Standard logging output stream. 

 + *std::cin*  => Basic Input stream or stdin. Used for reading data
   from console. 

Operators: 

| Name                | Operator | Parent class          | Derived Classes                             |
|---------------------+----------+-----------------------+---------------------------------------------|
| Insertion Operator  | <<       | std::ostream / Output | std::cout, std::cerr, std::ofstream         |
| Extraction Operator | >>       | std::istream / Input  | std::cin, std::ifstream, std::sstringstream |
|---------------------+----------+-----------------------+---------------------------------------------|
*** Example - Old C-IO functions 

Sometimes the old C-IO functions such as printf, puts and perror may
be convenient due to its simplicity and less verbosity.

 + Header: [[https://en.cppreference.com/w/cpp/header/cstdio][<cstdio>]]

Functions puts, perror 

#+BEGIN_SRC cpp 
  // C++ header equivalent to C <stdio.h>
  #include <cstdio>
  #include <string>

  // Print to STDOUT (cout)
  >> std::puts(" => System programming.");
   => System programming.

  // Print to STDERR (cerr)
  >> std::perror(" => Print error and logging to stderr.");
   => Print error and logging to stderr.: No such file or directory


  // Write to file (disk file, or pseudo-files such as stderr or stdout)
  // U-nix where C comes from see everything as files. 

  >> std::fputs("Hello world\n", stdout);
  Hello world
  >> std::fputs("Hello world\n", stderr);
  Hello world
  >> 

#+END_SRC

Functions puts, perror and fputs with C++ strings 

#+BEGIN_SRC cpp 
  >> std::string text;
  >> text = "Hello world C-IO facilities\n";

  // Failure => Cannot print C++ string, only const char 
  >> std::puts(text);
  ROOT_prompt_5:1:11: error: no viable conversion from 'std::string' ...

  >> std::puts(text.c_str());
  Hello world C-IO facilities

  >> std::perror(text.c_str());
  Hello world C-IO facilities

#+END_SRC

Old C-printf and fprintf 

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

   >> std::printf("The value of pi is equal to: %.4f\n", M_PI);
   The value of pi is equal to: 3.1416

   >> std::printf("The value of pi is equal to: %.5f\n", M_PI);
   The value of pi is equal to: 3.14159
   >> 
   >> std::fprintf(stdout, "The value of pi is equal to: %.5f\n", M_PI);
   The value of pi is equal to: 3.14159
   >> 
   >> std::fprintf(stderr, "The value of pi is equal to: %.5f\n", M_PI);
   The value of pi is equal to: 3.14159
   >> 

   std:string userName = "Julius Caesar";
   int points = 200;

   >> std::printf(" => User = '%s' ; Points = %d\n", userName.c_str(), points);
    => User = 'Julius Caesar' ; Points = 200

   >> std::fprintf(stdout, " => User = '%s' ; Points = %d\n", userName.c_str(), points) 
    => User = 'Julius Caesar' ; Points = 200

   >> std::fprintf(stderr, " => User = '%s' ; Points = %d\n", userName.c_str(), points) 
    => User = 'Julius Caesar' ; Points = 200
   >> 
#+END_SRC

Printf is not type safe: 

 + It is easy to get a segmentation fault and runtime crash if the
   printf arguments are not correct. Another problem is that the
   compiler cannot give any help to catch this bug.
 + See:
   + [[http://www.zverovich.net/2015/02/26/comparison-of-cppformat-and-printf.html][Comparison of C++ Format and C library's printf]]
   + [[https://stackoverflow.com/questions/17789396/how-cout-is-more-typesafe-than-printf][c++ - How cout is more typesafe than printf() - Stack Overflow]]

#+BEGIN_SRC cpp 
   std:string userName = "Julius Caesar";
   int points = 200;

   >> std::printf("User = '%s' ; Points = %d\n", points, userName.c_str());
   *** Break *** segmentation violation

   // Expected "c-string" (const char*) but provided int
   >> std::printf("%s\n", 100);
   *** Break *** segmentation violation
#+END_SRC

*** Example - Reading from Console

 *Reading a single variable from console (stdin):*

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

  >> double x;
  >> std::cin >> x;
  342.34
  >> x
  (double) 342.34000
  >> 
  >> std::cout << "Enter x: "; std::cin >> x; std::cout << " => x = " << x << "\n";
  Enter x: 100
   => x = 100
  >> 

  >> std::string user;
  >> std::cout << "Name: "; std::cin >> user; std::cout << " => user is = " << user <<Name: Julius Caesar
   => user is = Julius
  >> 
#+END_SRC

 *Read line as string*

The statement _std::cin >> stringVariable_ can only read a single word
and will ignore remaining words separated by space. In order to read
the entire line until the new line delimiter is found, it is necessary
to used the C++ function std::getline. 

#+BEGIN_SRC cpp 
  >> std::string some_line;

  // User types something and then hit RETURN when he is done.
  >> std::cin >> some_line;
  some message to compute     

  // The remaining words were ignored. 
  >> some_line
  (std::string &) "some"
  >> 

  // User types something and then hit RETURN when he is done.
  >> std::getline(std::cin, some_line); 
   C++ is an old cool programming language.

  >> some_line
  (std::string &) " C++ is an old cool programming language."
  >> 

  >> std::cout << " COMMAND => " ; std::getline(std::cin, some_line);
   COMMAND => go to position 200 300

  >> some_line
  (std::string &) "go to position 200 300"
  >> 

#+END_SRC

 *Read multiple lines until user sends EOF*

This code reads multiple lines from console untile the user sends the
EOF (End Of Signal) by typing Ctrl + D on U-nix (OSX, Linux, BSD) or
Ctrl + Z on Windows.

 + Read multiple lines example 1.

#+BEGIN_SRC cpp 
  std::string line;

  // Read lines until user types something invalid or sends EOF 
  // Ctlr + Z on Windows, Ctrl + D on U-nix (Linux, BSD, OSX ...)
  while(std::getline(std::cin, line)){ 
    std::cout << "You typed = " << line << "\n";
  }

   Caesar cypher
  You typed =  Caesar cypher
   Hardening encryption 
  You typed =  Hardening encryption
   Digital Signal Processors
  You typed =  Digital Signal Processors
    ASICS and FPGAs custom hardware
  You typed =   ASICS and FPGAs custom hardware
  >> 
  >> 

#+END_SRC

 + Read multiple lines example 2.

#+BEGIN_SRC cpp 
  void runREPL(){
    std::string line;
    if(std::cin.fail()){
      std::cerr << " [INFO] Input stream failure " << "\n";
      std::cin.clear();
      std::cin.ignore();
    }
    while((std::cout << " CMD=> " << std::flush), std::getline(std::cin, line)){
      std::cout << " + Typed command was = " << line << "\n";
    }
    std::cout << "\n" << " === Finish REPL session. OK ===" << "\n";
    std::cin.clear();
  }
#+END_SRC

Running: 

#+BEGIN_SRC txt 
  >> runREPL()
   CMD=> Testing C++ on ROOT REPL.
   + Typed command was = Testing C++ on ROOT REPL.
   CMD=> Clang is the best compiler out there
   + Typed command was = Clang is the best compiler out there
   CMD=> Clang has the best and less cryptic error messages
   + Typed command was = Clang has the best and less cryptic error messages
   CMD=>   
   === Finish REPL session. OK ===
  >> 
#+END_SRC

 *Read multiple variables from console (stdin):*

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

  int         id, quantity;
  double      price;
  std::string name;

  // Read from console
  >> std::cin >> id >> name >> quantity >> price ;
  2351 Cooking-oil 20 3.12

  >> id
  (int) 2351
  >> quantity
  (int) 20
  >> name
  (std::string &) "Cooking-oil"
  >> price
  (double) 3.1200000
  >> 
#+END_SRC

 *Reading structured data from console:*

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

  struct Product{
      unsigned long id;
      std::string   name;		
      double        price;
      unsigned int  quantity;
      Product(){}
  };

  // Or it could also be:
  class Product{
  public:
      unsigned long id;
      std::string   name;		
      double        price;
      unsigned int  quantity;
      Product(){}
  };

  Product readProductFromConsole(){
      Product p;
      std::cin >> p.id >> p.name >> p.price >> p.quantity;
      return p;
  };

  // Type Alias 	
  using Inventory = std::deque<Product>;

  Inventory readInventory(){
     Inventory inv;
     std::cin.clear();
     std::cout << "Enter product ID, product Name, product Price, product Quantity." << "\n";
     std::cout << "Type CTRL+D on U-nix or CTRL+Z on Windows when you are done." << "\n";   	
     while(std::cin.good() && !std::cin.eof()){
         std::cout << " => ";
         inv.push_back(readProductFromConsole());
     }
     return inv;
  }																		   
#+END_SRC

 + Reading a single object / record: 

#+BEGIN_SRC cpp 
  // User types "2000 Sugar 1.45 9000" and then types RETURN when he is done.
  //------------------------------------------
  >> auto x = readProductFromConsole()
  2000 Sugar 1.45 9000
  (Product &) @0x7f16eb8fc010

  >> x.id
  (unsigned long) 2000
	
  >> x.name
  (std::string &) "Sugar"
	
  >> x.price
  (double) 1.4500000
	
  >> x.quantity
  (unsigned int) 9000
#+END_SRC

 + Reading multiple data:

#+BEGIN_SRC cpp 
  >> auto inventory = readInventory()
  Enter product ID, product Name, product Price, product Quantity.
  Type CTRL+D on U-nix or CTRL+Z on Windows when you are done.
   => 803 Cooking-oil 10.23 200
   => 2001 Sugar 2.40 500
   => 9134 Car-battery 50.0 6000
   => 8023 Milk 4.50 300 
#+END_SRC

 + Print inventory value: 

#+BEGIN_SRC cpp 
     // Print inventory data: 
     for(const auto& prod: inventory){
         double value = prod.quantity * prod.price;
         std::cout << "Id       = " << prod.id       << "\n"
                   << "Name     = " << prod.name     << "\n"
                   << "Quantity = " << prod.quantity << "\n"		
                   << "Price    = " << prod.price    << "\n"
                   << "Value    = " << value         << "\n"
                   << "----------------------------" << "\n";
     }

     //--------- Output -------------
     Id       = 803
     Name     = Cooking-oil
     Quantity = 200
     Price    = 10.23
     Value    = 2046
     ----------------------------
     Id       = 2001
     Name     = Sugar
     Quantity = 500
     Price    = 2.4
     Value    = 1200
     ----------------------------
    ... ... .... 
#+END_SRC

*** Basic IO program 

 *Example*

File: [[file:src/basic-io.cpp][file:src/basic-io.cpp]]

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

  int main(){	
      // Everything is initialized as zero
      double price, sum, min, max;
      std::vector<double> dataset;
      sum = 0.0;
      min = 1e10;
      max = -1e10;		

      // Print float point numbers with 2 decimal places and fixed notation 
      std::cout << std::setprecision(2) << std::fixed;
      std::cout << "Enter the prices and type CTRL+D you are done." << "\n";

      // Execute this code block while there is any error on the stream.
      // It means, the user did not type any bad input or
      //  CTRL + D (Send EOF End of File - signal)
      int n = 0;
      while(std::cin.good()){
         // (i++) Post increment i, increment variable i after it is print.
         std::cout << " => price[" << n++ << "] = ";
         // Read the price from stdin (standard input or console). 
         std::cin >> price;
         if(!std::cin.good()){
            std::cerr << " [LOG] " << "User typed invalid input. Exit loop." << "\n";
            // Force exiting the loop 
            break;
         }
         sum += price;
          dataset.push_back(price);
         if(price > max)
            max = price;
         if(price < min)
            min = price;
      }
      // Clear stream error flag 
      std::cin.clear();

      std::cout << "Sum  = " << sum       << "\n";
      std::cout << "Mean = " << (sum / n) << "\n";
      std::cout << "Min  = " << min       << "\n";
      std::cout << "Max  = " << max       << "\n";

      std::cout << "Dataset = [ ";
      for(size_t i = 0; i < dataset.size(); i++)
         std::cout << " " << dataset[i] ;
      std::cout << "] \n";

      #ifdef _WIN32 
       std::cout << "\n" << "Type RETURN to quit." << "\n";
       std::cin.clear(); 
       std::cin.ignore(10, '\n');
       // Wait for single character 
       std::cin.get();
      #endif 		
      return EXIT_SUCCESS;
  };
#+END_SRC

Compiling:

#+BEGIN_SRC sh 
 $ clang++ basic-io.cpp -o basic-io.bin -g -std=c++1z -Wall -Wextra
 # OR 
 $ clang++ basic-io.cpp -o basic-io.bin -g -std=c++1z -Wall -Wextra && ./basic-io.bin 
#+END_SRC

Running: 

#+BEGIN_SRC txt 
   $ ./basic-io.bin 
   Enter the prices and type CTRL+D you are done.
    => price[0] = 20 
    => price[1] = 21.35
    => price[2] = 51.2
    => price[3] = 40.23
    => price[4] = 60.243
    => price[5] = 78
    => price[6] =  [LOG] User typed invalid input. Exit loop.
   Sum  = 271.02
   Mean = 38.72
   Min  = 20.00
   Max  = 78.00
   Dataset = [  20.00 21.35 51.20 40.23 60.24 78.00] 

   $ echo "30.12 40.23 100.34 90.23 52.0" | ./basic-io.bin 
   Enter the prices and type CTRL+D you are done.
    => price[0] =  => price[1] =  => price[2] =  => price[3] =  => price[4] =  => price[5] =  [LOG] User typed invalid input. Exit loop.
   Sum  = 312.92
   Mean = 52.15
   Min  = 30.12
   Max  = 100.34
   Dataset = [  30.12 40.23 100.34 90.23 52.00] 
#+END_SRC
** TODO Functions/Procedures 
*** Overview 

C++ Functions has the following features: 

 * _Overload_
   + Unlike in C, in C++, it is possible to define multiple functions
     implementation sharing the same name, although with the same type
     signature.

 * _Default Parameters_
   + C++ functions can have default parameters. 

 * _C++11 auto syntax_

 * _C++14 return type deduction_ 
*** Simple function with all possible declarations

 *Example - Simple function => all possible declaration*

Simple function which returns anything: 

 + Alternative syntax 1:

#+BEGIN_SRC cpp 
  void someFunction(){
       std::puts("I am a C++ free function");
  }
#+END_SRC

 + Alternative syntax 2:
   + Note: The early return statement can be used for doing early
     return and avoiding many nested if-else statements.

#+BEGIN_SRC cpp 
  void someFunction(){
       std::puts("I am a C++ free function");
       return;
  }
#+END_SRC

 + Alternative syntax 3:

#+BEGIN_SRC cpp 
  void someFunction(void){
       std::puts("I am a C++ free function");
       // return;       
  }
#+END_SRC

 + Alternative syntax 4 (C++11):

#+BEGIN_SRC cpp 
  auto someFunction(void) -> void {
       std::puts("I am a C++ free function");
       return;       
  }
#+END_SRC

 + Alternative syntax 5 (C++14) - uses type deduction (aka type
   inference) for return type. 

#+BEGIN_SRC cpp 
  auto someFunction() {
       std::puts("I am a C++ free function");
       return;       
  }
#+END_SRC

*** Functions with default parameters 

 + Syntax 1: 

#+BEGIN_SRC cpp 

  double someFunction(double x, int n = 4, double z = 3.5 )
  {
      std::cout << "  x = "  << x
                << " ; n = " << n
                << " ; z = " << z
                << "\n";
      return x * n + 4.0 * z;
  }

  // OR: 
  double 
  someFunction(double x, int n = 4, double z = 3.5 )
  {
      std::cout << "  x = "  << x
                << " ; n = " << n
                << " ; z = " << z
                << "\n";
      return x * n + 4.0 * z;
  }

  // Testing: Cling REPL:

  >> someFunction(3.0)
    x = 3 ; n = 4 ; z = 3.5
  (double) 26.000000
  >> 
  >> someFunction(3.0, 10, 5)
    x = 3 ; n = 10 ; z = 5
  (double) 50.000000
  >> 
  >> someFunction(4.0)
    x = 4 ; n = 4 ; z = 3.5
  (double) 30.000000
  >> 
#+END_SRC

 + Syntax 2 (C++11). In C++14, the return type can be omitted.

#+BEGIN_SRC cpp 
  auto someFunction(double x, int n = 4, double z = 3.5) -> double
  {
      std::cout << "  x = "  << x
                << " ; n = " << n
                << " ; z = " << z
                << "\n";
      return x * n + 4.0 * z;
  }

  >> someFunction(3.0)
    x = 3 ; n = 4 ; z = 3.5
  (double) 26.000000

  >> someFunction(4.0)
    x = 4 ; n = 4 ; z = 3.5
  (double) 30.000000

  >> someFunction(4.0, 10, 5)
    x = 4 ; n = 10 ; z = 5
  (double) 60.000000
  >> 

#+END_SRC
*** Function overload 

Functions can be overloaded as long as they have unique type signature
and the same return type.

#+BEGIN_SRC cpp 
  #include <iostream> 

  void show(){
       std::cout << "Call Version0." << "\n";
  }

  void show(int x){
       std::cout << "Call Version1 with =>" << " x [int] = " << x << "\n";
  }

  void show(double x){
       std::cout << "Call Version2 with =>" << " x [double] = " << x << "\n";
  }

  void show(const char* str){
       std::cout << "Call Version2 with =>" << " x [const char*] = " << str << "\n";
  }

  void show(int x, double z){
       std::cout << "Call Version4 with =>"
                 << " x [int] = " << x
                 << " z [double] = " << z
                 << "\n";
  }

  void show(int x, double z, const char* str){
       std::cout << "Call Version5 with =>"
                 << " x [int] = " << x
                 << " z [double] = " << z
                 << " std [const char*] = " << str
                 << "\n";
  }
#+END_SRC

Testing: 

#+BEGIN_SRC cpp 
  >> .L script.C

  >> show()
  Call Version0.

  >> show(10)
  Call Version1 with => x [int] = 10

  >> show(3.1415)
  Call Version2 with => x [double] = 3.1415

  >> show(100, 3.1415)
  Call Version4 with => x [int] = 100 z [double] = 3.1415

  >> show("Function overload")
  Call Version2 with => x [const char*] = Function overload

  >> show(100, 3.1415, "overload")
  Call Version5 with => x [int] = 100 z [double] = 3.1415 std [const char*] = overload
  >> 

#+END_SRC
*** Functions with static variables - stateful functions 

Variables inside of functions annotated with "static" keyword are
similar to global variables (global static variables), they are
initialized after the first function invocation and keeps their state
during successive function invocations. 

Features: 
 + Initialized until first function invocation.
 + Lifetime: Entire program runtime, just like global variables, they
   are destroyed when the program execution ends.
 + Once initialized, keeps their state during function calls.
 + Stored in the program's and process' data segment.

Use cases: 
 + Lazy-initialization in singleton design-patterns.
 + Create stateful functions.
 + Solve the static initialization order fiasco
   + See:
   + [[http://www.cs.technion.ac.il/users/yechiel/c++-faq/static-init-order-on-first-use.html][How do I prevent the "static initialization order fiasco"?, C++ FAQ]]
   + [[http://www.cs.technion.ac.il/users/yechiel/c++-faq/construct-on-first-use-v2.html][Why doesn't the construct-on-first-use idiom use a static object instead of a static pointer?, C++ FAQ]]

Example: 

 + Counter function with automatic variable (stack-allocated). 

#+BEGIN_SRC cpp 
  void counterAuto(){
     int x = 0;
     std::cout << "counter = " << x++ << "\n";
  }

  >> counterAuto()
  counter = 0
  >> counterAuto()
  counter = 0
  >> counterAuto()
  counter = 0
  >> counterAuto()
  counter = 0
#+END_SRC

 + counter function with static variable. 

#+BEGIN_SRC cpp 
  void counterStatic(){
     static int x = 0;
     std::cout << "counter = " << x++ << "\n";
  }

  >> counterStatic()
  counter = 0
  >> counterStatic()
  counter = 1
  >> counterStatic()
  counter = 2
  >> counterStatic()
  counter = 3
  >> counterStatic()
  counter = 4
  >> 
#+END_SRC
** String Manipulation 
*** Class std::string 

In C++, it is better to use std::string than the old "C-string" 
(const char*) since the class std::string is easier and safer to use
than the old C-string class. In addition, std::string can grow or
shrink at runtime automatically taking care of memory allocation.

Header: 
 + <string> 

Documentation: 
 + [[http://www.cplusplus.com/reference/string/][<string> - C++ Reference]]
 + [[http://www.cplusplus.com/reference/string/string/][string - C++ Reference]]
 + [[http://www.cplusplus.com/reference/string/wstring/][wstring - C++ Reference]]

Intialization: 

#+BEGIN_SRC cpp 
  #include <string>

  // Create an empty string 
  >> std::string s1
  (std::string &) ""
  >> 

  >> std::string s2("I am a C++ std::string")
  (std::string &) "I am a C++ std::string"
  >> 
  >> std::string s3 = "C++ CPP 20 is coming soon!!"
  (std::string &) "C++ CPP 20 is coming soon!!"
  >> 

  >> const char* msg = "C++ strings";
  >> std::string s4 {msg}
  (std::string &) "C++ strings"
  >> 

  >> std::string s5(10, '-')
  (std::string &) "----------"
  >>
#+END_SRC

String size: 

 -- [[http://www.cplusplus.com/reference/string/string/size/][string::size - C++ Reference]]

#+BEGIN_SRC cpp 
  >> std::string sx = "high performance computing - finite element methods";

  >> sx.size()
  (unsigned long) 51

  >> sx.length()
  (unsigned long) 51
  >> 
#+END_SRC

String concatenation: 

#+BEGIN_SRC cpp 
  >> std::string s;
  >> s
  (std::string &) ""

  >> s = s + " string " + " C++ " + " Move "
  (std::__cxx11::basic_string &) " string  C++  Move "

  >> s
  (std::string &) " string  C++  Move "
  >> s += " C " + " Assembly " + " HEX "

  >> std::cout << "s = '" << s << "'" << "\n";
  s = ' string  C++  Move  C '
  >> 
#+END_SRC

String concatenation with append: 

#+BEGIN_SRC cpp 
  >> std::string s;
  >> s
  ""
  >> s.append("hello")
  "hello"
  >> s.append(" c++ ")
  "hello c++ "
  >> s.append(" std::string ")
  "hello c++  std::string "
  >> s
  "hello c++  std::string "
  >> 
#+END_SRC

Clear string: 

#+BEGIN_SRC cpp 
  >> std::string ss1 = "I am some string"
  (std::string &) "I am some string"

  >> ss1.clear()

  >> ss1
  (std::string &) ""

  >> ss1.size()
  (unsigned long) 0
  >> 
#+END_SRC

Substring: 

#+BEGIN_SRC cpp 
  >> std::string str = "Early computers were designed for number crunching.";

  >> str.substr(0, 10)
  "Early comp"

  >> str.substr(0, 15)
  "Early computers"

  >> str.substr(20, str.length())
  " designed for number crunching."
#+END_SRC

String comparison: 

#+BEGIN_SRC cpp 
  >> std::string pass;
  >> pass
  (std::string &) ""
  >>
  >> pass == "access"
  (bool) false
  >> pass = "access"
  "access"
  >> pass == "access"
  (bool) true
  >> 

  >> std::string("hello") == "world"
  (bool) false
  >> std::string("hello") == "hello"
  (bool) true
  >>  

  void checkPassword(const std::string& passwd){
     if(passwd == "87afx")
             std::puts("Access granted. OK.");
     else
             std::puts("Access denied. FAILURE.");
  }

  >> checkPassword("aa")
  Access denied. FAILURE.
  >> checkPassword("")
  Access denied. FAILURE.
  >> checkPassword("87afx")
  Access granted. OK.
  >> 
#+END_SRC

Reverse string: 

#+BEGIN_SRC cpp 
  >> std::string ssa = "hello world string";
  >> ssa
  (std::string &) "hello world string"

  >> std::reverse(std::begin(ssa), std::end(ssa))
  >> ssa
  (std::string &) "gnirts dlrow olleh"

  >> std::reverse(ssa.begin(), ssa.end())
  >> ssa
  (std::string &) "hello world string"
  >> 
#+END_SRC

*** Concatenate string literals 

Example: concatenate string literas and pass the to the function
perror of signature:

#+BEGIN_SRC cpp 
  void std::perror(const char*);
#+END_SRC

Trial:

#+BEGIN_SRC cpp 
  const char* s1 = " world ";
  const char* s2 = " C++ ";
  const char* s3 = " strings ";

  // Compilation error:
  >> std::perror( " literal1 " + "literal 2" + s1 + s2 + s3);
  ROOT_prompt_4:1:27: error: invalid operands to binary expression ('const char *' and 'const char *')
  std::perror( " literal1 " + "literal 2" + s1 + s2 + s3);
#+END_SRC

Solution: Wrap the first argument into an std::string. The method
.data() from the std::string class returns a pointer of type (const
char*) or a C-null terminated character array.

#+BEGIN_SRC cpp
  >> std::string text = std::string(" literal1 ") + "literal 2" + s1 + s2 + s3;
  >> text
  (std::string &) " literal1 literal 2 world  C++  strings "
  >> 
  >> std::perror(text.data())
   literal1 literal 2 world  C++  strings : No such file or directory
  >> 
#+END_SRC
*** C++14 String literals and C++11 Raw string literals 

 *C++14 String literals* 

In C++, it is not possible to concatenate or compare string literals
directly using only operators without any function such as
strcmp. Example CLING REPL:

Documentation: [[https://en.cppreference.com/w/cpp/string/basic_string/operator""s][operator""s - cppreference.com]]

#+BEGIN_SRC cpp 
   $ ~/opt/cling_2018-09-16_fedora27/bin/cling -std=c++17

   #include <iostream>
   #include <string>

   [cling]$ std::string s = "concatenate " + "string"
   input_line_8:2:33: error: invalid operands to binary expression ('const char *' and 'const char *')
    std::string s = "concatenate " + "string"
                    ~~~~~~~~~~~~~~ ^ ~~~~~~~~
   [cling]$ 

   [cling]$ "hello" == "hello"
   input_line_15:2:10: warning: result of comparison against a string literal is unspecified
         (use strncmp instead) [-Wstring-compare]
    "hello" == "hello"
    ~~~~~~~ ^
#+END_SRC

C++14 provides string literal suffix operator (s) which can simplify
string concatenation and comparison: 

#+BEGIN_SRC cpp 
   $ ~/opt/cling_2018-09-16_fedora27/bin/cling -std=c++17
   #include <iostream>
   #include <string>
   using namespace std::string_literals;

   [cling]$ auto a_std_string = "this is an std::string object"s
   "this is an std::string object"

   [cling]$ typeid(a_std_string) == typeid(std::string)
   (bool) true

   // Instead of: 
   [cling]$ s = std::string("concatenate ") + "string"
   "concatenate string"

   // The string literal operator (s) makes this code shorter:
   [cling]$ auto s2 = "concatenate "s + "string"
   "concatenate string"
#+END_SRC

String literal comparison can be peformed in two ways, one is using
the function strcmp and other one is by wrapping the first literal
with the constructor std::string(const char*). The last form of
comparison can be simplified using the suffix operator (s):

#+BEGIN_SRC cpp 
  #include <cstring>

  const char* str1 = "c++ ASM";
  const char* str2 = "Fortran";

  [cling]$ std::string("c++ ASM") == str1
  (bool) true

  [cling]$ std::string("c++ ASM") == str2
  (bool) false

  // === Shorter alternative ===========//
  [cling]$ "c++ ASM"s == str1
  (bool) true
  [cling]$ "c++ ASM"s == str2
  (bool) false
  [cling]$ 
#+END_SRC

 *C++11 Raw string literals*

Raw string literals allows writing multi line strings, regular
expressions (regex) without boilerplate and not escaped strings with
backward slashes such as Windows paths.

Form: 

#+BEGIN_SRC cpp 
  R"(<some string ...>)"
#+END_SRC

Example: 

 + file: string-literal.cpp 

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

  int main()
  {
         std::cout << std::boolalpha;
         std::cerr << std::boolalpha;

         // Raw string literals does not need escaping. 
         std::string raw1 = R"(C:\Users\nobody\tests\path)";	

         auto raw2 = std::string(R"(C:\Users\nobody\tests\path)");

         const char* raw3 = R"(
    This is a multiline 
    string
    path = C:\Users\somebody\else\docs
  \n  New line char - LF (Line Feed - LF)   
  \r  New line char - CR (Carriage Return)
  \t  Tab char
  \b  Backspace character 
         )";
         std::cout << "raw 1 = " << raw1 << std::endl;		
         std::cout << "raw 2 = "	<< raw2 << std::endl;
         std::cout << "raw 3 = " << raw3 << std::endl;
         std::cout << "typeid(raw2) == typeid(std::string) ? "
                           << (typeid(raw2) == typeid(std::string))
                           << std::endl;

         return EXIT_SUCCESS;
  }
#+END_SRC

Output: 

#+BEGIN_SRC sh 
  $ clang++ -std=c++1z -g -Wall -Wextra cpp14-string-literals.cpp -o cpp14-string-literals.bin 
  $ ./cpp14-string-literals.bin

  raw 1 = C:\Users\nobody\tests\path
  raw 2 = C:\Users\nobody\tests\path
  raw 3 = 
     This is a multiline 
     string
     path = C:\Users\somebody\else\docs
   \n  New line char - LF (Line Feed - LF)   
   \r  New line char - CR (Carriage Return)
   \t  Tab char
   \b  Backspace character 

  typeid(raw2) == typeid(std::string) ? true

#+END_SRC

Without the raw string literal operator the Windows path raw1 would
have to be written in following way. 

#+BEGIN_SRC cpp
   std::string raw1 = "C:\\Users\\nobody\\tests\\path";	
#+END_SRC

*** Numerical Parsers Functions (C++11)

Header: <string> 

Documentation: 
 + [[http://www.cplusplus.com/reference/string/][<string> - C++ Reference]]

Functions: 

| Functions | Convert to:                        |
|-----------+------------------------------------|
| stoi      | string to integer                  |
| stol      | Convert string to long int         |
| stoul     | Convert string to unsigned integer |
| stoll     | string to long long                |
| stoull    | unsigned long long                 |
| stof      | Convert string to float            |
| stod      | Convert string to double           |
| stold     | Convert string to long double      |

 + *std::stoi*
   + Convert a string to integer and throws an exception, if the
     operation is not successful.

#+BEGIN_SRC cpp 
  >> std::string s = "200"
  (std::string &) "200"

  >> std::stoi(s)
  (int) 200
  >> s = "-400"
  "-400"

  >> s = "-400";
  >> std::stoi(s)
  (int) -400

  // Throws exception 
  >> s = "aaabb -400";
  >> std::stoi(s)
  Error in <TRint::HandleTermInput()>: std::invalid_argument caught: stoi
  >> 

  //  Read hexadecimal number 
  >> s = "0xFFAB";
  >> std::stoi(s, nullptr, 16)
  (int) 65451
  >> 

  >> std::stoi("0xFF", nullptr, 16)
  (int) 255
  >> std::stoi("0xFFFF", nullptr, 16)
  (int) 65535
  >> 
#+END_SRC

 + *std::stod*
   + Convert a string to double. (double precision float point from  IEEE754)

#+BEGIN_SRC cpp 
  >> std::string s = "21.4e3";
  >> std::stod(s)
  (double) 21400.000

  >> s = "  .4e-6";
  >> std::stod(s)
  (double) 4.0000000e-07
  >> 

  // Throw exception and terminates program, if the exception is not caught.
  >> s = "failure case  .4e-6";
  >> std::stod(s)
  Error in <TRint::HandleTermInput()>: std::invalid_argument caught: stod
  >> 

  >> s = "NAN";
  >> std::stod(s)
  (double) nan
  >> s = "INFINITY";
  >> std::stod(s)
  (double) inf
  >> s = "-INFINITY";
  >> std::stod(s)
  (double) -inf
  >> 
  >> s = "3.1415";
  >> std::stod(s)
  (double) 3.1415000
  >> 

  >> std::stod("1.23e3")
  (double) 1230.0000
  >> 
#+END_SRC

*** Function to_string (C++11)

Note: This function is useful for concatenating numbers and string.

Documentation: 

 + [[http://www.cplusplus.com/reference/string/to_string/][to_string - C++ Reference]]

Overloads: 

#+BEGIN_SRC cpp 
  tring to_string (int val);
  string to_string (long val);
  string to_string (long long val);
  string to_string (unsigned val);
  string to_string (unsigned long val);
  string to_string (unsigned long long val);
  string to_string (float val);
  string to_string (double val);
  string to_string (long double val);
#+END_SRC

Example: 

#+BEGIN_SRC cpp
  >> std::string s;
  >> 
  >> double x = 3.1415;

  >> s = std::string("The value of x = ") + std::to_string(x)
   "The value of x = 3.141500"
  >> 

  >> s.clear()
  >> int n = 100;
  >> s = std::string("The value of n (integer) = ") + std::to_string(n)
  "The value of n (integer) = 100"
  >> 
#+END_SRC
*** Printing to string with std::stringstream 

Header:  [[http://www.cplusplus.com/reference/sstream/][<sstream>]]

Other useful headers: 
 + [[http://www.cplusplus.com/reference/iomanip/][<iomanip>]] - Stream manipulators, std::setw, std::setprecision and so on.
 + [[http://www.cplusplus.com/reference/ostream/][<ostream>]] - Class std::ostream, generic output.

Documentation: 
 + [[http://www.cplusplus.com/reference/sstream/][<sstream> - C++ Reference]]
 + [[http://www.cplusplus.com/reference/sstream/stringstream/][stringstream - C++ Reference]]

The class std::stringstream is a better option for concatenating
strings or printing to string. 

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

  >> std::stringstream ss;
  >> 

  >> std::stringstream ss;
  >> ss << "Hello world" << "\n";
  >> ss << "PI = " << M_PI << "\n";
  >> ss << std::fixed << std::setprecision(3) << "g = " << 9.81723 << "\n";

  // Get std::string from ss
  >> ss.str()
  "Hello world
  PI = 3.14159
  g = 9.817
  "
  >> 

  >> std::string s_copy = ss.str()
  (std::string &) "Hello world
  PI = 3.14159
  g = 9.817
  "
  >> 

  // Clear string stream 
  >> ss.str(); ss.str("");
  >> ss.str()
  ""
  >> 
#+END_SRC

 *Example:* Polymorphic function which can print to stdout (cout), stderr
(cerr) or to string.

#+BEGIN_SRC cpp 
  void printReport(std::ostream& os){
    os << std::setprecision(3);
    os << std::fixed;
    os << std::boolalpha;
    char nl = '\n';
    os << "Report Data" << nl
       << " x = " << 23.123 << nl
       << " d = " << true   << nl
       << " z = " << M_PI   << nl;
    os.flush();
  }
#+END_SRC

Print to stdout and stderr: 

#+BEGIN_SRC cpp 
  // Print to stdout (Standard output)
  >> printReport(std::cout)
  Report Data
   x = 23.123
   d = true
   z = 3.142

  // Print to stderr (Standard error output)
  >> printReport(std::cerr)
  Report Data
   x = 23.123
   d = true
   z = 3.142
  >> 
#+END_SRC

Print to string stream: 

#+BEGIN_SRC cpp 
  // Print to string stream 
  >> std::stringstream ss;
  >> printReport(ss)

  >> ss.str()
   "Report Data
   x = 23.123
   d = true
   z = 3.142
  "

  >> std::cout << ss.str() << '\n';
  Report Data
   x = 23.123
   d = true
   z = 3.142

  >> printReport(ss)
  >> std::cout << ss.str() << '\n';
  Report Data
   x = 23.123
   d = true
   z = 3.142
  Report Data
   x = 23.123
   d = true
   z = 3.142
#+END_SRC

*** TODO Parsing strings with std::stringstream

Header: <sstream>

Documentation: 
 + [[http://www.cplusplus.com/reference/sstream/][<sstream> - C++ Reference]]
 + [[http://www.cplusplus.com/reference/sstream/stringstream/][stringstream - C++ Reference]]

 *Example 1:* Parse integers from string. 

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

  std::string data = " 200 400  50.232 100 200 440";
  auto ss = std::stringstream{data};
  double x;

  size_t i = 0;
  while(!ss.eof() && !ss.fail()){
     ss >> x;
     std::cout << "x[" << i << "] = " << x << "\n";
     i++;
  }
#+END_SRC

Output: 

#+BEGIN_SRC text 
  x[0] = 200
  x[1] = 400
  x[2] = 50.232
  x[3] = 100
  x[4] = 200
  x[5] = 440
#+END_SRC

 *Example 2:* Extract all unique words from a given line: 

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

  std::string line;
  line =  "hex binary data always key hard narrow path bug hex";
  line += " binary data path words key";

  auto words = std::set<std::string>{};
  auto ss = std::stringstream{line};
  std::string w;
  while(!ss.eof() && ss.good()){
    ss >> w;
    words.insert(w);
  }

  >> line
  (std::string &) "hex binary data ... binary data path words key"
  >> 

  >> words
  { "always", "binary", "bug", "data", "hard", "hex", "key", "narrow", "path", "words" }
  >> 

  >> for(const auto& w: words) { std::cout << w << "\n";}
  always
  binary
  bug
  data
  hard
  hex
  key
  narrow
  path
  words
  >> 
#+END_SRC

 *Example 3:* Extract lines from string. 

#+BEGIN_SRC cpp 
  std::string text;
  text += "C++ => FEM -> Finite Element Methods\n";
  text += "C++ => High Performance Computing\n";
  text += "C++ => Monte Carlo Simulations\n";

  >> std::cout << text << "\n";
  C++ => FEM -> Finite Element Methods
  C++ => High Performance Computing
  C++ => Monte Carlo Simulations

  std::deque<std::string> lines;
  std::string line;
  // Input Stream                                                                
  auto is = std::stringstream {text};

  while(std::getline(is, line)) lines.emplace_back(line);

  >> lines
  { "C++ => FEM -> Finite Element Methods", "C++ => High Performance Computing", "C++ => Monte Carlo Simulations" }
  >> 

  >> for(const auto& lin: lines) { std::cout << " + line = " << lin << "\n"; }
   + line = C++ => FEM -> Finite Element Methods
   + line = C++ => High Performance Computing
   + line = C++ => Monte Carlo Simulations
  >> 
#+END_SRC

Or, putting it all together: 

 + Version: read lines from string 

#+BEGIN_SRC cpp 
  // Requires: <string> <sstream> and <iostream>                                 
  auto splitLines1(const std::string& text)
    -> std::deque<std::string>
  {
    auto lines = std::deque<std::string>{};
    auto line  = std::string{};
    auto is    = std::stringstream{text};
    while(std::getline(is, line))
      lines.emplace_back(line);
    return lines;
  }

  std::string text;
  text += "=> FEM -> Finite Element Methods\n";
  text += "=> High Performance Computing\n";
  text += "=> Monte Carlo Simulations\n";
  text += "=> Global Markets Trends\n";
  text += "=> Growth forecast survery.\n";

  >> for(const auto& lin: splitLines1(text)) { std::cout << " +=> " << lin << "\n"; }
   +=> => FEM -> Finite Element Methods
   +=> => High Performance Computing
   +=> => Monte Carlo Simulations
   +=> => Global Markets Trends
   +=> => Growth forecast survery.
  >> 
#+END_SRC

  *Example 4:* Extract lines from input stream. 

 + Read lines from input stream - this second version can read from
   any sublcass of std::istream, thus, it can also get lines from
   files and starndard input stream std::cin (console or stdin).

#+BEGIN_SRC cpp 
  // Read all lines from stram to container Requires: <string> <sstream>
  // and <iostream>
  auto splitLines2(std::istream& is) -> std::deque<std::string>
  {
    std::cerr << " [INFO] L-value reference."
    auto lines = std::deque<std::string>{};
    auto line  = std::string{};
    while(std::getline(is, line))
      lines.emplace_back(line);
    return lines;
  }
  // Overload to work with temporary objects (R-values)
  auto splitLines2(std::istream&& is) -> std::deque<std::string>
  {
    std::cerr << " [INFO] R-value reference."
    auto lines = std::deque<std::string>{};
    auto line  = std::string{};
    while(std::getline(is, line))
      lines.emplace_back(line);
    return lines;
  }

#+END_SRC

Running: 

 + Read lines from string

#+BEGIN_SRC cpp 
  std::string text;
  text += "=> FEM -> Finite Element Methods\n";
  text += "=> High Performance Computing\n";
  text += "=> Monte Carlo Simulations\n";
  text += "=> Global Markets Trends\n";
  text += "=> Growth forecast survery.\n";

  auto ss = std::stringstream(text) ;

  // Read from an L-value (object bounded to a memory location)
  >> auto ss = std::stringstream(text) ;
  >> auto lines = splitLines2(ss);
   [INFO] L-value reference.

  >> lines2
  { "=> FEM -> Finite Element Methods", "=> High Performance Computing", ...}
  >> 

  // Read from an R-value (temporary object)
  >> auto lines = splitLines2(std::stringstream(text));
   [INFO] R-value reference.
  >> lines
   { "=> FEM -> Finite Element Methods", "=> High Performance Computing", ...}
  >> 
#+END_SRC

 + Read lines from file 

#+BEGIN_SRC cpp 
  // Read lines from file: 
  >> res = splitLines2(std::ifstream("/etc/protocols"));
   [INFO] R-value reference.

  >> res.size()
  (unsigned long) 162
  >> 

  >> for(const auto& lin: res) { std::cout << " + line = " << lin << "\n";}
   + line = # /etc/protocols:
   + line = # $Id: protocols,v 1.12 2016/07/08 12:27 ovasik Exp $
   + line = #
   + line = # Internet (IP) protocols
   + line = #
   + line = #	from: @(#)protocols	5.1 (Berkeley) 4/17/89
   + line = #
   + line = # Updated for NetBSD based on RFC 1340, Assigned Numbers (July 1992).
   + line = # Last IANA update included dated 2011-05-03
   + line = #
     ... ... ... ... .... 
#+END_SRC

 + Read lines from console 

#+BEGIN_SRC cpp 
  // Types many line and then  CTRL + D (Send EOF - End Of File) when you are done.
  >> auto res2 = splitLines2(std::cin);
   [INFO] L-value reference.
  hello world
  c++ C++11 is awesome
  C++17 is amazing
  C++20 RULEZ! High peformance technical computing
    Monte Carlo Methods
    High Energy Physics
    Electronic Engineering - Embedded Processors    
  >> 

  >> res2
   { "hello world", "c++ C++11 is awesome", "C++17 is amazing", ...}
  >> 

  >> auto res2copy = std::vector<std::string>(res2.begin(), res2.end())
   { "hello world", "c++ C++11 is awesome", "C++17 is amazing", ...}
  >> 

  >> for(const auto& lin: res2){ std::cout << " [+] line = " << lin << "\n";}
   [+] line = hello world
   [+] line = c++ C++11 is awesome
   [+] line = C++17 is amazing
   [+] line = C++20 RULEZ! High peformance technical computing
   [+] line =   Monte Carlo Methods
   [+] line =   High Energy Physics
   [+] line =   Electronic Engineering - Embedded Processors
  >> 

#+END_SRC

*** Transform string to uppercase or lowercase 

Headers: 
 + <string>
 + <cstring>
 + <algorithm> 

Convert string to upper case:

#+BEGIN_SRC cpp 
  >> std::string text = "c++ is suitable for system programming";
  >> 
  std::transform( text.begin(),
                  text.end(),
                  text.begin(),
                  [](char x){ return std::toupper(x); }
                  );
  >> text
  (std::string &) "C++ IS SUITABLE FOR SYSTEM PROGRAMMING"
  >>

  auto toUpper(const std::string& text) -> std::string {
    std::string out = text;
    std::transform( out.begin(),
                    out.end(),
                    out.begin(),
                    [](char x){ return std::toupper(x); }
                    );
    return out;
  }

  >> toUpper("c++ system programming embedded high performance")
  (std::string) "C++ SYSTEM PROGRAMMING EMBEDDED HIGH PERFORMANCE"
  >> 
#+END_SRC

Convert string to lower case:

#+BEGIN_SRC cpp 
  std::string text = "c++ IS Suitable foR System proGramMing";
  std::transform( text.begin(),
                  text.end(),
                  text.begin(),
                  [](char x){ return std::tolower(x); }
                  );

  >> text
  (std::string &) "c++ is suitable for system programming"
  >> 
#+END_SRC

*** Check whether a string contains substring 

#+BEGIN_SRC cpp 
  bool containsStr(const std::string& str, const std::string& substr){
       return str.find(substr) != std::string::npos;
  }

  >> containsStr("cpp plus plus cee c++ 34", "c++")
  (bool) true
  >> containsStr("cpp plus plus cee c++ 34", "cpp11")
  (bool) false
  >> containsStr("cpp plus plus cee c++ 34", "cee")
  (bool) true
  >> 
#+END_SRC
*** Search and replace 

#+BEGIN_SRC cpp 
  auto replaceStr( const std::string& text,                              
                   const std::string& rep,                                
                   const std::string& subst                               
                ) -> std::string {                                                     
    // Copy paraemter text (Invoke copy constructor)                             
    std::string out = text;                                                      
    // Find position of character matching the string                            
    size_t i = out.find(rep);                                                    
    while(i != std::string::npos){                                               
      out.replace(i, rep.size(), subst);                                         
      i = out.find(rep, i);                                                      
    }                                                                            
    return out;                                                                  
  } 

  >> replaceStr(" c++11 high c++future c++15 peformance cpp c++17", "c++", "")
  (std::string) " 11 high future 15 peformance cpp 17"

  >> replaceStr(" c++11 high c++future c++15 peformance cpp c++17", "c++", "DLang")
  (std::string) " DLang11 high DLangfuture DLang15 peformance cpp DLang17"
  >> 

  >> replaceStr(" c++11 high c++future c++15 peformance cpp c++17", "c++", "CXX")
  (std::string) " CXX11 high CXXfuture CXX15 peformance cpp CXX17"
#+END_SRC

*** Character Testing 

|---------------------+---------------------------------------------------------|
| Function            | Return                                                  |
|---------------------+---------------------------------------------------------|
| int isalphanum(int) | Non-zero if input is letter or digit                    |
| int isalpha(int)    | Non-zero if input is letter                             |
| int iscntr(int)     | Non-zero if input is control character                  |
| int isdigit(int)    | Non-zero if input is digit                              |
| int isgraph(int)    | Non-zero if input is not whitespace printable character |
| int isprint(int)    | ... if input is printable character                     |
| int ispunct(int)    | ... if input is neither alphanumeric nor whitespace     |
| int isspace(int)    | ... if input is whitespace                              |
| int isxdigit(int)   | ... if input is hexadecimal digit                       |
|---------------------+---------------------------------------------------------|

 - Check whether string is number: 

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

  bool isNumber(const std::string& str){
    if(str == "") return false;
    return std::all_of(
               str.begin(),
               str.end(),
               [](char x){
                 return std::isdigit(x);
               });
  }

  >> isNumber("1213")
  (bool) true
  >> isNumber("12x13")
  (bool) false
  >> isNumber("")
  (bool) false
  >> 
#+END_SRC

 - Check whether string is an hexadecimal number 

#+BEGIN_SRC cpp 
 bool isNumberHex(const std::string& str){
    if(str == "") return false;
    return std::all_of(
               str.begin(),
               str.end(),
               [](char x){
                 return std::isxdigit(x);
               });
  }

  >> isNumberHex("0fabcd92813")
  (bool) true
  >> 
  >> isNumberHex("0fxabcd92813")
  (bool) false
  >> isNumberHex("")
  (bool) false
  >> isNumberHex("ff")
  (bool) true
  >> isNumberHex("0xff")
  (bool) false
#+END_SRC

 - Check whether string contains only letters 

#+BEGIN_SRC cpp
  bool isAlphaOnly(const std::string& str){
    if(str == "") return false;
    return std::all_of(
               str.begin(),
               str.end(),
               [](char x){
                 return std::isalpha(x);
               });
  }

  >> isAlphaOnly("helloworld")
  (bool) true
  >> isAlphaOnly("hello54world")
  (bool) false
  >> isAlphaOnly("")
  (bool) false
  >> isAlphaOnly("w")
  (bool) true
  >> isAlphaOnly("sa.ds-a")
  (bool) false
  >> 
#+END_SRC
*** Split string by delimiter

Testing: 

#+BEGIN_SRC cpp 
  >> std::string t = "key =  value";
  >> size_t i = t.find("=")
  (unsigned long) 4

  >> t.substr(0, i)
  "key "
  >> 
  >> t.substr(i, t.size())
  "=  value"
  >> t.substr(i + 1, t.size())
  "  value"
  >> 
#+END_SRC

Encapsulating into a function: 

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

  auto splitString(const std::string& str,
                   const std::string& delim
                   ) -> std::deque<std::string> {
    std::deque<std::string> xs;
    size_t i = str.find(delim);
    if(i == std::string::npos){
      xs.push_back("");
      xs.push_back("");
      return xs;
    }
    xs.push_back(str.substr(0,    i));
    xs.push_back(str.substr(i + 1, str.size()));
    return xs;
  };

  >> splitString("key value", "=")
  (std::deque<std::string>) { "", "" }
  >> splitString("key = value", "=")
  (std::deque<std::string>) { "key ", " value" }
  >> splitString("key  va=lue", "=")
  (std::deque<std::string>) { "key  va", "lue" }
  >> splitString("key  value=", "=")
  (std::deque<std::string>) { "key  value", "" }
  >> splitString("", "=")
  (std::deque<std::string>) { "", "" }
  >> splitString("key  value=", "")
  (std::deque<std::string>) { "", "ey  value=" }
  >> 
#+END_SRC
*** Extract quoted string (C++14)

Documentation: [[https://en.cppreference.com/w/cpp/io/manip/quoted][std::quoted - cppreference.com]]

#+BEGIN_SRC cpp
  #include <iostream>
  #include <string>
  #include <sstream>
  #include <iomanip> // std::quoted in C++14

  std::string s = " 200 key value \" aquoted string \"  \"next quote\"";
  std::stringstream ss{s};

  std::string out;

  while(!ss.eof()){
    ss >> std::quoted(out);
    std::cout << "word = " << out << "\n";
  }
#+END_SRC

Output: 

#+BEGIN_SRC text 
 word = 200
 word = key
 word = value
 word =  aquoted string 
 word = next quote
 word = next quote
#+END_SRC

Hand-rolled quoted string parser: 

 + Useful if C++14 is not avaiable.

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

  // Requires headers: <string> and <sstream>
  auto readQuoted(std::istream& is) -> std::string {
       char ch;
       std::ostringstream so;
       if(is.eof()) return "";
       // Find first quote:
       //-------------------------------------
       do {
          ch = static_cast<char>(is.get());
       } while(is.good() && !is.eof() && std::isspace(ch));	
       //std::cout << "ch = " << ch  << "\n";	
       if(ch != '\"'){
          so << ch;
          do {
              ch = static_cast<char>(is.get());
              so << ch;
          } while(is.good() && !is.eof() && !std::isspace(ch));
          if(is.eof()) return "";
          return so.str();
       }
       //std::cout << "ch = " << ch  << "\n";	
       do {
          ch = static_cast<char>(is.get());
          if(ch != '\"') so << ch;
       } while(is.good() && !is.eof() && ch != '\"');
       if(is.eof()) // Did not find a matching quote.
          return "";
       //std::cout << "ch = " << ch  << "\n";
       return so.str();
  }
#+END_SRC

Running: 

#+BEGIN_SRC cpp
   std::string s = "  \" 200 99 888 quoted - string \" KEY \" VALUE PAIR \"  100 \" Sao Paulo City\" 4500 key ";
   std::stringstream ss{s};

   >>> while(ss.good()) std::cout << "quoted = " << readQuoted(ss) << "\n";
   quoted =  200 99 888 quoted - string 
   quoted = KEY 
   quoted =  VALUE PAIR 
   quoted = 100 
   quoted =  Sao Paulo City
   quoted = 4500 
   quoted = key 
   quoted = 
#+END_SRC

*** Parse comma separated value - CSV row 

Note: the following CSV parser functions fails for heterogeneous data
or when there are quotes characters. It is better to use a proper CSV
parser library as CSV is not a standardized data exchange format and
has lots of tricky edge cases.

 + Example: Simple CSV line parser. 

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

  std::vector<double> parseCSVRow(const std::string& line, char delim = ','){
    auto out   = std::vector<double>{};
    auto token = std::string{};
    auto ss    = std::stringstream{line};
    while(std::getline(ss, token, delim)){
      out.push_back(std::stod(token));
    }
    return out;
  }
#+END_SRC

Testing: 

#+BEGIN_SRC cpp 
  std::string raw_data = "100,   200,  400, -100.23, 60.23, 90.32";

  >> parseCSVRow(raw_data)
  (std::vector<double>) { 100.00000, 200.00000, 400.00000, -100.23000, 60.230000, 90.320000 }
  >> auto xs = parseCSVRow(raw_data);
  >> xs[0]
  (double) 100.00000
  >> xs[1]
  (double) 200.00000
  >> xs[2]
  (double) 400.00000
  >> xs[3]
  (double) -100.23000
  >> 
#+END_SRC

 + Example: Generic CSV line Parser. 

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

  template<class Type = double>
  std::vector<Type> parseCSVRowGeneric(const std::string& line,
                                       char delim = ','
                                       ){
    auto out   = std::vector<Type>{};
    auto token = std::string{};
    auto ss    = std::stringstream{line};
    auto is    = std::stringstream{};
    Type value{};
    while(std::getline(ss, token, delim)){
      // Clear error flags                                                                                                                              
      is.clear();
      // Set is stream value to token                                                                                                                   
      is.str(token);
      // Extract from 'is' stream                                                                                                                       
      is >> value;
      out.push_back(value);
    }
    return out;
  }
#+END_SRC

Testing: 

#+BEGIN_SRC cpp 
  // Test data
  std::string lineB = "2002.23, 434.34, 90.23, -23.23, 1e3";
  std::string lineC = "100; 200; 300; 150; 500; 600";
  std::string lineD = "Apple: oranges : juice beans : rice";

  >> parseCSVRowGeneric(lineB)
  (std::vector<double>) { 2002.2300, 434.34000, 90.230000, -23.230000, 1000.0000 }

  >> parseCSVRowGeneric<>(lineB)
  (std::vector<double>) { 2002.2300, 434.34000, 90.230000, -23.230000, 1000.0000 }
  >> 

  >> parseCSVRowGeneric<double>(lineB, ',')
  (std::vector<double>) { 2002.2300, 434.34000, 90.230000, -23.230000, 1000.0000 }
  >> 

  >> parseCSVRowGeneric<int>(lineC, ';')
  (std::vector<int>) { 100, 200, 300, 150, 500, 600 }
  >> 

  >> parseCSVRowGeneric<std::string>(lineD, ':')
  { "Apple", "oranges", "juice", "rice" }
#+END_SRC

*** C++11 Regular Expressions Regex 
**** Overview  

C++11 STL provides a regular expression library with ECMAScript
(Javascript) engine. It makes easier to use regular expressions
without third-party libraries.

 *Documentation:*

 + [[https://en.cppreference.com/w/cpp/regex][Regular expressions library - cppreference.com]]
 + [[http://www.cplusplus.com/reference/regex/][<regex> - C++ Reference]]
 + [[https://docs.microsoft.com/en-us/cpp/standard-library/regex?view=vs-2017][<regex> | Microsoft Docs]]
 + [[https://www.boost.org/doc/libs/1_69_0/libs/regex/doc/html/index.html][Boost.Regex]] - predecessor of the STL regex library, so it is a
   practical documentation of the current STL <regex> library.

 *ECMAScript Regex Syntax*
 
 + [[http://www.cplusplus.com/reference/regex/ECMAScript/][ECMAScript syntax - C++ Reference]]
 + [[https://en.cppreference.com/w/cpp/regex/ecmascript][Modified ECMAScript regular expression grammar - cppreference.com]]
 + [[https://o7planning.org/en/12219/ecmascript-regular-expressions-tutorial][ECMAScript / Javascript Regular Expressions Tutorial]]

 *Engines*

Regular expression grammars supported by the C++11 regex library: 

 + ECMAScript ("JavaScript" is an [[https://news.ycombinator.com/item?id=8344049][Oracle inc.]] trademark) - default regex engine
 + basic
 + extended 
 + awk
 + grep
 + egrep 

 *Classes:*

|------------------------+-------------------------------------------------------------------------|
| Class                  | Description                                                             |
|------------------------+-------------------------------------------------------------------------|
| [[https://en.cppreference.com/w/cpp/regex/basic_regex][std::regex]]             | Regular expression object. It is the same as  [[https://en.cppreference.com/w/cpp/regex/basic_regex][std::basic_regex]]          |
|                        |                                                                         |
| *Regex Matching*         |                                                                         |
|------------------------+-------------------------------------------------------------------------|
| [[https://en.cppreference.com/w/cpp/regex/match_results][std::match]]             | Regex matching results. It is  the same as  [[https://en.cppreference.com/w/cpp/regex/match_results][std::match_results]]          |
| std::smatch   	 | std::match_results<std::string::const_iterator>                         |
| std::cmatch	         | ~std::match_results<const char*>~                                         |
| std::wcmatch           | ~std::match_results<const wchar_t*>~                                      |
| std::wsmatch	         | ~std::match_results<std::wstring::const_iterator>~                        |
|                        |                                                                         |
| *Iterators*              |                                                                         |
|------------------------+-------------------------------------------------------------------------|
| [[https://en.cppreference.com/w/cpp/regex/regex_iterator][std::regex_iterator]]<T> | Regex iterator object - provides access to regex matches.               |
| cregex_iterator        | ~regex_iterator<const char*>~ - Specialization for type _const char*_       |
| wcregex_iterator       | ~regex_iterator<const wchar_t*>~ - Specialization for type _const wchar_t*_ |
| sregex_iterator        | ~regex_iterator<std::string::const_iterator>~                             |
| wsregex_iterator       | regex_iterator<std::wstring::const_iterator>                            |
|------------------------+-------------------------------------------------------------------------|

 *Online REGEX Testers* 
 
 + [[https://myregextester.com/index.php#resultstab][Myregextester.com]]

 + [[https://regexr.com/][RegExr: Learn, Build, & Test RegEx]]

 + https://regex101.com/

**** Example 

 + File: [[file:src/regex1.cpp][file:src/regex1.cpp]]
 + Online Compiler: https://rextester.com/RKT35657

Compile and run:  

#+BEGIN_SRC sh  
  $ clang++ regex1.cpp -o regex1.bin -std=c++1z -O0 -Wall && ./regex1.bin
  $ g++ regex1.cpp -o regex1.bin -std=c++1z -O0 -Wall && ./regex1.bin

  # Compilation is slow: it takes 2 seconds [Non optimized]!!
  $ time clang++ regex1.cpp -o regex1.bin -std=c++1z -O0 -Wall
  real	0m2.356s
  user	0m2.200s
  sys	0m0.112s

  # Compilation time is even slower when optimized!! 6 seconds to build!
  $ time clang++ regex1.cpp -o regex1.bin -std=c++1z -O3 -Wall
  real	0m6.027s
  user	0m5.584s
  sys	0m0.107s
#+END_SRC

 *Macro DBG_DISP for displaying expressions:*

#+BEGIN_SRC cpp 
   #define DBG_DISP(expr)  std::cerr << __FILE__ << ":" << __LINE__ << ":" \
           << " ; " <<  #expr << " = " << (expr)  <<  std::endl
#+END_SRC

 *Headers*

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

 *Experiment 1: Match entire string*

#+BEGIN_SRC cpp 
    std::puts("\n ======== EXPERIMENT 1 === Match entire string =====");
    std::regex numRegex("\\d+");		
    DBG_DISP(std::regex_match("3423", numRegex));
    DBG_DISP(std::regex_match("AAB786", numRegex));
    DBG_DISP(std::regex_match("  9745", numRegex));
    DBG_DISP(std::regex_match(" 634 ", numRegex));
#+END_SRC

Output: 

#+BEGIN_SRC text 
    ======== EXPERIMENT 1 === Match entire string =====
   regex1.cpp:17: ; std::regex_match("3423", numRegex) = true
   regex1.cpp:18: ; std::regex_match("AAB786", numRegex) = false
   regex1.cpp:19: ; std::regex_match("  9745", numRegex) = false
   regex1.cpp:20: ; std::regex_match(" 634 ", numRegex) = false
#+END_SRC

 *Experiment 2: Check whether text has regex*

#+BEGIN_SRC cpp 
    std::puts("\n ======== EXPERIMENT 2 === Check whether text has regex =====");
    std::regex variable("\\s?[a-zA-Z][a-zA-Z|\\d]*\\b");
    DBG_DISP(std::regex_search("3423", variable));
    DBG_DISP(std::regex_search("dot.com\\ -buble hello variable4561 ", variable));
    DBG_DISP(std::regex_search("  -dot.com.buble.burst ", variable));
#+END_SRC

Output: 

#+BEGIN_SRC text 
    ======== EXPERIMENT 2 === Check whether text has regex =====
   regex1.cpp:25: ; std::regex_search("3423", variable) = false
   regex1.cpp:26: ; std::regex_search("dot.com\\ -buble hello variable4561 ", variable) = true
   regex1.cpp:27: ; std::regex_search("  -dot.com.buble.burst ", variable) = true
#+END_SRC

 *Experiment 3: Extract text*

#+BEGIN_SRC cpp 
   std::puts("\n ======== EXPERIMENT 3 === Extract text =====");
   std::regex phoneRe{"phone:\\s*(\\d{8})\\s*$"};
   std::string line;
   std::smatch result;

   line = "phone:85619751";
   if(std::regex_search(line, result, phoneRe) && result.size() > 1)
      std::cout << "Result1 = " << result.str(1) << "\n";
   else
      std::cout << "Result1 = <<NOT MATCH>>" << std::endl;

   line = "phone:  65658741  ";
   if(std::regex_search(line, result, phoneRe) && result.size() > 1)
       std::cout << "Result2 = " << result.str(1) << "\n";
   else
       std::cout << "Result2 = <<NOT MATCH>>" << std::endl;

   line = "phone:  756596213434";
   if(std::regex_search(line, result, phoneRe) && result.size() > 1)
      std::cout << "Result3 = " << result.str(1) << "\n";
   else
      std::cout << "Result3 = <<NOT MATCH>>" << std::endl;

   line = "phone:  ABBX621";
   if(std::regex_search(line, result, phoneRe) && result.size() > 1)
      std::cout << "Result4 = " << result.str(1) << "\n";
   else
      std::cout << "Result4 = <<NOT MATCH>>" << std::endl;		
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ======== EXPERIMENT 3 === Extract text =====
  Result1 = 85619751
  Result2 = 65658741
  Result3 = <<NOT MATCH>>
  Result4 = <<NOT MATCH>>
#+END_SRC

 *Experiment 4-A: Finding all regex matches*

#+BEGIN_SRC cpp 
  std::puts("\n ======== EXPERIMENT 4-A === Finding all regex matches  ======");		
  std::regex nregex("[0-9]+\\b", std::regex::ECMAScript);	
  std::string line = " 565 923 100 -934  AABB56 0835";
  std::sregex_iterator it_beg(line.begin(), line.end(), nregex);
  std::sregex_iterator it_end;
  std::cout << " Number of matches = " << std::distance(it_beg, it_end) << "\n";
  int i = 0;
  for(auto it  = it_beg; it != it_end; it++){ 
     std::cout << " => x[" << i++ << "] = " << it->str() << "\n";
  }
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ======== EXPERIMENT 4-A === Finding all regex matches  ======
   Number of matches = 6
   => x[0] = 565
   => x[1] = 923
   => x[2] = 100
   => x[3] = 934
   => x[4] = 56
   => x[5] = 0835

#+END_SRC

 *Experiment 4-B: Finding all regex matches*

#+BEGIN_SRC cpp 
   std::puts("\n ======== EXPERIMENT 4-B === Finding all regex matches  ======");
   // Matches 4 letters followed by 3 digits
   // first capture group 4 letters set, second capture group: 3 digits set 
   std::regex re("([A-Z]{4})([0-9]{3})");	
   std::string line = " ABCD367 XYAZ561 baa 341 MNPQ456 ";
   std::sregex_iterator begin(line.begin(), line.end(), re);
   std::sregex_iterator end;
   for(auto it  = begin; it != end; it++)
       std::cout << " capture[0] = "   << it->str() 
                 << " ; capture[1] = " << it->str(1)
                 << " ; capture[2] = " << it->str(2)
                 << "\n";
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ======== EXPERIMENT 4-B === Finding all regex matches  ======
   capture[0] = ABCD367 ; capture[1] = ABCD ; capture[2] = 367
   capture[0] = XYAZ561 ; capture[1] = XYAZ ; capture[2] = 561
   capture[0] = MNPQ456 ; capture[1] = MNPQ ; capture[2] = 456
#+END_SRC

 *Experiment 4-C: Finding all regex matches*

#+BEGIN_SRC cpp 
   std::puts("\n ======== EXPERIMENT 4-C === Finding all regex matches range-based loop ===");
   // Matches 4 letters followed by 3 digits
   // first capture group 4 letters set, second capture group: 3 digits set 
   std::regex re("([A-Z]{4})([0-9]{3})");	
   std::string line = " ABCD367 XYAZ561 baa 341 MNPQ456 ";
   std::smatch matches;
   std::regex_search(line, matches, re);
   for(const auto& m : matches )
      std::cout << " =>>> "   << m << "\n";
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ======== EXPERIMENT 4-C === Finding all regex matches range-based loop ===
   =>>> ABCD367
   =>>> ABCD
   =>>> 367
#+END_SRC

 *Experiment 5: Replace all matches*

#+BEGIN_SRC cpp 
   std::puts("\n ======== EXPERIMENT 5 === Replace matches  ======");
   // Matches 4 letters followed by 3 digits
   // first capture group 4 letters set, second capture group: 3 digits set 
   std::regex re("([A-Z]{4})([0-9]{3})");	
   std::string line = " ABCD367 XYAZ561 baa 341 MNPQ456 ";
   std::string out = std::regex_replace(line, re, "{$1=$2} - ");
   std::cout << " out = " << out << std::endl;
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ======== EXPERIMENT 5 === Replace matches  ======
   out =  {ABCD=367} -  {XYAZ=561} -  baa 341 {MNPQ=456} -  
#+END_SRC

** C++11 - Uniform Initialization

The C++11 uniform initialization feature allows classes, STL
containers (collections) and primitives values to be initialized in a
uniform way similar to vectors and C-arrays. 

 - Uniform initialization of primitive types: 

#+BEGIN_SRC cpp 
  int    x {};   // x = 0
  double fd {};  // fd = 0.0
  float  ff {};  // ff = 0.0f
  bool   flag{}; // flag = false = 0 
#+END_SRC

 - Uniform initialization of C-arrays 

#+BEGIN_SRC cpp 
  int xs[] {10, 20, 30};  //  int xs[] =  {10, 20, 30};
  double ys[3] {1.0};     //  double ys[] = {1.0};
#+END_SRC

 - Uniform initialization of pointers 

#+BEGIN_SRC cpp 
  double* fdptr{} ; // fdptr = nullptr 
#+END_SRC

 - Uniform initialization of STL containers: 

#+BEGIN_SRC cpp 
  std::string s {};                // s = ""
  std::string s {"Hello world"};   // s = "Hello World"

  // Vectors 
  std::vector<double> xs {};                      
  std::vector<double> ys {2.0, 3.0, 4.0, 5.0};
  std::vector<string> zs {"apple", "orange", "grape", "banana"};
  // Lists
  std::list<double>   xs {};
  std::list<double>   ys{2.0, 3.0, 4.0, 5.0};   
  // Sets 
  std::set<double>    xs{};
  std::set<double>    ys {3.0, 4.0, 3.0, 10.0};
  // Unordered set 
  std::unordered_set<int>    xs{};
  std::unordered_set<string> zs {"apple", "orange", "grape", "banana"};

  // Maps, aka hash map, aka dictionary, aka hash table 
  std::map<std::string,double> prices {{"orange", 10.0}, {"grapes", 25.12}, {"apple", 4.12}};
#+END_SRC

 - Initialization of C-structus POD - Plain Old Data 

#+BEGIN_SRC cpp 
  struct Point3D{
      double x;
      double y;
      double z;
  };

  // Before C++11
  //---------------------------
  Point3D pa;
  pa.x = 10.0;
  pa.y = 20.0;
  pa.z = 35.0;

  // After C++11
  //---------------------------
  Point3D pb {10.0, 20.0, 35.0};
  Point3D pc = {10.0, 20.0, 35.0};

  // C++ Vector - way 1
  std::vector<Point3D> {{ 20.0, 15.0, 5.0}, { 10.0, 25.0, 12.4}, {-14.0, 0.32, 51.43}};

  // C++ Vector - way 2 
  std::vector<Point3D> {
        Point3D{ 20.0, 15.0, 5.0}
       ,Point3D{ 10.0, 25.0, 12.4}
       ,Point3D{-14.0, 0.32, 51.43}
  };

  // C++ Map Containers 
  std::map<std::string, Point3D> locations = {
       {"City 1",    { 20.0, 15.0, 5.0}}
      ,{"Somewhere", { 10.0, 25.0, 12.4}}
      ,{"Nowhere",   {-14.0, 0.32, 51.43}}     
  };

  // or in more pleasant notation 
  // C++ Map Containers 
  auto locations2 = std::map<std::string, Point3D> {
       {"City 1",    { 20.0, 15.0, 5.0}}
      ,{"Somewhere", { 10.0, 25.0, 12.4}}
      ,{"Nowhere",   {-14.0, 0.32, 51.43}}     
  };

  //--- Functions -------//

  Point3D makeOriginPoint(){
      // return Point3D{0.0, 0.0, 0.0};
      return {0.0, 0.0, 0.0};
  }

#+END_SRC

Classes: 

#+BEGIN_SRC cpp 
  class A{
  public: 
      A(double x, double y, double z, std::string name):
          m_x(x),
          m_y(y),
          m_z(z),
          m_name(name) {      
      }
      auto getX() -> double{ return m_x;}
      auto getY() -> double {return m_y;}
      auto getZ() -> double {return m_z;} 
  private:
      double m_x;
      double m_y;
      double m_z; 
  };

  void display(const A& a){
      std::cout << "A (" << a.getX() << " " << a.getY() << a.getZ() << ")" << "\n";
  }

  int main(){
      A instance1 {10.0, 20.0, 15.0, "unknown binary blob"};  
      display(instance1);
      display({10.0, 20.0, 15.0, "unknown binary blob"});
      return 0;
  }

#+END_SRC

References: 

 + [[http://scottmeyers.blogspot.com/2015/09/thoughts-on-vagaries-of-c-initialization.html][The View from Aristeia: Thoughts on the Vagaries of C++ Initialization]]
 + [[https://www.codeguru.com/cpp/cpp/article.php/c19081/C-2011-Uniform-Initialization.htm][C++ 2011: Uniform Initialization]]
 + [[https://mbevin.wordpress.com/2012/11/16/uniform-initialization/][Lesson #3: Uniform Initialization | Mike's C++11 Blog]]
 + [[https://softwareengineering.stackexchange.com/questions/133688/is-c11-uniform-initialization-a-replacement-for-the-old-style-syntax][c++ - Is C++11 Uniform Initialization a replacement for the old style syntax? - Software Engineering Stack Exchange]]
 + 
 + 
** Iterator based loops and for-range based loops 
*** Iterator based loop 

Loop over a vector: 

#+BEGIN_SRC cpp 
  std::vector<std::string> xs {"Hello", "world", "C++", "HPC", "awesome"};

  for(std::vector<std::string>::iterator it = xs.begin(); it != xs.end(); ++it){
       std::cout << "word = '" << *it << "' size = " << it->size() << "\n";
  }

  /** Output: 
     word = 'Hello' size = 5
     word = 'world' size = 5
     word = 'C++' size = 3
     word = 'HPC' size = 3
     word = 'awesome' size = 7
     >> 
   ,*/

  // === OR =====//

  for(auto it = xs.begin(); it != xs.end(); ++it){
       std::cout << "word = '" << *it << "' size = " << it->size() << "\n";
  }

  /** Output: 
          word = 'Hello' size = 5
          word = 'world' size = 5
          word = 'C++' size = 3
          word = 'HPC' size = 3
          word = 'awesome' size = 7
   ,*/
#+END_SRC

Loop over a deque: 

#+BEGIN_SRC cpp 
  auto ds = std::deque<std::string> {"Physics", "C++", "STL", "Math", "Algebra", "Electronics"};

  for(std::deque<std::string>::iterator it = ds.begin(); it != ds.end(); ++it){
        std::cout << "word = '" << *it << "' size = " << it->size() << "\n";
  }

  // Or: 
  for(auto it = ds.begin(); it != ds.end(); ++it){
        std::cout << "word = '" << *it << "' size = " << it->size() << "\n";
  }

  /** Output: 
     word = 'Physics' size = 7
     word = 'C++' size = 3
     word = 'STL' size = 3
     word = 'Math' size = 4
     word = 'Algebra' size = 7
     word = 'Electronics' size = 11
   ,*/

#+END_SRC

Loop over a list: 

#+BEGIN_SRC cpp 
  // Struct is a class with everything public 
  struct Waypoint{
      std::string name;
      double      lat;
      double      lon;
      // This constructor is necessary for storing this object
      // in STL collections/containers 
      Waypoint(){}
      Waypoint(const std::string& name, double lat, double lon):
              name(name), lat(lat), lon(lon){}
  };

  >> auto wp = Waypoint("Paris", 48.23, 22.12)
  >> wp.name
  (std::string &) "Paris"
  >> wp.lat
  (double) 48.230000
  >> wp.lon
  (double) 22.120000
  >> 
  >> 

  auto waypoints = std::list<Waypoint>{};
  waypoints.emplace_back("Paris", 48.8566, 2.3522);
  waypoints.emplace_back("Tokyo", 35.6895, 139.6917);
  waypoints.emplace_back("Beijing", 39.9042, 116.4074);
  waypoints.emplace_back("Cape Town", -33.9249, 18.4241);
  waypoints.emplace_back("Buenos Aires", -34.6037, -58.3816);

  std::cout << std::fixed << std::setprecision(2);

  for(auto it = waypoints.begin(); it != waypoints.end(); ++it){
          std::cout << std::setw(15) << std::left  << it->name
                            << std::setw(15) << std::right << it->lat
                            << std::setw(15) << it->lon
                            << "\n";
  }
#+END_SRC

Output: 

#+BEGIN_SRC text 
  Paris                    48.86           2.35
  Tokyo                    35.69         139.69
  Beijing                  39.90         116.41
  Cape Town               -33.92          18.42
  Buenos Aires            -34.60         -58.38
#+END_SRC

Loop over a map:

#+BEGIN_SRC cpp 
  auto values = std::map<std::string, double>{
        {"x",  2.1023}
       ,{"y",  sqrt(2)}
       ,{"e",  exp(1)}
       ,{"pi", 3.1415}
       ,{"3/4", 3.0 / 4.0}
  };

  std::cout << std::fixed << std::setprecision(2);

  for(std::map<std::string, double>::iterator it = values.begin(); it != values.end(); it++){
          std::cout << std::setw(5) << std::left  << it->first
                    << std::setw(5) << std::right << it->second
                    << "\n";
  }

  // OR:
  for(auto it = values.begin(); it != values.end(); it++){
          std::cout << std::setw(5) << std::left  << it->first
                    << std::setw(5) << std::right << it->second
                    << "\n";
  }

  /** Output: 
     3/4   0.75
     e     2.72
     pi    3.14
     x     2.10
     y     1.41
   ,*/
#+END_SRC

*** For-range based loops 

C++11 and new standards allow to iterate over any STL container or
class with methods (member functions) .begin() or .end() using a
simpler and cleaner syntax than the old iterator loop syntax.

 *Loop over literals*

#+BEGIN_SRC cpp
  #include <iostream>

  // Possible since C++11
  >> for(const auto& x: {10, 20, 40, 50, 60}) {
         std::cout << " x = " << x << "\n";
      }
   x = 10
   x = 20
   x = 40
   x = 50
   x = 60

  >> for(const auto& word: {"C++", "C++11", "Real Time"}) {
         std::cout << " word = " << word << "\n";
      }
   word = C++
   word = C++11
   word = Real Time

   >> for(const std::string& word: {"C++", "C++11", "Real Time"}) {
          std::cout << " word = "+ word
                    << "  size = " << word.size()
                    << "\n";
      }
   word = C++  size = 3
   word = C++11  size = 5
   word = Real Time  size = 9
#+END_SRC


 *Loop over a vector:*

#+BEGIN_SRC cpp 
  std::vector<std::string> xs {"Hello", "world", "C++", "HPC", "awesome"};

  // Use: const auto&  to avoid uncessary copies, use auto& if there is modification of x.
  // The const keyword will generate a compiler error if there is 
  // any attempt to modify the value of x. 
  for(const auto& x: xs){
       std::cout << "word = '" << x << "' size = " << x.size() << "\n";
  }

  /** Output: 
     word = 'Hello' size = 5
     word = 'world' size = 5
     word = 'C++' size = 3
     word = 'HPC' size = 3
     word = 'awesome' size = 7
   ,*---------------*/

#+END_SRC

 *Loop over a list:*

#+BEGIN_SRC cpp 
  // Struct is a class with everything public 
  struct Waypoint{
          std::string name;
          double      lat;
          double      lon;
          // This constructor is necessary for storing this object
          // in STL collections/containers 
          Waypoint(){}
          Waypoint(const std::string& name, double lat, double lon):
                  name(name), lat(lat), lon(lon){}
  };

  auto waypoints = std::list<Waypoint>{
         {"Paris", 48.8566, 2.3522}
        ,{"Tokyo", 35.6895, 139.6917}
        ,{"Beijing", 39.9042, 116.4074}
        ,{"Cape Town", -33.9249, 18.4241}
        ,{"Buenos Aires", -34.6037, -58.3816}};


  std::cout << std::fixed << std::setprecision(2);

  for(const auto& wp: waypoints){
          std::cout << std::setw(15) << std::left  << wp.name
                            << std::setw(15) << std::right << wp.lat
                            << std::setw(15) << wp.lon 
                            << "\n";
  }

#+END_SRC

Ouput: 

#+BEGIN_SRC text 
  Paris                    48.86           2.35
  Tokyo                    35.69         139.69
  Beijing                  39.90         116.41
  Cape Town               -33.92          18.42
  Buenos Aires            -34.60         -58.38
#+END_SRC

 *Loop over a map*

#+BEGIN_SRC cpp 
  auto values = std::map<std::string, double>{
        {"x",  2.1023}
       ,{"y",  sqrt(2)}
       ,{"e",  exp(1)}
       ,{"pi", 3.1415}
       ,{"3/4", 3.0 / 4.0}
  };

  std::cout << std::fixed << std::setprecision(3);

  for(const auto& p: values){
          std::cout << std::setw(5) << std::left  << p.first
                    << std::setw(5) << std::right << p.second
                    << "\n";
  }

  /** Output: 
     3/4  0.750
     e    2.718
     pi   3.142
     x    2.102
     y    1.414
   ,*==============*/
#+END_SRC
** C++11 - Scoped Enum

Scoped enumerations are a more type-safe alternative to the old
C-enums as it has several problems realated to namespace conflicts and
implicit conversions that can introduce bugs hard to catch and reason
about. 

Syntax: 

 - Simple scoped enum class 

#+BEGIN_SRC cpp 
  enum class Color {
     white,
     black,
     yellow,
     red,
     blue,
  };

  >> Color::white
  (Color) (Color::white) : (int) 0
  >> Color::blue
  (Color) (Color::blue) : (int) 4
  >> Color::yellow
  (Color) (Color::yellow) : (int) 2
  >> Color::red
  (Color) (Color::red) : (int) 3
  >> 

  >> static_cast<int>(Color::blue)
  (int) 4
  >> static_cast<int>(Color::white)
  (int) 0
  >> static_cast<int>(Color::yellow)
  (int) 2
  >> 
#+END_SRC

 - Scoped enum with hexadecimal error codes.
 
#+BEGIN_SRC cpp 
  enum class ErrorCode: std::uint32_t {
     tankNotFilled = 0xff,
     missingSupply = 0x2f,
     lowBattery    = 0x2a,
     unknown       = 0x24                                         
  };
#+END_SRC

 - Scoped enums with chars 

#+BEGIN_SRC cpp 
  enum class ErrorCodeLetter: char {
     tankNotFilled = 'x',
     missingSupply = 'y',
     lowBattery    = 'a',
     unknown       = 'k'                                         
  };

  >> ErrorCodeLetter::tankNotFilled
  (ErrorCodeLetter) (ErrorCodeLetter::tankNotFilled) : (char) 120
  >> ErrorCodeLetter::missingSupply
  (ErrorCodeLetter) (ErrorCodeLetter::missingSupply) : (char) 121
  >> ErrorCodeLetter::unknown
  (ErrorCodeLetter) (ErrorCodeLetter::unknown) : (char) 107
  >> static_cast<char>(ErrorCodeLetter::unknown)
  (char) 'k'
  >> static_cast<char>(ErrorCodeLetter::missingSupply)
  (char) 'y'
  >> 
#+END_SRC


 *More Exhaustive Example:*

#+BEGIN_SRC cpp 
  enum class MachineStatus: std::uint32_t {
     running = 0xf5,
     iddle   = 0x2a,
     waiting = 0x35,
     failure = 0x24                                         
  };
#+END_SRC

Example: CERN's root shell. 

#+BEGIN_SRC cpp 
   >> MachineStatus::running
   (MachineStatus) (MachineStatus::running) : (unsigned int) 245
   >> MachineStatus::iddle
   (MachineStatus) (MachineStatus::iddle) : (unsigned int) 42
   >> MachineStatus::waiting
   (MachineStatus) (MachineStatus::waiting) : (unsigned int) 53
   >> MachineStatus::failure
   (MachineStatus) (MachineStatus::failure) : (unsigned int) 36
   >> 

   >> auto status = MachineStatus::running
   (MachineStatus) (MachineStatus::running) : (unsigned int) 245

   >> std::cout << "Machine status = " << std::hex << "0x" << static_cast<std::uint32_t>(status) << std::endl;
   Machine status = 0xf5
   >> 
   >> 

   >> status = MachineStatus::iddle 
   (MachineStatus) (MachineStatus::iddle) : (unsigned int) 42
   >> std::cout << "Machine status = " << std::hex << "0x" << static_cast<std::uint32_t>(status) << std::endl;
   Machine status = 0x2a
   >> 

   >> if(status == MachineStatus::iddle) { std::cout << "Machine is iddle" << std::endl; }
   Machine is iddle
   >> 

   >> status = MachineStatus::running
   (MachineStatus) (MachineStatus::running) : (unsigned int) 245
   >> if(status == MachineStatus::running) { std::cout << "Machine is running" << std::endl; }
   Machine is running
   >> 

   >> static_cast<std::uint32_t>(MachineStatus::running)
   (unsigned int) 245
   >> static_cast<std::uint32_t>(MachineStatus::iddle)
   (unsigned int) 42
   >> static_cast<std::uint32_t>(MachineStatus::iddle) == 0x2a
   (bool) true
   >> 
   >> static_cast<MachineStatus>(0x2a) 
   (MachineStatus) (MachineStatus::iddle) : (unsigned int) 42
   >> 
   >> static_cast<MachineStatus>(0x2a) == MachineStatus::iddle
   (bool) true
   >> 
#+END_SRC
** OOP Simple Class

 - File: [[file:src/cppClasses1.cpp][file:src/cppClasses1.cpp]]

#+BEGIN_SRC cpp :tangle src/cppClasses1.cpp

  #include <iostream>
  using namespace std;

  class Date
  {
  public:
    int year, month, day;

    // ---- Public Class Members ----- //

    void showDate();
    void showDate2();
    int  getYear();
    int  getDay();
    int  getMonth();
  };


  void Date::showDate(){
    cout << "Date = " << this->year << "-" << this->month << "-" << this->day << endl;
  }

  void Date::showDate2(){
    cout << "Date = " << year << "-" << month << "-" << day << endl;
  }

  int Date::getYear(){
    return year;
  }

  int Date::getMonth(){
    return month;
  }

  int Date::getDay(){
    return day;
  }

  Date makeDate (int y, int m, int d){
    Date date;
    date.year  = y ;
    date.month = m ;
    date.day   = d ;
    return date;
  }

  void printDate(Date d){
    cout << "Date is " << d.year << "-" << d.month << "-" << d.day << endl;
  }


  int main(){
    Date d;
    d.day   = 10;
    d.month = 4;
    d.year  = 1998;

    cout << "Date (YMD) is = " << d.year << "-" << d.month << "-" << d.day << endl;
    d.showDate();
    d.showDate2();
    printDate(d);

    cout << "Year of date d is  = " << d.getYear() << endl;
    cout << "Month of date d is = " << d.getMonth() << endl;

    printDate(makeDate(1996, 8, 20));

    return 0;
  }
#+END_SRC

Running:

#+BEGIN_SRC sh
$ g++ cppClasses1.cpp -o cppClasses1.bin&& ./cppClasses1.bin
Date (YMD) is = 1998-4-10
Date = 1998-4-10
Date = 1998-4-10
Date is 1998-4-10
Year of date d is  = 1998
Month of date d is = 4
Date is 1996-8-20
#+END_SRC

** Conversion Constructor X Explicit Constructor - explicit keyword

A converting constructor (aka conversion constructor or implicit
constructor) is any constructor member function callable with a single
argument not annotated with the _explicit_ keyword. A converting
constructor allows implicit initialization by assignment or when
passing a parameter to a function. 

Example: 

#+BEGIN_SRC cpp 
  class TestClass{
  public:
      // Constructor 1: Conversion constructor 
      TestClass(int x)
         : m_x(x)
      {
           std::printf(" [LOG] Intialize m_x = %d\n", x);
      }
      // Constructor 2: Conversion constructor 
      TestClass(char ch)
         : m_ch(ch)
      {
           std::printf(" [LOG] Intialize m_ch = %c\n", ch);
      }
      // Constructor 3: Not conversion constructor / explicit constructor 
      explicit TestClass(const std::string& text)
         : m_text(text)
      {
           std::printf(" [LOG] Initialize m_text = %s\n", text.c_str());
      }
      // Constructor 4: 
      TestClass(int x, char ch)
      {
           std::printf("[LOG] Intialize m_x = %d - m_ch = %c\n", x, ch);
      }
      void show(){
           std::printf("[LOG] TestClass{ m_x = %d ; m_ch = '%c' ; m_text = '%s' }\n"
           ,m_x, m_ch, m_text.c_str());
      }
      // --- Member variables ---- // 
      int        m_x;
      char       m_ch;
      std::string m_text;
  };

#+END_SRC

Example: 

 + The constructors 1 and 2 not annotated with _explicit_ allows
   implicit initialization by assignment. While this behavior can be
   useful, it can lead unintended type conversions. In order to avoid
   the implicit conversion, it is necessary to annotate the member
   function with explicit. After this modification, any attempt to
   implicit conversion will yield a compilation error.

Testing conversion constructors:

#+BEGIN_SRC cpp 

  >> TestClass cls1 = 100;
   [LOG] Intialize m_x = 100
  >> 
  >> TestClass cls2 = 'k';
   [LOG] Intialize m_ch = k

  // Show contents of cls1 and cls2 
  >> cls1.show()
  [LOG] TestClass{ m_x = 100 ; m_ch = '' ; m_text = '' }
  >> 

  >> cls2.show()
  [LOG] TestClass{ m_x = 0 ; m_ch = 'k' ; m_text = '' }

  >> cls1 = 200;
   [LOG] Intialize m_x = 200
  >> cls1 = 400;
   [LOG] Intialize m_x = 400
  >> 
  >> cls1.show()
  [LOG] TestClass{ m_x = 400 ; m_ch = '�' ; m_text = '' }
  >> 

#+END_SRC

Testing explicit constructor (constructor 3 annotated with explicit):

 + It will result in a compiation error. 

#+BEGIN_SRC cpp 
  // Compilation error - because constructor was annotated with explicit.
  >> TestClass cls3 = std::string("binary data");
  ROOT_prompt_5:1:11: error: no viable conversion from 'std::string' (aka 'basic_string<char>') to
        'TestClass'
  TestClass cls3 = std::string("binary data");
            ^      ~~~~~~~~~~~~~~~~~~~~~~~~~~
  input_line_15:1:7: note: candidate constructor (the implicit copy constructor) not viable: no known
        conversion from 'std::string' (aka 'basic_string<char>') to
        'const TestClass &' for 1st argument
#+END_SRC

A constructor annoatated with explicit can only be initialized in the
following ways: 

#+BEGIN_SRC cpp 
  >> TestClass cls3b(std::string("binary data"));
   [LOG] Initialize m_text = binary data

  >> TestClass cls3c("binary data");
   [LOG] Initialize m_text = binary data

  >> auto cls3d = TestClass("binary data");
   [LOG] Initialize m_text = binary data

  >> auto cls3e = TestClass{"binary data"};
   [LOG] Initialize m_text = binary data
  >> 
#+END_SRC

Functions and implicit constructors: 

#+BEGIN_SRC cpp 
  void clientCode(const TestClass& cls){
      std::printf(" ==> TestClass { m_x = %d ; m_ch = %c ; m_text = %s }\n",
      cls.m_x, cls.m_ch, cls.m_text.c_str());
  }

  >> clientCode(10)
   [LOG] Intialize m_x = 10
   ==> TestClass { m_x = 10 ; m_ch = � ; m_text =  }
  >> 

  >> clientCode('x')
   [LOG] Intialize m_ch = x
   ==> TestClass { m_x = 305009792 ; m_ch = x ; m_text =  }
  >> 

  //===========>  Implicit Conversion doesn't happen! ==============//  

  // std::string cannot be implicit converted to TestClass since the 
  // constructor is annoatated with 'explicit'. 
  >> clientCode(std::string("helo world"));
  ROOT_prompt_52:1:1: error: no matching function for call to 'clientCode'
  clientCode(std::string("helo world"));
  ^~~~~~~~~~
  ROOT_prompt_45:1:6: note: candidate function not viable: no known conversion from 'std::string' (aka
        'basic_string<char>') to 'const TestClass' for 1st argument
  void clientCode(const TestClass& cls){

  // In this case, the only way to perform the operation is by calling
  // the constructor explicitly.
  >> clientCode(TestClass("helo world"));
   [LOG] Initialize m_text = helo world
   ==> TestClass{ m_x = 876161456 ; m_ch = '�' ; m_text = 'helo world' }
#+END_SRC

Further reading: 
  + [[http://doc.bccnsoft.com/docs/cppreference2015/en/cpp/language/implicit_cast.html][Implicit conversions - cppreference.com]]
  + [[https://foonathan.net/blog/2017/10/11/explicit-assignment.html][foonathan::blog() - Write explicit constructors - but what about assignment?]]
  + [[https://us7.proxysite.com/process.php?d=c%2B%2FjhdODjkv4sHHC7%2FRQPgWbtJ5O5I9zVZ9Cygk7QLQ6mLoQqx91dNnmQ5YkU1TwSjpU3PhqjvymyZ77PnD0M6esDzpuEm3res5tpzjq2r3VLz2s3shiyUONdvkj&b=1][What is a converting constructor in C++ ? What is it for? - Stack Overflow]]
  + [[https://msdn.microsoft.com/en-us/library/wwywka61.aspx][User-Defined Type Conversions (C++)]]
  + [[https://akrzemi1.wordpress.com/2015/10/22/more-than-you-need/][More than you need | Andrzej's C++ blog]]
  + [[https://softwareengineering.stackexchange.com/questions/190716/is-relying-on-implicit-argument-conversion-considered-dangerous][c++ - Is relying on implicit argument conversion considered dangerous? - Software Engineering Stack Exchange]]
** OOP Value Semantics X Reference Semantics 

 According to the - [[https://isocpp.org/wiki/faq/value-vs-ref-semantics][ISO C++]], value and reference semantics are defined
 as: 

 #+BEGIN_QUOTE
   With reference semantics, assignment is a pointer-copy (i.e., a
   reference). Value (or “copy”) semantics mean assignment copies the
   value, not just the pointer. C++ gives you the choice: use the
   assignment operator to copy the value (copy/value semantics), or use
   a pointer-copy to copy a pointer (reference semantics). C++ allows
   you to override the assignment operator to do anything your heart
   desires, however the default (and most common) choice is to copy the
   value.
 #+END_QUOTE

  *Definitions:*

 _Reference Semantics_: Behavior where composite types are passed by
 reference when assigned; passed as function or method parameters or
 returned from functions. This is the default behavior of most object
 oriented programming languages, except C++.
 
 In Java, C#, Scala, Python and etc. Objects have reference semantics
 by default. This example in Scala programming language shows how
 _reference semantics_ works in most languages.

 #+BEGIN_SRC scala 
   class Foo(name: String){
     private var _name = name
     def setName(name: String) =
       _name = name
     def getName() =
       name
     override def toString() =
       s"Foo { name = $name }"
   }

   scala> var x = 10
   x: Int = 10

   // Primitive types have value semantics: assignment of variables of
   // primitive types, creates a copy, so both variables can be modified
   // without changing each other.
   scala> var y = x
   y: Int = 10

   // By modifying x, the value of y remains the same.
   scala> x = 25
   x: Int = 25

   scala> y
   res5: Int = 10

   scala> 

   //===> Composite and complexity types have reference semantics by default 
   // in languages other than C++.

   scala> val foo = new Foo("bar")
   foo: Foo = Foo { name = bar }

   // Assignment doesn't create a copy like assignment 
   // of primitive type, actually the assignment creates 
   // a reference to the object foo. As result, modifying 
   // one of the objects, modifies the other.
   scala> val bar = foo
   bar: Foo = Foo { name = bar }

   // Modifying bar modifes foo. 
   scala> bar.setName("something")

   scala> bar
   res3: Foo = Foo { name = something }

   scala> foo
   res4: Foo = Foo { name = something }

   // Passing as function parameter doesn't create a copy like in C++, 
   // it passes the object by reference, so if the parameter is modified inside
   // the function, the original object will be modified too. 
    def setFooPrint(param: Foo){
      param.setName("dummy name")
      println(foo)
    }

    scala> setFooPrint(foo)
    Foo { name = dummy name }

    scala> foo
    res8: Foo = Foo { name = dummy name }

    // Returning an object from a function doesn't create a copy as would happen 
    // with primitive types.
    def modifyReturn(param: Foo, newName: String) = {
      param.setName(newName)
      param
    }
    scala> val foob = modifyReturn(foo, "Scala + C++ + JNI == HPC")
    foob: Foo = Foo { name = Scala + C++ + JNI == HPC }

    scala> foo
    res9: Foo = Foo { name = Scala + C++ + JNI == HPC }
 #+END_SRC

 _Value Semantics_: Behavior where composite types such as instances of
 classes are treated as primitive type such as booleans, integers or
 float point numbers. In the value semantics, a copy is created when
 variables are assigned; passed as parameters to functions or methods
 and returned from functions. So modifying one of the variables doesn't
 change the other. 

Unlike other languages, C++ uses value semantics by default, it means
that in operations such as assignment; returning objects from
functions and passing objects as parameters create a full copy of the
object, instead of creating a reference to the object as would happen
in most object oriented programming languages such as Java, C#,
Python, Ruby and etc. C++ also supports reference semantics, however
it is not the default behavior and unlike in the majority of
programming languages, requires explicit annotation to pass objects by
reference or create a reference to the object.

  *Value Semantics in C++*

  Example: demonstration of value semantics in C++ tested in the CERN's
  C++ ROOT REPL:

  - Note: this code can be copied and pasted in the CERN's ROOT REPL.
 
 #+BEGIN_SRC cpp 
   #include <iostream>
   #include <string>

   class Foo{
   private:
     std::string _name;
   public:
     // Constructor 
     Foo(std::string name):_name(name){}
     // Copy constructor
     //--------------------------
     // Note: If it is not defined, the compiler, defines 
     // a default copy constructor. It was created to demonstrate
     // when the copy constructor is invoked.
     Foo(const Foo& rhs){
       _name = rhs._name;    
       std::cout << " [INFO] Copy constructor invoked." << std::endl;    
     }
     // Copy assignment-operator
     //--------------------------
     // Note: It is similar to the copy constructor and
     // default assignment copy-assignment-operator is created
     // by the compiler if the user doesn't define it.
     Foo operator= (const Foo& rhs){    
       std::cout << " [INFO] Copy-assignment operator invoked." << std::endl;
       return Foo(rhs._name);
     }
     void setName(std::string name){
       _name = name;
     }
     std::string getName() const {
       return _name;
     }
     void show(){
       std::cout << "Foo { name = " << _name << " } " << std::endl;
     }
     void show2() const {
       std::cout << "Foo { name = " << _name << " } " << std::endl;
     }
   };

 #+END_SRC

 Assignment creates a copy, unlike in most OOP languages like Java, C#,
 Python and so on. 

 #+BEGIN_SRC cpp 
   >> Foo foo("foo");
   >> foo.show()
   Foo { name = foo } 

   // Assingment creates a copy, unlike in most OO languages
   >> Foo bar = foo; 
    [INFO] Copy constructor invoked.

   // Modifying one of the objects, doens't change the other. 
   >> bar.show()
   Foo { name = foo } 

   >> bar.setName("I am object bar")

   >> bar.show()
   Foo { name = I am object bar } 

   >> foo.show()
   Foo { name = foo } 
   >> 

   // foo and bar objects aren't the same as they have 
   // different memory locations. 
   >> &foo == &bar
   (bool) false
   >>
 #+END_SRC

 Primitive and composite types are passed by value in C++, unlike in
 most OOP languages. So, it means that a copy of the object is created.

 #+BEGIN_SRC cpp
   void setFooPrint(Foo param, std::string name){
     param.setName(name);
     param.show();
     std::cout << " name = " << param.getName() << std::endl;
   }

   // Modifying the function paramenter, doesn't modify the passed object.
   >> setFooPrint(foo, "dummy name")
    [INFO] Copy constructor invoked.
   Foo { name = dummy name } 
    name = dummy name

   >> foo.show()
   Foo { name = foo } 
   >> 
 #+END_SRC

 Returning an object from function, creates a copy of the object
 instead of returning a reference to it like in Java, Scala, Python and
 most languages.

 #+BEGIN_SRC cpp 
   Foo modifyReturn(Foo param, std::string newName) {
     param.setName(newName);
     return param;
   }

   >> auto ret = modifyReturn(foo, "New name")
    [INFO] Copy constructor invoked.
    [INFO] Copy constructor invoked.
   (Foo &) @0x7f54f0288050

   >> &ret == &foo
   (bool) false

   >> ret.show()
   Foo { name = New name } 

   >> foo.show()
   Foo { name = foo } 
   >> 

 #+END_SRC

 Value semantics and STL 

  - Objects can be stored in STL containers by value, reference or by
    pointers. 

 #+BEGIN_SRC cpp 
   #include <deque> // Double ended queue collection 

   >> std::deque<Foo> xs;

   // Temporary objects are created on the stack, 
   // copied to the deque data structure and then 
   // put on the collection. 
   // 
   >> xs.push_back(Foo("hello"));
    [INFO] Copy constructor invoked.
   >> xs.push_back(Foo("world"));
    [INFO] Copy constructor invoked.
   >> xs.push_back(Foo("value"));
    [INFO] Copy constructor invoked.
   >> xs.push_back(Foo("semantics"));
    [INFO] Copy constructor invoked.
   >> 

   >> xs
   (std::deque<Foo> &) { @0x1393820, @0x1393840, @0x1393860, @0x1393880 }
   >> 

   >> xs.size()
   (unsigned long) 4
   >> 

   >> xs.at(0).show()
   Foo { name = hello } 
   >> xs.at(0).show2()
   Foo { name = hello } 
   >> 
   >> xs.at(2).show()
   Foo { name = value } 
   >> 

   // Error: invoke const reference method which is not annotated with 'const'
   >> for(const auto& x: xs) { x.show(); }
   ROOT_prompt_56:1:26: error: member function 'show' not viable: 
   'this' argument has type 'const Foo', but function is not marked const
   for(const auto& x: xs) { x.show(); }

   // Works as show2() is annotated with 'const'
   >> for(const auto& x: xs) { x.show2(); }
   Foo { name = hello } 
   Foo { name = world } 
   Foo { name = value } 
   Foo { name = semantics } 
   >> 

   // Watesful for-loop: performs uncessary copies which could slow down and inccur 
   // on a significant performance overhead in case of a large object.
   >> for(auto x: xs) { x.show(); }
    [INFO] Copy constructor invoked.
   Foo { name = hello } 
    [INFO] Copy constructor invoked.
   Foo { name = world } 
    [INFO] Copy constructor invoked.
   Foo { name = value } 
    [INFO] Copy constructor invoked.
   Foo { name = semantics } 
   >> 

   // By using emplace_back - a copy is not created.
   >> auto xs2 = deque<Foo>()
   (std::deque<Foo, std::allocator<Foo> > &) {}
   >> 
   >> xs2.emplace_back("hello")
   >> xs2.emplace_back("world")
   >> xs2.emplace_back("value")
   >> xs2.emplace_back("semantics")
   >> xs2
   (std::deque<Foo, std::allocator<Foo> > &) { @0x411ff30, @0x411ff50, @0x411ff70, @0x411ff90 }
   >> 

   >> for(const auto& x: xs2) { x.show2(); }
   Foo { name = hello } 
   Foo { name = world } 
   Foo { name = value } 
   Foo { name = semantics } 
   >> 
 #+END_SRC

  *Reference Semantics in C++*

 Unlike in most programming languages where reference semantics for
 complex types such as object is the default behavior, in C++ reference
 semantics requires explicit annotation with reference operator (&) or
 passing objects by pointer. 

 The default behavior of passing by value cause significant memory and
 performance overhead. In order to avoid unnecessary copies, it is
 preferable to pass objects by reference with operator (&) or by const
 reference when the object is not supposed to be modified by the
 function the objects are passed to.

  - Create a reference in assignment operation instead of a copy.

 #+BEGIN_SRC cpp 
   >> foo.show()
   Foo { name = foo } 

   >> Foo& ref1 = foo;

   >> ref1.setName("I am foo reference")
   >> foo.show()
   Foo { name = I am foo reference } 
   >> 

   // The reference has the same memory location of foo.
   >> &foo == &ref1
   (bool) true
   >> 
 #+END_SRC

  - Passing a parameter by reference instead of passing it by
    value. Note: that the copy constructor is not invoked when passing
    by reference.

 #+BEGIN_SRC cpp 
   void setFooPrintRef(Foo& param, const std::string& name){
     param.setName(name);
     param.show();
     std::cout << " name = " << param.getName() << std::endl;
   }

   >> setFooPrintRef(foo, "dummy name")
   Foo { name = dummy name } 
    name = dummy name

   >> foo.show()
   Foo { name = dummy name } 
   >> 
 #+END_SRC

  - Returning objects from functions as references. 

 #+BEGIN_SRC cpp 
   Foo& modifyReturnRef(Foo& param, std::string newName) {
     param.setName(newName);
     return param;
   }

   >> foo.setName("unnamed")

   >> fooRefx.setName("I am foo reference")
   >> foo.show()
   Foo { name = I am foo reference } 

   >> &foo == &fooRefx
   (bool) true
   >> 

   >> auto& fooRefAuto = modifyReturnRef(foo, "C++ type inference auto!")
   (Foo &) @0x7f54f0288010

   >> foo.show()
   Foo { name = C++ type inference auto! } 

   >> fooRefAuto.show()
   Foo { name = C++ type inference auto! } 

   >> fooRefAuto.setName("C++17")

   >> foo.show()
   Foo { name = C++17 } 
   >> 

   >> &foo == &fooRefAuto
   (bool) true
   >> 
 #+END_SRC

  - Const references cannot be modified as any attempt to change it
    will result in a compile-time error. 

 #+BEGIN_SRC cpp 
   >> Foo foo("foo");

   >> foo.show()
   Foo { name = foo } 

   >> foo.getName()
   (std::string) "foo"

   >> const Foo& fooRefConst = modifyReturnRef(foo, "C++ constant ref.")
   (const Foo &) @0x7fbf2003c010

   >> foo.show()
   Foo { name = C++ constant ref. } 

   >> foo.getName()
   (std::string) "C++ constant ref."
   >> 

   >> fooRefConst.show2()
   Foo { name = C++ constant ref. } 
   >> 

   // Any attempt to call a method not annotated with const will result 
   // in a compile-time error. 
   >> fooRefConst.show()
   ROOT_prompt_52:1:1: error: member function 'show' not viable: 'this' 
   argument has type 'const Foo', but function is not marked const
   fooRefConst.show()
   ^~~~~~~~~~~
   ROOT_prompt_30:1:6: note: 'show' declared here
   void show(){ 
 #+END_SRC

  *Summary* 

  + Value Semantics X Reference Semantics
    + _Value Semantics_ -> Objects are assigned, passed to functions and
      return from functions as primitive types without being modified
      as what is modified is a copy of the object. This is default
      behavior of C++.

      + Object A = B; => (C++ Only) Creates object A as a copy of the object B.

      + Object A = B.copy() (C#, Java, Python ...) Creates object A as
        copy of object B. As value-semantics is not the default
        behavior in thoses languages, it is necessary to invoke some
        deep copy method explicity.

    + _Reference Semantics_ -> Objects are passed by reference or
      pointer; assigned by pointer and so on. Objects passed to
      functions using reference semantics can modified. This is the
      default behavior of Java, Python, C# and other programming
      languages.

      + Object A = B; (C#, Java, Python ...) => The object A is
        reference to object B. Any modification to A or B will modify
        both as the refer to the same memory location.

      + Object& A = B; (C++ only) => Creating a reference in C++
        requires an explicit annotation with operator (&) as it is
        non-default behavior.

  + Most programming languages, except C++, use value-semantics for
    primitive types and reference semantics for complex or composite
    types such as classes due to performance reasons and avoid
    uncessary copies.

  + C++ uses _values-semantics_ by default for all types, unlike most
    programming languages, when any primitive type or composite type such
    as class when assigned, passed to functions or returned from 
    functions, a copy is created and the original object is not
    changed.

  + _C++ supports both value and reference semantics_ which is not
    default for objects linke in Java, Python and other languages. The
    reference semantics requires explicit annotation.

  + In order to avoid unncessary copies that can lead memory or
    peformance overhead, it is preferable to use reference semantics.
    In other words, large objects should be passed by reference, const
    reference or pointer to functions or methods. 

  + Move semantics optimizes return-by value avoiding unnecessary
    copies. The copy overhead that happens when returning an object
    from a function can be avoided by defining a move constructor (see
    C++11's move semantics) which transfer resource ownership from the
    object defined locally within the function body to the returned
    object.

  *Further Reading:*

  + ISO C++ - Reference and Value Semantics -
    <https://isocpp.org/wiki/faq/value-vs-ref-semantics>
    + Note: Provides a good and clear definition about what really is
      value and reference semantics.

  + Taligent Inc. 1995 - Reference and value semantics: C++ versus everything else
    + <https://root.cern.ch/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_85.html>

  + Andrezj's C++ blog - Value Semantics -
    <https://akrzemi1.wordpress.com/2012/02/03/value-semantics/> 

  + Value Semantics - Code of the danmed
    + <http://codeofthedamned.com/index.php/value-semantics>

  + What do ‘value semantics’ and ‘pointer semantics’ mean?
    + <https://stackoverflow.com/questions/166033/what-do-value-semantics-and-pointer-semantics-mean>

  + MSDN - Value Types (Modern C++) -
    <https://msdn.microsoft.com/en-us/library/hh438479.aspx>

  + My Precious Compile Time Bool (long introduction to Move
    Semantics)
    + <https://medium.com/@gaussnoise/my-precious-compile-time-bool-long-introduction-to-move-semantics-c9ee73c370c7>

** TODO Memory Allocation - Stack X Heap 
*** Program/Process memory 

The memory of a process or running program (compile object-code) can
be divided into the _segments_:

 + *Code* (text segment):
   + Contains the program compiled as object-code. Generally, this
     segment is read-only.

 + *Bss*:
   + Contains non-initialized global variables. 

 + *Data*:
   + Contains intialized global variables.

 + *Stack* (aka Call-stack) or stack memory 
   + Contains function arguments and current function's _local variables_.
   + In C++, variables, objects and arrays are allocated on the stack
     by default.
   + Variables: allocated at compile-time.
   + Stack-allocated variables are also called automatic variables.     
   + Limit: Stack is limited, on Linux Kernel 8 kb (kbytes). Large
     objects should not be allocated on the stack.
   + Memory management: Variables are automatically deleted when out
     of scope.

 + *Heap* (dynamic memory or free-store)
   + Dynamically allocated variables or objects (variables allocated
     with C++ new operator or C-malloc) are instatiated on the heap.
   + Example - heap-allocated array: _int* ptr = new int [10]_;
   + Variables: allocated at runtime.
   + Limit: The limit is the RAM memory or the virtual memory. 
   + Memory management: Manual (C++ is not garbage collected), for
     every statement with _new_ operator, there must be a matching
     delete operator releasing the allocated memory in order to avoid
     memory leak.
   + Only accessible through pointers.

Further reading: 
 + [[https://en.wikipedia.org/wiki/Data_segment][Data segment - Wikipedia]]
 + [[https://en.wikipedia.org/wiki/Memory_segmentation][Memory segmentation - Wikipedia]]
 + [[https://en.wikipedia.org/wiki/Virtual_memory][Virtual memory - Wikipedia]]
 + [[https://en.wikipedia.org/wiki/.bss][.bss - Wikipedia]]
 + [[https://en.wikipedia.org/wiki/Page_table][Page table - Wikipedia]]
 + [[https://wiki.osdev.org/ELF][ELF - OSDev Wiki]] 

*** stack Allocation - Automatic Variables 
**** Overview 

In C++, variables, objects or arrays defined inside functions are
allocated on the stack by default. The memory allocated is
automatically released when they go out scope, thus there is no need
to worry about allocation in this case. 

Stack allocation features: 

 + Variables allocated on the stack are also called _automatic variables_.

 + The array size cannot be changed at runtime and it cannot grow or
   shrink. Therefore, it is not possible to allocate an array in this way:
   + _int n = 10; double array[n]_; 

 + _The stack has limited size_, the Linux Kernel has an 8 Mbs stack,
   as a result, large objects cannot be allocated in the stack. So, if
   one tries to allocate an array: _int array[1000000000]_, it will cause
   segmentation fault.

   + TL;DR: Large objects should be allocated on the heap or dynamic
     memory.

 + Primitive type variable, objects and arrays are automatically
   released (aka deleted) when they go out of scope. In the case of
   objects, their dectructors methods or member functions are always
   called.
**** Example: Stack-allocated arrays

Try to define/allocate a variable-size array. 

#+BEGIN_SRC cpp
  >> int k = 4;

  // Error: It is impossible to allocate variable-size array on stack or
  // static memory (as global variable).
  >> double arr_flt[k];
  ROOT_prompt_38:1:8: error: variable length array 
  declaration not allowed at file scope

#+END_SRC

Defining an stack-allocated array with size set by const variable. In
C++, it is preferable to use const variable instead of preprocessor
macros for defining consts.

#+BEGIN_SRC cpp 
  // DO NOT: #define arra_size 3 
  >> const size_t arr_size = 3;
  >> double arr_flt[arr_size]
  (double [3]) { 0.0000000, 0.0000000, 0.0000000 }
  >> 
#+END_SRC


Defining an stack-allocated array, assuming that all statements are
executed inside a function.

#+BEGIN_SRC cpp 
  // Define array 
  >> int arr1[5];

  >> arr1
  (int [5]) { 0, 0, 0, 0, 0 }
  >> 

  // Set elements 
  >> arr1[0] = 10, arr1[1] = 5; arr1[2] = 6, arr1[3] = 9, arr1[4] = 15;
  >> 

  >> arr1
  (int [5]) { 10, 5, 6, 9, 15 }
  >> 

  // Query elements 
  >> arr1[0]
  (int) 10
  >> arr1[2]
  (int) 6
  >> arr1[3]
  (int) 9
  >> 
#+END_SRC

Loop over array: 

#+BEGIN_SRC cpp 
  >> for(int i = 0; i < 5; i++){ std::cout << " " << arr1[i] << "\n"; }
   10
   5
   6
   9
   15
  >> 
#+END_SRC

Array as a pointer: 

 - The array _arr1_ is actually a pointer to its first element. This
   array is a memory block of five consecutive allocated integers with
   the same size. 

#+BEGIN_SRC cpp 
  // The array is actually a pointer to array[0] or the 0-th 
  // first element of memory block.
  //-------------------------------------------------
  >> *arr1
  (int) 10
  // Second memory block 
  >> *(arr1 + 1)
  (int) 5
  // Third memory block 
  >> *(arr1 + 2)
  (int) 6
  >> *(arr1 + 3)
  (int) 9
  >> *(arr1 + 4)
  (int) 15
  >>

  >> *(&arr1[0] + 0)
  (int) 10
  >> *(&arr1[0] + 1)
  (int) 5
  >> *(&arr1[0] + 2)
  (int) 6
  >> *(&arr1[0] + 3)
  (int) 9
  >> *(&arr1[0] + 4)
  (int) 15
  >> 
#+END_SRC

Many ways to manipulate the third element (index 2):

#+BEGIN_SRC cpp 
  >> *(&arr1[0] + 2)
  (int) 6
  >> *(&arr1[0] + 2) = 25
  (int) 25
  >> *(&arr1[0] + 2)
  (int) 25
  >> arr1[2]
  (int) 25
  >> 
#+END_SRC

Passing arrays to functions: 

 + An array (C-arrays) is not aware of its size, thus this parameter
   must be passed to functions alongside the array or pointer to
   first element.

#+BEGIN_SRC cpp 
  void printArray(size_t size, int xs []){
    for(size_t i = 0; i < size; i++)
      std::cout << " => xs[" << i << "] = " << xs[i] << "\n";
  }

  void printArray2(size_t size, int* xs){
    for(size_t i = 0; i < size; i++)
      std::cout << " => xs[" << i << "] = " << xs[i] << "\n";
  }

  void printArray3(size_t size, int* xs){
    for(size_t i = 0; i < size; i++)
      std::cout << " => xs[" << i << "] = " << *(xs + i) << "\n";
  }

  >> printArray(5, arr1)
   => xs[0] = 10
   => xs[1] = 5
   => xs[2] = 25
   => xs[3] = 9
   => xs[4] = 15
  >> 

  >> printArray2(5, arr1)
   => xs[0] = 10
   => xs[1] = 5
   => xs[2] = 25
   => xs[3] = 9
   => xs[4] = 15

  >> printArray2(3, arr1)
   => xs[0] = 10
   => xs[1] = 5
   => xs[2] = 25
  >> 

#+END_SRC
**** Example: Stack-allocated objects
     
 Example: *Stack-allocated object.*

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

  class SomeClass{
     // Internal state 
     std::string _id; 
  public:
     // Default constructor is created by the compiler
     // if not defined. 
     SomeClass()
       : _id("unnamed") {}

     SomeClass(const std::string& id)
        : _id(id) 
     {
        std::cout << "[LOG] Object created = <" << _id << "> \n"; 
     }
     std::string getID(){ 
        return _id;  
     }
     void setID(const std::string& id){ 
        _id = id;  
     }
     // Copy-constructor is created by default by the compiler,
     SomeClass(const SomeClass& rhs){
       std::cout << "[LOG] Copy-constructo Object copyed = <" << rhs._id << ">\n";
       this->_id = rhs._id;
     }
     // Copy-assignment operator -
     SomeClass& operator=(const SomeClass& rhs){
       std::cout << "[LOG] Copy-assign operator Object copyed = <" << rhs._id << ">\n";
       this->_id = rhs._id;
       return *this;
     }
 
     // Destructor - is always generated by compiler
     // if not specified. 
     ~SomeClass()
     {
        std::cout << "[LOG] I was deleted <" << _id << "> " << "\n";
     }
  };
#+END_SRC
 
 *Object - Allocated on stack or static memory*

Any object allocated on the stack (locally on the function) such as
the variable cls is automatically deleted when it goes out of scope. 

#+BEGIN_SRC cpp
  // Return reference.
  SomeClass& Function(){  
     SomeClass cls("object-1");
     std::cout << "Object id = " << cls.getID() << "\n";
     return cls;
  }
#+END_SRC

Testing: 

#+BEGIN_SRC cpp
  >> SomeClass& clsref = Function()

  [LOG] Object created = <object-1> 
  Object id = object-1
  [LOG] I was deleted <object-1> 
  (SomeClass &) @0x7ffcbbe2eed0

  // DO NOT DO IT! Reference to deleted object
  >> clsref.getID()

   *** Break *** segmentation violation
#+END_SRC

 *Stack-allocated array of objects*

 + An array of objects is always intialized with default-constructor
 
#+BEGIN_SRC cpp 
  >> SomeClass arr1[3];
  [LOG] Copy-constructo Object copyed = <unnamed>
  [LOG] Copy-constructo Object copyed = <unnamed>
  [LOG] Copy-constructo Object copyed = <unnamed>
  >> 

>> arr[0].getID()
(std::string) "unnamed"
>> arr[1].getID()
(std::string) "unnamed"
>> arr[2].getID()
(std::string) "unnamed"
>> 
>> 

#+END_SRC

 + Intialized array 

#+BEGIN_SRC cpp 
  // Intialized array 
  >> SomeClass arr2[3] = { SomeClass("obj1"), SomeClass("obj2"), SomeClass("obj3")};
  [LOG] Object created = <obj1> 
  [LOG] Object created = <obj2> 
  [LOG] Object created = <obj3> 
  [LOG] Copy-constructo Object copyed = <obj1>
  [LOG] Copy-constructo Object copyed = <obj2>
  [LOG] Copy-constructo Object copyed = <obj3>

  >> arr2[0].getID()
  (std::string) "obj1"
  >> arr2[1].getID()
  (std::string) "obj2"
  >> arr2[2].getID()
  (std::string) "obj3"
  >> 

  // Uniform initialization 
  >> SomeClass arr3[3] = { {"objA"}, {"objB"}, {"objC"}};
  >> SomeClass arr3[3] = { {"objA"}, {"objB"}, {"objC"}};
  [LOG] Object created = <objA> 
  [LOG] Object created = <objB> 
  [LOG] Object created = <objC> 
  [LOG] Copy-constructo Object copyed = <objA>
  [LOG] Copy-constructo Object copyed = <objB>
  [LOG] Copy-constructo Object copyed = <objC>
  >> 
#+END_SRC

 + Manipulating objects in array:

#+BEGIN_SRC cpp 
  >> arr1[0].setID("O1"), arr1[1].setID("O2"), arr1[2].setID("O3");
  >> arr1[0].getID()
  (std::string) "O1"
  >> arr1[1].getID()
  (std::string) "O2"
  >> arr1[2].getID()
  (std::string) "O3"
  >>
#+END_SRC

 + Loop over array elements:

#+BEGIN_SRC cpp 
  void showArray(size_t n, SomeClass xs []){
    for(int i = 0; i < n; i++)
      std::cout << "obj[" << i << "] = " << xs[i].getID() << ", ";
    std::cout << "\n";
    std::cout.flush();
  }

  >> showArray(3, arr1)
  obj[0] = O1, obj[1] = O2, obj[2] = O3, 

  >> showArray(3, arr2)
  obj[0] = obj1, obj[1] = obj2, obj[2] = obj3, 

  >> showArray(3, arr3)
  obj[0] = objA, obj[1] = objB, obj[2] = objC, 
  >> 
#+END_SRC

 + Assign array elements:

#+BEGIN_SRC cpp 
  >> showArray(3, arr2)
  obj[0] = obj1, obj[1] = obj2, obj[2] = obj3, 
  >> 

  >> arr2[0] = SomeClass("1st-object");
  [LOG] Object created = <1st-object> 
  [LOG] Copy-assign operator Object copyed = <1st-object>
  [LOG] I was deleted <1st-object> 

  >> arr2[0].getID()
  (std::string) "1st-object"

  >> arr2[1] =  {"2nd-element"}; // Uniform initialization
  [LOG] Object created = <2nd-element> 
  [LOG] Copy-assign operator Object copyed = <2nd-element>
  [LOG] I was deleted <2nd-element> 

  >> arr2[1].getID()
  (std::string) "2nd-element"
  >> 

  >> showArray(3, arr2)
  obj[0] = 1st-object, obj[1] = 2nd-element, obj[2] = obj3, 
#+END_SRC

 + Defining an array inside a function: 

#+BEGIN_SRC cpp 
  void exampleFunction(){
    const size_t n = 4;
    // Deleted when out of scope.
    SomeClass xss [n] = {{"C++98"}, {"C++11"}, {"C++17"}, {"C++20"}} ;
    showArray(n, xss);
  }

  >> exampleFunction()
  [LOG] Object created = <C++98> 
  [LOG] Object created = <C++11> 
  [LOG] Object created = <C++17> 
  [LOG] Object created = <C++20> 
  obj[0] = C++98, obj[1] = C++11, obj[2] = C++17, obj[3] = C++20, 
  [LOG] I was deleted <C++20> 
  [LOG] I was deleted <C++17> 
  [LOG] I was deleted <C++11> 
  [LOG] I was deleted <C++98> 
#+END_SRC

*** Dynamic/Heap Allocation 
**** Overview 

 *When dynamic allocation is needed*

Situation where dynamic allocation is needed: 

 + The number of elements to be allocated is not known in advance.
 + The array or data structure needs to allocate more memory on
   demand. 
 + Return an instance of a polymorphic class from a function. (Factory
   function.)
 + Type erasure: any object allocated on the heap can have its pointer
   casted to void* and then casted back to the object type. 

Note: 

 + Using new and delete with raw pointers is error prone and not
   safe. In C++ >= C++11, it is safer and better to use RAII technique
   through the usage of smart pointers.
   + SUMMARY: Use std::unique_ptr or std::shared_ptr instead of new
     and delete.

 + Dynamic allocation of arrays is often not needed as STL containers
   already encapsulates the heap allocation and automatically
   allocate new memory when a new element is added.
   + SUMMARY: Use std::vector, std::array, std::deque instead of
     dynamically allocated arrays. 

Potential pitfalls: 

 + Dangling pointer
 + Null-pointer access
 + Wild pointers
 + Heap corruption
 + Ownership Semantics 
 + Non deterministic allocation on embedded systems or real time
   systems. 

 *Operators new and delete for a single element*

The following code shows the general usage of the operator new.

Allocation with exception: 

 + Note: The operator _new_ always throws an exception bad_alloc if the
   allocation fails. 

#+BEGIN_SRC cpp 
 try{
  Type* object_pointer1 = new Type;
  //  Intialized with constructor arguments
  Type* object_pointer2 = new Type(arg0, arg1, arg2 ...);
  } catch(const std::bad_alloc& ex){
     std::cerr << "Error: failed to allocate memory." << "\n";
     std::cerr << "Error = " << ex.what() << "\n";
     exit(1);
  }
#+END_SRC

Allocation without exception:

 + When the allocation fails, the operator returns a null pointer. 

#+BEGIN_SRC cpp 
  Type* object_pointer1 = new (nothrow) Type;
  //  Intialized with constructor arguments
  Type* object_pointer2 = new (nothrow) Type(arg0, arg1, arg2 ...);
  if(!object_pointer1){
     std::cerr << "Error: failed to allocate memory for obj1." << "\n";
     exit(1);
  }
  if(object_pointer1 == nullptr){
     std::cerr << "Error: failed to allocate memory for obj1." << "\n";
     exit(1);
  }
#+END_SRC

Deallocation: 

 - After the heap-allocated object is no longer needed, it is
   necessary to release the allocated memory by using the delete
   operator.

#+BEGIN_SRC cpp
  delete object_pointer1;
  // A good practice is to set the pointer to null
  // after the object is released.
  object_pointer1 = nullptr;

  // Deleting a null pointer is always safe and does nothing.  
  delete object_pointer1;
#+END_SRC


 *Operators new and delete for array allocation*

An array of elements of type Type can be allocated on the heap with:

Allocation with exception: 

#+BEGIN_SRC cpp 
  const size_t SIZE = 10;
  try {
     Type* array_pointer = new Type [SIZE];
  } catch(const std::bad_alloc& ex) {
     std::cerr << "Error: failed to allocate memory." << "\n";
     std::cerr << "Error = " << ex.what() << "\n";
  }
#+END_SRC

Allocation without exception: 

#+BEGIN_SRC cpp 
  const size_t SIZE = 10;
  Type* array_pointer = new (nothrow) Type [SIZE];
  if(!array_pointer){
    std::cerr << "Error: failed to allocate memory." << "\n";
    exit(1);
  }
  // Or more explicitly
  if(array_pointer == nullptr){
    std::cerr << "Error: failed to allocate memory." << "\n";
    exit(1);
  }
#+END_SRC

Deallocation: 

#+BEGIN_SRC cpp 
  delete [] array_pointer;
#+END_SRC

**** Heap allocation for primitive types

Allocation of single value on the heap: 

#+BEGIN_SRC cpp 
  >> double* ptr = new (nothrow) double;

  >> if(ptr != nullptr) std::cout << "OK, proceed" << "\n";
  OK, proceed
  >> 

  >> *ptr = 100.0;

  >> *ptr
  (double) 100.00000
  >> 3.0 * *ptr
  (double) 300.00000
  >> 

  // Always delete the pointer when the 
  // allocated object is no longer needed.
  >> delete ptr;

  // Always set the pointer to null 
  >> ptr = nullptr;

  // Deleting a null pointer is safe and does nothing.
  >> delete ptr;
#+END_SRC

Array allocation on the heap: 

 + Allocate array. 

#+BEGIN_SRC cpp 
size_t n = 6;

// Array of size 6
int* arr = new (nothrow) int [n];

>> arr
(int *) 0x216cbf0

// Not initialized, can have any value. 
>> arr[0]
(int) 36003472
>> arr[1]
(int) 0
>> arr[2]
(int) 1864399218
>> 
#+END_SRC

 + Set array elements: 

#+BEGIN_SRC cpp 
>> arr[0] = 10;
>> arr[0] = 0, arr[1] = 15, arr[2] = 20, arr[3] = 90;
>> arr[4] = 4, arr[5] = 3;

>> arr[0]
(int) 0
>> arr[3]
(int) 90
>> arr[5]
(int) 3
>> 

#+END_SRC

 + Access array elements with pointer offset.

#+BEGIN_SRC cpp 
  // Access with pointer + offset 
  >> *(arr + 0)
  (int) 0
  >> *(arr + 1)
  (int) 15
  >> *(arr + 2)
  (int) 20
  >> *(arr + 3)
  (int) 90
  >> *(arr + 4)
  (int) 4
  >> *(arr + 5)
  (int) 3
  >> 

  >> *(arr + 3) = 100;
  >> arr[3]
  (int) 100
  >> 
#+END_SRC

 + Delete heap-allocated array.

#+BEGIN_SRC cpp 
  >> delete [] arr;

  // Avoid dangling pointer
  >> arr = nullptr;
#+END_SRC

**** Heap allocation for objects

Consider the following testing class: 

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

  class SomeClass{
     // Internal state 
     std::string _id; 
  public:
     // Default constructor is created by the compiler
     // if not defined. 
     SomeClass()
       : _id("unnamed") {
        std::cout << "[LOG] CTOR0 - Object created = <" << _id << "> \n"; 
     }
     SomeClass(const std::string& id)
        : _id(id) 
     {
        std::cout << "[LOG] Object created = <" << _id << "> \n"; 
     }
     std::string getID(){ 
        return _id;  
     }
     void setID(const std::string& id){ 
        _id = id;  
     }
     // Copy-constructor is created by default by the compiler,
     SomeClass(const SomeClass& rhs){
       std::cout << "[LOG] Copy-constructo Object copyed = <" << rhs._id << ">\n";
       this->_id = rhs._id;
     }
     // Copy-assignment operator -
     SomeClass& operator=(const SomeClass& rhs){
       std::cout << "[LOG] Copy-assign operator Object copyed = <" << rhs._id << ">\n";
       this->_id = rhs._id;
       return *this;
     }
 
     // Destructor - is always generated by compiler
     // if not specified. 
     ~SomeClass()
     {
        std::cout << "[LOG] I was deleted <" << _id << "> " << "\n";
     }
  };
#+END_SRC

 *Creating a single object on the heap:*

Create object:

#+BEGIN_SRC cpp 
   // SomeClass* heapPtr = new (nothrow) SomeClass
  >> SomeClass* heapPtr = new (nothrow) SomeClass("heap-obj1")
  [LOG] Object created = <heap-obj1> 
  (SomeClass *) 0x2c10fe0
  >> 

  >> if(heapPtr != nullptr) std::cout << " [LOG] Everything OK." << "\n";
   [LOG] Everything OK.
  >> 

  >> heapPtr->getID()
  (std::string) "heap-obj1"
  >> 
  >> heapPtr->setID("Object100")
  >> heapPtr->getID()
  (std::string) "Object100"
  >> 
  >> (*heapPtr).getID()
  (std::string) "Object100"
  >> 
#+END_SRC

Delete object:

 + The delete operator always invokes destructor.

#+BEGIN_SRC cpp 
  >> delete heapPtr;
  [LOG] I was deleted <Object100> 

  >> heapPtr = nullptr;
#+END_SRC

 *Creating an array of objects on the heap* 

 + Create array: 

#+BEGIN_SRC cpp 
  >> SomeClass* p = new (nothrow) SomeClass[3];
  [LOG] CTOR0 - Object created = <unnamed> 
  [LOG] CTOR0 - Object created = <unnamed> 
  [LOG] CTOR0 - Object created = <unnamed> 
  >> 

  >> p[0].getID()
  (std::string) "unnamed"
  >> p[1].getID()
  (std::string) "unnamed"
  >> p[2].getID()
  (std::string) "unnamed"
  >> 
#+END_SRC

 + Access elements 

#+BEGIN_SRC cpp 

  // Comman operator.
  >> p[0].setID("obj0"), p[1].setID("obj1"), p[2].setID("obj2");

  >> p[0].getID()
  (std::string) "obj0"

  >> p[1].getID()
  (std::string) "obj1"

  >> p[2].getID()
  (std::string) "obj2"
  >>

#+END_SRC

 + Access elements by pointer offset
   + Note: It is possible because the array is a pointer to the first
     allocated element. Thus, an array is not aware of its size that
     must be remembered and passed as function argument alongside the
     array. 

#+BEGIN_SRC cpp 
  // Get ID of first element 
  >> (p + 0)->getID()
  (std::string) "obj0"
  >> 
  >> p->getID()
  (std::string) "obj0"

  >> (p + 1)->getID()
  (std::string) "obj1"

  >> (p + 2)->getID()
  (std::string) "obj2"

  >> (p + 0)->setID("elem-zero");
  >> (p + 1)->setID("elem-one");
  >> (p + 2)->setID("elem-two");

  >> (p + 0)->getID()
  (std::string) "elem-zero"
  >> (p + 1)->getID()
  (std::string) "elem-one"
  >> (p + 2)->getID()
  (std::string) "elem-two"
#+END_SRC

 + Array assignment 

#+BEGIN_SRC cpp 
  >> p[0] = SomeClass("objA");
  [LOG] Object created = <objA> 
  [LOG] Copy-assign operator Object copyed = <objA>
  [LOG] I was deleted <objA> 

  >> p[0].getID()
  (std::string) "objA"
  >> 

  >> p[1] = {"ObjB"}; // Uniform initialization
  [LOG] Object created = <ObjB> 
  [LOG] Copy-assign operator Object copyed = <ObjB>
  [LOG] I was deleted <ObjB> 
  >> 

  >> p[1].getID()
  (std::string) "ObjB"
  >> 

#+END_SRC

 + Pass array to function: 

#+BEGIN_SRC cpp 
  void showArray(size_t n, SomeClass xs []){
    for(int i = 0; i < n; i++)
      std::cout << "obj[" << i << "] = " << xs[i].getID() << ", ";
    std::cout << "\n";
    std::cout.flush();
  }

  >> showArray(3, p)
  obj[0] = objA, obj[1] = ObjB, obj[2] = elem-two, 
  >> 
#+END_SRC

 + Release memory by deleting the heap-allocated array.

#+BEGIN_SRC cpp 
  >> delete [] p;
  [LOG] I was deleted <elem-two> 
  [LOG] I was deleted <ObjB> 
  [LOG] I was deleted <objA> 

  >> p = nullptr;
  >> 
#+END_SRC

*** Limits of stack and heap allocation 

This small program aims to test the limits of stack and heap
allocation by allowing the user to set the size of a float point array
and whether its allocation will happen on stack or heap using
pre-processor directives. 

File: [[file:src/stack-allocation-test.cpp][file:src/stack-allocation-test.cpp]]

#+BEGIN_SRC cpp
  // File:   stack-allocation-test 
  // Brief:  Test limits of stack or heap allocation. 
  // Author: Caio Rodrigues
  //------------------------------------------------------
  #include <iostream>
  #include <string> 

  #ifndef ARRAY_SIZE
     #define ARRAY_SIZE 8000
  #endif 

  int main(){
      size_t sizeKB = static_cast<size_t>(ARRAY_SIZE) * sizeof(double) / 1024;
      std::cout << " [LOG] Number of elements = " << ARRAY_SIZE << "\n";
      std::cout << " [LOG] Array size in Kbytes = " << sizeKB << "\n";
      #if !defined HEAP || HEAP == 0
         // ===> Stack allocation 
         std::cout << " [LOG] Stack allocation." << "\n";
         double array [ARRAY_SIZE];
      #else
         // ===> Heap allocation 
         std::cout << " [LOG] Heap (dynamic memory) allocation." << "\n";
         // Note: It throws std::bad_alloc exception. 
         double* array = new double [ARRAY_SIZE];	  	  
         delete [] array;
      #endif
         std::cout << " [LOG] Program ended gracefully OK." << "\n";
      return 0;
  }
#+END_SRC

 *Testing stack-allocation limit:*

 + Note: Tested on Linux-64 bits - Kernel 4.16.3

 + Result: Core dump due to stack overflow happens when the array size is
   10,000,000, 10 million doubles or 7812 kb (kbytes) or 7.6 Mb
   (Megabytes). This behavior depends on the operating system and
   may be not be the same on other operating systems or new Linux's
   kernel versions.

#+BEGIN_SRC sh 
  $ clang++ stack-allocation-test.cpp -o out.bin -DHEAP=false -DARRAY_SIZE=100 && ./out.bin
   [LOG] Number of elements = 100
   [LOG] Array size in Kbytes = 0
   [LOG] Stack allocation.
   [LOG] Program ended gracefully OK.

  $ clang++ stack-allocation-test.cpp -o out.bin -DHEAP=false -DARRAY_SIZE=1000000 && ./out.bin
   [LOG] Number of elements = 1000000
   [LOG] Array size in Kbytes = 7812
   [LOG] Stack allocation.
   [LOG] Program ended gracefully OK.

  $ clang++ stack-allocation-test.cpp -o out.bin -DHEAP=false -DARRAY_SIZE=10000000 && ./out.bin
  Segmentation fault (core dumped)

  $ ./out.bin
  Segmentation fault (core dumped)
#+END_SRC

 *Testing heap (dynamic memory) allocation limit:*

 + Note: Tested on Linux-64 bits - Kernel 4.16.3

 + Result: bad_alloc exception happens when the array size is 10
   billions or 78125000 kb (= 76293 Mb or 74 GB. The limit of the heap
   allocation is the size of the virtual memory or RAM memory.  

#+BEGIN_SRC sh 
  # 10 millions
  $ clang++ stack-allocation-test.cpp -o out.bin -DHEAP=true -DARRAY_SIZE=10000000 && ./out.bin
   [LOG] Number of elements = 10000000
   [LOG] Array size in Kbytes = 78125
   [LOG] Heap (dynamic memory) allocation.
   [LOG] Program ended gracefully OK.

  # 100 millions 
  $ clang++ stack-allocation-test.cpp -o out.bin -DHEAP=true -DARRAY_SIZE=100000000 && ./out.bin
   [LOG] Number of elements = 100000000
   [LOG] Array size in Kbytes = 781250
   [LOG] Heap (dynamic memory) allocation.
   [LOG] Program ended gracefully OK.

  # 10 billions
  $ clang++ stack-allocation-test.cpp -o out.bin -DHEAP=true -DARRAY_SIZE=10000000000 && ./out.bin
   [LOG] Number of elements = 10000000000
   [LOG] Array size in Kbytes = 78125000
   [LOG] Heap (dynamic memory) allocation.
  terminate called after throwing an instance of 'std::bad_alloc'
    what():  std::bad_alloc
  Aborted (core dumped)
#+END_SRC
*** New and delete overloading functions 
**** Overloadings for new and delete operators  

 *Global new and delete operators free functions* 

  + size_t => Size of object being allocated in bytes. This parameter
    is implicitly passed by the compiler. 

  + Returns => A void* pointer to the beginning of the allocated
    memory block.

  + Note: The operator 'new' allocates objects in the heap memory
    segment.

 *Overloading for _new_ operator*

  + Operator new for single object (throws std::bad_alloc on failure)

  + For all overloadings se:
    + https://en.cppreference.com/w/cpp/memory/new/operator_new

#+BEGIN_SRC cpp 
   // Signature 
   void* operator new (std::size_t size);

   // Example: allocate single object
   //--------------------------------------------------//
   BaseClass* ptr = nullptr;
   try {
       ptr = new DerivedClassA(param0, param1, param2, ...);
       ptr->CallVirtualMethod1(); 
       delete ptr;    // Always delete when the object is no longer needed 
       ptr = nullptr; // Always set to nullptr 
   catch(std::bad_alloc const& ex) {
       printf(" [INFO] Allocation failed.")
   }
#+END_SRC

  + Operator new for single object, without exception
    + => Returns null pointer nullptr on failure. The second parameter
      is type tag, used only for making the type signature different.

#+BEGIN_SRC cpp 
    // Signature 
   void* operator new (std::size_t size, const std::nothrow_t& tag);

   // Example: allocate single object
   //--------------------------------------------------//
   BaseClass* ptr = new (std::nowthrow) DerivedClassA(param0, param1, param2, ...);
   ptr->CallVirtualMethod1(); 
   if(!ptr){ 
       std::printf(" [FAILURE] Abort operation. \n");
       return;
   }
   delete ptr;    
#+END_SRC

 + Operator new for array allocation, throws _std::bad_alloc_ exception. 

#+BEGIN_SRC cpp 
    // Signature 
    void* operator new[] (std::size_t size);

    // Example: => Allocates 10 integers 
    //----------------------------------------------------
    int* pArray = nullptr;
    try{ 
      pArray = new int[10]
    } catch (std::bad_alloc const& ex) {
      // Abort operation 
      return; 
    }
    pArray[0] = 100; pArray[2] = 25; 
    delete [] pArray; // Always call delete 
    pArray = nullptr; // Always set the pointer to nullptr after calling delete
#+END_SRC

**** Example: Raw memory allocation with new operator 

The 'new' operator can be used for raw memory allocation without
calling constructor, in the same way as the C-function malloc. 

 *Experiment 1*

Allocating an array in heap for 4 integers. (CERN's Root REPL)

#+BEGIN_SRC cpp 
   >> void* pi = ::operator new (4 * sizeof(int))
   (void *) 0x3184af0

   >> assert(pi != nullptr);

   >> int* pint = static_cast<int*>(pi)
   (int *) 0x3184af0

   >> pint[0] = 20, pint[1] = 100, pint[2] = 3, pint[3] = 25;

   >> pint[0]
   (int) 20

   >> pint[1]
   (int) 100

   >> pint[2]
   (int) 3

   >> pint[3]
   (int) 25
   >> 

   >> std::for_each(pint, pint + 4, [](int x){ std::printf(" x = %d \n", x); });
    x = 20 
    x = 100 
    x = 3 
    x = 25 

   // Call operator delete 
   >> delete pint

   // Set to null when no longer used. 
   >> pi = nullptr; 
   >> pint = nullptr;
#+END_SRC

 *Experiment 2* 

Allocating raw memory for an instance of a class with new operator: 

#+BEGIN_SRC cpp 
  struct Circle{
     int x; 
     int y;  
     int radius;

     Circle(): x(10), y(20), radius(2) 
     { 
        std::printf(" [INFO] Cirlce constructed OK.\n");
     }

     ~Circle()
     { 
        std::printf(" [INFO] Cirlce destroyed OK.\n");
     }

     void set_radius(int r) 
     {
        radius = r;
     }

     void plot() const 
     { 
        std::printf(" [INFO] Draw circle at Point(%d, %d) with radius = %d\n"
           , this->x, this->y, this->radius);
     }
  };
#+END_SRC

REPL Session part 1:
 + The following call to operator 'new' only allocates memory for the
   object without calling its constructor. 

#+BEGIN_SRC cpp 
   // Constructor is not called!!! 
   // =>> Throws std::bad_alloc on failure. 
   >> void* p = ::operator new(sizeof(Circle))
   (void *) 0x1f30150

   assert(p != nullptr); 

   // Constructor is not called!!!
   >> Circle* cp1 = (Circle*) p
   (Circle *) 0x1f30150

   // =========>>> Manually Initialize Object <<=============//
   //--------------------------------------------------------- 


   // Solution: Initialize object manually. 
   >> cp1->x = 10;
   >> cp1->y = 20;
   >> cp1->radius = 25;

   >> cp1->plot()
    [INFO] Draw circle at Point(10, 20) with radius = 25
   >> 

   // =========>>> Destroy object and release memory <<=============//
   //----------------------------------------------------------------- 

   // Call destructor when the object is no longer needed
   >> delete cp1
    [INFO] Cirlce destroyed OK.

   // Set pointer to null 
   >> cp1 = nullptr
#+END_SRC

REPL Session Part 2:
 + The constructor could be called if the placement-new operator was
   used. 

#+BEGIN_SRC cpp 
  >> void* pp = ::operator new(sizeof(Circle))
  (void *) 0x32acf00

  // Abort computation if pp is null. 
  assert( pp != nullptr ); 

  // Now constructor is called. 

  >> Circle* cpp = new (pp) Circle
   [INFO] Cirlce constructed OK.
  (Circle *) 0x32acf00

  >> cpp->x
  (int) 10

  >> cpp->y
  (int) 20

  >> cpp->plot()
   [INFO] Draw circle at Point(10, 20) with radius = 2

  >> delete cpp
   [INFO] Cirlce destroyed OK.
#+END_SRC
**** Example: User-defined new and delete operators 
 
It is possible to override the global _new_ and _delete_ operators free
functions. 

  + Note: replacing the default _new_ and _delete_ operators is not recommended.

  + Instead of replacing the default _new_ and _delete_ operators, a
    better alternative is defining class-specific operators as static
    member functions. 

 *File: new-delete-experiment1.cpp*

 + File: [[file:src/new-delete-experiment1.cpp][file:src/new-delete-experiment1.cpp]]

Class _SomeClass_: 

#+BEGIN_SRC cpp 
  class SomeClass{
  public:
      int x;
      int y;
      char buffer[200];

      SomeClass(): x(125), y(2561), buffer("Hello world")
      {
          std::puts(" [TRACE] SomeClass object created OK");
      }

      void show() const
      {
          std::printf(" =>> SomeClass { x = %d, y = %d, buffer = %s } \n", x, y, buffer);
      }

      ~SomeClass()
      {
          std::puts(" [TRACE] SomeClass object destroyed OK");
      }
  };
#+END_SRC

Class _SomeClassB_:

#+BEGIN_SRC cpp 
  class SomeClassB{
      char m_name[200] = "Unnamed";
      int  m_id = -1;

      SomeClassB()
      {
          std::printf(" [TRACE] <CTOR1> Object of SomeClassB created => addr = %p "
                      " id = %d - name = '%s'"
                      , static_cast<void*>(this), m_id, m_name);
      }

      ~SomeClassB()
      {
          std::printf(" [TRACE] <DTOR> Object of SomeClassC deleted => addr = %p \n"
                      , static_cast<void*>(this));
      }

  };
#+END_SRC

Class _SomeClassC_:

  + This class has class-specific _new_ and _delete_ operators defined as
    static member functions. In this case, The keyword _static_ case can
    be omitted, but it was used for making the code more explicit.

#+BEGIN_SRC cpp 
  class SomeClassC {
  public:
      char m_name[200] = "Unnamed";
      int  m_id = -1;

      SomeClassC()
      {
          std::printf(" [TRACE] <CTOR1> Object of SomeClassC created => addr = %p "
                      " id = %d - name = '%s'"
                      , static_cast<void*>(this), m_id, m_name);
      }

      SomeClassC(const char* name, int id)
      {
          std::strcpy(m_name, name);
          m_id = id;
          std::printf(" [TRACE] <CTOR2> Object of SomeClassC created => addr = %p "
                      " id = %d - name = '%s' \n"
                      , static_cast<void*>(this), m_id, m_name);
      }

      ~SomeClassC()
      {
          std::printf(" [TRACE] <DTOR> Object of SomeClassC deleted => addr = %p \n"
                      , static_cast<void*>(this));
      }

      // Member fuction overloading of new operator
      // -------------------------------------------------------
      // Note: the keyword static is redundant, this operator is a static member function
      // even without the keyword 'static'. It was added to make the declaration more explicit.
      static void* operator new(size_t sz)
      {
          void* ptr = std::malloc(sz);
          if(!ptr) std::puts(" [ERROR] Not enough memory");
          std::printf(" [TRACE] SomeClassB => Custom new operator called. Allocated %lu Bytes => "
                      " ptr = %p \n"
                      , sz, ptr);
          return ptr;
      }

      // Member fuction overloading of delete operator
      // Static keyword redundant
      static void operator delete(void* addr)
      {
          std::printf(" [TRACE] Custom delete operator called for SomeClassB => p = %p \n"
                      , addr);
          free(addr);
      }
  };
#+END_SRC

Global operator _new_ free-function:

  + Note: This overloading throws exceptin std::bad_alloc when there
    is no enough memory. 

#+BEGIN_SRC cpp 
  // Global free-function overloading of new operator Note: Cannot be
  // declared inside a namespace Note: DO NOT DO IT!
  void* operator new(size_t size)
  {
      std::printf(" [TRACE] NEW - Called operator new, Allocated %lu Bytes\n", size);
      void* ptr = std::malloc(size);
      if(!ptr) {
          std::puts(" [ERROR] Not enough memory");
          throw std::bad_alloc();
      }
      return ptr;
  }
#+END_SRC

Global operator _new_ free-function (std::nothrow):

 + Note: This overloading does not throw exception. It just returns a
   null pointer when there is no enough memory.

#+BEGIN_SRC cpp 
  // Global free-function overloading of new operator (std::notrhow)
  // Note: Cannot be declared inside a namespace
  // Note: Does not throw exception, just returns a null pointer when there is no
  //       memory available
  void* operator new(size_t size, std::nothrow_t const& tag)
  {
      std::printf(" [TRACE] NEW (std::nothrow) - Called operator new, Allocated %lu Bytes\n", size);
      void* ptr = std::malloc(size);
      if(!ptr) {
          std::puts(" [ERROR] Not enough memory");
          return nullptr;
      }
      return ptr;
  }
#+END_SRC

Global operator _delete_ free function: 

#+BEGIN_SRC cpp 
  // Global free-function overloading of delete operator
  // Note: Cannot be delcared inside a namespace
  void operator delete(void* ptr) noexcept
  {
      std::puts(" [TRACE] DELETE - Called operator delete");
      free(ptr);
  }
#+END_SRC

 *Main Function / Experiment 1*

  + Allocate primitive type with custom _new_ operator. 

#+BEGIN_SRC cpp 
  std::puts("\n ==>> Experiment 1 == Global overloading -test with primitive type \n");
  {
      int* ptr = new int(25);
      ,*ptr = 10 + *ptr;
      std::printf(" Value of ptr[%p] = %d \n", static_cast<void*>(ptr), *ptr);
      delete  ptr;
  }
#+END_SRC

Output: 

#+BEGIN_SRC sh 
   ==>> Experiment 1 == Global overloading -test with primitive type 

   [TRACE] NEW - Called operator new, Allocated 4 Bytes
   Value of ptr[0x2478e80] = 35 
   [TRACE] DELETE - Called operator delete
#+END_SRC

 *Main Function / Experiment 2* 

  + Allocate and instantiate an object of class SomeClass in the
    process heap using the user-defined global _new_ (std::bad_alloc)
    operator. Note: The default constructor is called. 

#+BEGIN_SRC cpp 
  std::puts("\n ==>> Experiment 2 == Global Overloading - test with class ====\n");
  {
      SomeClass* pcls = new SomeClass;
      pcls->x = 25;
      pcls->y = 1005;
      pcls->show();
      delete pcls;
  }
#+END_SRC

Output: 

#+BEGIN_SRC sh 
  ==>> Experiment 2 == Global Overloading - test with class ====

  [TRACE] NEW - Called operator new, Allocated 208 Bytes
  [TRACE] SomeClass object created OK
  =>> SomeClass { x = 25, y = 1005, buffer = Hello world } 
  [TRACE] SomeClass object destroyed OK
  [TRACE] DELETE - Called operator delete
#+END_SRC


 *Main Function / Experiment 3*

  + Allocate and instantiate an object of class SomeClass in the
    process heap using the user-defined global _new_ (std::nothrow)
    operator. Note: The default constructor is called. 

#+BEGIN_SRC cpp 
  std::puts("\n ==>> Experiment 3 == (std::notrhow) Global Overloading - test with class ====\n");
  {
      SomeClass* pcls = new (std::nothrow) SomeClass;
      pcls->x = 25;
      pcls->y = 1005;
      pcls->show();
      delete pcls;
  }
#+END_SRC

Output: 

#+BEGIN_SRC sh 
  ==>> Experiment 3 == (std::notrhow) Global Overloading - test with class ====

   [TRACE] NEW (std::nothrow) - Called operator new, Allocated 208 Bytes
   [TRACE] SomeClass object created OK
   =>> SomeClass { x = 25, y = 1005, buffer = Hello world } 
   [TRACE] SomeClass object destroyed OK
   [TRACE] DELETE - Called operator delete
#+END_SRC

 *Main Function / Experiment 4*

  + The global operator _new_ is used only for raw allocation, in the
    same way as _malloc_. The object is not instantiated and no
    constructor is called.

#+BEGIN_SRC cpp 
  std::puts("\n ==>> Experiment 4 - Explicit raw allocation  == Global Overloading - test with class ====\n");
  {
      // Raw memory allocation => Without calling the constructor
      void* raw_pcls = ::operator new(sizeof(SomeClass));
      // Note: The constructor is not called
      SomeClass* pcls = static_cast<SomeClass*>(raw_pcls);
      pcls->x = 251;
      pcls->y = -1005;
      std::strcpy(pcls->buffer, "raw-memory-allocated");
      pcls->show();
      delete pcls;
  }
#+END_SRC

Output: 

#+BEGIN_SRC sh 
   ==>> Experiment 4 - Explicit raw allocation  == Global Overloading - test with class ====

   [TRACE] NEW - Called operator new, Allocated 208 Bytes
   =>> SomeClass { x = 251, y = -1005, buffer = raw-memory-allocated } 
   [TRACE] SomeClass object destroyed OK
   [TRACE] DELETE - Called operator delete
#+END_SRC

 *Main Function / Experiment 5*

  + Calls new and delete operators specific for SomeClassC defined as
    static meber functions. 

#+BEGIN_SRC cpp 
  std::puts("\n ==>> Experiment 5 === Member Function Overloading ==========\n");
  {
      SomeClassC* pclassB = new SomeClassC("Hello", 2005);
      std::printf(" =>>  Print object => pclassB->m_name = %s; pclassB->m_id = %d \n"
                  , pclassB->m_name, pclassB->m_id);

      delete pclassB;
  }
#+END_SRC

Output: 

#+BEGIN_SRC sh 
   ==>> Experiment 5 === Member Function Overloading ==========

   [TRACE] SomeClassB => Custom new operator called. Allocated 204 Bytes =>  ptr = 0x2478ea0 
   [TRACE] <CTOR2> Object of SomeClassC created => addr = 0x2478ea0  id = 2005 - name = 'Hello' 
   =>>  Print object => pclassB->m_name = Hello; pclassB->m_id = 2005 
   [TRACE] <DTOR> Object of SomeClassC deleted => addr = 0x2478ea0 
   [TRACE] Custom delete operator called for SomeClassB => p = 0x2478ea0 
#+END_SRC

*** Placement new and delete operators 
**** Overview 

The _placement new_ operator has an additional parameter void* which
allows instantiating a type or class in a specific memory
location. 

Notes: 

  + This operator does not allocate any storage. It instantiantes
    object at a pre-allocated storage or at specific memory
    address.

  + The global new and delete placement operators cannot be replaced
    by user-defined ones.

Some *use-cases* for this operator are: 

  + Instantiate object in shared memory between two processes. 

  + Instantiate object in memory mapped file. 

  + Instantiate object in some pre-allocated buffer, it allows
    instantiating polymorphic objects at runtime in a 
    static-allocated buffer (global variable) or in a stack-allocated
    buffer. This technique is useful in *embedded systems* for enabling
    polymorphism without heap allocation.
    + Note: A buffer in this cases is a byte array: _char buffer [BUFFER_SIZE]_

  + Instantiate object in some specific hardware address - Memory
    Mapped IO, MMIO (*embedded systems*)

  + Custom allocators 

 *Placemente new and delete operators for single object* 

  + The parameter _size_ is the size of the data type to be
    allocated. 

  + The pointer _place_ holds the address where the object will be
    instantiated.

  + The return value is the pointer to the allocated object.

  + Note: This gloabl new placement operator cannot be replaced by
    an user-defined one. However, it is possible to define
    class-specific one as static member function.

#+BEGIN_SRC cpp 
  // Placement new operator:
  void* operator new(std::size_t size, void* location); 

  // Placement delete operator: 
  void delete(void* p_object, void* location);
#+END_SRC

Usage example: 

#+BEGIN_SRC cpp 
  // Allocate object in pre-allocated buffer 
  constexpr size_t BUFFER_SIZE = 2048; // 2048 bytes or 2kb
  char buffer[BUFFER_SIZE];

  // Construct object at buffer 
  BaseClass* obj = new (buffer) DerivedClass(arg0, arg1, arg2, ... argN-1)

  obj->callVirtualMethod(); 
  
  // Invoke destructor when object is no longer needed
  obj->~BaseClass();  

  // Call placement delete operator 
  ::operator delete(obj, buffer);
#+END_SRC

 *Placemente new and delete operators for arrays* 

#+BEGIN_SRC cpp 
  // Placement new operator for arrays
  void* operator new[](std::size_t size, void* location); 

  // Placement new operator for arrays 
  void* operator delete[](void* p_object, void* location); 
#+END_SRC

**** Example - placement-new experiment in REPL

Note: This example was run in the CERN's Root REPL.

Class Dummmy: 

#+BEGIN_SRC cpp 
  class Dummy{   
  public:
      int x = 200;
      int y = 25;
      char name[200] = "Unnamed";
   
      Dummy()
      {
          std::printf(" [INFO] Default ctor called. => this = %p \n"
                    , static_cast<void*>(this));
      }

      Dummy(int x, int y, const char* name)
      {
          std::strcpy(this->name, name);
          this->x = x;
          this->y = y;
      }

      ~Dummy()
      {
          std::printf(" [INFO] Dtor called. => this = %p \n"
                      , static_cast<void*>(this));
      }

      void show() const
      {
          std::printf(" [INFO] Dummy { name = '%s' ; x = %d; y = %d } \n"
                      , this->name, this->x, this->y);
      }
  };
#+END_SRC

 *REPL Session:* 

Get size of type 'Dummy' in bytes 

#+BEGIN_SRC cpp 
  >> sizeof(Dummy)
  (unsigned long) 208
#+END_SRC

Pre-allocated static (global) or stack buffer large enough for storing
an instance of class dummy. 

#+BEGIN_SRC cpp 
  // Create a buffer with 416 bytes 
  std::uint8_t buffer[416];
#+END_SRC

Buffer before instantiation: 

#+BEGIN_SRC cpp 
  >> buffer
  (std::uint8_t [416]) { '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', .... '0x00', '0x00' }

  >> (int) buffer[0]
  (int) 0

  >> (int) buffer[1]
  (int) 0

  >> (int) buffer[2]
  (int) 0
  >> 
#+END_SRC

Use the placment-new operator for creating an object of class Dummy in
the buffer.

#+BEGIN_SRC cpp 
  >> Dummy* p = new (buffer) Dummy
   [INFO] Default ctor called. => this = 0x7fda9fe7a010 
  (Dummy *) 0x7fda9fe7a010

  >> p->show()
   [INFO] Dummy { name = 'Unnamed' ; x = 200; y = 25 } 
  >> 

  >> p->x
  (int) 200

  >> p->y
  (int) 25

  >> p->name
  (char [200]) "Unnamed\0\0\0\0\0\0\0\0 ... ... \0\0\0"
#+END_SRC

Buffer after instantiation: 

#+BEGIN_SRC cpp 
  >> buffer
  (std::uint8_t [416]) { 
    '0xc8', '0x00', '0x00', '0x00', '0x19', '0x00', '0x00', '0x00', 'U', 'n', 'n', 'a', 'm', 'e', 'd',
    '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00' .... ... '0x00'}

  >> (int) buffer[0]
  (int) 200

  >> (int) buffer[4]
  (int) 25
#+END_SRC

Manipulating  object variable:

#+BEGIN_SRC cpp 
  >> int xx1 = 0x4ABC7852
  (int) 1253865554

  >> int yy1 = 0x3DFCA3E2
  (int) 1039967202

  >> p->x = xx1;
  >> p->y = yy1;
  >> std::strcpy(p->name, "I_am_dummy_object_in_C++1z");

  >> p->show()
   [INFO] Dummy { name = 'I_am_dummy_object_in_C++1z' ; x = 1253865554; y = 1039967202 } 
#+END_SRC

Check buffer: 

#+BEGIN_SRC cpp 
  >> buffer
  (std::uint8_t [416]) { 'R', 'x', '0xbc', 'J', '0xe2', '0xa3', '0xfc'
  , '=', 'I', '_', 'a', 'm', '_', 'd', 'u', 'm', 'm', 'y', '_', 'o', 'b', 'j', 'e'
  , 'c', 't', '_', 'i', 'n', '_', 'C', '+', '+', '1', 'z', '0x00', '0x00', '0x00', '0x00' .. ... }
#+END_SRC

Create function display_buffer for showing buffer content in decimal,
hexadecimal and char format: 

#+BEGIN_SRC cpp 
   void display_bytes(std::uint8_t* buffer, size_t min, size_t max){
       if(min > max) throw std::runtime_error("Error: supposed min <= max");
       for(size_t i = min; i < max; i++)
       {
           char ch = std::isprint(buffer[i]) ? buffer[i] : ' ';
           std::printf(" => byte[%lu] = 0x%X %d %c\n", i
                       , static_cast<int>(buffer[i])
                       , static_cast<int>(buffer[i])
                       , ch);
       }
   }
#+END_SRC

Analyze buffer bytes 0 to 3: 

#+BEGIN_SRC cpp 
  >> printf(" => xx1 = %X \n", xx1);
   => xx1 = 4ABC7852 

  // Value of p->x == 0x4ABC7852 
  // 0x 4A BC 78 52 
  >> display_bytes(buffer, 0, 4)
   => byte[0] = 0x52 82 R
   => byte[1] = 0x78 120 x
   => byte[2] = 0xBC 188  
   => byte[3] = 0x4A 74 J

  >>  int x1_value = (buffer[3] << 24) + (buffer[2] << 16) + (buffer[1] << 8) + buffer[0]
  (int) 1253865554

  >> p->x
  (int) 1253865554

  x1_value == p->x
  (bool) true

  >> std::printf(" p->x = %X ; x1_value = %X \n", p->x, x1_value);
   p->x = 4ABC7852 ; x1_value = 4ABC7852 
#+END_SRC
 
Analyze buffer bytes 4 to 7: 

#+BEGIN_SRC cpp 
  >> printf(" => yy1 = %X \n", yy1);
   => yy1 = 3DFCA3E2 

  // p->y = 0x3DFCA3E2 
  // Bytes: 0x 3D FC A3 E2 
  // In the buffer, the bytes are stored in "Little Endian Format" 
  // as E2 A3 FC 3D
  >> display_bytes(buffer, 4, 8)
   => byte[4] = 0xE2 226  
   => byte[5] = 0xA3 163  
   => byte[6] = 0xFC 252  
   => byte[7] = 0x3D 61 =

  >> int y1_value = (buffer[7] << 24) + (buffer[6] << 16) + (buffer[5] << 8) +  buffer[4]
  (int) 1039967202

  >> printf(" p->y = %X ; y1_value = %X \n", p->y, y1_value);
   p->y = 3DFCA3E2 ; y1_value = 3DFCA3E2 
#+END_SRC

Copy character portion to a std::string object.

#+BEGIN_SRC cpp 
  >> std::string str(buffer + 8, buffer + 40);

  >> str
  (std::string &) "I_am_dummy_object_in_C++1z\0\0\0\0\0\0"
  >> 
#+END_SRC

Release memory: 

#+BEGIN_SRC cpp
  // Call destructor 
  >> p->~Dummy() 
   [INFO] Dtor called. => this = 0x7ff08c52c010 

  // Call placement-delete operator 
  >> ::operator delete(p, buffer)
#+END_SRC

*** References and further reading 

General: 

 + [[https://www.gribblelab.org/CBootCamp/7_Memory_Stack_vs_Heap.html][7. Memory : Stack vs Heap]]

 + [[http://www.yolinux.com/TUTORIALS/Cpp-DynamicMemory.html][C / C++ and Dynamic memory allocation]]

 + [[http://www.modernescpp.com/index.php/strategies-for-the-allocation-of-memory][Strategies for the Allocation of Memory - ModernesCpp.com]]

 + [[https://www.design-reuse.com/articles/25090/dynamic-memory-allocation-fragmentation-c.html][Dynamic Memory Allocation and Fragmentation in C and C++]]

 + [[https://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/][7.9 — The stack and the heap | Learn C++]]

 + *CS 414: Operating Systems Fall 2005 - Operating Systems*
   + http://www.cs.virginia.edu/~son/cs414.f05/lec11.slides.pdf

 + *Thinking in C++, 2nd ed. Volume 1*
   + http://www.cs.ust.hk/~dekai/library/ECKEL_Bruce/TICPP-2nd-ed-Vol-one/TICPP-2nd-ed-Vol-one-html/Chapter13.html

 + *Dynamic Memory Allocation and Deallocation*
   + http://www.umsl.edu/~lawtonb/224/dynamic0.html

 + *Dynamic Memory in Real Time Systems - a solution?*
   + https://blogs.mentor.com/colinwalls/blog/2014/05/06/dynamic-memory-in-real-time-systems-a-solution/

 + *Dynamic Memory Allocation in Critical Embedded Systems*
   + https://critical.eschertech.com/2010/07/30/dynamic-memory-allocation-in-critical-embedded-systems/

 + *Favorite Tools: C++11 std::array*
   + https://www.embeddedrelated.com/showarticle/1031.php

Placement New and Delete Opeators:

  + Wikipedia - *Placement syntax* 
    * <https://en.wikipedia.org/wiki/Placement_syntax>

  + *Thinking in C++, 2nd ed. Volume 1* - Dynamic Object Creation  - Bruce Eckel
    + <http://www.cs.ust.hk/~dekai/library/ECKEL_Bruce/TICPP-2nd-ed-Vol-one/TICPP-2nd-ed-Vol-one-html/Chapter13.html>
 
  + *Calling Constructors with Placement New*
    + <https://www.drdobbs.com/cpp/calling-constructors-with-placement-new/232901023?pgno=2>

  + [[https://stackoverflow.com/questions/222557/what-uses-are-there-for-placement-new][c++ - What uses are there for "placement new"? - Stack Overflow]]

C++ Idioms related to Heap-Allocation: 

 + [[https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Requiring_or_Prohibiting_Heap-based_Objects][More C++ Idioms/Requiring or Prohibiting Heap-based Objects - Wikibooks, open books for an open world]]

Debugging: 
 
 + [[https://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm#.W-RbqB6YW00][Debugging Software Crashes in C and C++ - II]]
** OOP Object Lifecycle 
   :PROPERTIES:
   :ID:       69b48bc0-1b18-4997-b954-3da566a3508a
   :END:

This code shows how object lifecycle works in C++ by instrumenting
constructors and destructors member functions.

 - File: [[file:src/object-lifecycle.cpp][file:src/object-lifecycle.cpp]]
 - Online Compiler: https://rextester.com/QUQ52793 

C++ can allocated objects in three different areas or memories: 

 + *stack* - Objects allocated by default on the stack when instantiated
   inside functions, member functions or local scope. Objects
   instantiated on the stack are automatically deleted or released
   when they go out of scope and then the destructor is called.

   + Summary and further notes:
     + Objects allocated on the stack are automatically released when
       they go out of scope.
     + There is a size limit for objects allocated on the stack which
       depends on the operating system, therefore very large objects
       allocated on the stack can cause segmentation fault. If it is
       the case, it is better to allocate the object on the heap or
       dynamic memory.

 + *static memory* - Objects, declared outside functions or member
   functions are instantiated on the static memory and they are only
   deleted when the program finishes.

 + *heap memory* - Objects are allocated on the heap memory (aka
   dynamic memory) when they are instantiated with operator
   *new*. Unlike stack or static allocated objects, heap allocated
   objects are not automatically destroyed, so they must be released
   manually with the *delete* operator. However, deleting heap-objects
   manually is error prone since it is easy to forget to call delete
   operator. A better approach to deal with heap object is to use C++
   smart pointers that wraps raw pointers and automatically deletes
   heap objects when they go out of scope. 

Code Highlights: 

 - Object allocated in static memory - lives during the entire program
   execution and are only destroyed when the program execution ends.

#+BEGIN_SRC cpp 
  DummyClass dummyGlobal("dummy-global");

  int main(){ 
    ... ... 
  };
#+END_SRC

 - Object allocated in stack: (dummy1, dummy2, object d in testObject())

#+BEGIN_SRC cpp 
    // ... 
   int main(){
       // Allocated on stack 
       DummyClass dummy1("dummy1-stack");

       {
         std::cerr << "\n" << " ---- ENTER LOCAL SCOPE " << "\n\n";
         TRACE("Create local scope");
         // Allocated on stack 
         DummyClass dummy2("dummy2-stack-local-scope");
             ... ... .. 
         std::cerr << "\n" << "EXIT LOCAL SCOPE " << "\n\n";
       } // dummy2 deleted here 

   } // dummy1 is deleted here 
#+END_SRC

 - Objects allocated on the heap (dummyInHeap) must be released
   manually or automatically with smart pointers (not used in this
   code).
   - Note: For every object allocated on the heap,  it is necessary a
     delete operator if smart pointers are not used. 

#+BEGIN_SRC cpp 
   auto makeDummyHeap() -> DummyClass* {
     // ... ... 
     // Heap-allocated object 
     DummyClass* ptr = new DummyClass("dummy-heap");
     // ...
     return ptr; 
   };

   int main(){
     // ... ... ... .
     DummyClass* dummyInHeap =  makeDummyHeap();

     // ....   
     dummyInHeap->speakWithUser();
     // ....

     delete dummyInHeap;
   }

#+END_SRC

 - Deterministic destructor

   - In C++, destructors are *deterministic*. They are always called
     automatically when an object allocated on the static memory
     (global object) or stack goes out of scope or an exception
     happens. Due to this feature, it is safe to release resources like
     allocated memory, database handlers, file handlers, socket
     handlers or perform other cleanup tasks on the destructor. It is
     the foundation of the RAAI technique/idiom - "Resource Acquisition
     is Initialization". 
    
#+BEGIN_SRC cpp 
   try {
        std::cerr << "\n" << " ---- ENTER LOCAL EXCEPTION SCOPE " << "\n\n";
        DummyClass dummyException("dummy2-stack-local-scope");
        dummyException.speakWithUser();
        throw std::runtime_error(" ERROR Throw a failure for testing deterministic destructor");
        std::cerr << "\n" << " ---- EXIT LOCAL EXCEPTION SCOPE " << "\n\n";
   } catch (const std::runtime_error& ex){
        std::cerr << "\n" << " ---- ENTER EXCEPTION HANDLER" << "\n\n";		
        std::cerr << "Failure = " << ex.what() << "\n";
        std::cerr << "\n" << " ---- EXIT EXCEPTION HANDLER" << "\n\n";
   }
#+END_SRC 

Output: 

#+BEGIN_SRC text 
   ---- ENTER LOCAL EXCEPTION SCOPE 

  object-lifecycle.cpp:21: - fun = DummyClass ; name = dummy2-stack-local-scope - I was created.
  I am a dummy object called = dummy2-stack-local-scope
  object-lifecycle.cpp:54: - fun = ~DummyClass ; name = dummy2-stack-local-scope - I was destroyed

   ---- ENTER EXCEPTION HANDLER

  Failure =  ERROR Throw a failure for testing deterministic destructor

   ---- EXIT EXCEPTION HANDLER

#+END_SRC


Complete Code: 

#+BEGIN_SRC cpp :tangle src/object-lifecycle.cpp
  // File:  object-lifecycle.cpp 
  // Brief: Demonstrate Object Lifecycle 
  #include <iostream>
  #include <string>

  #define DEBUG_TRACE

  #ifdef DEBUG_TRACE
    #pragma message "Logging Enabled"
    #define TRACE(msg) \
      std::cerr << __FILE__ << ":" << __LINE__ << ": - fun = " << __FUNCTION__ << " ; " << msg << "\n"
  #else
    #pragma message ("Logging disabled")
    #define TRACE(msg)
  #endif 

  class DummyClass{
  public:
          // Constructor 
          DummyClass(const std::string& name): _object_name(name){
                  TRACE(std::string("name = ") + name + " - I was created.");
          }
          // Copy constructor 
          DummyClass(const DummyClass& rhs){
                  TRACE("Enter copy constructor");
                  TRACE("name = " + _object_name + " - I was copied. ");
                  this->_object_name = rhs._object_name + "-COPIED";
          }
          // Move constructor 
          DummyClass( DummyClass&& rhs){
                  TRACE("Enter move constructor");
                  TRACE("name = " + _object_name + " - I was moved");
                  this->_object_name = rhs._object_name + "-MOVED";
          }
          // Copy assignment operator
          DummyClass& operator= (const DummyClass& rhs){
                  TRACE("Enter copy assignment operator");
                  TRACE("name = " + _object_name + " - I was copied. ");
                  this->_object_name = rhs._object_name + "-COPIED";
                  return *this;
          }
          //DummyClass& operator= (DummyClass&& rhs) = delete;

      // Move assignment operator 
          DummyClass& operator= (DummyClass&& rhs){
                  TRACE("Enter move assignment operator");
                  TRACE("name = " + _object_name + " - I was moved. ");
                  this->_object_name = rhs._object_name + "-MOVED";
                  return *this;
          }
	
          // Destructor 
          ~DummyClass(){
                  TRACE(std::string("name = ") + _object_name  + " - I was destroyed");
          }
          void speakWithUser(){
                  std::cout << "I am a dummy object called = " << _object_name << "\n";
          }
	
  private:
          std::string _object_name;	
  };

  // Object allocated on the static memory 
  // is deleted when the programs finishes. 
  DummyClass dummyGlobal("dummy-global");

  auto testObject() -> DummyClass {
          std::cerr << "\n" << " ==> ENTER FUNCTION  testObject()" << "\n\n";
      TRACE("Enter function");
          auto d  = DummyClass("local-dummy-in-function");
          d.speakWithUser();
          std::cerr << "\n" << " ==> EXIT FUNCTION  testObject()" << "\n\n";
      TRACE("Exit function");
          // Object d is deleted here when it goes out scope
          // and then a copy of it is returned from here.
          // Therefore, the copy constructor is invoked.
          return d;
  }

  auto makeDummyHeap() -> DummyClass* {
          std::cerr << "\n" << " ==> ENTER FUNCTION  makeDummyHeap()" << "\n\n";	
          // Object allocated in dynamic memory, so it survives this scope
          // and is not deleted when returned from function. 
          DummyClass* ptr = new DummyClass("dummy-heap");
          ptr->speakWithUser();
          std::cerr << "\n" << " ==> EXIT FUNCTION  makeDummyHeap()" << "\n\n";
          return ptr; 
  };

  int main(){
          std::cerr << "\n" << "ENTER FUNCTION MAIN" << "\n\n";
          TRACE("Main function started.");
          // Object allocated on the stack -> auto storage class, it is
          // destroyed when it goes out of scope 
          DummyClass dummy1("dummy1-stack");
          dummy1.speakWithUser();

          DummyClass* dummyInHeap =  makeDummyHeap();
          dummyInHeap->speakWithUser();
	
          {
                  std::cerr << "\n" << " ---- ENTER LOCAL SCOPE " << "\n\n";
                  TRACE("Create local scope");
                  DummyClass dummy2("dummy2-stack-local-scope");
                  dummy2.speakWithUser();
                  dummyGlobal.speakWithUser();
                  dummyInHeap->speakWithUser();
                  TRACE("End local scope");
                  // Object dummy2 deleted here
                  std::cerr << "\n" << "EXIT LOCAL SCOPE " << "\n\n";
          }

          try {
                  std::cerr << "\n" << " ---- ENTER LOCAL EXCEPTION SCOPE " << "\n\n";
                  DummyClass dummyException("dummy2-stack-local-scope");
                  dummyException.speakWithUser();
                  throw std::runtime_error(" ERROR Throw a failure for testing deterministic destructor");
                  std::cerr << "\n" << " ---- EXIT LOCAL EXCEPTION SCOPE " << "\n\n";
          } catch (const std::runtime_error& ex){
                  std::cerr << "\n" << " ---- ENTER EXCEPTION HANDLER" << "\n\n";		
                  std::cerr << "Failure = " << ex.what() << "\n";
                  std::cerr << "\n" << " ---- EXIT EXCEPTION HANDLER" << "\n\n";
          }

	
          TRACE("Copy object returned from function");
          DummyClass dummy2 = testObject();
          dummy2.speakWithUser();

          dummyInHeap->speakWithUser();

          // Objects allocated on the heap must be released manually or a
          // memory leak will happen. However, it is easy to forget to
          // delete a heap-allocated object, so the this approach is error
          // prone and better solution is to use C++11 smart pointers.
          delete dummyInHeap;

          std::cerr << "\n" << "EXIT FUNCTION MAIN" << "\n\n";
          TRACE("Main function finished.");
          return 0;
          // Object dummy1 and dummyGlobal deleted here 
  }

#+END_SRC

Complete Output: 

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

  object-lifecycle.cpp:9:19: note: #pragma message: Logging Enabled
     #pragma message "Logging Enabled"
                     ^~~~~~~~~~~~~~~~~
  object-lifecycle.cpp:21: - fun = DummyClass ; name = dummy-global - I was created.

  ENTER FUNCTION MAIN

  object-lifecycle.cpp:93: - fun = main ; Main function started.
  object-lifecycle.cpp:21: - fun = DummyClass ; name = dummy1-stack - I was created.
  I am a dummy object called = dummy1-stack

   ==> ENTER FUNCTION  makeDummyHeap()

  object-lifecycle.cpp:21: - fun = DummyClass ; name = dummy-heap - I was created.
  I am a dummy object called = dummy-heap

   ==> EXIT FUNCTION  makeDummyHeap()

  I am a dummy object called = dummy-heap

   ---- ENTER LOCAL SCOPE 

  object-lifecycle.cpp:104: - fun = main ; Create local scope
  object-lifecycle.cpp:21: - fun = DummyClass ; name = dummy2-stack-local-scope - I was created.
  I am a dummy object called = dummy2-stack-local-scope
  I am a dummy object called = dummy-global
  I am a dummy object called = dummy-heap
  object-lifecycle.cpp:109: - fun = main ; End local scope

  EXIT LOCAL SCOPE 

  object-lifecycle.cpp:54: - fun = ~DummyClass ; name = dummy2-stack-local-scope - I was destroyed

   ---- ENTER LOCAL EXCEPTION SCOPE 

  object-lifecycle.cpp:21: - fun = DummyClass ; name = dummy2-stack-local-scope - I was created.
  I am a dummy object called = dummy2-stack-local-scope
  object-lifecycle.cpp:54: - fun = ~DummyClass ; name = dummy2-stack-local-scope - I was destroyed

   ---- ENTER EXCEPTION HANDLER

  Failure =  ERROR Throw a failure for testing deterministic destructor

   ---- EXIT EXCEPTION HANDLER

  object-lifecycle.cpp:127: - fun = main ; Copy object returned from function

   ==> ENTER FUNCTION  testObject()

  object-lifecycle.cpp:70: - fun = testObject ; Enter function
  object-lifecycle.cpp:21: - fun = DummyClass ; name = local-dummy-in-function - I was created.
  I am a dummy object called = local-dummy-in-function

   ==> EXIT FUNCTION  testObject()

  object-lifecycle.cpp:74: - fun = testObject ; Exit function
  I am a dummy object called = local-dummy-in-function
  I am a dummy object called = dummy-heap
  object-lifecycle.cpp:54: - fun = ~DummyClass ; name = dummy-heap - I was destroyed

  EXIT FUNCTION MAIN

  object-lifecycle.cpp:140: - fun = main ; Main function finished.
  object-lifecycle.cpp:54: - fun = ~DummyClass ; name = local-dummy-in-function - I was destroyed
  object-lifecycle.cpp:54: - fun = ~DummyClass ; name = dummy1-stack - I was destroyed
  object-lifecycle.cpp:54: - fun = ~DummyClass ; name = dummy-global - I was destroyed
#+END_SRC

** OOP Polymorphism and Inheritance 
*** Overview 

 Dynamic or subtyping polymorphis is basically, the ability
 of the client code to deal with any any instance of derived classes in
 the same way it deals with an instance of the base class. 

 In C++, it is only possible to use OOP subtyping polymorphism with
 pointers or references. As a result, it is not possible to store
 instances of base class in STL containers by value, or to create
 polymorphic functions which return instance of derived classes by
 value or take instance derived classes as argument passed by value.

 To summarize: 

  + Object Oriented Polymorphism, is aso called:
    + Dynamic polymorphism
    + Runtime polymorphism 
  + In C++ it is only possible to use polymorphism with references or
    pointers.
  + A polymorphic function which returns any instance of the derived
    class casted as an instance of the base class can only return them
    *by pointer to objects allocated on the heap* (dynamic memory) with
    *new* operator. Functions like this are called factory functions and
    in this case, it is better to wrap the pointer in smart pointer,
    ~unique_ptr~ or ~shared_ptr~.
*** OOP - Dynamic Polymorphism in deep

 + File: [[file:src/polymorphism1.C][file:src/polymorphism1.C]] (CLING - Script)

Classes in the script [[file:src/polymorphism1.C][file:src/polymorphism1.C]]

#+BEGIN_SRC cpp 
  class Base{
  public:
     Base(){}
     // Copy constructor
     Base(const Base& rhs){
         std::cerr << " [TRACE] " << __FILE__ << ":" << __LINE__ << " "
                   << " Base copy constructor invoked." << "\n";
     }
     // Copy assignment operator
     Base& operator= (const Base& rhs){
          std::cerr << " [TRACE] " << __FILE__ << ":" << __LINE__ << " " 
                    << " Base copy assignment operator invoked." << "\n";
          return *this;
     }
     // The base class always need a virtual
     // destructor 
     virtual ~Base() = default;	

     virtual std::string getType() const {
        return "Base";
     }	
     std::string getType2() const {
        return "Base";
     }
     void showType(){
        // OR: std::cout << "Class type = " << getType() << "\n";
        std::cout << "Class type = " << this->getType() << "\n";
     }
  };

  class DerivedA: public Base{
  public:
      DerivedA(){}
      std::string getType() const {
         return "DerivedA";
      }
      std::string getType2() const {
         return "DerivedA";
      }		
  };

  class DerivedB: public Base{
  public:
     DerivedB(){}
     std::string getType() const {
        return "DerivedB";
     }
     std::string getType2() const {
        return "DerivedB";
     }		
  };
#+END_SRC

Load classes from script and create instances.

#+BEGIN_SRC cpp 
  >> .L polymorphism1.C
  Base base;
  DerivedA da;
  DerivedB db;
#+END_SRC

 *Testing methods:*

#+BEGIN_SRC cpp 
  // Test method getType
  >> base.getType()
  (std::string) "Base"

  >> da.getType()
  (std::string) "DerivedA"

  >> db.getType()
  (std::string) "DerivedB"
  >> 

  // Test method get
  >> base.showType()
  Class type = Base
  >> da.showType()
  Class type = DerivedA
  >> db.showType()
  Class type = DerivedB
  >> 
#+END_SRC

 *Testing object slicing on assingment by value*

 - Object: slicing => Happens when the an object of derived class is
   assigned to a base class object, the virtual methods overridden in
   the derived class are sliced off from the derived class. As a
   result, any method call performed by the assigned object will call
   the method base version, instead of the method overridden by the
   derived class.
   - Summary: An object loses its polymorphic abilities when assigned
     by value.
 - Note: assignment in C++, is different from assignment in Java and
   other OO languages. In C++, the assignment copies the object from
   right side to the assigned object discarding all previous state
   from the assigned object. In Java and other OO languages, the
   assignment copies the reference (pointer) from the right-hand side
   object to the left-hand side object, thus the assigned object
   becomes an alias or mirror to right-hand side object.

#+BEGIN_SRC cpp 
  >> base = da
   [TRACE] polymorphism1.C:19  Base copy assignment operator invoked.
  (Base &) @0x7f9882578010
  >> 
  // It should print "DerivedA", however due to object slicing, it prints "Base"
  >> base.getType()
  (std::string) "Base"

  >> base.showType()
  Class type = Base
  >> 
  >> 

  >> da.getType()
  (std::string) "DerivedA"
  >> da.showType()
  Class type = DerivedA
#+END_SRC

 *Assignment by pointer*

The solution for avoiding object slicing on assignment is to assign by
pointer instead of assigning by value.

#+BEGIN_SRC cpp 
  >> Base* p = nullptr;

  // Point to object base ------------------------------------
  >> p = &base;
  >> p->getType()
  (std::string) "Base"
  >> p->getType2()
  (std::string) "Base"
  >> p->showType()
  Class type = Base
  >> 

  // Point to object da (class DerivedA)
  //------------------------------------
  >> p = &da;
  >> p->getType()
  (std::string) "DerivedA"
  // Note: overriding doesn't work because getType2() is annotated as virtual· 
  >> p->getType2()
  (std::string) "Base"
  >> p->showType()
  Class type = DerivedA
  >> 

  // Point to object da (class DerivedB)
  //------------------------------------
  >> p = &db;
  >> p->getType()
  (std::string) "DerivedB"
  >> p->getType2()
  (std::string) "Base"
  >> p->showType()
  Class type = DerivedB
  >> 
#+END_SRC

 *Assigning by reference*

Another solution for keeping the polymorphic behavior and avoid object
slicing is using references. 
 + Note: Unlike pointers, references cannot be reassigned once they
   are created. 

#+BEGIN_SRC cpp 
  >> Base& refb = base;

  >> refb.getType()
  (std::string) "Base"

  >> refb.getType2()
  (std::string) "Base"

  >> refb.showType()
  Class type = Base
  >> 

  // Failure: object slicing!
  >> refb = da;
   [TRACE] polymorphism1.C:19  Base copy assignment operator invoked.
  >> 
  >> refb.getType()
  (std::string) "Base"
  >> refb.showType()
  Class type = Base
  >> 

  // Now, it works.
  >> Base& refda = da;
  >> refda.getType()
  (std::string) "DerivedA"
  >> refda.getType()
  (std::string) "DerivedA"
  >> refda.showType()
  Class type = DerivedA
  >> refda.getType2()
  (std::string) "Base"
#+END_SRC

 *Passing by value*

Testing object slicing on passing parameters by value: 
 + Object slicing also happens when objects are passed by value. 

#+BEGIN_SRC cpp 
  void printClassNameValue(Base obj){
       std::cout << "Object type is: " << obj.getType() << "\n";
  }

  >> printClassNameValue(base)
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.
  Object type is: Base
  >> 
  // Should print Object type is: DerivedA 
  >> printClassNameValue(da)
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.
  Object type is: Base
  >> 
  // Should print Object type is: DerivedB 
  >> printClassNameValue(db)
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.
  Object type is: Base
  >> 
#+END_SRC

 *Passing by Pointer*

The solution for avoiding *object slicing* is passing objects by pointer
or reference:

#+BEGIN_SRC cpp
  // Pass by pointer => Object slicling doesn't happen.
  void printClassNamePtr(const Base* obj){
       std::cout << "Object type is: " << obj->getType() << "\n";
  }

  >> printClassNamePtr(&base)
  Object type is: Base

  >> printClassNamePtr(&da)
  Object type is: DerivedA

  >> printClassNamePtr(&db)
  Object type is: DerivedB
  >> 
  >> Base* ptr = nullptr;
  >> ptr = &da;
  >> printClassNamePtr(ptr)
  Object type is: DerivedA
  >> 
  >> ptr = &db;
  >> printClassNamePtr(ptr)
  Object type is: DerivedB
  >> 

#+END_SRC

 *Passing by Reference*

 + Passing by reference
   + Note: In most object oriented languages, objects are passed by
     reference by default, unlike C++ where objects are passed by
     value.

#+BEGIN_SRC cpp 
  void printClassNameRef(const Base& obj){
       std::cout << "Object type is: " << obj.getType() << "\n";
  }

  >> printClassNameRef(base)
  Object type is: Base

  >> printClassNameRef(da)
  Object type is: DerivedA

  >> printClassNameRef(db)
  Object type is: DerivedB
  >> 
#+END_SRC

 *Factory function:*

 + A factory function returns any instance of any derived class of a
   given base class. 

Object slicing also happens when polymorphic types are returned by
value: 

#+BEGIN_SRC cpp 
  // This factory functon will fail due to object slicing 
  Base factoryFunctionValue(const std::string& type){
       if(type == "base")
               return Base();
       if(type == "da")
               return DerivedA();
       if(type == "db")
               return DerivedB();
       throw std::runtime_error("Error: class type not found.");
  }

  >> Base rbase = factoryFunctionValue("base")
  (Base &) @0x7f9882578038
  >> rbase.getType()
  (std::string) "Base"
  >> rbase.showType()
  Class type = Base
  >> 

  >> Base rda = factoryFunctionValue("da")
   [TRACE]/home/archbox/root-scripts/polymorphism1.C:13  Base copy constructor invoked.
  (Base &) @0x7f9882578040

  // Fails! It should return derivedA 
  >> rda.getType()
  (std::string) "Base"
  >> rda.showType()
  Class type = Base
  >> 
#+END_SRC

A workaround to the object slicing problem could be returning by
reference. However, this approach doesn't work because the function
_factoryFunctionRef_ returns a reference to the object p allocated on
the stack, which is destroyed when the function returns, thus any
attempt to use this returned reference to a destroyed object will
result in a segmentation fault.

#+BEGIN_SRC cpp 
   // This factory functon will fail due to object slicing 
  Base& factoryFunctionRef(const std::string& type){
       Base p;
       if(type == "base")
          p = Base();
       else if(type == "da")
          p = DerivedA();
       else if(type == "db")
          p = DerivedB();
       else throw std::runtime_error("Error: class type not found.");
       return p;
  }

  >> Base& retda2 = factoryFunctionRef("da");
   [TRACE]/home/archbox/root-scripts/polymorphism1.C:19  Base copy assignment operator invoked.
  >> retda2.getType()

   ,*** Break *** segmentation violation

#+END_SRC

An alternative approach is to return a pointer an object allocated on
the heap. 

#+BEGIN_SRC cpp 
  Base* factoryFunctionRawPointer(const std::string& type){
        if(type == "base")
           return new Base();
        else if(type == "da")
           return new DerivedA();
        if(type == "db")
           return new DerivedB();
        return nullptr;
  }

  // Instantiate of class Base
  //--------------------------------
  >> Base* ptr_base1 = factoryFunctionRawPointer("base")
  (Base *) 0x2564130
  >> ptr_base1->getType()
  (std::string) "Base"
  >> ptr_base1->getType2()
  (std::string) "Base"
  >> ptr_base1->showType()
  Class type = Base
  >> 
  // 

  // Every heap-allocated object must be disposed when no longer 
  // needed by calling the operator delete. 
  >> delete ptr_base1 ;
  // It is advisable to set the pointer of disposed heap-allocated
  // object to null.
  >> ptr_base1 = nullptr;
  >> 

  // Instantiate of class DerivedA 
  //--------------------------------
  >> Base* ptr_da = factoryFunctionRawPointer("da")
  (Base *) 0x334e4c0

  >> ptr_da->getType()
  (std::string) "DerivedA"

  >> ptr_da->getType2()
  (std::string) "Base"

  >> ptr_da->showType()
  Class type = DerivedA
  >> 

  >> delete ptr_da;
  >> ptr_da = nullptr;
  >> 
#+END_SRC

 *Safer Factory Function with smart pointers*

The factory function factoryFunctionRawPointer is vulnerable to memory
leaks since it returns a raw pointer to a heap-allocated object which
needs to be disposed with the operator delete once the object is no
longer needed. However, it is easy to forget to call delete and to
track all possible return paths and objects needing this pointer. A
solution to this issue is to use smart pointers which are
stack-allocated objects that delete pointed objects when the the they
go out of scope. It is possible to use ~unique_ptr~ which is only
movable and not copiable or ~shared_ptr~ which is copiable.

#+BEGIN_SRC cpp 
  // Requires header: <memory>
  std::unique_ptr<Base> 
  factoryFunctionSafe(const std::string& type){
      if(type == "base")
         return std::make_unique<Base>();
      else if(type == "da")
         return std::make_unique<DerivedA>();
      if(type == "db")
         return std::make_unique<DerivedB>();
      return nullptr;
  }
#+END_SRC

Running: 

#+BEGIN_SRC cpp 
  >> auto uptr_base = factoryFunctionSafe("base");

  >> uptr_base
  (std::unique_ptr<Base, std::default_delete<Base> > &) @0x7f9882578088

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

  >> uptr_base->showType()
  Class type = Base


  >> auto uptr_da = factoryFunctionSafe("da");

  >> uptr_da->getType()
  (std::string) "DerivedA"

  >> uptr_da->getType2()
  (std::string) "Base"

  >> uptr_da->showType()
  Class type = DerivedA
#+END_SRC

 *STL Containers and Polymorphic Types* 

 + Storing by value => Leads to object slicing. 

#+BEGIN_SRC cpp 
  // NOTE: Objects base, da and db are copied to the vector, not stored in the vector.
  >>  std::vector<Base> objlist = {base, da, db};
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.
   [TRACE] polymorphism1.C:13  Base copy constructor invoked.

   >> objlist[0].getType()
   (std::string) "Base"
   // Expected DerivedA 
   >> objlist[1].getType()
   (std::string) "Base"
   // Expected DerivedB
   >> objlist[2].getType()
   (std::string) "Base"
   >> 

   // Objects stored in the vector don't have 
   // the same memory location as the following objects.
   >> &objlist[0] == &base
   (bool) false
   >> &objlist[1] == &da
   (bool) false
   >> &objlist[2] == &db
   (bool) false
   >> 
#+END_SRC
 
 + Storing by Pointer => Object Slicing does not happen. 

#+BEGIN_SRC cpp 
  >> auto objects = std::deque<Base*>{}
  (std::deque<Base *, std::allocator<Base *> > &) {}
  >> objects.push_back(&base)
  >> objects.push_back(&da)
  >> objects.push_back(&db)

  >> for(const auto& e : objects) { std::cout << "type = " << e->getType() << "\n";}
  type = Base
  type = DerivedA
  type = DerivedB
  >> 

  >> 
  >> objects[0]->getType()
  (std::string) "Base"
  >> objects[0]->showType()
  Class type = Base

  >> objects[1]->getType()
  (std::string) "DerivedA"
  >> objects[1]->showType()
  Class type = DerivedA

  >> objects[2]->getType()
  (std::string) "DerivedB"
  >> objects[2]->showType()
  Class type = DerivedB
  >> 
#+END_SRC

 + Storing by Reference (Since C++11 with reference wrapper) => Object
   Slicing does not happen.
   + See: [[https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper][std::reference_wrapper]]
   + Requires: C++11 and header <functional>

#+BEGIN_SRC cpp 
  #include <functional> // Provides: std::reference_wrapper

  // DOES NOT WORK: Ugly, cryptic and verbose  error!! 
  >> std::vector<Base&> objRef;
    18: error: 'pointer' declared as a pointer to a reference of type 'Base &'
         typedef _Tp*       pointer;

  // Header: 
  >> std::vector<std::reference_wrapper<Base>> objRef;
  >> auto objRefList = std::vector<std::reference_wrapper<Base>>{};

  >> objRefList.push_back(base)
  >> objRefList.push_back(da)
  >> objRefList.push_back(db)

  >> objRefList[0].get()
  (Base &) @0x7f3604aa6010

  >> objRefList[0].get().getType()
  (std::string) "Base"

  >> objRefList[1].get().getType()
  (std::string) "DerivedA"

  >> objRefList[2].get().getType()
  (std::string) "DerivedB"
  >> 

  >> for(const auto& p: objRefList){ std::cout << "type = " << p.get().getType() << "\n";}
  type = Base
  type = DerivedA
  type = DerivedB
  >> 

  // Check whether objects stored in the vector were not copied.
  >> &objRefList[0].get() == &base
  (bool) true
  >> &objRefList[1].get() == &da
  (bool) true
  >> &objRefList[2].get() == &db
  (bool) true
  >> 
#+END_SRC

 + Storing objects heap-allocated objects (aka free store or dynamic memory)
   * Requires: C++11 + header <memory> which provides smart pointers.
   * See: [[http://www.cplusplus.com/reference/memory/][<memory>]]
   * In order to avoid memory leaks, it is better to store
     heap-allocated objects in STL containers using smart pointers as
     they delete the allocated objects when out of scope or an
     exception happens (RAII). If raw pointers were used, the heap
     allocated-objects would not be disposed automatically without the
     _delete_ operator, as a result, a memory leak could happen.
   * Note: this example assumes single ownership of the allocated
     objects, in other words, only the container is responsible for
     deleting the objects. So, shared_ptr is a better option when
     multiple ownership is required, 

#+BEGIN_SRC cpp 
  #include <functional>
  #include <memory>
  // Custom deleter type alias 
  using Deleter = std::function<void (Base*)>;

  // Type synonym for unique_ptr which manages objects 
  // from class Base and its classes.
  //-----------------------------------
  // To use without the custom delter: 
  // using Ubase = std::unique_ptr<Base>;
  using Ubase = std::unique_ptr<Base, Deleter>;

  // Custom deleter used for logging 
  // and demonstrate what the smart pointer does.
  auto deleter = [](Base* b){
    std::cerr << " [TRACE] Deleted  object of type = " << b->getType() << "\n";
    delete b;
  };

  auto xlist = std::deque<Ubase>{};
  xlist.emplace_back(new Base, deleter)
  xlist.emplace_back(new DerivedA, deleter)
  xlist.emplace_back(new DerivedB, deleter)

  >> xlist[0]->getType()
  (std::string) "Base"

  >> xlist[1]->getType()
  (std::string) "DerivedA"

  >> xlist[2]->getType()
  (std::string) "DerivedB"
  >> 

  >> for(int i = 0; i < xlist.size(); i++) { std::cout << "type = " << xlist[i]->getType() << "\n";}
  type = Base
  type = DerivedA
  type = DerivedB
  >> 

  >> xlist.clear()
   [TRACE] Deleted  object of type = Base
   [TRACE] Deleted  object of type = DerivedA
   [TRACE] Deleted  object of type = DerivedB
  >> 

  >> xlist.size()
  (unsigned long) 0
  >> 
#+END_SRC

 *Summary:* 

 + An object loses its polymorphic abilities if assigned by value,
   passed by value or returned by value. It is called *object slicing*.

 + Polymorphic types cannot be stored by value in STL containers due
   to object slicing. The only way to store them is by pointer or
   reference. 

 + In C++, polymorphism only works when objects are assigned by
   pointer or reference or when passed by pointer or reference.
   + *Polymorphism (dynamic) only works with references or pointers.*

 + Methods, aka member functions not annotated as virtual cannot be
   overridden by derived classes.

 + The only way to return polymorphic objects from functions is to
   return pointers (prone to memory leaks) or smart-pointers (safer)
   to heap-allocated objects.
*** Dynamic Polymorphism example - code 

 File: polymorphism.cpp 

 #+BEGIN_SRC cpp 
   #include <iostream>
   #include <string>
   #include <memory>   // C++11 Smart pointers (unique_ptr and shared_ptr)
   #include <map>      // Hash table, hash map or dictionary
   #include <vector>
   #include <deque>

   #include <cassert> // assertions tests 

   // Interface class 
   class GenericDBDriver{
   public:
     GenericDBDriver() = default;
     virtual auto driverName()  const -> std::string {
       return "generic";   
     }
     virtual auto getID() const -> std::string {
       return "unknown";
     }
     virtual auto connect(std::string url) -> void {
       std::cout << "Connecting to generic driver url = " << url << std::endl;
     }
     virtual auto isConnected()  const -> bool {
       return false;
     }
     // Default destructor
     virtual ~GenericDBDriver() {
       std::cout << "Disconnecting from generic driver - id = " << "unknown"<< std::endl;
     }
   };

   class DriverSQLiteDriver: public GenericDBDriver{
   private:
     bool m_connected = false;
     std::string m_id = "unknown";
   public:
     DriverSQLiteDriver() = default;
     DriverSQLiteDriver(const std::string& name): m_id(name){}
    
     // Const keyword in this case indicates that the member function (method)
     // doesn't change the current object.
     auto driverName() const -> std::string override{
       return "sqlite";
     }
     auto getID() const -> std::string override {
       return m_id;
     }  
     // This keyword override -> indicates visually that the method
     // is being overriden and also provides some safety features which
     // helps to improve type-safety and compile-time correctness.
     // For instance, if member function (aka method) being overriden
     // is not annotated as virtual in the base class, this C++11 keyword
     // will generate a compile-time error. It also will generate a compile-time
     // error if the member function being overriden doesn't exist in the base class.  
     auto connect(std::string url) -> void override {
       std::cout << "Connecting to " << url << std::endl;
       m_connected = true;
     }
     auto isConnected() const -> bool override {
       return m_connected;
     }
     ~DriverSQLiteDriver(){
       std::cout << "Disconnecting from PosgresDB - m_id = " << m_id << std::endl;
     }
   };


   class DriverPostgresSQL: public GenericDBDriver{
   private:
     bool m_connected = false;
     std::string m_id = "unknown";  
   public:
     // DriverPostgresSQL () = default;
     DriverPostgresSQL(const std::string& name): m_id(name){}
 
     auto driverName() const -> std::string override{
       return "PostGresSQL";
     }
     virtual auto getID() const -> std::string override {
       return m_id;
     }   
     auto connect(std::string url) -> void override {
       std::cout << "Connecting to " << url << std::endl;
       m_connected = true;
     }
     auto isConnected() const -> bool override {
       return m_connected;
     }
     ~DriverPostgresSQL(){
       std::cout << "Disconnecting from PostGresSQL - id = " << m_id << std::endl;
     }  
   };


   class DriverSQLServer : public GenericDBDriver{
   private:
     bool m_connected = false;
     std::string m_id = "unknown";  
   public:
     DriverSQLServer() = default;
     DriverSQLServer(const std::string& name): m_id(name){}
      
     auto driverName() const -> std::string override{
       return "SQLServer";
     }
     auto getID() const -> std::string override {
       return m_id;
     }    
     auto connect(std::string url) -> void override {
       std::cout << "Connecting to " << url << std::endl;
       m_connected = true;
     }
     auto isConnected() const -> bool override {
       return m_connected;
     }
     ~DriverSQLServer(){
       std::cout << "Disconnecting from SQLServer - id = " << m_id << std::endl;
     }  
   };


   // Non-polymorphi function -> Parameters passed by value cannot be polymorphic
   // void showDriverStatus(const GenericDBDriver driver){ ... }

   // Polymorphic function using references 
   void showDriverStatus1(const GenericDBDriver& driver){
     std::cout << std::boolalpha;
     std::cout << " [INFO] Driver = " << driver.driverName()
               << " id = " << driver.getID()
               << " ; status = " << driver.isConnected() <<  std::endl;
   }

   // Polymorphic function using pointers 
   void showDriverStatus2(const GenericDBDriver* driver){
     std::cout << std::boolalpha;
     std::cout << " [INFO] Driver = " << driver->driverName()
               << " id = " << driver->getID()
               << " ; status = " << driver->isConnected() <<  std::endl;
   }


   // Factory method
   enum class DriverType{
    generic,
    sqlite,
    postgres,
    sqlserver                        
   };

   auto dbDriverFactory(const DriverType& dbtype, const std::string& id = "unknown")
     -> std::shared_ptr<GenericDBDriver>{
     if(dbtype == DriverType::generic)
       return std::make_shared<GenericDBDriver>();   
     if(dbtype == DriverType::sqlite)
       return std::make_shared<DriverSQLiteDriver>(id);   
     if(dbtype == DriverType::postgres)
       return std::make_shared<DriverPostgresSQL>(id);   
     if(dbtype == DriverType::sqlserver)
       return std::make_shared<DriverSQLServer>(id);    
     // Failure -> DO NOT return old C++98 NULL as it is not typesafe 
     return nullptr;
   }


   class DriverFactory{
   private:
  
   public:

     DriverFactory() = delete;
     DriverFactory(const DriverFactory& lhs) = delete;

     static auto getInstance() 
   };

   int main(){

     {
       std::cout << "\n====== Test 1 ===========" << std::endl;
       // Uniform initialization 
       GenericDBDriver   d0;
       DriverSQLServer   d1{"d1"};
       DriverPostgresSQL d2 = {"d2"};
       DriverSQLServer   d3 = {"d3"};

       showDriverStatus1(d0);
       showDriverStatus1(d1);
       d1.connect("file:///home/user/datbase.sqlite");
       showDriverStatus1(d1);
       showDriverStatus1(d2);
       showDriverStatus1(d3);

       std::cout << "====== End of test 1 ===========" << std::endl;
     }

     {
       std::cout << "\n====== Test 2 ===========" << std::endl;
       // Uniform initialization 
       GenericDBDriver   d0;
       DriverSQLServer   d1{"d1"};
       DriverPostgresSQL d2 = {"d2"};
       DriverSQLServer   d3 = {"d3"};

       showDriverStatus2(&d0);
       showDriverStatus2(&d1);
       d1.connect("file:///home/user/datbase.sqlite");
       showDriverStatus2(&d1);
       showDriverStatus2(&d2);
       showDriverStatus2(&d3);

       std::cout << "====== End of test 2 ===========" << std::endl;
     }

     { // Failure ! -> It only calls the methods of GenericDBDriver
       // It is not possible to polymorphism (subtyping polymorphism) in C++
       // without pointers or references.
       std::cout << "\n====== Test 3 ===========" << std::endl;
       std::deque<GenericDBDriver> xs;

       xs.push_back(GenericDBDriver{});
       xs.push_back(DriverSQLServer {"d1"});
       xs.push_back(DriverPostgresSQL{"d2"});
       xs.push_back(DriverSQLServer{"d3"});

       for(const auto& x: xs){
         std::cout << " - driver = " << x.driverName() << " ; id = " << x.getID() << std::endl;
       }

       assert(xs.at(0).driverName() == "generic");
       assert(xs.at(1).driverName() == "generic");
       assert(xs.at(2).driverName() == "generic");
       assert(xs.at(3).driverName() == "generic");
    
       std::cout << "\n====== End of test 3 ===========" << std::endl;
     }


     { std::cout << "\n====== Test 4 ===========" << std::endl;
       std::deque<GenericDBDriver*> xs;

       auto d0 = GenericDBDriver{};
       auto d1 = DriverSQLiteDriver {"d1"};
       auto d2 = DriverPostgresSQL{"d2"};
       auto d3 = DriverSQLServer{"d3"};
       xs.push_back(&d0);
       xs.push_back(&d1);
       xs.push_back(&d2);
       xs.push_back(&d3);

       for(const auto& x: xs){
         std::cout << " - driver = " << x->driverName() << " ; id = " << x->getID() << std::endl;;
       }
       assert(xs.at(0)->driverName() == "generic");
       assert(xs.at(1)->driverName() == "sqlite");
       assert(xs.at(2)->driverName() == "PostGresSQL");
       assert(xs.at(3)->driverName() == "SQLServer");
    
       std::cout << "====== End of test 4 ===========" << std::endl;
     }  

     { std::cout << "\n====== Test 5 ===========" << std::endl;
       std::deque<std::shared_ptr<GenericDBDriver>> xs;
       xs.push_back(dbDriverFactory(DriverType::generic));
       xs.push_back(dbDriverFactory(DriverType::sqlite,    "d1"));
       xs.push_back(dbDriverFactory(DriverType::postgres,  "d2"));
       xs.push_back(dbDriverFactory(DriverType::sqlserver, "d3"));
       for(const auto& x: xs){
         std::cout << " - driver = " << x->driverName() << " ; id = " << x->getID() << std::endl;;
       }
       assert(xs.at(0)->driverName() == "generic");
       assert(xs.at(1)->driverName() == "sqlite");
       assert(xs.at(2)->driverName() == "PostGresSQL");
       assert(xs.at(3)->driverName() == "SQLServer");
    
       std::cout << "====== End of test 5 ===========" << std::endl;
     }  
     return EXIT_SUCCESS;
   }
 #+END_SRC

 Running: 

 #+BEGIN_SRC sh
   $ clang++ polymorphism.cpp -std=c++1z -Wall -Wextra && ./a.out

   ====== Test 1 ===========
    [INFO] Driver = generic id = unknown ; status = false
    [INFO] Driver = SQLServer id = d1 ; status = false
   Connecting to file:///home/user/datbase.sqlite
    [INFO] Driver = SQLServer id = d1 ; status = true
    [INFO] Driver = PostGresSQL id = d2 ; status = false
    [INFO] Driver = SQLServer id = d3 ; status = false
   ====== End of test 1 ===========
   Disconnecting from SQLServer - id = d3
   Disconnecting from generic driver - id = unknown
   Disconnecting from PostGresSQL - id = d2
   Disconnecting from generic driver - id = unknown
   Disconnecting from SQLServer - id = d1
   Disconnecting from generic driver - id = unknown
   Disconnecting from generic driver - id = unknown

   ====== Test 2 ===========
    [INFO] Driver = generic id = unknown ; status = false
    [INFO] Driver = SQLServer id = d1 ; status = false
   Connecting to file:///home/user/datbase.sqlite
    [INFO] Driver = SQLServer id = d1 ; status = true
    [INFO] Driver = PostGresSQL id = d2 ; status = false
    [INFO] Driver = SQLServer id = d3 ; status = false
   ====== End of test 2 ===========
   Disconnecting from SQLServer - id = d3
   Disconnecting from generic driver - id = unknown
   Disconnecting from PostGresSQL - id = d2
   Disconnecting from generic driver - id = unknown
   Disconnecting from SQLServer - id = d1
   Disconnecting from generic driver - id = unknown
   Disconnecting from generic driver - id = unknown

   ====== Test 3 ===========
   Disconnecting from generic driver - id = unknown
   Disconnecting from SQLServer - id = d1
   Disconnecting from generic driver - id = unknown
   Disconnecting from PostGresSQL - id = d2
   Disconnecting from generic driver - id = unknown
   Disconnecting from SQLServer - id = d3
   Disconnecting from generic driver - id = unknown
    - driver = generic ; id = unknown
    - driver = generic ; id = unknown
    - driver = generic ; id = unknown
    - driver = generic ; id = unknown

   ====== End of test 3 ===========
   Disconnecting from generic driver - id = unknown
   Disconnecting from generic driver - id = unknown
   Disconnecting from generic driver - id = unknown
   Disconnecting from generic driver - id = unknown

   ====== Test 4 ===========
    - driver = generic ; id = unknown
    - driver = sqlite ; id = d1
    - driver = PostGresSQL ; id = d2
    - driver = SQLServer ; id = d3
   ====== End of test 4 ===========
   Disconnecting from SQLServer - id = d3
   Disconnecting from generic driver - id = unknown
   Disconnecting from PostGresSQL - id = d2
   Disconnecting from generic driver - id = unknown
   Disconnecting from PosgresDB - m_id = d1
   Disconnecting from generic driver - id = unknown
   Disconnecting from generic driver - id = unknown

   ====== Test 5 ===========
    - driver = generic ; id = unknown
    - driver = sqlite ; id = d1
    - driver = PostGresSQL ; id = d2
    - driver = SQLServer ; id = d3
   ====== End of test 5 ===========
   Disconnecting from generic driver - id = unknown
   Disconnecting from PosgresDB - m_id = d1
   Disconnecting from generic driver - id = unknown
   Disconnecting from PostGresSQL - id = d2
   Disconnecting from generic driver - id = unknown
   Disconnecting from SQLServer - id = d3
   Disconnecting from generic driver - id = unknown

 #+END_SRC

*** STL containers and polymorphism 

C++'s STL (Standard Template Library) containers/collections such as
vector, deque, map, stack and so on can only store pointers to
instances of different derived classes from a given base
class. However the STL containers cannot store references to those
instances. The STL std::reference_wrapper solves this problem. 

Documentation: 
  + http://www.cplusplus.com/reference/functional/reference_wrapper/operator_func/

Demonstration in CERN's ROOT C++ REPL: 

 - Create test classes.

#+BEGIN_SRC cpp 
  // Base class 
  class IRoot{
  public:
    virtual auto getName() const -> std::string {
      return "root";
    }
  };

  //===== Derived Classes ====== //
 
  class A: public IRoot{
  public:
    auto getName() const -> std::string {
      return "Class A";
    }
  };

  class B: public IRoot{
  public:
    auto getName() const -> std::string {
      return "Class B";
    }
  };
#+END_SRC

 - Play with sample objects:

#+BEGIN_SRC cpp 
  // Create test objects 
  auto r = IRoot();
  auto a = A();
  auto b = B();

  // Test objects 
  >> r.getName()
  (std::string) "root"
  >> a.getName()
  (std::string) "Class A"
  >> b.getName()
  (std::string) "Class B"
  >>
#+END_SRC

 - Store those objects in a collection by pointer:

#+BEGIN_SRC cpp 
  >> auto xsp = std::deque<IRoot*>()
  (std::deque<IRoot *, std::allocator<IRoot *> > &) {}
  >> xsp.push_back(&r)
  >> xsp.push_back(&a)
  >> xsp.push_back(&b)
  >> xsp
  (std::deque<IRoot *, std::allocator<IRoot *> > &) { @0x2f01990, @0x2f01998, @0x2f019a0 }
  >>
  >>

  >> for(auto x: xsp) { std::cout << "name = " << x->getName() << std::endl; }
  name = root
  name = Class A
  name = Class B
  >>

#+END_SRC

 - Try to store those object r, a and b in a container/collection by
   reference.

#+BEGIN_SRC cpp 
  /** Many of errors: new_allocator.h:63:18: error: 'pointer' declared
   ,* as a pointer to a reference of type 'IRoot &' typedef _Tp* pointer;
   ,*/
  auto xs = std::deque<IRoot&>() 
#+END_SRC

 - Try to store those object r, a and b in a container/collection by
   reference using _std::reference_wrapper_.

#+BEGIN_SRC cpp 
  >> auto xsr = std::deque<std::reference_wrapper<IRoot>> {}
  (std::deque<std::reference_wrapper<IRoot>, std::allocator<std::reference_wrapper<IRoot> > > &) {}
  >>

  xsr.push_back(a)
  xsr.push_back(r)
  xsr.push_back(b)

  >> xsr
  (std::deque<std::reference_wrapper<IRoot>, std::allocator<std::reference_wrapper<IRoot> > > &)
  { @0x31013c0, @0x31013c8, @0x31013d0 }
  >>

  >> xsr.at(0).get().getName()
  (std::string) "Class A"
  >> xsr.at(1).get().getName()
  (std::string) "root"
  >> xsr.at(2).get().getName()
  (std::string) "Class B"
  >> 
  >>

  >> for(auto x: xsr) { std::cout << "name = " << x.get().getName() << std::endl; }
  name = Class A
  name = root
  name = Class B
  >> 

  >> for(const auto& x: xsr) { std::cout << "name = " << x.get().getName() << std::endl; }
  name = Class A
  name = root
  name = Class B
  >> 
#+END_SRC

References: 

 + https://oopscenities.net/2012/08/09/reference_wrapper/

 + How to correctly use std::reference_wrappers -
   <https://stackoverflow.com/questions/18127469/how-to-correctly-use-stdreference-wrappers>
** OOP Operator Overloading
*** Overview  

Operator overloads allows defining common primitives types operations
for user defined types such as classes. Seom types of operators are arithmentic
operators (+, *, /), comparison operators ( ~==~, !=, <, >, <=, >=),
assignment +=, *=, /=, and so on.

Types of operator overloading: 

 * Member function operator overloading.
   + The operator such as +, *, / or == is a class method, the left
     hand-side of a binary operator is the current object passed as
     implicit argument and the right-hand-side is the operator
     argument.

 * Free function operator overloading (a non member function, non method):
   + _Non-friend function operator overloading_ - The operator is
     defined as a free function, just as an ordinary function without
     access to class private data. There is no implicit argument, both
     left-hand-side and right-hand-side are function arguments.

   + _Friend function Operator overloading_ - The operator is defined as
     a free function (non member function or non method) and has
     access to class private data and private member functions.

Operators that cannot be overloaded: 

 + (.) Object.member() - Member access operator
 + (?) Ternary operator
 + (::) Escope Resolution operator 

Operator properties: 

 + Precedency
 + Associativity
 + Arity - number of operands (operator arguments)
   + Unary Operators:  -Object, !Object, ... 
   + Binary Operators: (+), (=), (*), ...
 + Types of operators:
   + Arithmetic: +, /, *, 
   + Logical: &&, || 
   + Assignment: =, ~+=~, ~*=~, ..
   + Bitwise: &, |, ^ ... 
   + Function-call:
     + Object(10), Object.operator()(10) .. 
   + Increment/Decrement: Object++, --Object ... 
   + Pointer
     + Array index,  ([]), Object[10]
     + Deference operator  (*), *Object 
     + Address-of operator (&), &Object

*** Example: Arithmetic member function operator overloading  

Source:
 + File: [[file:src/operator-overload1.cpp][file:src/operator-overload1.cpp]]
 + Online compiler: https://rextester.com/QVFZX23695

Class Complex declaration (file: Complex.hpp):

#+BEGIN_SRC cpp 
  /** Complex number */
  class Complex{
  private:
       double m_real, m_imag;
  public:
       /** Make class printable */
       friend std::ostream& operator<<(std::ostream&, const Complex&);	

       /** Constructors */
       Complex();
       Complex(double real, double imag);
       /** Named constructor */
       static Complex fromReal(double real);
       static Complex fromImag(double imag);

       double Real() const;
       double Imag() const;

       Complex operator-();
       Complex operator+(const Complex& rhs);
       Complex operator-(const Complex& rhs);
       Complex operator*(const Complex& rhs);
       Complex operator/(const Complex& rhs);

       Complex operator+(double d);
       Complex operator-(double d);
       Complex operator*(double scale);
       Complex operator/(double factor);
  };
#+END_SRC

Class Complex implementation (file: Complex.cpp):

 + Arithmetic operator overloading definitions for Complex as operator
   explicit argument:

#+BEGIN_SRC cpp 
  Complex Complex::operator-(){
       return {-m_real, -m_imag};
  }

  Complex Complex::operator+(const Complex& rhs)
  {
       const auto& self = *this;
       return {self.m_real + rhs.m_real, self.m_imag + rhs.m_imag };
  }

  Complex Complex::operator-(const Complex& rhs)
  {
       const auto& self = *this;
       // (x1 + j . y1)(x2 + j . y2) = x1.x2 + j( -y1.y2 )
       return Complex{self.m_real - rhs.m_real, self.m_imag - rhs.m_imag };
  }

 Complex Complex::operator*(const Complex& rhs)
  {
      return Complex{
          m_real * rhs.m_real - m_imag * rhs.m_imag,
          m_real * rhs.m_imag + m_imag * rhs.m_real
                  };
  }
#+END_SRC

 + Arithmetic operator overloading definitions for double as explicit
   argument. 

#+BEGIN_SRC cpp 
  Complex Complex::operator+(double d){
       return Complex{m_real + d, m_imag + d};
  }
  Complex Complex::operator-(double d){
       return Complex{m_real - d, m_imag - d};
  }
  Complex Complex::operator*(double scale){
       return {this->m_real * scale, this->m_imag *  scale};
  }
  Complex Complex::operator/(double factor){
       return Complex(this->m_real / factor, this->m_imag / factor);
  }
#+END_SRC

 *Test in CERN's ROOT REPL:*

Load file and instantiate some variables:

#+BEGIN_SRC cpp 
  >> .L operator-overload1.cpp 

  >> Complex c1;

  >> Complex c2{2, 5}
  (Complex &) @0x7f4088144020

  >> Complex c3{3, 4}
  (Complex &) @0x7f4088144030
#+END_SRC

Test operators: 

#+BEGIN_SRC cpp 
  >> std::cout << "c1 + c2 + c3 = " << (c1 + c2 + c3) << std::endl;
  c1 + c2 + c3 = Complex{ 5 + 9j }

  >> std::cout << c2 + c3 << std::endl;
  Complex{ 5 + 9j }

  >> std::cout << c3 + c2 << std::endl;
  Complex{ 5 + 9j }
#+END_SRC

Call operator explicitly:

 * c2 + c3 = c2.operator+()(c3)
 * c3 + c2 = c3.operator+()(c2)

#+BEGIN_SRC cpp 
  // c2 + c3 = c2.operator+(c3) 
  >> std::cout << c2.operator+(c3) << std::endl;
  Complex{ 5 + 9j }

  // c3 + c2 = c2.operator+(c3)
  >> std::cout << c3.operator+(c2) << std::endl;
  Complex{ 5 + 9j }
#+END_SRC

Member function operator overloading is not symmetric:
 + c2 + 10 = c2.operator+(10) => OK.
 + 10 + c2 = 10.operator+(c2) ?? => Compile-time ERROR!

#+BEGIN_SRC cpp 
  >> std::cout << "c2 + 10 = " << c2 + 10 << std::endl;
  c2 + 10 = Complex{ 12 + 15j }
  >> 

  // ERROR!!!
  > std::cout << "10 + c2 = " << 10 + c2 << std::endl;
  ROOT_prompt_17:1:33: error: invalid operands to binary expression ('int' and 'Complex')
  std::cout << "10 + c2 = " << 10 + c2 << std::endl;
                               ~~ ^ ~~
  /home/archbox/opt/root/include/TString.h:531:1: note: candidate function not viable: no known conversion from 'Complex' to
        'const TString' for 2nd argument
  operator+(T i, const TString &s)
  ^
#+END_SRC

*** Example: Arithmetic free-function function operator overloading

Operators can also be defined as ordinary functions (aka free
functions), or non-member and non-friend function, it means without
access to private members.

Source:
 + File: [[file:src/operator-overload2.cpp][file:src/operator-overload2.cpp]]
 + Online Compiler: https://rextester.com/UBME18391

Syntax for non-friend free-function operator overloading: 

 + Unary operator 

#+BEGIN_SRC cpp
   RETURN_TYPE operator <<UNARY-OPERATOR>>(const LSH& lhs);
   // Or, C++11 syntax 
   auto operator <<UNARY-OPERATOR>>(const LSH& lhs) -> RETURN_TYPE;

   // Example: Invert vector 
   Vector3D operator-(const Vector3D& lhs);
   auto operator-(const Vector3D& lhs) -> Vector3D;
#+END_SRC

 + Binary operator 

#+BEGIN_SRC cpp 
   RETURN_TYPE operator <<BINARY-OPERATOR>>(const LSH& lhs, const RHS& rhs);
   // Or, C++11 flavor: 
   auto operator <<BINARY-OPERATOR>>(const LSH& lhs, const RHS& rhs) -> RETURN_TYPE;

   // Example: 
   Vector3D operator+(const Vector3D& lhs, double rhs);
   auto operator+(const Vector3D& lhs, double rhs) -> Vector3D;
#+END_SRC


Declaration (It should be Vector2D.hpp)

#+BEGIN_SRC cpp 
  /** A struct is just a class with everything public by default. */
  struct Vector2D{
      double x, y;
      Vector2D();
      Vector2D(double x, double y);
  };

  std::ostream& operator<<(std::ostream& os, const Vector2D& vec);
  Vector2D operator+ (const Vector2D& lhs, const Vector2D& rhs);

  /** C++11 Notation */
  auto operator- (Vector2D const& lhs, Vector2D const& rhs) -> Vector2D;
  auto operator-(const Vector2D& lhs) -> Vector2D;

  Vector2D operator*(double k, const Vector2D& rhs);
  Vector2D operator*(const Vector2D& rhs, double k);

  auto operator/(const Vector2D& lhs, double k) -> Vector2D;
#+END_SRC

Implementation (It should be Vector2D.cpp)

 + Constructors:

#+BEGIN_SRC cpp 
  Vector2D::Vector2D(): x(0.0), y(0.0)
  {
  }

  Vector2D::Vector2D(double x, double y): x(x), y(y)
  {
  }
#+END_SRC

 + Operators as free-functions:

#+BEGIN_SRC cpp 
  std::ostream& operator<<(std::ostream& os, const Vector2D& vec)
  {
      return os << "Vector2D{ x = " << vec.x << " ; "
                << " y = " << vec.y << " } ";
  }

  Vector2D operator+ (const Vector2D& lhs, const Vector2D& rhs)
  {
      return Vector2D(lhs.x + rhs.x, lhs.y + rhs.y);
  }

  auto operator- (Vector2D const& lhs, Vector2D const& rhs) -> Vector2D
  {
      return Vector2D(lhs.x - rhs.x, lhs.y - rhs.y);
  }
    ... .... ... ... 

  // Symmetric operator 

  Vector2D operator*(const Vector2D& rhs, double k)
  {
      return {k * rhs.x, k * rhs.y};
  }

  auto operator/(const Vector2D& lhs, double k) -> Vector2D
  {
     return {lhs.x / k, lhs.y / k};
  }
#+END_SRC

 *REPL Test:*

Load file in the CERN's ROOT REPL.

#+BEGIN_SRC cpp 
  >> .L operator-overload2.cpp

  >> Vector2D v1{3, 5};
  >> Vector2D v2{5, 6};

  >> std::cout << "v1 = " << v1 << std::endl;
  v1 = Vector2D{ x = 3 ;  y = 5 } 
  >> std::cout << "v2 = " << v2 << std::endl;
  v2 = Vector2D{ x = 5 ;  y = 6 } 
#+END_SRC

Test operator overloading:

#+BEGIN_SRC cpp 
  >> auto v = v1 + v2
  (Vector2D &) @0x7fb99c26d030

  >> v.x
  (double) 8.0000000

  >> v.y
  (double) 11.000000

  >> std::cout << "v1 + v2 = " << v << std::endl;
  v1 + v2 = Vector2D{ x = 8 ;  y = 11 } 
#+END_SRC

Test symmetry:

#+BEGIN_SRC cpp 
>> std::cout << " v1 * 5 = " << v1 * 5 << std::endl;
 v1 * 5 = Vector2D{ x = 15 ;  y = 25 } 

>> std::cout << " 5 * v1 = " <<  5 * v1 << std::endl;
 5 * v1 = Vector2D{ x = 15 ;  y = 25 } 
#+END_SRC

Explicitly calling operator function: 

#+BEGIN_SRC cpp 
  >> std::cout << " v1 * 5 = " <<  operator*(v1, 5) << std::endl;
   v1 * 5 = Vector2D{ x = 15 ;  y = 25 } 

  >> std::cout << " 5 * v1 = " <<  operator*(5, v1) << std::endl;
   5 * v1 = Vector2D{ x = 15 ;  y = 25 } 

  >> std::cout << " v1 + v2 = " <<  v1 + v2 << std::endl;
   v1 + v2 = Vector2D{ x = 8 ;  y = 11 } 

  >> std::cout << " v1 + v2 = " << operator+(v1, v2) << std::endl;
   v1 + v2 = Vector2D{ x = 8 ;  y = 11 } 
#+END_SRC

*** Example: Arithmetic friend function operator overloading 

Operators can also be defined as class friend-functions, in this case
the opertor is just a ordinary function, however with access to class
privage member variable and memebr functions.

Source: 
 + File: [[file:src/operator-overloading3.cpp][file:src/operator-overloading3.cpp]]
 + Online Compiler: https://rextester.com/ABWWL87635

Class declaration: (It should be in header file Vector2D.hpp)

#+BEGIN_SRC cpp 
  class Vector2D{
  private:
     double m_x, m_y;
  public:
     Vector2D();
     Vector2D(double x, double y);
     double X() const;
     double Y() const;	
     friend std::ostream& operator<<(std::ostream& os, const Vector2D& vec);
     friend Vector2D operator+ (const Vector2D& lhs, const Vector2D& rhs);

     /** C++11 Notation */
     friend auto operator- (Vector2D const& lhs, Vector2D const& rhs) -> Vector2D;
     friend auto operator-(const Vector2D& lhs) -> Vector2D;

     friend Vector2D operator*(double k, const Vector2D& rhs);
     friend Vector2D operator*(const Vector2D& rhs, double k);
     friend auto operator/(const Vector2D& lhs, double k) -> Vector2D;
  };
#+END_SRC

Class implementation: (It should be in header file Vector2D.cpp)

 + Constructors and member functions:

#+BEGIN_SRC cpp 
  Vector2D::Vector2D(): m_x(0.0), m_y(0.0)
  {
  }

  Vector2D::Vector2D(double x, double y): m_x(x), m_y(y)
  {
  }
  double Vector2D::X() const {
      return this->m_x;
  }

  double Vector2D::Y() const {
      return this->m_y;
  }
#+END_SRC


 + Some class operators functions:
   + Note: They are not member functions (methods).

#+BEGIN_SRC cpp 
  std::ostream& operator<<(std::ostream& os, const Vector2D& vec)
  {
       return os << "Vector2D{ x = " << vec.m_x << " ; "
                 << " y = " << vec.m_y << " } ";
  }

  Vector2D operator+ (const Vector2D& lhs, const Vector2D& rhs)
  {
       return Vector2D(lhs.m_x + rhs.m_x, lhs.m_y + rhs.m_y);
  }

  auto operator- (Vector2D const& lhs, Vector2D const& rhs) -> Vector2D
  {
       return Vector2D(lhs.m_x - rhs.m_x, lhs.m_y - rhs.m_y);
  }

      . .. ... ... .. 

  Vector2D operator*(double k, const Vector2D& rhs)
  {
       return {k * rhs.m_x, k * rhs.m_y};
  }

  Vector2D operator*(const Vector2D& rhs, double k)
  {
       return {k * rhs.m_x, k * rhs.m_y};
  }
#+END_SRC

REPL Testing: 

#+BEGIN_SRC cpp 
  >> .L operator-overloading3.cpp 

  >> Vector2D v1{3, 5};
  >> v1.X()
  (double) 3.0000000

  >> v1.Y()
  (double) 5.0000000

  >> (v1 * 4).X()
  (double) 12.000000

  >> (v1 * 4).Y()
  (double) 20.000000

  >> Vector2D v2{5, 6}
  (Vector2D &) @0x7f181a05b020

  >> v = v1 + v2
  (Vector2D &) @0x7f181a05b030

  >> v.X()
  (double) 8.0000000

  >> v.Y()
  (double) 11.000000
#+END_SRC

*** Example: Insertion << and extraction >> operator overload 

Moved to: [[file:STL_Input_and_output.org][STL IO - Input and Output]] advanced IO.

*** Member function operator overloading reference card 

Member functions operators are binary or unary class methods and the
left hand-side of a binary operator is its implicit argument.

 *Arithmetic Operators* 

#+CAPTION: Arithmetic member function operator overloading
| Name           | Operator  | Member function signature      |
|                |           | for class C and RHS type R     |
|----------------+-----------+--------------------------------|
| Addition       | LHS + RHS | C C::operator+(const RHS& rhs) |
| Subtraction    | LHS - RHS | C C::operator-(const RHS& rhs) |
| Multiplication | LHS * RHS | C C::operator*(const RHS& rhs) |
| Division       | LSH / RHS | C C::operator/(const RHS& rhs) |
| Remainder      | LSH % RHS | C C::operator%(const RHS& rhs) |
|----------------+-----------+--------------------------------|


 + C: Class that the operator belongs to. 
 + LHS - Left-hand-side type (Implicit argument current object of class C.)
 + RHS - Right-hand-side type or class (a class is also a type)

 *Comparison Operators*

#+CAPTION: Comparison member function operator overloading
| Name                  | Operator   | Member function signature          |
|                       |            | for class C and RHS type R         |
|-----------------------+------------+------------------------------------|
| Equal                 | LHS == RHS | bool C::operator==(const RHS& rhs) |
| Not equal             | LHS != RHS | bool C::operator-(const RHS& rhs)  |
| Greater than          | LHS >  RHS | bool C::operator>(const RHS& rhs)  |
| Greater or equal than | LHS >= RHS | bool C::operator>=(const RHS& rhs) |
| Less than             | LHS <  RHS | bool C::operator<(const RHS& rhs)  |
| Less or equal than    | LHS <= RHS | bool C::operator<=(const RHS& rhs) |
|-----------------------+------------+------------------------------------|


 *Prefix/Postfix - Increment / Decrement*

#+CAPTION: Increment and decrement operator overloading.
| Name              | Operator | Expansion           | Member function signature |
|-------------------+----------+---------------------+---------------------------|
| Prefix increment  | ++Object | Object = Object + 1 | C& C::operator++()        |
| Postfix increment | Object++ | Object = Object + 1 | C  C::operator++(int)     |
|                   |          |                     |                           |
| Prefix decrement  | --Object | Object = Object - 1 | C&  C::operator--()       |
| Postfix decrement | Object-- | Object = Object - 1 | C   C::operator--(int)    |
|-------------------+----------+---------------------+---------------------------|


 + Note: The argument is postfix operator is a dummy parameter, it is
   unnused. The point of this parameter is just allow the compiler
   differ between prefix and postfix operators.

 + _Prefix operator_: The increment or decrement happens before the operattion
   being performed on the variable.
   + Example: For an int variable set to 10, the statement
      printVar(++x), will print 11, the increment happens before the
      operation, then the value of x will be 11.

 + _Postfix operator_: The increment or decrement happens after the operation
   being performed on the variable.
   + Example: For an int variable set to 10, the statement
     printVar(x++), will print 10, the increment happens after the
     operation, then the value of x will be 11.

 + Semantics Summary: (Note <- array means assignment)
   + Prefix:
     * x = ++y; Means y <- y + 1 and x <- y
     * x = --y; Means y <- y - 1 and x <- y 
   + Postfix:
     * x = y++; Means x <- y and y <- y + 1
     * x = y--; Means x <- y and y <- y - 1

 *Assignment Operators*

#+CAPTION: Assignment operator overloading
| Name                                    | Operator       | Expansion           | Member function signature           |
|                                         |                |                     | for class C and RHS type R          |
|-----------------------------------------+----------------+---------------------+-------------------------------------|
| Assignment                              | LHS = RSH      |                     | C& C::operator= (const RHS& rhs)    |
| *Copy-assignment operator*                | LHS = RSH      |                     | C& C::operator= (const C& rhs)      |
|                                         |                |                     |                                     |
| Assignment sum                          | LHS += RHS     | LHS = LHS + RHS     | C C::operator+=(const RHS& rhs)     |
| Assignment subtraction (aka difference) | LHS -= RHS     | LHS = LHS - RHS     | C C::operator=-(const RHS& rhs)     |
| Assignment product (multiplication)     | LHS *= RHS     | LHS = LHS * RHS     | C C::operator*=(const RHS& rhs)     |
| Assignment division                     | LSH /= RHS     | LHS = LHS / RHS     | C C::operator/=(const RHS& rhs)     |
| Assignment remainder                    | LHS %= RHS     | LHS = LHS % RHS     | C C::operator%=(const RHS& rhs)     |
|                                         |                |                     |                                     |
| Assignment bitwise AND                  | LHS &= RHS     | LHS = LHS & RHS     | C C::operator&=(const RHS& rhs)     |
| Assignment bitwise OR                   | LHS \vert= RHS | LHS = LHS \vert RHS | C C::operator\vert=(const RHS& rhs) |
| Assignment bitwise exclusive OR (XOR)   | LHS ^= RHS     | LHS = LHS ^ RHS     | C C::operator^=(const RHS& rhs)     |
| Assignment left shift                   | LHS <<= RHS    | LHS = LHS << RHS    | C C::operator<<=(const RHS& rhs)    |
| Assignment right shift                  | LHS >>= RHS    | LHS = LHS >> RHS    | C C::operator>>=(const RHS& rhs)    |
|                                         |                |                     |                                     |
|-----------------------------------------+----------------+---------------------+-------------------------------------|


 *Function-Call Operators*

Function-call operators allow objects to be called as they were
functions and define "functors" - function-objects.

 + Note: The operator is '()' parenthesis.

#+CAPTION: Function call operator overloading - "functors"
| Operator Usage                     | Member function signature for class C and RHS type R  |
|------------------------------------+-------------------------------------------------------|
| RHS x = Object()                   | R C::operator()()                                     |
| int a = Object("hello world")      | int C::operator()(const char* text)                   |
| std::string text = AnObject(count) | std::string C::operator()(std::size_t count)          |
| RHS result = Object(x, y, text)    | RHS C::operator() (int x, double y, char const* text) |
|------------------------------------+-------------------------------------------------------|


 *Pointer Operarators*

#+CAPTION: Pointer operator overloading.
| Name                                        | Operator  | Usage                     | Member function signature            |
|                                             |           |                           | for class C and RHS type R           |
|---------------------------------------------+-----------+---------------------------+--------------------------------------|
| Subscript, array index                      | []        | Object[Index]             | X C::operator[] (const Index& index) |
| Indirection - deference                     | *         | *Object                   | X& C::operator*()                    |
| Indirection - deference                     | *         | *Object                   | X& C::operator*()  const             |
| Class member access or dereference operator | ->        | pointerToOjbect->Member() | X* C::operator->()                   |
| Class member access or dereference operator | ->        | pointerToOjbect->Member() | X* C::operator->()  const            |
|---------------------------------------------+-----------+---------------------------+--------------------------------------|
| Address or reference                        | &         | &Object                   | X* C::operator&()                    |
| Heap allocation - single object             | new       | C* ptr = new C;           |                                      |
| Heap allocation - array                     | new []    | C* ptr = new C[10];       |                                      |
| Delete operator                             | delete    | delete ptr;               |                                      |
| Delete array operator                       | delete [] | delete [] ptr;            |                                      |
|---------------------------------------------+-----------+---------------------------+--------------------------------------|

 + Note:
   + The overloading of operators (*) and (->) is useful for implementing smart pointers.
   + The overloading of operators new and delete can be used for
     implementing custom allocators.

*** Free function operator overloading tables reference card 

Note: The following operators cannot be overloaded by non-member
functions, in other words, they cannot be free functions.

 + =   - assignment operator 
 + []  - array index
 + ()  - Function-call operator
 + ->  - Deference operator

 *Arithmetic Operators* 

#+CAPTION: Free-function arithmetic operator overloading 
| Name           | Operator  | Operator function signature               |
|----------------+-----------+-------------------------------------------|
| Addition       | LHS + RHS | LHS operator+(const LHS&, const RHS& rhs) |
| Subtraction    | LHS - RHS | LHS operator-(const LHS&, const RHS& rhs) |
| Multiplication | LHS * RHS | LHS operator*(const LHS&, const RHS& rhs) |
| Division       | LSH / RHS | LHS operator/(const LHS&, const RHS& rhs) |
| Remainder      | LSH % RHS | LHS operator%(const LHS&, const RHS& rhs) |
|----------------+-----------+-------------------------------------------|


 + C: Class that the operator belongs to. 
 + LHS - Left-hand-side type 
 + RHS - Right-hand-side type or class (a class is also a type)

 *Comparison Operators*

#+CAPTION: Free-function comparison operator overloading
| Name                  | Operator   | Operator function signature                 |
|-----------------------+------------+---------------------------------------------|
| Equal                 | LHS == RHS | bool operator==(const LHS&, const RHS& rhs) |
| Not equal             | LHS != RHS | bool operator-(const LHS&, const RHS& rhs)  |
| Greater than          | LHS >  RHS | bool operator>(const LHS&, const RHS& rhs)  |
| Greater or equal than | LHS >= RHS | bool operator>=(const LHS&, const RHS& rhs) |
| Less than             | LHS <  RHS | bool operator<(const LHS&, const RHS& rhs)  |
| Less or equal than    | LHS <= RHS | bool operator<=(const LHS&, const RHS& rhs) |
|-----------------------+------------+---------------------------------------------|


 *Prefix/Postfix - Increment / Decrement*

#+CAPTION: Free-function prefix and postfix increment/decrement operator overloading
| Name              | Operator | Expansion           | Operator function signature          |
|-------------------+----------+---------------------+--------------------------------------|
| Prefix increment  | ++Object | Object = Object + 1 | LHS& operator++(LHS& lhs)            |
| Postfix increment | Object++ | Object = Object + 1 | LHS  operator++(LSH& lhs, int dummy) |
|                   |          |                     |                                      |
| Prefix decrement  | --Object | Object = Object - 1 | LHS& operator--(LHS& lhs)            |
| Postfix decrement | Object-- | Object = Object - 1 | LHS  operator--(LHS&,int dummy)      |
|-------------------+----------+---------------------+--------------------------------------|

 *Insertion / Extraction operators* 

#+CAPTION: Free-function stream insertion/extraction operator overloading
| Name                             | Operator      | Operator function signature                                        |
|----------------------------------+---------------+--------------------------------------------------------------------|
| Insertion operator  (<<)         | OS << Object; | std::ostream& operator<<(std::ostream& os, const RHS& rhs)         |
| Insertion operator  (<<) [C++11] | OS << Object; | auto operator<<(std::ostream& os, const RHS& rhs) -> std::ostream& |
| Extraction operator (>>)         | IS >> Object; | std::istream& operator>>(std::istream& os, RHS& rhs)               |
| Extraction operator (>>) [C++11] | IS >> Object; | auto operator>>(std::istream& os, RHS& rhs) -> std::istream&       |
|----------------------------------+---------------+--------------------------------------------------------------------|

 + OS: Output stream: derived class of std::ostream (std::cout,
   std::cerr, std::stringstream ...)

 + IS: Inoput stream: derived clas sof std::istream (std::cin,
   std::ifstream, std::stringstream ...)

 + Object: An instance of the class or type RHS (Right-hand side).

 + Insertion operator (<<)
   + Insert or write object to output stream.

 + Extraction operator (>>)
   + Extract or read object from input stream.
 
Calling the operator (<<) explicitly:

#+BEGIN_SRC cpp 
  >> std::cout << " [1] Hello world C++" << std::endl;
   [1] Hello world C++

  >> operator<<(std::cout, " [2] Hello world C++\n");
   [2] Hello world C++

  >> std::cout << " [3] Hello world C++" << "\n [3] This is a new line.\n";
   [3] Hello world C++
   [3] This is a new line.
  >> 

  >> operator<<(operator<<(std::cout, " [3] Hello world C++"), "\n [3] This is a new line.\n");
   [3] Hello world C++
   [3] This is a new line.

   template<class T> std::ostream& printStream(std::ostream& os, T const& object){
       return os << object;
   }

   >> printStream(std::cout, "hello world\n");
   hello world

   >> printStream(printStream(std::cout, "hello world\n"), " A new line\n");
   hello world
    A new line
#+END_SRC

*** References 

 *C++ ISO Standard - Language Specification:*

 + [[https://en.cppreference.com/w/cpp/language/operator_incdec][Increment/decrement operators]]

 + Overloading - <http://eel.is/c++draft/over.oper>

 + https://isocpp.org/wiki/faq/operator-overloading  

 *Further Reading* 

 + [[http://www.modernescpp.com/index.php/c-core-guidelines-rules-for-overloading-and-overload-operators][C++ Core Guidelines: Rules for Overloading and Overload Operators]] 
** Lambda Expressions 
   :PROPERTIES:
   :ID:       02be1a97-c100-44ce-ad76-63835818d406
   :END:
*** Overview 

Lambda expressions, also known as lambda functions or lambda
abstractions, are ubiquitous in functional programming languages such
as Haskell, OCaml, Scala and Scheme. They were by introduced in a
theoretical way by Alonzo Church in the lambda calculus. Lisp was
first programming language to use lambda functions and now this
function programming feature has made its way into mainstream and has
arrived to C# (Cshap), Java 8 and C++11.

In C++, Lambda functions are not ordinary functions, actually, they
are special function-objects or "C++ functors". Lambda abstractions
can be passed as arguments to any function; returned from functions;
can have state and also they can be defined locally at the call-site
simplifying all the boilerplate code necessary to pass a function to
callbacks, event handlers and higher order functions.

Summary:

  * Lambda functions were introduced in C++11. Before C++11 lambdas
    were available as Boost.Lambda. 

  * Lambda functions can be:
    + returned from functions.
    + be passed as function parameters.
    + Can be stored in data structures.
    + Hold state and capture variables (closure).
    + Non-capturing lambdas can be converted to function pointers what
      is useful with old C-APIs.

  * Lambda turns C++11 is a *game changer* and turns C++ into an
    quasi-functional programming language.

  * Practical Use Cases:
    + Callbacks
    + Higher order functions
    + Simplify design patterns
    + Asynchronous code
    + Create functions at runtime. 

*Main parts* 
 
 - Capture list between square brackets ~[ ]~
 - Argument list between parenthesis ~()~
 - Function body between curly braces ~{}~

Syntax: 

#+BEGIN_SRC text 
  [capture](parameters) -> return-type {body}
#+END_SRC

Some lambda functions: 

#+BEGIN_SRC cpp 
 auto fn = [](int n){ return n * 10; }

 // Test in CERN's ROOT REPL
 >> auto fn = [](int n){ return n * 10; }
 ((lambda) &) @0x7f5e578f2010
 >> 

 >> auto fn = [](int n){ return n * 10; }
 ((lambda) &) @0x7f5e578f2010
 >> 
#+END_SRC


*Parts of a C++'s lambda expression:*  - ([[https://msdn.microsoft.com/en-us/library/dd293608.aspx][Microsoft Inc. Lambda C++]])

 1. Capture clause - Specifies captured variables (closure).
    - ~[ ]~ - Empty capture clause means that no variable from escope
      is captured.
    - ~[x, y]~- The variables x and y are captured by value and the
      the lambda body will get a copy of x and y. They cannot be
      modified in the body of the lambda expression. 
    - ~[&x , y]~ - The variable x is captured by reference and y by
      value, therefore x can be modified in the body of the lambda
      expression and y cannot.
    - ~[&]~ - Capture all variables used in the lambda's body by
      reference.
    - ~[=]~- Captures all variables used in the body by value
      (copy). The variables cannot be modifed as they are passed by
      value.
    - ~[=, &blob]~- The variable blob is captured by reference and all
      other variables are captured by value (copy).
    - ~[this]~ - Captures the "this" pointer of the enclosing class.

 2. Parameter list (Optional)- Parameters, aka arguments, of the lambda expression.
 3. Mutable specification (optional)
 4. exception-specification (optional)
 5. trailing return type (optional)
 6. lambda-body - The body can access variables such as:
    - Lambda parameters passed between parenthesis:  ~(int x)~
    - Captured variables from the enclosing scope.
    - Global variables.
    - Class data members if the lambda expression is defined inside a
      class. 

#+BEGIN_SRC text 
  --
              (1)  (2)    (3)       (4)         (5)
                 |    |         |            |           |
                ...  ....  .....+....  ...+....     ......
                [ ]  ( )  mutable  throw()  -> int
                {                                                   
                  // (6)                                              
                  // Lambda body 
                  int n = x + y;
                  x = y;
                  y  = n;
                  return n;
                }
#+END_SRC

*** TODO Basic Examples 

*Proof-of-concept code* 

 + File: [[file:src/lambdaFun.cpp][file:src/lambdaFun.cpp]]
 + Online Compiler: http://rextester.com/SCQP30593

Code Highlights:

 - Lambda function - lambda1 

#+BEGIN_SRC cpp 
  // Example (1)
  auto lambda1 = [](const std::string& str){
     std::cout << "Lambda1: : I got the value = " << str << "\n";
  };

  // Alternative 1:
  //------------------------------
  std::function<void (const std::string&)> lambda1A = [](const std::string& str) {
    std::cout << "Lambda1: : I got the value = " << str << endl;
  };

  // Alternative 2:
  //------------------------------
  std::function<auto (const std::string&) -> void> lambda1B = [](const std::string& str) {
    std::cout << "Lambda1: : I got the value = " << str << endl;
  };

  // Alternative 3:
  //------------------------------
  // Type synonym 
  using FnAction = std::function<void (const std::string&)>;
  // Alternative type synonym: 
  using FnAction = std::function<auto (const std::string&) -> void>;

  FnAction lambda1C = [](const std::string& str) {
    std::cout << "Lambda1: : I got the value = " << str << endl;
  };

  >> lambda1("hello world")
  Lambda1: : I got the value = hello world

  >> lambda1("hola mundo")
  Lambda1: : I got the value = hola mundo

  >> lambda1A("testing C++")
  Lambda1: : I got the value = testing C++

  >> lambda1B("Running lambda1B")
  Lambda1: : I got the value = Running lambda1B

  >> lambda1C("I am lambda1C function")
  Lambda1: : I got the value = I am lambda1C function
  >> 	
#+END_SRC


 - Higher order function which returns a lambda function which takes
   two ints as parameters returning an int. This function captures the
   parameter m by value, it means that the parameter is copied in the
   function body. 

#+BEGIN_SRC cpp 
  // As it is in the code.
  //-----------------------------------------	
  std::function<int (int, int)> makeFunction1(int m){
      return [m](int x, int y){ return m * (x + y); };
  }

  >> auto fn = makeFunction1(4)
  (std::function<int (int, int)> &) @0x7fb73017f010
  >> fn(3, 5)
  (int) 32
  >> fn(4, 3)
  (int) 28
  >> 

  // Alternative 1:
  //-----------------------------------------
  auto makeFunction1A(int m) -> std::function<int (int, int)>{
      return [m](int x, int y){ return m * (x + y); };
  }

  >> fna(3, 5)
  (int) 32
  >> fna(4, 3)
  (int) 28
  >> auto fna6 = makeFunction1A(6)
  (std::function<int (int, int)> &) @0x7f696d823030
  >> fna6(3, 5)
  (int) 48
  >> fna6(4, 3)
  (int) 42
  >> 

  // Alternative 2:
  //-----------------------------------------
  auto makeFunction1B(int m) -> std::function<auto (int, int) -> int>{
      return [m](int x, int y){ return m * (x + y); };
  }

  // Alternative 3:
  //-----------------------------------------
  // C++11 Type synonym
  using BinaryIntFunctionA = std::function<int (int, int)>;
  using BinaryIntFunctionB = std::function<auto (int, int) -> int>;
  // Prior to C++11 type synonym
  typedef std::function<auto (int, int) -> int> BinaryIntFunction;

  auto makeFunction1C(int m) -> BinaryIntFunctionB {
      return [m](int x, int y){ return m * (x + y); };
  }

  >> auto fnc = makeFunction1C(8)
  (std::function<int (int, int)> &) @0x7f696d823050
  >> fnc(3, 5)
  (int) 64
  >> fnc(6, 7)
  (int) 104
  >> 8 * (6 + 7)
  (int) 104
  >> 
#+END_SRC


Complete program output ([[file:src/lambdaFun.cpp][file:src/lambdaFun.cpp]]) : 

#+BEGIN_SRC sh
  g++ lamdaFun.cpp -o bin/lamdaFun.bin && bin/lamdaFun.bin

  -----------------------------------------------------------------------------------------
  >> Example(1) - Testing function lambda1
  Lambda1: : I got the value = Hello
  Lambda1: : I got the value = World

  -----------------------------------------------------------------------------------------
  >> Example(2) Testing function lambda2
  Lambda 2 :: I got the value  = Japan
  Lambda 2 :: I got the value  = Korea

  -----------------------------------------------------------------------------------------
  >> Example(3) Testing function lambda3
     - Lambda function can be defined and executed at the call-site
  Lambda 3 :: I got the value = C++11 is awesome!

  -----------------------------------------------------------------------------------------
  >> Example(4) Testing function sumLambda
     - Lambda functions  can return values as any function.
  sumLambda(10.0, 25.34) = 35.34
  sumLambda(-10.23, 4.56) = -5.67

  -----------------------------------------------------------------------------------------
  >> Example(5) Testing function lamdaCapture
     - Lambda functions  can capture its environment (closures) and have state as "function objects"
    x  = 5  c = 3
  lamdaCapture(2, 5)  = 32
    x  = 5  c = 4
    lamdaCapture(1, 2) =  16
    x  = 5  c = 5

  -----------------------------------------------------------------------------------------
  >> Example(6) Testing function sumLambda
     - Lambda functions  can play well with STL algorithms
  Print all vector elements - Version 1
    v[0] = 1
    v[1] = 2
    v[2] = 3
    v[3] = 4
    v[4] = 5
    v[5] = 6
    v[6] = 7
    v[7] = 8
  Print all vector element Version 2  - local state with 'static' keyword
    v[0] = 1
    v[1] = 2
    v[2] = 3
    v[3] = 4
    v[4] = 5
    v[5] = 6
    v[6] = 7
    v[7] = 8

  -----------------------------------------------------------------------------------------
  >> Example(7) 
     Playing with STL transform algorithm.
    Vector transformed =  
  v  [0] = 4
  v  [1] = 7
  v  [2] = 10
  v  [3] = 13
  v  [4] = 16
  v  [5] = 19
  v  [6] = 22
  v  [7] = 25

  -----------------------------------------------------------------------------------------
  >> Example(8) 
     Lambda functions can be returned from functions and be generated at run-time.
    mulSumBy2(2, 4) = 12
    mulSumBy2(3, 1) = 8
    mulSumBy5(2, 4) = 30
    mulSumBy5(9, 2) = 55

  -----------------------------------------------------------------------------------------
  >> Example(9) 
     Lambda functions can be returned from functions and have state.
    Running dummy function
      (*) m = 2, n = 0, x = 1, y = 3, z = 8
    Running dummy function
      (*) m = 2, n = 1, x = 2, y = 5, z = 15
    Running dummy function
      (*) m = 3, n = 0, x = 1, y = 3, z = 12
    Running dummy function
      (*) m = 3, n = 1, x = 2, y = 5, z = 22

  -----------------------------------------------------------------------------------------
  >> Example(10) 
     Lambda functions can return lambda functions!!
    addTo5(4) = 9
    addTo5(3) = 8
    addTo10(4) = 14
    addTo10(3) = 13

  -----------------------------------------------------------------------------------------
  >> Example(11) 
     Lambda functions can be passed as function arguments!
  foldVector(dataset2, 0, add) = 28
  foldVector(dataset2, 1, mul) = 5040

  -----------------------------------------------------------------------------------------
  >> Example(12) - Observer pattern
  (observer 1) Temperature changed to 30.5 C
  (observer 2) Sensor temperature changed to 30.5 C
  (observer 1) Temperature changed to 20.5 C
  (observer 2) Sensor temperature changed to 20.5 C

#+END_SRC

*References*

 - *Lambda Expressions in C++* -
   <https://msdn.microsoft.com/en-us/library/dd293608.aspx>

 - *Lambda expressions (since C++11)* -
   <http://en.cppreference.com/w/cpp/language/lambda> 

 - *C++ Core Guidelines: Function Objects and Lambdas* -
   <http://www.modernescpp.com/index.php/c-core-guidelines-function-objects-and-lambas> 

 - *C++11/C++14 lambda functions - 2017* -
   <http://www.bogotobogo.com/cplusplus/C11/C11_lambda_functions_expressions.php>

 - *Lambda Functions in C++11 - the Definitive Guide* -
   <https://www.cprogramming.com/c++11/c++11-lambda-closures.html> 

 - *Fun with Lambdas: C++14 Style (part 1)* -
   <https://www.slideshare.net/SumantTambe/fun-with-lambdas-c14-style> 

 - *ICS 45C Fall 2016 - Notes and Examples: Functions and Lambdas* -
   <http://www.ics.uci.edu/~thornton/ics45c/Notes/FunctionsAndLambdas/>

 - *Creating Recursive Lambdas ... and returning them too!* -
   <http://cpptruths.blogspot.com.br/2013/10/creating-recursive-lambdas-and.html> 
*** Lambdas in Deep 

Define two test functions: 

#+BEGIN_SRC cpp 
  >> auto add_10 = [](int x){ return x + 10; };
  >> auto mul_3  = [](int x){ return x * 3; };

  >> add_10(5)
  (int) 15

  >> mul_3(5)
  (int) 15
#+END_SRC

The lambda objects add_10 and mul_3 can be called like functors
(callable objects) overloading the function-call operator. 

#+BEGIN_SRC cpp 
  >> add_10.operator()(5)
  (int) 15

  >> mul_3.operator()(5)
  (int) 15
  >> 
#+END_SRC

Define two functions fun_add_10 and fun_mul_3; 

#+BEGIN_SRC cpp 
  >> int fun_add_10(int n){ return n + 10; }
  >> int fun_mul_3(int n){ return n * 3; }

  >> fun_add_10(2)
  (int) 12

  >> fun_add_10(5)
  (int) 15

  >> fun_mul_3(5)
  (int) 15
#+END_SRC

Both functions have the same type and can be reffered by the same
function-pointer: 

#+BEGIN_SRC cpp 
  >> if(typeid(fun_add_10) == typeid(fun_mul_3)) puts(" => Function have same type"); 
  => Function have same type

  >> int (* funptr)(int) = nullptr;

  >> funptr = fun_add_10;
  >> funptr(4)
  (int) 14

  >> funptr = fun_mul_3;
  >> funptr(4)
  (int) 12
#+END_SRC

Lambdas does not have the same type: 

#+BEGIN_SRC cpp 
  >> if(typeid(add_10) != typeid(mul_3)) puts(" => Lambdas do not have the same type");
   => Lambdas do not have the same type

  >> std::cout << std::boolalpha;
  >> std::cout << "value = " << (typeid(add_10) != typeid(mul_3)) << std::endl;
  value = true
#+END_SRC

Lambdas cannot be referred by the same pointer. 

#+BEGIN_SRC cpp 
  // Take the address of the object add_10 
  >> auto ptr = &add_10;
  >> ptr
  ((lambda) *) @0x7ffed74b7368

  // Apply to a value 
  >> (*ptr)(4)
  (int) 14
  >> 
  >> ptr->operator()(4)
  (int) 14

  // FAILURE!!! because both lambdas do not have the same type.  Attempt
  // to assing the address of mul_3 to the pointer to add_10.
  >> ptr = &mul_3;
  ROOT_prompt_76:1:7: error: assigning to '(lambda at ROOT_prompt_0:1:15) *' from incompatible type '(lambda
        at ROOT_prompt_2:1:15) *'
  ptr = &mul_3;
        ^~~~~~
#+END_SRC

Both objects are *add_10* and *mul_3* are instance of different anonymous
classes created by the compiler which overloads the function-call
operator member function. 

The lambda object _add_10_ is equivalent to: 

#+BEGIN_SRC cpp 
  class _anonymous_lambda_class1
  {
  public:
       int operator()(int n) const { return n + 10; }
  };

  _anonymous_lambda_class1 add_10; 
#+END_SRC

The lambda object _mul_3_ is equivalent to: 

#+BEGIN_SRC cpp 
  class _anonymous_lambda_class2
  {
  public:
       int operator()(int n) const { return n * 3; }
  };

  _anonymous_lambda_class2 mul_3; 
#+END_SRC


The following capturing lambda is equivalent to: 

#+BEGIN_SRC cpp 
  // ----------- Capturing lambda -----------------// 
  double x = 10; 
  std::string name = "Somebody";

  auto capture_lambda = [x, &name] (int n, const char* word) -> void 
  {
     printf(" n = %d ; word = %s, x = %f ; name = %s", n, word, x, name.c_str());
  };

  //--- The capturing lambda (closure) is the same as --------// 
  // 
  class _anonymous_lambda_class
  {
     double _x;
     std::string& _name;  
  public:     
    _anonymous_lambda_class(double x, std::string& name): 
       _x(x)
     , _name(name) 
    { 
    }   

    void operator()(int n, const char* word) const 
    {
       printf(" n = %d ; word = %s, x = %f ; name = %s", n, word, x, name.c_str());
    }

  } capture_lambda(x, name);
#+END_SRC


 *Passing lambdas as function parameters:*

Both lambda objects can be passed by using templated function like in
the following code. The function apply_function, accepts any function
pointer with type _int (*) (int)_, any callable object (functor) that
takes an integer and returns an integer and also lambdas that are also
callable objects.

#+BEGIN_SRC cpp 
  template<typename TFunc> void apply_function(TFunc func, int n){    
      for(int i = 0; i < n; ++i){
         printf(" i = %d\n", func(i));
      }
  }
#+END_SRC

Passing function pointers as parameter to the templated function: 

#+BEGIN_SRC cpp 
  >> apply_function(fun_add_10, 3)
   i = 10
   i = 11
   i = 12

  >> apply_function(&fun_add_10, 4)
   i = 10
   i = 11
   i = 12
   i = 13

  >> apply_function(fun_mul_3, 3)
   i = 0
   i = 3
   i = 6
#+END_SRC

Passing lambdas, aka lambda objects as parameters to the templated
function: 

#+BEGIN_SRC cpp 
  // Pass lambda object add_10 
  >> apply_function(add_10, 3)
   i = 10
   i = 11
   i = 12

  // Pass lambda object mul_3 as parameter 
  >> apply_function(mul_3, 3)
   i = 0
   i = 3
   i = 6

  >> apply_function([](int x){ return 5 * x; }, 3)
   i = 0
   i = 5
   i = 10  
#+END_SRC

Passign a functor to the templated function: 

#+BEGIN_SRC cpp 
  struct AFunctor{
     int operator()(int x) { return 4 * x + 5; }
  };

  >> afc(4)
  (int) 21

  >> afc.operator()(4)
  (int) 21
  >> 

  >> apply_function(afc, 3)
   i = 5
   i = 9
   i = 13

  >> apply_function(AFunctor(), 3)
   i = 5
   i = 9
   i = 13
#+END_SRC


As a result: 

 * C++ *lambdas expressions are not functions*, as in most functional
   languages such as Haskell, OCaml and so on. They are functors or
   callable-objects instances of anonymous classes generated by the
   compiler.

 * Lambda expressions with the same type parameters and same return
   type do not have the same type and cannot be assigned to the same
   variable or referred by the same pointer.

 * Lambdas can be passed as parameters by using templated
   functions. In this case lambdas and functors are better than
   passing function pointers as the both are most likely to be inlined
   by the compiler removing the function-call overhead.

 * The only way to store lambdas in the same container or in an
   std::vector container is by using type-erasure or type-erasure
   containers such as [[https://en.cppreference.com/w/cpp/utility/functional/function][std::function]].

 * std::function<int (int)> is not the type of any of those lambda
   functions.
*** Stateful lambdas 

The function-call operator member function operator()(args) of a
lambda object is annotated with _const_, therefore it cannot modify
captured parameters by value. 

#+BEGIN_SRC cpp 
  // Compile-time error!! 
  auto incrementer = [n = 1]() { return ++n; };
#+END_SRC

The previous line is equivalent to: 

#+BEGIN_SRC cpp 
  // The previous line is the same as: 
  class __Anonymous_lambda_classA {
      int n = 1;
  public: 
      __Anonymous_lambda_class() = default;
 
      // Function-call operator annotated as const 
      int operator()() const 
      {  
         // Value n cannot be modified!! 
         // Compiel-time error!!
         return ++n; 
      }
  };

  __Anonymous_lambda_classA incrementer;
#+END_SRC

The _mutable_ keyword allows variables captured by value to be modified
in the lambda expression.

#+BEGIN_SRC cpp 
  // Now it works
  auto incrementer = [n = 1]() mutable { return ++n; };

  // Could also be written as: 
  auto incrementer = [n = 1]() mutable -> int 
                    {  
                       return ++n; 
                    };

  // Could also be written as: 
  auto incrementer = [n = 1](void) mutable -> int 
                     { 
                       return ++n; 
                     };
#+END_SRC

The previous lambda expression 'incrementer' is equivalent to: 

#+BEGIN_SRC cpp 
  // The previous line is the same as: 
  class __Anonymous_lambda_classB {
      int n = 1;
  public: 
      __Anonymous_lambda_class() = default;
 
      // Function-call operator non cost 
      int operator()()  
      {  
         return ++n; 
      }
  };

  __Anonymous_lambda_classB incrementer;
#+END_SRC

Test in Cling REPL: 

#+BEGIN_SRC cpp 
   $ ~/opt/cling_2018-09-16_fedora27/bin/cling -std=c++1z
   // Now it works
   auto incrementer = [n = 1]() mutable { return ++n; };
   auto incrementerB = incrementer;

   [cling]$ incrementer()
   (int) 2
   [cling]$ incrementer()
   (int) 3
   [cling]$ incrementer()
   (int) 4
   [cling]$ incrementer()
   (int) 5

   [cling]$ incrementerB()
   (int) 2
   [cling]$ incrementerB()
   (int) 3
   [cling]$ incrementerB()
   (int) 4

   [cling]$ inc()
   (int) 6
   [cling]$ inc()
   (int) 7
   [cling]$ inc()
   (int) 8
   [cling]$ incrementer()
   (int) 6
   [cling]$ 
#+END_SRC

 *Example: stateful lambda X captured variable* 

Sample code: main-stateful-lambda.cpp 

#+BEGIN_SRC cpp 
  #include <iostream>

  int main()
  {
      int n = 10;
      auto func = [n]() mutable { n = n + 1; return n; };

      std::cout << " func() = " << func() << std::endl;
      std::cout << " func() = " << func() << std::endl;
      std::cout << " func() = " << func() << std::endl;
      std::cout << " n = " << n << std::endl;
      return 0;
  }
#+END_SRC

Output: 

#+BEGIN_SRC sh 
 func() = 11
 func() = 12
 func() = 13
 n = 10
#+END_SRC

*** Generic lambdas C++14
**** Overview  

C++14 introduced _generic-lambdas_ language feature which allows
defining lambda with _auto_ keyword which behaves like templated
functions. 

Papers: 

  * N3559 / *Proposal for Generic (Polymorphic) Lambda Expressions*
    + <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3559.pdf>

  * N3649 / *Generic (Polymorphic) Lambda Expressions (Revision 3)*
    * <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3649.html>

  * *C++ lambda expressions and closures*
    * https://core.ac.uk/download/pdf/82307163.pdf
    * https://eel.is/c++draft/expr.prim.lambda.closure

Generic lambda expression named 'print_lambda' with generic parameter a.

#+BEGIN_SRC cpp 
     auto print_lambda = [](const auto& a){ std::cout << " Value of a = " << a << '\n'; };

     // Or equivalent: 
     auto print_lambda = [](auto const& a){ std::cout << " Value of a = " << a << '\n'; };
#+END_SRC

The previous lamba is an anonymous Functor (function-object) created
by the compiler with a templated parameter in the function-call
operator.

#+BEGIN_SRC cpp 
  // Anonymous functor 
  class __Anonymous_generic_lambda
  {
  public: 
     template<typename T>
     void operator(const T& a)
     {  
         std::cout << " Value of a = " << a << '\n';
     }
  };
#+END_SRC
**** Example 1 - Basic Generic Lambdas

File: cpp-generic-lambda.cpp 

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

  template<typename iterable, typename Callable>
  void custom_algorithm(iterable const& seq, Callable func)
  {
      for(auto const& x: seq) func(x);
  }

  int main(int argc, char** argv)
  {
      auto print_lambda = [](auto a){ std::cout << " Value of a = " << a << '\n'; };

      std::puts(" ---------- Apply to single argument ---------------");
      print_lambda(10);
      print_lambda('x');
      print_lambda("<generic-lambda-on-the-rocks!>");

      std::puts("\n ---- Apply to integer vector / st::for_each ------------");
      std::vector<int> xs{10, 2, 5, 9};
      std::for_each(xs.begin(), xs.end(), print_lambda);

      std::puts("\n -- [1] Apply to string vector / std::for_each ------------");
      std::vector<std::string> words = {"C++",  "ADA", "RUST", "DLang", "Dart" };
      std::for_each(words.begin(), words.end(), print_lambda);

      std::puts("\n -- [2] Apply to string vector / std::for_each ------------");

      int i = 0;
      // Capturing lambda defined at call-site.
      std::for_each(words.begin(), words.end(),
                    [&i](auto const& x){
                          std::cout << " x[" << i++ << "] = " << x << '\n';
                    });

      std::puts("\n - Generic lambda with custom algorithm ----------------");
      custom_algorithm(xs, print_lambda);

     return 0;
  }
#+END_SRC

Building: 

#+BEGIN_SRC sh 
  $ g++  cpp-generic-lambda.cpp -o app1.bin -std=c++1z -Wall -ggdb
#+END_SRC

Running: 

#+BEGIN_SRC sh 
  $ ./app1.bin 
   ---------- Apply to single argument ---------------
   Value of a = 10
   Value of a = x
   Value of a = <generic-lambda-on-the-rocks!>

   ---- Apply to integer vector / st::for_each ------------
   Value of a = 10
   Value of a = 2
   Value of a = 5
   Value of a = 9

   -- [1] Apply to string vector / std::for_each ------------
   Value of a = C++
   Value of a = ADA
   Value of a = RUST
   Value of a = DLang
   Value of a = Dart

   -- [2] Apply to string vector / std::for_each ------------
   x[0] = C++
   x[1] = ADA
   x[2] = RUST
   x[3] = DLang
   x[4] = Dart

   - Generic lambda with custom algorithm ----------------
   Value of a = 10
   Value of a = 2
   Value of a = 5
   Value of a = 9

#+END_SRC
**** Example 2 - Generic lambdas and templates 

Generic lambdas work in a similar way to templated functions or
classes. A lambda generic expression can be applied to any type
satisfying its type requirements (concepts). In the following code,
the generic lambda _mygen_lambda1_ which is similar to the functor
_functor1_, can be applied to any class or type with members _get_param_
and _get_name_ regardless of its class hierarchy. It works in a similar
way to *duck typing* of dynamic languages such as Python, Ruby,
JavaScript and so on. The difference for dynamic typed languages is
that, if the type does not satisfy the requirements of the generic
lambda, a compile-time error will happen.

File: generic-lambda2.cpp 

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

   struct Circle
   {
       int rad = 0;

       std::string get_name(){ return "circle"; }

       void set_parameter(int rad)
       {
           std::printf("[INFO] Circle parameter set to %d \n", rad);
           this->rad = rad;
       }
       int get_param() const {return rad; }
   };

   class Gearbox
   {
       int x = 10;
    public:
       std::string get_name(){ return "gearbox"; }

       void set_parameter(int x)
       {
           std::printf("[INFO] Gearbox parameter set to %d \n", x);
           this->x = x;
       }

       int get_param() const {return x; }

       void dummy_non_common_method() { }
   };

   // The generic lambda mygen_lambda1 is similar to this
   // templated functor.
   struct functor1
   {
       template<typename T>
       void operator()(T& obj, int k)
       {
           std::cout << " Object name = " << obj.get_name() << "\n";
           obj.set_parameter(k);
           std::cout << " Parameter set to " << k << "\n";
       }
   };


   int main(int argc, char** argv)
   {
       auto mygen_lambda1 = [](auto& obj, int k){
           std::cout << " Object name = " << obj.get_name() << "\n";
           obj.set_parameter(k);
           std::cout << " Parameter set to " << k << "\n";
       };

       std::puts("\n --- Apply lambda on Circle object ");
       Circle c1;
       mygen_lambda1(c1, 5);

       std::puts("\n --- Apply lambda on Gearbox object ");
       Gearbox g1;
       mygen_lambda1(g1, 9);

       std::puts("\n --- Apply functor on Gearbox object ");
       functor1 fun1;
       fun1(g1, 9);

           return 0;
   }

#+END_SRC

Program output: 

#+BEGIN_SRC sh 
   --- Apply lambda on Circle object 
   Object name = circle
  [INFO] Circle parameter set to 5 
   Parameter set to 5

   --- Apply lambda on Gearbox object 
   Object name = gearbox
  [INFO] Gearbox parameter set to 9 
   Parameter set to 9

   --- Apply functor on Gearbox object 
   Object name = gearbox
  [INFO] Gearbox parameter set to 9 
   Parameter set to 9

#+END_SRC
*** Self-executable lambda for complex initialization 

Self-executable lambdas functions can also be used for performing
complex local or global static variables initialization.


 *Example 1:* Initialization of global variables.

 + Online compiler: https://rextester.com/CHRT64707

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

  class AClass{
  private:
      double x, y, z;	
  public:
      AClass(): x(0), y(0), z(0) { }
      ~AClass(){
         std::printf("Object deleted\n");
      }
      void setX(double x){ this->x = x; }
      void setY(double y){ this->y = y; }
      void setZ(double z){ this->z = z; }
      void show(){
         std::printf("AClass{ x = %.3f ; y = %.3f ; z = %.3f}\n", x, y, z);
      }	
  };

  AClass globalObject =
      [](){
          AClass cls;
          cls.setX(10.0);
          cls.setY(20.0);
          cls.setZ(15.0);
          cls.show();
          return cls;
      }();

  int main(){
      std::cout << "Program Initialized" << std::endl;
      globalObject.show();
      std::cout << "Program end" << std::endl;
      return 0;
  }
#+END_SRC

Output: 

#+BEGIN_SRC text 
  $ clang++ init1.cpp -o init1.bin -g -std=c++1z -Wall -Wextra
  $ ./init1.bin

  AClass{ x = 10.000 ; y = 20.000 ; z = 15.000}
  Program Initialized
  AClass{ x = 10.000 ; y = 20.000 ; z = 15.000}
  Program end
  Object deleted
#+END_SRC


 *Example 2:* Initialization of function static variables.

 - Online compiler: https://rextester.com/RIGN6626

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

  int getDayOfWeekNum2(const std::string& weekDay){
      // Type alias / synonym 
      using WeekDayTable = std::map<std::string, int>;
      static WeekDayTable week_table =
               [](){ // Lambda function
                  std::cerr << " [LOG] Initializing month table" << "\n";
                  WeekDayTable tbl;
                  tbl["Sun"] = 1;
                  tbl["Mon"] = 2;
                  tbl["Tue"] = 3;
                  tbl["Wed"] = 4;
                  tbl["Thu"] = 5;
                  tbl["Fri"] = 6;
                  tbl["Sat"] = 7;
                  std::cerr << " [LOG] Month table initialization end. OK." << "\n";
                  return tbl;
          }();
      if(week_table.find(weekDay) != week_table.end())
         return week_table[weekDay];	
      return -1;
  }
  int main(){
      std::cout << "getDayOfWeekNum2(Mon)   = " << getDayOfWeekNum2("Mon")   << "\n";
      std::cout << "getDayOfWeekNum2(Tue)   = " << getDayOfWeekNum2("Tue")   << "\n";
      std::cout << "getDayOfWeekNum2(Sat)   = " << getDayOfWeekNum2("Sat")   << "\n";
      std::cout << "getDayOfWeekNum2(ERROR) = " << getDayOfWeekNum2("ERROR") << "\n";
      return 0;
  };
#+END_SRC

Output stderr (Program logging)

#+BEGIN_SRC txt 
 [LOG] Initializing month table
 [LOG] Month table initialization end. OK.
#+END_SRC

Output stdout (Program output) 

#+BEGIN_SRC txt 
  getDayOfWeekNum2(Mon)   = 2
  getDayOfWeekNum2(Tue)   = 3
  getDayOfWeekNum2(Sat)   = 7
  getDayOfWeekNum2(ERROR) = -1
#+END_SRC
*** Universal function adapter - std::bind 
**** Overview

The operator std::bind can simplify help simplifying turning ordinary
functions, instance methods (member functions) and static methods
(static member functions) into ordinary functions.

Example 1: Turn a function of signature: 
  + Input Signature:
    + double functionABC(double a, double c, double c)
  + Target signature: 
    + function<double (double)> 

For the function functionABC

#+BEGIN_SRC cpp 
  double functionABC(double a, double c, double c);
#+END_SRC

The expression:

#+BEGIN_SRC cpp 
 // Type of fnFunOfA is std::function<double (double)>
 auto fnFunOfA = std::bind(functionABC, _1, 10.0, 20.0)
 // It is the same as 
 auto fnFunOfA = [](double x){ return functionABC(x, 10.0, 20.0); };
 // It also equivalent to 
 std::function<double (double)> fnFunOfA = [](double x){ return functionABC(x, 10.0, 20.0); };
#+END_SRC

So, it follows that: 

#+BEGIN_SRC cpp 
  auto fnFunOfB = std::bind(functionABC, 25.0 , _1, 20.0);
  // It is equivalent to 
  auto fnFunOfB = [](double x){ return (functionABC, 25.0 , _1, 20.0); };
#+END_SRC

By using more lambda placeholders it is also possible to generate
multi variable functions: 

#+BEGIN_SRC cpp 
  #include <functional> 
  using namespace std::placeholders; // Import placeholders, _1, _2, _3 ...  

  //----------------------------------//
  auto fnFunOfAB = std::bind(functionABC, _1 , _2, 20.0);
  // Equivalent to 
  auto fnFunOfAB = [](double x, double y){ return functionABC( x , y, 20.0);};

  //----------------------------------//
  auto fnFunOfAC = std::bind(functionABC, _1 , 10.0, _2);
  // Equivalent to 
  auto fnFunOfAC = [](double x, double y){ return functionABC( x , 10.0, y);};

  //----------------------------------//
  auto fnFunOfABC = std::bind(functionABC, _1 , 10.0, _2);
  // Equivalent to 
  auto fnFunOfABC = [](double x, double y, double z){ return functionABC( x , y, z);};
#+END_SRC


 *Binding non-static methods (member function)*

For the following class:

#+BEGIN_SRC cpp 
 struct FunctionObject{
      double x;
      double y;
      FunctionObject(double x, double y): x(x), y(y) {};      
      double operator ()(double a){   
         return a * a;
      }   
      double operator ()(double a, double b, double c){
          return a * x + b * y + c / (x + y);
      }
      double method1(double a){
          return this->x * a  + this->y / a;
      }
      double method2(double a, double b, double c){
          return  c * (a / x + b / y);
      }       
  };
#+END_SRC

It is possible to create lambda functions from those class methods
(member functions):

#+BEGIN_SRC cpp 
  FunctionObject obj;

  //-------------------------
  auto method1LambdaA = std::bind(&FunctionObject::method1, fobj, _1);
  // Equivalent to: 
  auto method1LambdaA = [&obj](double a){return obj.method1(x); };

  //-------------------------
  auto method2LambdaAsFnOfAC = std::bind(&FunctionObject::method2, &fobj, _1, 10.0, _2);
  // Equivalent to: 
  auto method2LambdaAsFnOfAC = [&obj](double a, double c){ return obj.method2(a, 10.0, c); }

  //-------------------------
  auto functionOfObj = std::bind(&FunctionObject::method1, _1, 10.0);
  // Equivalent to: 
  auto functionOfobj = [](FunctionObject a){ return obj.method1(obj, 10.0);};
#+END_SRC

**** std::bind Example 
     :PROPERTIES:
     :ID:       219c4de9-3e9e-446f-bdd5-1ae6e7d45b5b
     :END:

File: 
 +  [[file:src/lambda-bind.cpp][file:src/lambda-bind.cpp]]

Running: 

#+BEGIN_SRC sh 
  $ g++ lambda-bind.cpp -o lambda-bind.bin -g -std=c++11 -Wall -Wextra -ldl 
  $ ./lambda-bind.bin

  ======== Test 1 ========
  lambda-bind.cpp:58: ; sum10(2.0) = 12
  lambda-bind.cpp:59: ; sum10(4.5) = 14.5
  lambda-bind.cpp:60: ; sum10(25.0) = 35
  ======== Test 2 ========
  lambda-bind.cpp:66: ; vectorLenAsFunctionOfX(4.0) = 27.2213
  lambda-bind.cpp:67: ; std::bind(vectorLength, _1, 10.0, 25.0)(4.0) = 27.2213
  lambda-bind.cpp:68: ; vectorLenAsFunctionOfX(10.0) = 28.7228
  lambda-bind.cpp:69: ; std::bind(vectorLength, _1, 10.0, 25.0)(10.0) = 28.7228
  Tabulating - vectorLenAsFunctionOfX
       1.000    26.944
       2.000    27.000
       3.000    27.092
       4.000    27.221
       5.000    27.386
  ======== Test 3 ========
  lambda-bind.cpp:77: ; vectorLenAsFunctionOfY(14.0) = 30.348
  lambda-bind.cpp:78: ; vectorLenAsFunctionOfY(20.0) = 33.541
  Tabulating - vectorLenAsFunctionOfY
       1.000    26.944
       2.000    27.000
       3.000    27.092
       4.000    27.221
       5.000    27.386
  ======== Test 4 ========
  lambda-bind.cpp:92: ; vectorLenAsFunctionOfYZ(3.0, 6.0) = 12.0416
  lambda-bind.cpp:93: ; vectorLenAsFunctionOfYZ(15.0, 26.0) = 31.6386
  ======== Test 5 ========
  lambda-bind.cpp:97: ; fobj(4.0) = 16
  lambda-bind.cpp:98: ; fobj(5.0) = 25
  lambda-bind.cpp:99: ; fobj(10.0) = 100
  lambda-bind.cpp:101: ; fobj(4.0, 10.0, 5.0) = 104.357
  lambda-bind.cpp:102: ; fobj(6.0, 8.0, 9.0) = 100.643
  Running: tabulate(0.0, 5.0, 1.0, fobj)
       0.000     0.000
       1.000     1.000
       2.000     4.000
       3.000     9.000
       4.000    16.000
       5.000    25.000
  Turning class member function into lambda function 
   Note: it is not possible (0.0, 5.0, 1.0, fobj.method1)
  lambda-bind.cpp:111: ; fobj.method1(10.0) = 60.8
  lambda-bind.cpp:112: ; method1LambdaA(10.0) = 60.8
  lambda-bind.cpp:113: ; fobj.method1(20.0) = 120.4
  lambda-bind.cpp:114: ; method1LambdaA(20.0) = 120.4
  lambda-bind.cpp:115: ; fobj.method1(30.0) = 180.267
  lambda-bind.cpp:116: ; method1LambdaA(30.0) = 180.267
  Tabulating method1LambdaA
       0.000       inf
       1.000    14.000
       2.000    16.000
       3.000    20.667
       4.000    26.000
       5.000    31.600
  Tabulating method1LambdaA using direct lambda
       0.000       inf
       1.000    14.000
       2.000    16.000
       3.000    20.667
       4.000    26.000
       5.000    31.600
  ======== Test 6 ========
  lambda-bind.cpp:129: ; method2LambdaAsFnOfA(5.0) = 41.6667
  lambda-bind.cpp:130: ; method2LambdaAsFnOfA(6.0) = 45
  lambda-bind.cpp:131: ; method2LambdaAsFnOfA(10.0) = 58.3333
  lambda-bind.cpp:136: ; fobj.method2(3.0, 10.0, 4.0) = 7
  lambda-bind.cpp:137: ; method2LambdaAsFnOfAC(3.0, 4.0) = 7
  lambda-bind.cpp:138: ; fobj.method2(15.0, 10.0, 14.0) = 52.5
  lambda-bind.cpp:139: ; method2LambdaAsFnOfAC(15.0, 14.0) = 52.5


#+END_SRC
** Functor Function-Object and higher order functions 

Functor is any object which behaves like a function and callable like
a function. Unlike C++ ordinary functions, functors can have internal
state and change its internal data as well.

Functors are implementing in C++ by overloading the function
application operator. 

The code in the file: [[file:src/cpp-functor.cpp][file:src/cpp-functor.cpp]] shows an
exhaustive example about how to implement, use functors and implement
client code using dynamic polymorphism (aka subtyping or inheritance),
static polymorphism (aka template metaprogramming) and C++11's
function type _std::function_.

Example: 
 + File:            [[file:src/cpp-functor.cpp][file:src/cpp-functor.cpp]] 
 + Online Compiler: http://rextester.com/VGE78113

 + Math functor interface class representing a general math function. 

#+BEGIN_SRC cpp  
  class IMathFunctor {
  public:
          // Pure virtual function
          // => const -> Means that the function cannot change the object internal state.
          // => (= 0) -> Means abstract member function or abstract method.
          virtual double operator()(double x)	const = 0;
          virtual ~IMathFunctor() = default;
  };
#+END_SRC

 - Linear Function "C++ functor." - function-object 

#+BEGIN_SRC cpp 
  /** Linear Function "C++ functor." - function-object 
   ,*   LinFun(x) = A * x + B
   ,*/
  class LinFun: public IMathFunctor {
  private:
          // Linear coefficient or line slope 
          double _a; 
          double _b;
  public:
          LinFun(double a, double b): _a(a), _b(b){}
          auto getA()				-> double   { return _a;}
          auto setA(double a)			-> void	    { _a = a; }
          auto getB()				-> double   { return _b;}
          auto setB(double b)			-> void	    { _b = b; }

          // Function-call operator => Makes this object callable
          //------------------------------
          // double operator()(double x)	-> double	{ return _a * x + _b;}	
          double operator()(double x)	const { return _a * x + _b;}	
  };
#+END_SRC

Usage: 

#+BEGIN_SRC cpp 
  // Function linear object - modelling a linear function 3 * x + 4.0 
  LinFun fun1(3.0, 4.0);
  std::cout << "a = " << fun1.getA() << " ; b = " << fun1.getB() << nl;
  std::cout << "fun1(3.0) = " << fun1(3.0) << nl;  
  std::cout << "fun1(4.0) = " << fun1(4.0) << nl;
#+END_SRC

Output: 

#+BEGIN_SRC text 
  a = 3 ; b = 4
  fun1(3.0) = 13
  fun1(4.0) = 16
  fun1(5.0) = 19
#+END_SRC


Higher order functions (functions that calls or return functions) can
be implemented using dynamic polymorphis or inheritance; static
polymorphism, also known as template metaprogramming and using the
type std::function from C++11.


 - *Higher order function using dynamic polymorphism*
   (inheritance). This function only accepts implementations of
   IMathFunctor and cannot worth with an arbitrary function-object,
   ordinary functions or C++11 lambda function. Another drawback is
   the runtime overhead of virtual function-calls.

Example:

#+BEGIN_SRC cpp 
  void tabulateDynamic(const IMathFunctor& fun, double start, double stop, double step){
          std::cout << std::fixed << std::setprecision(3);
          for(double x = start; x <= stop ; x += step)
                  std::cout << std::setw(10) << x << std::setw(10) << fun(x) << "\n";
  }
#+END_SRC

Usage:

#+BEGIN_SRC cpp 
    tabulatDynamic(fun1, 0.0, 5.0, 1.0);
#+END_SRC

Sample Output: 

#+BEGIN_SRC text 
  -----> Tabulating fun1
      0.000     4.000
      1.000     7.000
      2.000    10.000
      3.000    13.000
      4.000    16.000
      5.000    19.000
#+END_SRC

 - *Higher order function using static polymorphism* - The advantage
   of this function is that it can work with any callable object like
   functors (function-objects), ordinary functions and C++11 lambda
   functions. Another benefit is the lower runtime overhead than the
   implementation using dynamic polymorphism. For this case, the
   runtime cost of dynamic polymorphism is not significant, however it
   can become noticeable on large scale computation or high
   performance computations.

 - Example:

#+BEGIN_SRC cpp 
  template<class Function>
  void tabulateStatic(const Function& fun, double start, double stop, double step){
          std::cout << std::fixed << std::setprecision(3);
          for(double x = start; x <= stop ; x += step)
                  std::cout << std::setw(10) << x << std::setw(10) << fun(x) << "\n";
  }
#+END_SRC

Usage:

#+BEGIN_SRC cpp 
    std::cout << " -----> Tabulating fun1" << nl;
    tabulateStatic(fun1, 0.0, 5.0, 1.0);
    std::cout << " -----> Tabulating fun2" << nl;
    tabulateStatic(fun2, 0.0, 5.0, 1.0);
#+END_SRC


 - *Higher order function using the C++11 type std::function* - The type
   std::function provides type erasure and can work with any functor,
   ordinary function and C++11 lambda functions, in addition it also
   allows all those types of functions to be stored in STL containers.

Example: 

#+BEGIN_SRC cpp 
  void tabulateLambdaList(
        const std::vector<std::function<double (double)>> funlist
       ,double start
       ,double stop
       ,double step
       ){
       std::cout << std::fixed << std::setprecision(3);
       for(double x = start; x <= stop ; x += step){
               std::cout << std::setw(10) << x;
               // const auto& is used for avoid uncessary copies 
               for(const auto& fun: funlist)
                       std::cout << std::setw(10) << fun(x);
               std::cout << "\n";
       }
  }
#+END_SRC

Usage:

#+BEGIN_SRC cpp 
   tabulateLambdaList({fun1, fun2, exp, ordinaryFunction}, 0.0, 5.0, 1.0)
#+END_SRC

Output:

#+BEGIN_SRC text 
         x         fun1     fun2      exp      ordinaryFunction
       0.000     4.000     4.000     1.000     0.000
       1.000     7.000     9.000     2.718     3.000
       2.000    10.000    18.000     7.389     6.000
       3.000    13.000    31.000    20.086     9.000
       4.000    16.000    48.000    54.598    12.000
       5.000    19.000    69.000   148.413    15.000
#+END_SRC

Compilation of [[file:src/cpp-functor.cpp][file:src/cpp-functor.cpp]] 

#+BEGIN_SRC sh 
  $ clang++ cpp-functor.cpp -o cpp-functor.bin -g -std=c++11 -Wall -Wextra &&
#+END_SRC

Complete program output of [[file:src/cpp-functor.cpp][file:src/cpp-functor.cpp]] 

#+BEGIN_SRC sh 
  ./cpp-functor.bin

  a = 3 ; b = 4
  fun1(3.0) = 13
  fun1(4.0) = 16
  fun1(5.0) = 19
  =======================
  a = 2 ; b = 3 ; c = 4
  fun2(3.0) = 31
  fun2(4.0) = 48
  fun2(5.0) = 69
  ======= [1] Client Code using dynamic polymorphism  ================
   -----> Tabulating fun1
       0.000     4.000
       1.000     7.000
       2.000    10.000
       3.000    13.000
       4.000    16.000
       5.000    19.000
   -----> Tabulating fun2
       0.000     4.000
       1.000     9.000
       2.000    18.000
       3.000    31.000
       4.000    48.000
       5.000    69.000
  ======= [2] Client Code using dynamic polymorphism  ================
       0.000     4.000     4.000
       1.000     7.000     9.000
       2.000    10.000    18.000
       3.000    13.000    31.000
       4.000    16.000    48.000
       5.000    19.000    69.000
  ======= Client Code using static polymorphism (template)  ================
   -----> Tabulating fun1
       0.000     4.000
       1.000     7.000
       2.000    10.000
       3.000    13.000
       4.000    16.000
       5.000    19.000
   -----> Tabulating fun2
       0.000     4.000
       1.000     9.000
       2.000    18.000
       3.000    31.000
       4.000    48.000
       5.000    69.000
   -----> Tabulating lambda function f(x) = x * x
       0.000     0.000
       1.000     1.000
       2.000     4.000
       3.000     9.000
       4.000    16.000
       5.000    25.000
   -----> Tabulating ordinary function f(x) = 3 * x
       0.000     0.000
       1.000     3.000
       2.000     6.000
       3.000     9.000
       4.000    12.000
       5.000    15.000
   -----> Tabulating ordinary function f(x) = exp(x)
       0.000     1.000
       1.000     2.718
       2.000     7.389
       3.000    20.086
       4.000    54.598
       5.000   148.413
  ======= Client Code using C++11 lambda std::function  ================
       0.000     4.000     4.000     1.000     0.000
       1.000     7.000     9.000     2.718     3.000
       2.000    10.000    18.000     7.389     6.000
       3.000    13.000    31.000    20.086     9.000
       4.000    16.000    48.000    54.598    12.000
       5.000    19.000    69.000   148.413    15.000
#+END_SRC
** TODO OOP Multiple Inheritance
*** Ambiguity resolution 

This example shows how to solve multiple inheritacne ambiguity
problems in C++ when a derived class inherits more than two base
classes containing member variables and member functions with same
name. 
 

File: [[file:src/inheritance-multiple-ambiguity.cpp][file:src/inheritance-multiple-ambiguity.cpp]]


 + Base class BaseA:

#+CAPTION: class BaseA label:code-baseA-class
#+BEGIN_SRC cpp 
  class BaseA{
  protected:
       std::string key = "KEY-BASEA";
  public:	
	
       std::string _name;

       BaseA(std::string name): _name(name) {
          std::cerr << " [LOG] BaseA instantiated. OK." << "\n";
       }
       // A base class always needs virtual constructor in order to avoid memory leaks.
       virtual ~BaseA() = default;

       void printName(){
          std::cout << " A - [printName] => Name = " << _name << "\n";
       }	
       void printNameA(){
          std::cout << " [printNameA] => NameA = " << _name << "\n";
       }
       void callOverridenVFun(){
          std::cout << " [BaseB::callOverridenVFun] BaseB::overridenVfun() returned"
                    << '\n' << " +=> RETURN = " << this->overridenVfun() << "\n";
       }
       virtual std::string overridenVfun() = 0;	

       virtual std::string nonOverridenVfun(){
          return "BaseA::nonOverridenVfun";
       }

       virtual std::string specificAVFun(){
         return "specificAVFun not overriden.";
       }

       static void staticMethod(){
         std::cout << " [BaseA] I am a static method from BaseA" << "\n";
       }	
  };
#+END_SRC

 + Base class BaseB

#+BEGIN_SRC cpp 
  class BaseB{
      // Only derived classes can access 
  protected: 
      std::string key = "KEY-BASEB";
	
     // Derived classes and any external code can access	
  public:    
      std::string _name;

      BaseB(std::string name): _name(name) {
          std::cerr << " [LOG] BaseB instantiated. OK." << "\n";
      }

      virtual ~BaseB() = default;

      void printName(){
          std::cout << " B - [printName] => Name = " << _name << "\n";
      }
      void printNameB(){
          std::cout << " [PrintName] => NameB = " << _name << "\n";
      }

      void callOverridenVFun(){
          std::cout << " [BaseB::callOverridenVFun] BaseB::overridenVfun() returned"
                    << '\n' << " +=> RETURN = " << this->overridenVfun() << "\n";
      }
      virtual std::string overridenVfun(){
          return " BaseB::overridenVfun not overriden";
      }	
      virtual std::string nonOverridenVfun(){
          return "BaseB::nonOverridenVfun";
      }
      virtual std::string specificBVFun(){
          return "specificBVFun not overriden.";
      }
      static void staticMethod(){
          std::cout << " [BaseB] I am a static method from BaseB" << "\n";
      }
  };

#+END_SRC


 + Class DerivedD - inherits both class BaseA and BaseB.

#+BEGIN_SRC cpp 
  class Derived: public BaseA, public BaseB{	
  public:
      // Base class constructos must always be initialized through
      // initialization list like this.
      Derived()
        : BaseA("nameA"), BaseB("nameB")
      {		
      }
      Derived(std::string nameA, std::string nameB)
        : BaseA(nameA), BaseB(nameB)
      {		
      }
      ~Derived(){
          std::cout << " [Derived] Destructor called. " << "\n";
      }
      // Access ambiguous protected field from base class 
      void showKeyBaseA(){
          std::cout << " [showKeyBaseA] Key-BaseA = " << BaseA::key << "\n";
          std::cout << " [showKeyBaseA] Key-BaseA = " << this->BaseA::key << "\n";
      }
      void showKeyBaseB(){
          std::cout << " [showKeyBaseB] Key-BaseB = " << BaseB::key << "\n";
          std::cout << " [showKeyBaseB] Key-BaseB = " << this->BaseB::key << "\n";
      }

      void printNameX(){
          BaseA::printName();
          // Or 'this' pointer can be used too.
          this->BaseB::printName();
      }

    /* The derived class overrides both virtual member functions, BaseA::overridenVfun()
      ,* and BaseB::overridenVfun(). As a result, both base classes will share the derived class 
      ,* implementation.
      ,*/
      #if true
      std::string overridenVfun() override {
           return "Both functions overriden, BaseA::overridenVfun() and BaseB::overridenVfun(). OK.";
      }
      #endif 

      // std::string specificAVFun() override {
      std::string specificAVFun() override{
          return "Overriden: specificAVFun";
      }
      std::string specificBVFun() override {
          return "Overriden: specificBVFun";
      }

      static void staticMethod(){
         std::cout << " [Derived] I am a static method from Derived" << "\n";
      }
  };
#+END_SRC

Loading the code in ROOT REPL: 

#+BEGIN_SRC cpp 
  >> .L inheritance-multiple-ambiguity.cpp 
#+END_SRC

Creating an instance of derived class named Derived.

#+BEGIN_SRC cpp 
  >> Derived d;
   [LOG] BaseA instantiated. OK.
   [LOG] BaseB instantiated. OK.
  >> 
#+END_SRC

 *Access ambiguous publi field*

 + Problem:

#+BEGIN_SRC cpp 
  // FAILURE - Compilation error: 
  >> d._name
  ROOT_prompt_2:1:3: error: member '_name' found in multiple base classes of different types
  d._name
    ^
  inheritance-multiple-ambiguity.cpp:12:14: note: member found by ambiguous name lookup
          std::string _name;
                      ^
  inheritance-multiple-ambiguity.cpp:53:14: note: member found by ambiguous name lookup
          std::string _name;
#+END_SRC

 + Solution: Use fully qualified field name. ~d.BaseA::_name~ or
   ~d.BaseB::_name~. Or upcast pointer from derived to pointer to base class.

#+BEGIN_SRC cpp
    
  // SOLUTION: 
  >> d.BaseA::_name
  (std::string &) "nameA"

  >> d.BaseB::_name
  (std::string &) "nameB"

  // Pointer to derived 
  >> Derived* ptr_derived = &d;

  >> ptr_derived->BaseA::_name
  (std::string &) "nameA"

  >> ptr_derived->BaseB::_name
  (std::string &) "nameB"

  // Access/refer by pointer - BaseA
  >> BaseA* ptr_baseA = &d;

  >> ptr_baseA->_name
  (std::string &) "nameA"

  // Access/refer by pointer - BaseB
  >> BaseB* ptr_baseB = &d;

  >> ptr_baseB->_name
  (std::string &) "nameB"
#+END_SRC

 *Call non-ambiguous methods* 

#+BEGIN_SRC cpp 
  >> d.printNameA()
   [printNameA] => NameA = nameA
  // OR:
  >> d.BaseA::printNameA()
   [printNameA] => NameA = nameA

  >> d.printNameB()
   [PrintName] => NameB = nameB
 
  // OR
  >> d.BaseA::printNameA()
   [printNameA] => NameA = nameA
 
#+END_SRC

 *Call ambiguous method printName:*

 - Problem:

#+BEGIN_SRC cpp 
  // COMPILATION ERROR:
  >> d.printName()
  ROOT_prompt_5:1:3: error: member 'printName' found in multiple base classes of different types
  d.printName()
    ^
  inheritance-multiple-ambiguity.cpp:20:7: note: member found by ambiguous name lookup
          void printName(){
               ^
  inheritance-multiple-ambiguity.cpp:61:7: note: member found by ambiguous name lookup
          void printName(){
               ^
#+END_SRC

 - Solution:

#+BEGIN_SRC cpp 
  >> d.BaseA::printName()
   A - [printName] => Name = nameA

  >> d.BaseB::printName()
   B - [printName] => Name = nameB
  >> 

  // Access/refer by pointer - BaseA
  >> BaseA* ptr_baseA = &d;

  >> ptr_baseA->printName()
   A - [printName] => Name = nameA

  >> ptr_baseA->_name
  (std::string &) "nameA"
  >> 

  // Access/refer by pointer - BaseA
  >> BaseB* ptr_baseB = &d;

  >> ptr_baseB->printName()
   B - [printName] => Name = nameB

  >> ptr_baseB->_name
  (std::string &) "nameB"
  >> 

#+END_SRC

 *Invoke Overriden Virtual Function* 

 + If a base class overrides a virtual member function required by
   multiple base classes, all of them will share the same
   implementation supplied by the derived class. There is no way to
   override or supply a different implementations to each one of them
   in the derived class.

#+BEGIN_SRC cpp
  >> d.overridenVfun()
  (std::string) "Both functions overriden, BaseA::overridenVfun() and BaseB::overridenVfun(). OK."
  >> 

  >> d.BaseB::overridenVfun()
  (std::string) " BaseB::overridenVfun not overriden"
  >> 

  // Access/refer by pointer - BaseA
  >> BaseA* ptr_baseA = &d;

  >> ptr_baseA->overridenVfun()
  (std::string) "Both functions overriden, BaseA::overridenVfun() and BaseB::overridenVfun(). OK."

  // Access/refer by pointer - BaseB
  >> BaseB* ptr_baseB = &d;

  >> ptr_baseB->overridenVfun()
  (std::string) "Both functions overriden, BaseA::overridenVfun() and BaseB::overridenVfun(). OK."
  >> 
#+END_SRC

 *Invoke method callOverridenVFun*

#+BEGIN_SRC cpp 
  // Compilation error: 
  >> d.callOverridenVFun()
  ROOT_prompt_19:1:3: error: member 'callOverridenVFun' found in multiple base classes of different types
  d.callOverridenVFun()

  >> d.BaseA::callOverridenVFun()
   [BaseB::callOverridenVFun] BaseB::overridenVfun() returned
   +=> RETURN = Both functions overriden, BaseA::overridenVfun() and BaseB::overridenVfun(). OK.

  >> d.BaseB::callOverridenVFun()
   [BaseB::callOverridenVFun] BaseB::overridenVfun() returned
   +=> RETURN = Both functions overriden, BaseA::overridenVfun() and BaseB::overridenVfun(). OK.
  >> 

  // Access/refer by pointer - BaseA
  >> BaseA* ptr_baseA = &d;

  // No ambiguity happens 
  >> ptr_baseA->callOverridenVFun()
   [BaseB::callOverridenVFun] BaseB::overridenVfun() returned
   +=> RETURN = Both functions overriden, BaseA::overridenVfun() and BaseB::overridenVfun(). OK.
  >> 

  // Access/refer by pointer - BaseB
  >> BaseB* ptr_baseB = &d;

  >> ptr_baseB->callOverridenVFun()
   [BaseB::callOverridenVFun] BaseB::overridenVfun() returned
   +=> RETURN = Both functions overriden, BaseA::overridenVfun() and BaseB::overridenVfun(). OK.
#+END_SRC

Call functions showKeyBaseA and showKeyBaseB:

#+BEGIN_SRC cpp 
  >> d.showKeyBaseA()
   [showKeyBaseA] Key-BaseA = KEY-BASEA
   [showKeyBaseA] Key-BaseA = KEY-BASEA
  >> 
  >> d.showKeyBaseB()
   [showKeyBaseB] Key-BaseB = KEY-BASEB
   [showKeyBaseB] Key-BaseB = KEY-BASEB
  >> 
#+END_SRC

Invoke a non-overriden ambiguous virtual function.

#+BEGIN_SRC cpp
  >> d.nonOverridenVfun()
  ROOT_prompt_40:1:3: error: member 'nonOverridenVfun' found in multiple base classes of different types
  d.nonOverridenVfun()
    ^

  >> d.BaseA::nonOverridenVfun()
  (std::string) "BaseA::nonOverridenVfun"
  >> 

  >> d.BaseB::nonOverridenVfun()
  (std::string) "BaseB::nonOverridenVfun"
  >> 

  // Pointer to derived 
  >> Derived* ptr_derived = &d;

  >> ptr_derived->BaseA::nonOverridenVfun()
  (std::string) "BaseA::nonOverridenVfun"
  >> 
  >> ptr_derived->BaseB::nonOverridenVfun()
  (std::string) "BaseB::nonOverridenVfun"
  >> 
#+END_SRC

Call static methods:

#+BEGIN_SRC cpp 
  >> BaseA::staticMethod()
   [BaseA] I am a static method from BaseA

  >> BaseB::staticMethod()
   [BaseB] I am a static method from BaseB

  >> Derived::staticMethod()
   [Derived] I am a static method from Derived
  >>

  >> d.staticMethod()
   [Derived] I am a static method from Derived
  >> 

  >> d.BaseA::staticMethod()
   [BaseA] I am a static method from BaseA

  >> d.BaseB::staticMethod()
   [BaseB] I am a static method from BaseB
  >> 

  // Pointer to derived 
  >> Derived* ptr_derived = &d;

  >> ptr_derived->staticMethod()
   [Derived] I am a static method from Derived
  >> 

  // Access/refer by pointer - BaseA
  >> BaseA* ptr_baseA = &d;

  // Access/refer by pointer - BaseB
  >> BaseA* ptr_baseB = &d;

  >> ptr_baseA->staticMethod()
   [BaseA] I am a static method from BaseA

  >> ptr_baseB->staticMethod()
   [BaseB] I am a static method from BaseB
  >> 
#+END_SRC
*** TODO OOP Diamond problem 
*** References and further reading: 

 + [[https://herbsutter.com/2013/05/22/gotw-5-solution-overriding-virtual-functions/][GotW #5 Solution: Overriding Virtual Functions | Sutter’s Mill]]

 + [[http://www.gotw.ca/gotw/069.htm][GotW #69: Enforcing Rules for Derived Classes]]

 + [[https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/cplr138.htm][IBM Knowledge Center - Ambiguous base classes (C++ only)]]

 + [[https://drive.google.com/viewerng/viewer?url=https://www.cs.bgu.ac.il/~spl181/wiki.files/Lecture5_OOP.pptx][Lecture 5 - Inheritance, Polymorphism and The Object Memory Model]]

 + [[http://www.msg.ucsf.edu/local/programs/IBM_Compilers/C:C++/html/language/ref/clrc14cplr140.htm#HDRCPLR140][Ambiguous Virtual Function Calls]]

 + [[http://architectworkshop.com/martin/papers/separation.pdf][The Separation of Interface and Implementation in C++]] 

 + [[https://slideplayer.com/slide/10302342/][Unit IV]] 

 + [[https://drive.google.com/viewerng/viewer?url=http://www.cs.nuim.ie/~markh/paradigms/CS351Lect10.ppt][CS351 - Programming Paradigms - Inheritance and Polymorphism]]

 + [[http://hep.ph.liv.ac.uk/~gwilliam/cppcourse/lecture8.pdf][Introduction to Programming using C++]] 

 + [[https://softwareengineering.stackexchange.com/questions/246273/code-re-use-in-c-via-multiple-inheritance-or-composition-or][interfaces - Code re-use in C++, via multiple inheritance or composition? Or...? - Software Engineering Stack Exchange]]

 + [[https://stackoverflow.com/questions/18529277/overriding-functions-from-two-abstract-base-classes-that-differ-only-by-their][c++ - Overriding functions (from two abstract base classes) that differ only by their return value - Stack Overflow]]

 + [[https://stackoverflow.com/questions/18398409/c-inherit-from-multiple-base-classes-with-the-same-virtual-function-name][C++ inherit from multiple base classes with the same virtual function name - Stack Overflow]]

 + [[https://stackoverflow.com/questions/28556872/ambiguous-inheritance-of-function-when-multiple-inheritance-of-classes-that-them][c++ - Ambiguous inheritance of function when multiple inheritance of classes that themselves have diamond inheritance in their hierarchy - Stack Overflow]]
** Type Casting / Type Conversion
*** Overview  

In addition to the old C-style castiung, C++ supports new casting
operators which are more type-safe and make the program's intent
explicit, thus enhancing the readability and maintanability. 

 *C-style Casting*

 + (NEW-TYPE) <EXPRESSION>
 + Note: should be avoided.
 + Example:
   + char x = (char) 65;

 *C++ Sytle-Casting*

  - ~static_cast<TYPE>(EXPR)~
    * Use-case: implicity type conversion of related types, conversion
      of base class to derived class, void* pointer to othe pointer
      (except function pointer.). static_cast is the most used C++
      casting operator.
    * When happens: this casting is performed at compile-time.
    * Can:
      * Convert between related types such as char to int, int to
        double,
      * Convert from and to void* pointer to other pointers: void* to
        double*, double* to void* and so on. 
      * Convert base class to derived class (downcasting).
    * Cannot:
      * Convert between unrelated types such as _unsigned long_ to _double*_.
      * Convert between pointers of unrelated types, for instance int*
        to double* or unsigned long to double*.

  - ~reinterpret_cast<TYPE>(EXPR);~
    * Use-cases: This is a dangerous low level casting used for
      converting unrelated types. WARNING: failed conversion can
      result in segmentation fault, core dump and subtle crashing use
      with care. 
      * Converting pointers of unrelated types such as double* to int*
      * Convert void* to function pointer.
        * Loading C-functions from shared libraries (.DLL files on
          Windows or .SO on U-nix, Linux, BSD, OSX ...)
        * Implement type erasure of function-pointers for reflection
          libraries.
      * Access hardware registers of Embedded Systems (_memory mapped_
        _IO_). Many embedded systems such as microcontrollers have
        memory mapped-IO which are hardware devices like Analog to
        Digital Convertes, digital Input/Output ports bound to
        specific memory addresses assigned by the manufacturer. By
        writing to those memory locations, it is possible to
        configure, control and read data from hardware
        devices. ~reinterpret_cast~ can be used for converting the
        numerical address given in usigned hexadecimal to some pointer
        of type int*, char*, double* and so on. 

  - ~dynamic_cast<TYPE>(EXPR);~
    * Use cases: Casting for polymorphic types, class hierachies for
      identifying at runtime instances of derived classes. This is
      part of the C++ RTTI - Runtime Type Identification. 
    * When happens: this casting is performed at run-time.

  - ~const_cast<TYPE>(EXPR);~
    - Use-case: Create non-const reference to const variable, so it
      can bypass the const constraint. 

*** Example: Old C-Style Casting: 

#+BEGIN_SRC cpp 
  >> int k = 10;
  >> int z = 7;

  >> (float) k
  (float) 10.0000f

  >> float(k) / z
  (float) 1.42857f
  >> 

  >> int m = 65
  (int) 65
 
  >> (char) m
  (char) 'A'
  >> 

  >> (char) (m+1)
  (char) 'B'
  >> (char) (m+2)
  (char) 'C'
  >> (char) (m+3)
  (char) 'D'
  >> (char) (m+5)
  (char) 'F'
  >> 
#+END_SRC

*** Example: Static Casting 

 - *Implicit conversion:*

#+BEGIN_SRC cpp 
  >> int k = 10;
  >> int z = 7;

  >> k / z
  (int) 1

  >> static_cast<double>(k) / z
  (double) 1.4285714

  >> static_cast<float>(k) / z
  (float) 1.42857f
  >> 

  >> int m = 65;
  >> char ch;
  >> ch = m
  (char) 'A'
  >> 
  // Implicit conversion 
  >> ch = static_cast<char>(m)
  (char) 'A'
  >> ch = static_cast<char>(m + 1)
  (char) 'B'
  >> ch = static_cast<char>(m + 2)
  (char) 'C'
  >> ch = static_cast<char>(m + 3)
  (char) 'D'
  >> 
#+END_SRC

 - *Pointer conversion:*

Conversion between pointer of unrelated types is not possible with
static casting. 

#+BEGIN_SRC cpp 

  >> double x = 10.2;
  >> int k = 10;
  >> x
 
  >> static_cast<int*>(&x)
  ROOT_prompt_5:1:1: error: static_cast from 'double *' to 'int *' is not allowed
  static_cast<int*>(&x)
  ^~~~~~~~~~~~~~~~~~~~~
  >> 


#+END_SRC

Conversion to and from void pointer to other pointer types (except
function pointer) is possible: 

#+BEGIN_SRC cpp 
  >> double x = 10.2;
  >> int k = 10;

  >> static_cast<void*>(&x)
  (void *) 0x7f639f3ca010
  >> 
  >> void* ptrErased = static_cast<void*>(&x)
  (void *) 0x7f639f3ca010
  >> 
  >> static_cast<double*>(ptrErased)
  (double *) 0x7f639f3ca010
  >> *static_cast<double*>(ptrErased)
  (double) 10.200000
  >> 

  >> ptrErased = &k
  (void *) 0x7f639f3ca018
  >> static_cast<double*>(ptrErased)
  (double *) 0x7f639f3ca018

  // However, it may fail without any notice. 
  >> *static_cast<double*>(ptrErased)
  (double) 4.9406565e-323
  >> 

  >> static_cast<int*>(ptrErased)
  (int *) 0x7f639f3ca018
  >> *static_cast<int*>(ptrErased)
  (int) 10
  >> 

#+END_SRC

Conversion from number (numeric value of address) to to pointer is not
possible with static casting.

#+BEGIN_SRC cpp 
  >> &x
  (double *) 0x7f639f3ca010
  >> 
  >> double* ptrX = static_cast<double*>(0x7f639f3ca010)
  ROOT_prompt_18:1:16: error: cannot cast from type 'long' to pointer type 'double *'
  double* ptrX = static_cast<double*>(0x7f639f3ca010)
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  >> double* ptrX = static_cast<double*>(0x7f639f3ca010UL)
  ROOT_prompt_19:1:16: error: cannot cast from type 'unsigned long' to pointer type 'double *'
  double* ptrX = static_cast<double*>(0x7f639f3ca010UL)
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  >> 
#+END_SRC

 - *Conversion between polymorphic types* / Classes from a given
   hierarchy.

#+BEGIN_SRC cpp 
  using cstring = const char*;

  class Base {
  public:
          Base() = default;
          virtual ~Base() = default;
          virtual cstring getID() const {
                  return "Base";
          }
  };

  class DerivedA: public Base{
  public:
           cstring getID() const override {
                  return "DerivedA";
          }
          void showA(){
                  std::cout << "Exclusive method of class A." << "\n";
          }
  };

  class DerivedB: public Base{
  public:
          cstring getID() const override {
                  return "DerivedB";
          }
          double method(double x){
                  return 3 * x;
          }
          void showB(){
                  std::cout << "Exclusive method of class B." << "\n";
          }
  };

  Base     b;
  DerivedA da;
  DerivedB db;

  Base* ptr = nullptr;

  >> ptr = &b
  (Base *) 0x7fd81941b010
  >> ptr->getID()
  (cstring) "Base"
  >> 

  >> ptr = &da;
  >> ptr->getID()
  (cstring) "DerivedA"

  >> ptr = &db;
  >> ptr->getID()
  (cstring) "DerivedB"
  >> 

  // Downcast/Convert at compile-time pointer from the base class
  // to derived class
  //-------------------------------------------------
  // Try access exclusive method:
  >> ptr = &da;
  >> ptr->showA()
  ROOT_prompt_42:1:6: error: no member named 'showA' in 'Base'
  ptr->showA()
  ~~~  ^

  >> static_cast<DerivedA*>(ptr)->getID()
  (cstring) "DerivedA"

  >> static_cast<DerivedA*>(ptr)->showA()
  Exclusive method of class A.
  >> 

  // Note: Can result in undefined behavior!
  >> static_cast<DerivedB*>(ptr)->showB()
  Exclusive method of class B.

  >> 
  >> ptr = &db;
  >> static_cast<DerivedB*>(ptr)->getID()
  (cstring) "DerivedB"
  >> static_cast<DerivedB*>(ptr)->showB()
  Exclusive method of class B.
  >> static_cast<DerivedB*>(ptr)->method(3.0)
  (double) 9.0000000
  >> 
#+END_SRC
 

 - *Conversio from/to void* to function pointer is not possible. 

#+BEGIN_SRC cpp 
  >> double someFunction(int x, int y){ return 3.0 * x + y; }

  >> someFunction(3, 5)
  (double) 14.000000

  >> void* ptrErasure = nullptr;

  >> ptrErasure = static_cast<void*>(someFunction)
  ROOT_prompt_26:1:14: error: static_cast from 'double (*)(int, int)' to 'void *' is not allowed
  ptrErasure = static_cast<void*>(someFunction)
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  // However, it is possible with the old C-style casting. 
  >> ptrErasure = (void*) &someFunction
  (void *) 0x7f639f3730a0

  // Or: 
  >> ptrErasure = (void*) someFunction
  (void *) 0x7f639f3730a0
  >> 

  // But, it works with C-style casting.
  >> auto fnPointer2 = (double (*)(int, int)) ptrErasure
  (double (*)(int, int)) Function @0x7f639f3730a0
  >> 
  >> fnPointer2(3, 4)
  (double) 13.000000
  >> fnPointer2(5, 4)
  (double) 19.000000

#+END_SRC

*** Example: Reinterpret Cast 

 + Casting function/pointer from and to void*
   - Note: this is useful for type erasure and reflection and loading
     functions/symbols from shared libraries at runtime.

#+BEGIN_SRC cpp 
  double someFunction(int x, int y){ return 3.0 * x + y; }
  double mfun1(double x){ return x * x + 10 * x - 25; }

  void* ptrErasure = nullptr;

  // Testing function some function:
  >> ptrErasure = reinterpret_cast<void*>(&someFunction)
  (void *) 0x7fe3b065a080

  >> auto fnPtr1 = reinterpret_cast<double (*) (int, int)>(ptrErasure)
  (double (*)(int, int)) Function @0x7fe3b065a080
	
  >> fnPtr1(3, 5)
  (double) 14.000000
  >> fnPtr1(5, 5)
  (double) 20.000000
  >> 
  >> reinterpret_cast<double (*) (int, int)>(ptrErasure)(3, 5)
  (double) 14.000000
  >> reinterpret_cast<double (*) (int, int)>(ptrErasure)(4, 5)
  (double) 17.000000
  >> 

  // Testing with mfun
  // --> C-style casting 	
  >> ptrErasure = (void*) mfun1
  (void *) 0x7f94856da090
  >> ptrErasure = (void*) &mfun1
  (void *) 0x7f94856da090
  >> 

  // Failed 	
  >> ptrErasure = static_cast<void*>(&mfun1)
  ROOT_prompt_7:1:14: error: static_cast from 'double (*)(double)' to 'void *' is not allowed
  ptrErasure = static_cast<void*>(&mfun1)

  >> auto fnPtr2 = reinterpret_cast<double (*) (double)>(mfun1)
  (double (*)(double)) Function @0x7f94856da090

  >> fnPtr2(4)
  (double) 31.000000
  >> fnPtr2(5)
  (double) 50.000000
  >> 

  // It is really dangerous as it can cast anything to anything!
  // and the compiler cannot help.	
  >> reinterpret_cast<double (*) (double)>(4)(5)
  // *** Break *** segmentation violation

#+END_SRC

 + Cast address/pointer to int and print it in hexadecimal format.

#+BEGIN_SRC cpp 
  >> 
  >> double x;
  >> &x
  (double *) 0x7fd510b760a0
  >> 
  >> std::cout << std::hex << "0x" << reinterpret_cast<std::uintptr_t>(&x) << std::dec << "\n";
  0x7fd510b760a0

  void printAddress(void* ptr){
       std::cout << "Address of variable is = " 
                 << std::hex << "0x" << reinterpret_cast<std::uintptr_t>(ptr)
                 << std::dec 
                 << "\n";
  }


  >> std::string s
  (std::string &) ""
  >> &s
  (std::string *) 0x7fd510b760b0
  >> 
  >> double m
  (double) 0.0000000
  >> 
  >> printAddress(&s)
  Address of variable is = 0x7fd510b760b0
  >> printAddress(&m)
  Address of variable is = 0x7fd510b760d0
#+END_SRC

 + Casting memory locations to pointer.
   + Note: It doesn't have applicability in most cases, but it can be
     useful for accessing memory mapped IO.

#+BEGIN_SRC cpp 
  >> double x = 10.0
  (double) 10.000000
  >> unsigned long n = 300
  (unsigned long) 300
  >> 

  >> &x
  (double *) 0x7f3fd32e9010
  >> &n
  (unsigned long *) 0x7f3fd32e9018
  >> 

  // =========== Variable x =================

  // Failure! Doesn't compile
  >> static_cast<double*>(0x7f3fd32e9010)
  ROOT_prompt_4:1:1: error: cannot cast from type 'long' to pointer type 'double *'
  static_cast<double*>(0x7f3fd32e9010)
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  >> 
  >> reinterpret_cast<double*>(0x7f3fd32e9010)
  (double *) 0x7f3fd32e9010
  >> *reinterpret_cast<double*>(0x7f3fd32e9010)
  (double) 10.000000
  >> *reinterpret_cast<double*>(0x7f3fd32e9010) = 100.0
  (double) 100.00000
  >> x
  (double) 100.00000
  >> 

  // =========== Variable n =================
  >> reinterpret_cast<int*>(0x7f3fd32e9018)
  (int *) 0x7f3fd32e9018
  >> *reinterpret_cast<int*>(0x7f3fd32e9018)
  (int) 300
  >> *reinterpret_cast<int*>(0x7f3fd32e9018) = 100
  (int) 100
  >> int& z = *reinterpret_cast<int*>(0x7f3fd32e9018)
  (int) 100
  >> z  = 500
  (int) 500
  >> n
  (unsigned long) 500
  >> n = 600
  (unsigned long) 600
  >> z
  (int) 600
  >> 
#+END_SRC

 + Load Symbols from a DLL / Shared Object
   + Note: Windows uses the Win32 API-Calls [[https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-loadlibrarya][LoadLibrary]], LoadLibraryA,
     LoadLibraryW, [[https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-getprocaddress][GetProcAddress]] and so on. 

#+BEGIN_SRC cpp 
  #include <dlfcn.h>

  // GNU Scientific Library - Linear Algebra CBLAS 
  auto dllPath = "/usr/lib64/libgslcblas.so";

  >> void* libHandle = dlopen(dllPath, RTLD_LAZY)
  (void *) 0x1be2de0
  >> 

  >> void* sym = dlsym(libHandle, "cblas_daxpy")
  (void *) 0x7f3fb97d2010

  >> sym == nullptr
  (bool) false
  >> 

  >> auto cblas_daxpy = reinterpret_cast<void (*) (int, double, const double*, int, double*, int)>(sym)
  (void (*)(int, double, const double *, int, double *, int)) Function @0x7f3fb97d2010
  >> 

  // Or 
  using cblas_daxpy_type = void (int, double, const double*, int, double*, int);

  >> auto xs = std::vector<double>{ 3.0, 5.0, 6.0, 10.0, 8.0};
  >> auto ys = std::vector<double>{ 2.0, 2.0, 2.0,  2.0, 2.0};
  >> 

  >> cblas_daxpy(xs.size(), 4.0, &xs[0], 1, &ys[0], 1)
  >> xs
  (std::vector<double, std::allocator<double> > &) 
  { 3.0000000, 5.0000000, 6.0000000, 10.000000, 8.0000000 }

  >> ys
  (std::vector<double, std::allocator<double> > &) 
  { 14.000000, 22.000000, 26.000000, 42.000000, 34.000000 }
  >> 

  // Close the library handle (Better use SMART POINTERS!!!!)
  >> dlclose(libHandle)
  (int) 0
  >> 
#+END_SRC

*** Example: Const cast 

Const cast is used for removing the const qualifier/modifier from const
reference or const pointer in order to modify the referenced memory
location. 

  + Note: The const cast cannot be used for removing the const
    qualifierfrom const variables. In this case the casting behavior
    is undefined.
  + Documentation: [[https://en.cppreference.com/w/cpp/language/const_cast][const_cast conversion - cppreference.com]]

#+BEGIN_SRC cpp 
  >> double x = 10.0;
  >> const double& xref = x;
  >> xref
  (const double) 10.000000
  >> 
  >> xref = 20.0
  ROOT_prompt_3:1:6: error: cannot assign to variable 'xref' with const-qualified type 'const double &'
  xref = 20.0
  ~~~~ ^
  ROOT_prompt_1:1:15: note: variable 'xref' declared const here
  const double& xref = x;
  ~~~~~~~~~~~~~~^~~~~~~~
  >> 
  // Remove the const qualifier of xref 
  >> const_cast<double&>(xref) = 25.0
  (double) 25.000000
  >> x
  (double) 25.000000
  >> xref
  (const double) 25.000000
  >> 

  // Creating a non-const reference from a const reference.
  >> double& usualRef = const_cast<double&>(xref) 
  (double) 25.000000
  >> usualRef = 16.0
  (double) 16.000000
  >> x
  (double) 16.000000
  >> xref
  (const double) 16.000000
  >> 
#+END_SRC

*** References and further reading

 - Cambridge University - *Casting in C++ (intermediate level)* -
   <http://www-h.eng.cam.ac.uk/help/tpl/languages/C++/casting.html> 

 - *4.4a — Explicit type conversion (casting)* -
   <http://www.learncpp.com/cpp-tutorial/4-4a-explicit-type-conversion-casting/> 

 - https://anteru.net/blog/2007/12/18/200/index.html

 - *Casting operators in C++ | Set 1 (const_cast)* -
   <http://www.geeksforgeeks.org/casting-operators-in-c-set-1-const_cast/>

 - *Casting – what could possibly go wrong?* -
   <https://blog.feabhas.com/2013/09/casting-what-could-possibly-go-wrong/>

 - *C++ Casting, or: "Oh No, They Broke Malloc!* -
   <https://embeddedartistry.com/blog/2017/2/28/c-casting-or-oh-no-we-broke-malloc> 

 - *When should static_cast, dynamic_cast, const_cast and
   reinterpret_cast be used?* - <https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used>

 - http://cppblogs.blogspot.com.br/2013/08/c-style-casts.html

 - *Type-Conversion operators* -
   <http://www.bogotobogo.com/cplusplus/typecast.php>
** OOP RTTI - Runtime Type Identification 
*** Overview 

RTTI - Runtime Type Identification is the ability to provide
information about types at rutime rather than at compile time. It is a
limited form of reflection. In C++, the RTTI functionality is provided
by the operators *typeid* getting type information and *dynamic_cast* used
for safely casting polymorphic types.

 *RTTI in C++:*

 + Operator *dynamic_cast*
 + Operator *typeid*
 + Class      std::type_info
 + Exception: std::bad_typeid (derived class of std::exception)

 *Further Reading* 

 + *Inneficiences of C++ - Fact or Fiction*
   + <https://www.iar.com/globalassets/about-us/events/atc2015/inefficiencies-of-c.pdf>

 + *How C++ Works*
   + <http://pages.cpsc.ucalgary.ca/~bdstephe/585_W11/d403_C++.pdf>

 + *Const, RTTI and Efficiency*
   + <https://www.artima.com/intv/const2.html>

 + *RTTI and Reflection*
   + <http://www.cs.huji.ac.il/course/2004/ood/docs/lec08.pdf>

 + *Visual RTTI Inspection*
   + https://blog.quarkslab.com/visual-c-rtti-inspection.html

 + *C++ RTTI - casting around*
   + http://www.two-sdg.demon.co.uk/curbralan/papers/RTTI.html

 + *Practical RTTI For Games*
   + https://gamedevcoder.wordpress.com/2013/02/16/c-plus-plus-rtti-for-games/

 + [[https://stackoverflow.com/questions/281818/unmangling-the-result-of-stdtype-infoname][c++ - Unmangling the result of std::type_info::name - Stack Overflow]]

 + [[https://stackoverflow.com/questions/579887/how-expensive-is-rtti][c++ - How expensive is RTTI? - Stack Overflow]]
 
*** Operator typeid 

The operator typeid retrives information about a given type by
returning a reference to an object of type _typeinfo_.

Header: 
 + <typeinfo>

 *Operator typeid:*

 + Documentaiton: [[https://en.cppreference.com/w/cpp/language/typeid][typeid operator - cppreference.com]]

#+BEGIN_SRC cpp
 const typeinfo& typeid(ARGUMENT);
#+END_SRC

Use cases: 

 + Compare types.
 + Recover wrapped type from type erasure. This approach is used by
   Boost.Any and std::any from C++17.
 + Debugging 

 *Class std::type_info:*

 + Documentation: [[https://en.cppreference.com/w/cpp/types/type_info][std::type_info - cppreference.com]]

#+BEGIN_SRC cpp 
  class type_info{
  public:
     virtual ~type_info();
     bool operator==(cons type_info& rhs) const;
     bool operator!=(cons type_info& rhs) const;
     bool before( const type_info& rhs ) const;
     const char* name() const;
     // Since: C++11
     size_t hash_code() const;
  };
#+END_SRC

Note: the type name returned by method .name() of type_info returns
the decorated name of type or the mangled name of type. The value
returned is compiler-dependent which means that a code should not rely
on the returned name. 

 *Example:*

Get type name: 

#+BEGIN_SRC cpp
  >> typeid(int).name()
  (const char *) "i"

  >> typeid(double).name()
  (const char *) "d"

  >> typeid(float).name()
  (const char *) "f"

  >> typeid(long).name()
  (const char *) "l"

  >> typeid(int*).name()
  (const char *) "Pi"

  >> typeid(double*).name()
  (const char *) "Pd"

  >> typeid(float*).name()
  (const char *) "Pf"

  >> typeid(long*).name()
  (const char *) "Pl"

  >> typeid(void).name()
  (const char *) "v"

  >> typeid(void*).name()
  (const char *) "Pv"

  >> typeid(void**).name()
  (const char *) "PPv"
  >> 

  >> typeid(std::vector<double>).name()
  (const char *) "St6vectorIdSaIdEE"

  >> typeid(std::deque<double>).name()
  (const char *) "St5dequeIdSaIdEE"
#+END_SRC

Explore type_info object:

#+BEGIN_SRC cpp 
  >> const std::type_info& ti = typeid(3.434);
  >> ti.name()
  (const char *) "d"

  >> ti.hash_code()
  (unsigned long) 14494284460613645429

  // Check whether type is int 
  >> ti == typeid(int)
  (bool) false

  // Check whether type is double 
  >> ti == typeid(double)
  (bool) true

  // Return the managled name of type 
  >> typeid(std::string).name()
  (const char *) "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"
 
  >> typeid(std::string*).name()
  (const char *) "PNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"


  >> typeid(std::string).hash_code()
  (unsigned long) 5774750460303204477
#+END_SRC

typeid and polymorphic types: 

#+BEGIN_SRC cpp 
  class Base{ virtual void dummy(){} };
  class Da: public Base{};
  class Db: public Base{};

  >> typeid(Base).name()
  (const char *) "4Base"

  >> typeid(Da).name()
  (const char *) "2Da"

  >> typeid(Db).name()
  (const char *) "2Db"

  >> typeid(Base*).name()
  (const char *) "P4Base"

  >> typeid(Da*).name()
  (const char *) "P2Da"
#+END_SRC

*** Operator dynamic_cast 

The operator _dynamic_cast_ is used for safely downcasting a base class
to a particular derived class and is also for checking whether a
pointer to the base class refers to an instance of a particular
derived class. In general, dynamic casting should be avoided as it
violates OOP good practices, for instance, the client code in most
cases should have no knowledge about which particular derived class it
is dealing with and it also should be able to work with new derived
classes without any modification. The usage of dynamic cast and
if-else in a client code for performing operation specific for each
derived class can be avoided by adding new a virtual member function
to the base class or by using the visitor design pattern or double
dispatching. 

The operator _static_cast_ can also be used for downcasting, however if
the operation is not possible, the result is undefined, thus using
_static_cast_ is unsafe. It is only safe using _static_cast_, if there is
no doubt that the conversion is possible.

Dynamic cast use case(s): 
 
 + Extend the functionality of a class hierarchy without modifying the
   base class or adding new virtual member functions. However, it will
   require modification of client code if a new derived class is
   created. 

Notes and remarks: 

 + The operator _dynamic_cast_ only works with polymorphic types, in
   other words, any class with at least one virtual member function.

 + _dynamic_cast_ operator only works with _pointers_  or _references_ to
   classes with at least one virtual method. 

 + _static_cast_ downcasting is unsafe. There is undefined behavior if
   the conversion is not possible.

 + _static_cast_ is a compile-time construct.

 + _dynamic_cast_ is a run-time construct.

 *Casting Pointers*

If the conversion fails, the pointer to the derived class is set to
null and no exception is thrown. 

#+BEGIN_SRC cpp 
  BaseClass* pointerToBase = &objectOfDerivedA;

  // Downcast pointer from base to derived class
  DerivedClass* pointertoDerived = dynamic_cast<DerivedClass*>(pointerToBase);
  // Or
  auto pointertoDerived = dynamic_cast<DerivedClass*>(pointerToBase);

  if(pointertoDerived){
    std::cout << "It is the derived class" << "\n";
    pointertoDerived->exclusiveMethod1();
    ... ... .. 
  } else { 
    std::cout << "Conversion failed." << "\n";
  }
#+END_SRC

 *Casting References*

In this case, if the casting fails, it throws a *std::bad_cast*
exception. 

#+BEGIN_SRC cpp 
   BaseClass& refBaseClass = objectOfDerivedA;   
   try{
      // Downcast reference 
      DerivedClass& refDerived = dynamic_cast<DerivedClass&>(refBaseClass);
      std::cout << "Found derived class ..." << "\n";
      refDerived.exclusiveMethod1(); 
      refDerived.exclusiveMethod2(); 
   } catch(const std::bad_cast& ex){
      std::cerr << "Error: casting not possible." << "\n";
      std::cerr << " [ERROR] " << ex.what() << "\n";
   }

#+END_SRC

 *Example:*

#+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";
     }
  };

  class DerivedA: public Base{
  public:
     DerivedA(){}
     auto getType() const  -> std::string {
        return "DerivedA";
     }
  };

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

Creating testing objects: 

#+BEGIN_SRC cpp 
  Base base;
  DerivedA da;
  DerivedB db;
 #+END_SRC

#+BEGIN_SRC cpp 
>> Base *ptr = nullptr;

// Point to stack-object base 
>> ptr = &base
(Base *) 0x7f6d9a022010

// Check whether pointed object is of type base 
>> Base* ptrBase = dynamic_cast<Base*>(ptr);

>> if(ptrBase) { std::cout << "Object of type Base" << "\n";}
Object of type Base
>> 

>> if(dynamic_cast<Base*>(ptr)) { std::cout << "Object of type Base" << "\n";}
Object of type Base
>> 
#+END_SRC

Point to the object da (DerivedA)

#+BEGIN_SRC cpp
  >> ptr = &da;

  // Cast pointer 
  >> DerivedA* ptrDA = dynamic_cast<DerivedA*>(ptr)
  (DerivedA *) 0x7f6d9a022018

  >> if(ptrDA != nullptr){ std::puts("Object of type DerivedA"); }
  Object of type DerivedA

  >> if(ptrDA){ std::puts("Object of type DerivedA"); }
  Object of type DerivedA
  >> 

  >> ptrDA->showType()
  Class type = DerivedA
  >> 

  // Check whether pointer refers to an object of type DerivedA
  >> if(dynamic_cast<DerivedA*>(ptr)) { std::cout << "Object of type A" << "\n";}
  Object of type A
#+END_SRC

Check whether pointer refers to an object of type DerivedB

 + If the casting is not possible, the dynamic_cast operator returns a
   null pointer. 

#+BEGIN_SRC cpp 
  >> ptr = &da;

  >> DerivedB* ptrDB = dynamic_cast<DerivedB*>(ptr)
  (DerivedB *) nullptr
  >> 

  >> if(ptrDB != nullptr) { std::puts("=> Type DerivedB"); } else { std::puts("Casting failed"); }
  Casting failed
  >> 

  >> if(ptrDB){ std::puts("=> Type DerivedB"); } else { std::puts("Casting failed"); }
  Casting failed
  >> 

  >> if(dynamic_cast<DerivedB*>(ptr)) { std::puts("=> Type DerivedB"); } else { std::puts("Casting failed"); }
  Casting failed
  >> 

  >> if(dynamic_cast<DerivedA*>(ptr)) { std::puts("=> Type DerivedA"); } else { std::puts("Casting failed"); }
  => Type DerivedA
  >> 
#+END_SRC

Function which applies operations specific to the derived class using pointers:  

#+BEGIN_SRC cpp 
  void processType(Base* ptr){
       auto ptrA = dynamic_cast<DerivedA*>(ptr);
       if(ptrA){
           std::puts("Found object of type = DerivedA");
           std::cout << ".getType() = " << ptrA->getType() << "\n";
           return;
       }
       auto ptrB = dynamic_cast<DerivedB*>(ptr);
       if(ptrB){
          std::puts(" Found object of type = DerivedB");
          std::cout << ".getType() = " << ptrB->getType() << "\n";
          return;
       }
       if(ptr){
          std::puts("Found object of type Base");
          std::cout << ".getType() = " << ptr->getType() << "\n";
          return;
       }
       std::puts("Null pointer or cannot determine instance type.");
  }


  >> processType(&da)
  Found object of type = DerivedA
  .getType() = DerivedA

  >> processType(&db)
   Found object of type = DerivedB
  .getType() = DerivedB

  >> processType(&base)
  Found object of type Base
  .getType() = Base

  >> processType(nullptr)
  Null pointer or cannot determine instance type.
#+END_SRC

Dynamic casting references: 

 + Note: References to polymorphic objects can be casted with dynamic
   cast too. In this case if the operation fails, it throws an
   _std::bad_cast_ exception.

#+BEGIN_SRC cpp
  >> Base& refb1 = base;

  // Throws exception, casting failed 
  >> DerivedA& refa1 = dynamic_cast<DerivedA&>(refb1)
  Error in <TRint::HandleTermInput()>: std::bad_cast caught: std::bad_cast
  >> 

  >> Base& refb2 = da;
  >> 
  >> DerivedA& refa2 = dynamic_cast<DerivedA&>(refb2)
  (DerivedA &) @0x7f9d32750018
  >> 
  >> refa2.getType()
  (std::string) "DerivedA"
  >> 
#+END_SRC

** Friend Functions 

A friend function is a function that can access the private and
protected member variables or member functions (methods) of some
class. There are lots of controversies about friend function over
breaking of encapsulation, however there are legitimate cases for
their usage such as serialization. 

Features: 

  + A friend function to some class has access to private and
    protected member variables and functions of that class.

  + F.F. can be friend to multiple classes via function overloading.

  + F.F. are not member functions or part of any class.

 *Example:*

Class: ClassA 

#+BEGIN_SRC cpp 
  class ClassA{
  private:
       std::string m_id;
       double m_x, m_y;
       void describe() const {
          std::cout << "This is the class: ClassA" << std::endl;
       }	
  public:
      ClassA(const std::string& id, double x, double y):
         m_id(id), m_x(x), m_y(y)
      {
      }
      double GetX() const { return m_x; }
      double GetY() const { return m_y; }	
      friend void showClassInfo(ClassA const& obj);
  }
#+END_SRC

Class: ClassB.

#+BEGIN_SRC cpp 
  class ClassB{
  private:
       std::string  m_id;
       int m_a, m_b, m_c;
  public:
      ClassB(std::string const& id, int a, int b, int c):
              m_id(id), m_a(a), m_b(b), m_c(c)
      {		
      }
      friend void showClassInfo(ClassB const& obj);
  };

#+END_SRC

Friend Implementation:

#+BEGIN_SRC cpp 
  void showClassInfo(ClassA const& obj){
       std::cout << "ClassA Information." << "\n";
       std::cout << "  id = "    << obj.m_id
                 << " ; x = " << obj.m_x
                 << " ; y =  " << obj.m_y
                 << "\n";
       obj.describe();
  }

  void showClassInfo(ClassB const& obj){
      std::cout << "ClassB Information." << "\n";
      std::cout << " id = " << obj.m_id
                << " ; a = " << obj.m_a
                << " ; b = " << obj.m_b
                << " ; c = " << obj.m_c
                << "\n";
  }
#+END_SRC

ROOT REPL Testing: 

#+BEGIN_SRC cpp 
   >> ClassA clsA{"objectA", 203.67, 9.345};
   >> ClassB clsB{"objB", 20, 824, 561};

   >> clsA.m_x
   ROOT_prompt_8:1:6: error: 'm_x' is a private member of 'ClassA'
   clsA.m_x
        ^
   input_line_17:5:9: note: declared private here
           double m_x, m_y;
                  ^

   >> showClassInfo(clsA)
   ClassA Information.
     id = objectA ; x = 203.67 ; y =  9.345
   This is the class: ClassA


   >> showClassInfo(clsB)
   ClassB Information.
    id = objB ; a = 20 ; b = 824 ; c = 561
#+END_SRC


Further Reading: 

 + Example - Usage of friend function for serialization:
   + https://perso.telecom-paristech.fr/elc/software/jsonserial.pdf
   + https://web.archive.org/web/20181227170325/https://perso.telecom-paristech.fr/elc/software/jsonserial.pdf

 + [[https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/rzarg/cplr042.htm][IBM Knowledge Center - Friends (C++ only)]]

 + [[http://www.cs.fsu.edu/~jestes/cop3330/notes/overload.html][Operator Overloads]]
** Namespaces
*** Summary 

| C++ Namespace                         | Python Equivalent                          | Description                                          |
| Operation                             |                                            |                                                      |
|---------------------------------------+--------------------------------------------+------------------------------------------------------|
| ~using namespace std;~                  | from std import *                          | Import everything from  a namespace.                 |
| ~using std::cout;~                      | from std import cout                       | Import an object, function from a namespace.         |
| using std::cout, std::cin, std::endl; | from std import cout, cin ...              | Import multiple items from a namespace (C++17 only.) |
| ~namespace mk = mathkit::ellipticfun;~  | import mathkit.ellipticfun as mk           | Create an alias to a namespace.                      |
| mathkit::function::sind(90);          | import mathkit; mathkit.function.sind(90); | Call a function from namespace.                      |
|                                       |                                            |                                                      |

*** Examples 

Open namespace:

 - =using namespace <namespace>=

#+BEGIN_SRC cpp  
 // Not recommended - It defeats the purpose of namespace which is prevent 
 // nameclashes and improve discoverability. 
 using namespace std;
 std::cout << "Hello world" << "\n";

 // Import everything from boost linear algebra library.
 using namespace boost::numeric::ublas;
#+END_SRC

Open namespace inside function:

#+BEGIN_SRC cpp 
  void printNumbers() {
          // Import everything from std namespace 
          using namespace std;
          for(int i = 0; i < 10; i++)
                  cout << "i = " << i << "\n";
  }

  // C++11 auto syntax for function declaration
  auto printNumbers() -> void {
          using namespace std;
          for(int i = 0; i < 10; i++)
                  cout << "i = " << i << "\n";
  }

  // C++14 return type deduction with optional type deduction.
  auto printNumbers() {
          // Import everything from std namespace 
          using namespace std;
          for(int i = 0; i < 10; i++)
                  cout << "i = " << i << "\n";
  }
#+END_SRC

Using element from namespace without import namespace. 

#+BEGIN_SRC cpp 
  std::cout << "hello world" << std::endl;
  auto matrixI3 =  boost::numeric::ublas::identity_matrix<double>(3));
#+END_SRC

Import specific elements from namespace 

#+BEGIN_SRC cpp 
  // Option 1 
  //----------------------------------------//
  using std::cout; 
  using std::cerr; 
  using std::endl; 
  using boost::numeric::ublas::identity_matrix;
  using boost::numeric::ublas::norm_1;
 
  // Option 2 => Multiple imports at same line. 
  //----------------------------------------//
  using std::cout; using std::cerr;  using std::endl; 
  using boost::numeric::ublas::identity_matrix; using boost::numeric::ublas::norm_1;

  // Option 3 => C++17 only 
  //----------------------------------------//
  using std::cout, std::cerr, std::endl; 
  using boost::numeric::ublas::identity_matrix, boost::numeric::ublas::norm_1;

#+END_SRC

Namespace synonym/alias:

#+BEGIN_SRC cpp
  // Create namespace alias ub 
  namespace ub = boost::numeric::ublas;

  ub::matrix<double> matrix1(3, 3, 2.5);
  // auto type inference + uniform initalization 
  auto matrix1 = ub::matrix<double> {3, 3, 2.5};

#+END_SRC

Creating a namespace: 

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <ostream>
  #include <functional>
  #include <cmath>

  namespace MyFunctions{
      // Import everything from namespace std 
      using namespace::std;

      // Type alias or synonym 
      using cstring = const char*;

      // Or: using MathFunc = std::function<double (double)>;
      using MathFunc = std::function<auto (double) -> double>;

      cstring description = "Utility functions";

      double add(double x, double y){
         return x + y;
      }

      auto saySomething() -> void {
          cout << "A computer was a skilled mathematician who computed firing tables." << endl;
      }
      struct Coord{
          // Latitude in degrees/decimal 
          double lat;
          // Longitude in degrees/decimal 
          double lon;
      };

      namespace math {
          auto showTable(MathFunc fun, std::ostream& os = std::cout) -> void{
              for(double x = 0; x < 10.0; x += 1.0){
                 os << setw(10) << x << setw(10) << fun(x) << "\n";
              }
          }
          auto makeMultiplier(double x) -> MathFunc {
               return [x](double y){return x * x; };
          }		
      }
	
  }; // End of namespace MyFunctions --/
#+END_SRC

Testing: (CERN's ROOT/Cling REPL.)

#+BEGIN_SRC cpp 
  >> MyFunctions::add(102.3, -93.4)
  (double) 8.9000000
  >> MyFunctions::add(102.3, -193.4)
  (double) -91.100000
  >>
  >> MyFunctions::saySomething()
  A computer was a skilled mathematician who computed firing tables
  >>

  >> MyFunctions::math::showTable([](double x){ return x * 3.0 + 4.0;} )
           0         4
           1         7
           2        10
           3        13
    ... ... ... ... 

  // import MyFunctions.math as m
  >> namespace m = MyFunctions::math;
  >> m::showTable([](double x){ return x * 3.0 + 4.0;} )
           0         4
           1         7
           2        10
           3        13
    ... ... ... ... 

  // from MyFunctions.math import *
  >> using namespace MyFunctions::math;

  >> showTable([](double x){ return x * x;}, std::cerr )
           0         0
           1         1
           2         4
           3         9
           4        16
      ... ... ... ...  

  >> showTable(exp, std::cerr )
  ROOT_prompt_34:1:1: error: no matching function for call to 'showTable'
  showTable(exp, std::cerr )
  ^~~~~~~~~

  >> showTable(static_cast<double (*)(double)>(exp), std::cerr)
           0         1
           1   2.71828
           2   7.38906
           3   20.0855
           4   54.5982
           5   148.413
           6   403.429
           7   1096.63
           8   2980.96
           9   8103.08
#+END_SRC

Define a function at some namespace: 

#+BEGIN_SRC cpp 
  int General::GetNumberOfDays(int d1, int d2){
     return d2 - d1;
  }
#+END_SRC

** Move Semantics 
*** r-value and l-values

 *Lvalues X Rvalues* 

The names LValues and RValues come from C, "L-value" name comes from
the left-hand side from an assignment operation referring to a memory
location from which it is possible to take the address.  The "R-value"
name come from the right-hand side from an assignment expression and
is a temporary value from which it is not possible to take the
address.

#+BEGIN_SRC text 
  <Lvalue> = <Rvalue>; 
      |         |
      |         \+-------->> R-value: right-hand side of assignment, 
      \                      non-addressable. Not possible to take address, 
       \                     temporary object.
        \ 
         +----------------->> L-value: left-hand side of assignment, 
                              addressable memory location. 
#+END_SRC

So: 

 + *Lvalue* => value with an addressable and identifiable memory
   location from which is possible to take the address with the
   ampersand operator (&), set or assign a new value. 

 + *Rvalue* => literal, expression or temporary object from which it is
   not possible to take the address with ampersand operator(&) or
   set a new value. For short, it can be said that, everything that is
   not an L-value, is an R-value.

 + More at: [[https://en.cppreference.com/w/cpp/language/value_category][value category]] (CppReference)

Examples: 

#+BEGIN_SRC cpp 
   // x => is a Lvalue, 10 is an Rvalue   
   int x = 10;                             

   // str1 is a Lvalue and "hello world" is a 
   std::string str1 = "hello world";       

   // str2 is a Lvalue and the right-hand side (str1 + " - rvalue") is a r-value 
   std::string str2 = str1 + " - rvalue;";

   class A{
   public:
      A() { ... }
   };

   void Function(){ 
      A a; 
      .... ... 
      return a; 
   }

   A obj; 

   //  obj is an L-value, while the object returned by 'Function()' is
   //  a R-value (temporary object).
   obj = Function(); 
#+END_SRC
*** r-value references and r-value references 

 *LValue Reference* 

A L-value reference is an alias to a non-temporary object with a
defined memory location, which is similar to a constant pointer.

#+BEGIN_SRC cpp 
  // 'x' is a Lvalue => 10 is a R-value 
  >> int x = 10;

  // refx is a L-value reference bound to 'x', in other words, refers to 'x'. 
  >> int& refx = x;
  >> 
  >> refx
  (int) 10

  // An L-value reference has the same address as the variable that the
  // reference it is bound to.
  >> if(&refx == &x) printf(" [INFO] Have the same address Ok.\n");
   [INFO] Have the same address Ok.
  
  >> refx = 50
  (int) 50
  >> x
  (int) 50
#+END_SRC

An L-value reference cannot bind to R-values or temporary objects: 

#+BEGIN_SRC cpp 
  >> 
  >> int& refy = x + 10;
  ROOT_prompt_6:1:6: error: non-const lvalue reference to type 'int' cannot bind to a temporary of type
        'int'
  int& refy = x + 10;
       ^      ~~~~~~
#+END_SRC

 *Rvalue References* 

RValue references are references which binds to temporary
objects. They were introduced in C++11 for enabling move semantics and
move-member functions, namely, move constructor and move assignment
operator which allow to reuse resources from temporary objects by
performing shallow copy instead of deep copy, which would be performed
by the copy-constructor and copy assignment operator. Therefore, as a
shallow copy is much less expansive than a deep copy, move semantics
can provide significant performance improvements eliminating wasteful
copies of temporary objects.

 + Example 1: Rvalue binding.

#+BEGIN_SRC cpp 
  >> int x = 10;

  // R-value reference
  >> int&& rv = x + 10;

  >> rv
  (int) 20

  >> rv = 25
  (int) 25

  // Compile-time error! R-value references cannot bind to L-values.
  >> int&& rv2 = x;
  ROOT_prompt_22:1:7: error: rvalue reference to type 'int' cannot bind to lvalue of type 'int'
  int&& rv2 = x;
        ^     ~
#+END_SRC

 + Example 2: Lvalue X Rvalue and function overload. 

Attempt to use the L-value reference overload of the function
printLines with a L-value and R-value.

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

  // Overload of printLine taking an L-value reference as parameter 
  void printLines(std::istream& is){
     std::cout << " [INFO] L-value reference overload" << std::endl;
     std::string line; 
     std::getline(is, line); 
     std::cout << " line1 =: " << line << std::endl;
     std::getline(is, line); 
     std::cout << " line2 =: " << line << std::endl;
  }

  >> std::ifstream fd1 {"/etc/protocols"};

  // Use the function with an L-value reference 
  >> printLines(fd1)
   [INFO] L-value reference overload
   line1 =: # /etc/protocols:
   line2 =: # $Id: protocols,v 1.12 2016/07/08 12:27 ovasik Exp $
#+END_SRC

Attempt to pass an R-value (temporary object in this case): 

#+BEGIN_SRC cpp 
  // 'std::ifstream{"/etc/protocols"}' is an R-value (temporary object)
  // It is not possible to take address of this expression. 
  // If the code was compiled, it would result in compile-time error. 
  >> printLines(std::ifstream{"/etc/protocols"})

  ROOT_prompt_10:1:1: error: no matching function for call to 'printLines'
  printLines(std::ifstream{"/etc/protocols"})
  ^~~~~~~~~~
  ROOT_prompt_0:1:6: note: candidate function not viable: no known conversion from 'std::ifstream' (aka
        'basic_ifstream<char>') to 'std::istream &' (aka 'basic_istream<char> &')
        for 1st argument
  void printLines(std::istream& is){
      ^
#+END_SRC

Solution, create a new overload of the function 'printLines' that
takes an r-value reference as parameter.

#+BEGIN_SRC cpp 
  // Overload of printLine taking an R-value reference as parameter 
  void printLines(std::istream&& is){
     std::cout << " [INFO] R-value reference overload" << std::endl;
     std::string line; 
     std::getline(is, line); 
     std::cout << " line1 =: " << line << std::endl;
     std::getline(is, line); 
     std::cout << " line2 =: " << line << std::endl;
  }

  >> printLines(std::ifstream{"/etc/protocols"})
   [INFO] R-value reference overload
   line1 =: # /etc/protocols:
   line2 =: # $Id: protocols,v 1.12 2016/07/08 12:27 ovasik Exp $
#+END_SRC




*** Move-semantics member functions 

 *Move Constructor and move assignment operator* 

C++11 introduced new special member functions for move semantics, the
move constructor and move assignment operator. Those special member
functions were added for enhancing performance through elimination of
temporary objects (R-values) _deep copies_, that were performed by the
copy constructor or copy assignment operator. 

Despite the name, the move constructor and move assignment operator
don't move anything, they just transfer the ownership of resources
from a temporary object (rvalue) to a new object, in the case of the
move-ctor and to an existing object, in the case of the
move-operator. After the transfer, the temporary object is left in a
valid, but undetermined state without any resources. 

Example: 

If a class manages a heap-allocated array: 

#+BEGIN_SRC cpp 
  int* p_res = new int [10];
#+END_SRC

The move assignment operator copies the pointer (_shallow copy_) p_res
from a temporary object, transferring it to an existing object on the
left-hand side of the assignment, then the OldObject.p_res is set
nullptr. Without the move assignment operator, the copy assignment
operator would be called creating a wasteful _deep copy_ due to a new
array allocation and copy of all elements.

  *Benefits* 

   + The move semantics makes returning by value from functions or
     member functions more efficient than before C++11 as only shallow
     copy is performed, therefore the return value no longer need to be
     returned as function parameter reference.

   + All STL containers, such as std::vector, std::deque,
     std::unique_ptr, std::shared_ptr, std::map and so on, define move
     member functions which makes returning any instance of them by
     value more efficient and without any deep copy overhead.


  *Default member functions* 

Before C++11, if class did not define any user declared special member
function, the compiler generated by default a default constructor,
copy-constructor, copy-assignment operator and a destructor. Since
C++11, in addition to those functions, the compiler also generates the
move constructor and move assignment operator in the absence of any
user declared member function. 

 *Rule of three* 

Before C++11, if a class manages a resource such as heap-allocated
object, file descriptor, socket handler, ... and so. And the class
implements a user-defined default destructor, copy constructor or
copy-assignment operator, it should implement all of three.

 *Rule of five* 

Since C++11, if a class managing a resource implement a user-defined
destructor, copy constructor, copy assignment operator, move
constructor or move assignment operator, it should implement all of
five. 

 + Note 1: If the copy member functions are annotated as deleted, only
   the destructor and move member functions needs to be implemented.

 + Note 2: If the user do not define or annotate the copy-member
   functions as deleted, the compiler may provide default copy-member
   functions that are not aware of the resources. As a result, a
   shallow-copy will be performed instead of deep copy resulting in a
   bug when any of objects using the same resources disposes them 
   while they are being used by other objects.

 + Note 3: Generally, classes that manages non-heap allocated
   resources such as sockets descriptors, handlers, database handlers
   should not be copiable, in other words, it should annotate copy
   member functions as deleted.

*** Signature of copy and move member functions 

 *Signature of copy member functions* 

Copy constructor: 

#+BEGIN_SRC cpp 
  AClass::AClass(const AClass& rhs);
  // Or 
  AClass::AClass(const AClass & rhs);
  // Or 
  AClass::AClass(AClass const& rhs);
#+END_SRC

Copy assignment operator: 

#+BEGIN_SRC cpp 
  AClass& AClass::operator=(const AClass& rhs);
  // Or 
  AClass& AClass::operator=(AClass const& rhs);
#+END_SRC

 *Signature of move member functions*

Move constructor:

#+BEGIN_SRC cpp 
  AClass::AClass(AClass&& temporary);
#+END_SRC

Move assignment operator: 

#+BEGIN_SRC cpp 
  AClass& AClass::operator=(AClass&& temporary);
#+END_SRC

*** Example: Move Semantics Member Functions

Full source code: 

 + [[file:src/move_member_funcs.cpp][file:src/move_member_funcs.cpp]]

Class: AClass. 
  + The class AClass manages a heap-allocated object resource.

#+BEGIN_SRC cpp 
  class AClass{
  public:
      // Object unique ID for easier identification
      const int m_id;
      // Simulates a resource (heap-allocated object)
      int* m_p;

      static int make_id()
      {
          static int id = 0;
          return ++id;
      }

      // Default constructor
      AClass(): AClass(0) { }

      AClass(int n): m_id{AClass::make_id()}, m_p{new int {n}}
      {
          printf(" [TRACE] Object created => id = %d ; *m_p = %d\n", m_id, *m_p);
      }

      // Copy constructor
      AClass(AClass const& that): m_id{AClass::make_id()}
      {
          m_p = new int (*that.m_p);
          printf(" [TRACE] Copy ctor invoked => Copied src=%d dest=%d \n"
                 , that.m_id, m_id);
      }

      // Copy assignment operator
      AClass& operator=(AClass const& that)
      {
          printf(" [TRACE] Copy asn. operator invoked. => src_id = %d - dest_id = %d \n"
                 , that.m_id, m_id);
          ,*m_p = *that.m_p;
          return *this;
      }

  #if 1
      // Move constructor: move resource from a temporary object (RValue) to a new object.
      AClass(AClass&& that): m_id{AClass::make_id()}
      {
          printf(" [TRACE] Move ctor invoked OK. => src_id = %d - dest_id = %d \n"
                 , that.m_id, m_id);
          // Transfer ownership of resource managed by temporary object that
          // to this object.
          m_p = that.m_p;
          // Make the temporary object empty
          that.m_p = nullptr;
      }

      // Move assignment operator: move resource from a temporary object (RValue)
      // to an existing object (this).
      AClass& operator=(AClass&& that)
      {
          printf(" [TRACE] Move asn operator invoked. OK. src_id = %d - dest_id = %d \n"
                 , that.m_id, m_id);
          int* p_temp = m_p;
          // Transfer ownership of resources from the temporary object(that) to
          // this object.
          m_p = that.m_p;
          // Diposes the resource of the existing object (this)
          that.m_p = p_temp;
          return *this;
      }
  #endif

      // Destructor
      ~AClass()
      {
          printf(" [TRACE] Object destroyed => Dtor called => id = %d \n", m_id);
          delete m_p;
          m_p = nullptr;
      }

      int get() const { return *m_p; }
      void set(int n) { *m_p = n; }
  };
#+END_SRC

Helper functions: 

#+BEGIN_SRC cpp 
  void is_lvalue_or_rvalue(AClass& arg)
  {
      printf(" ===> Passed LVALUE \n");
  }

  void is_lvalue_or_rvalue(AClass&& arg)
  {
      printf(" ===> Passed RVALUE \n");
  }
#+END_SRC


Load the file in CERN's root repl: 

#+BEGIN_SRC cpp 
  >> .L move_member_funcs.cpp 
#+END_SRC

Create some testing object: 

#+BEGIN_SRC cpp 
  >> AClass obj1;
   [TRACE] Object created => id = 1 ; *m_p = 0

  >> AClass obj2(8);
   [TRACE] Object created => id = 2 ; *m_p = 8

  >> AClass obj3(10);
   [TRACE] Object created => id = 3 ; *m_p = 10
#+END_SRC

Check R-values and L-values: 

#+BEGIN_SRC cpp 
  // Pass an L-value 
  >> is_lvalue_or_rvalue(obj1)
   ===> Passed LVALUE 
  >> 

  // Pass an R-value => temporary object
  >> is_lvalue_or_rvalue(AClass(100))
   [TRACE] Object created => id = 4 ; *m_p = 100
   ===> Passed RVALUE 
   [TRACE] Object destroyed => Dtor called => id = 4 

  >> is_lvalue_or_rvalue(make_object(4))
   [TRACE] Object created => id = 5 ; *m_p = 4
   [TRACE] FUN = make_object => Created object => id = 5 ; cls.get() = 8
   ===> Passed RVALUE 
   [TRACE] Object destroyed => Dtor called => id = 5 
#+END_SRC

Invoke copy constructor: 

#+BEGIN_SRC cpp 
  >> AClass objA(obj2);
   [TRACE] Copy ctor invoked => Copied src=2 dest=6 

  >> objA.get()
  (int) 8

  >> obj2.get()
  (int) 8
#+END_SRC

Return value-optimization RVO => neither the copy constructor or move
constructor are called. 

#+BEGIN_SRC cpp 
  >> AClass objB(make_object(6));
   [TRACE] Object created => id = 7 ; *m_p = 4
   [TRACE] FUN = make_object => Created object => id = 7 ; cls.get() = 10

  >> objB.m_id
  (const int) 7

  >> objB.get()
  (int) 10

  >> AClass objC = make_object(10);
   [TRACE] Object created => id = 8 ; *m_p = 4
   [TRACE] FUN = make_object => Created object => id = 8 ; cls.get() = 14
  >> 
  >> objC.m_id
  (const int) 8
  >> 
  >> objC.get()
  (int) 14
  >> 
#+END_SRC

Force invocation of move constructor with std::move which casts an
lvalue argument to an rvalue. 

#+BEGIN_SRC cpp 
  >> objB.m_p
  (int *) 0x39c38d0

  // ===> Before calling move ctor 

  >> AClass objM { std::move(objB) };
   [TRACE] Move ctor invoked OK. => src_id = 7 - dest_id = 10 
  >> 

  // ===> After calling move ctor 

  >> objB.m_p
  (int *) nullptr
  >> 

  // The resource was transfered to object objM and objB no longer owns
  // the resource.
  >> objM.m_p
  (int *) 0x39c38d0
  >> 

  >> *objM.m_p
  (int) 10
#+END_SRC

The copy assignment operator is called when assigning an l-vavlue to
an l-value or an addressable object to another.

#+BEGIN_SRC cpp 
  >> AClass c1;
   [TRACE] Object created => id = 11 ; *m_p = 0

  // Copy assignment operator called. 
  //-----------------------------------
  >> c1 = obj2;
   [TRACE] Copy asn. operator invoked. => src_id = 2 - dest_id = 11 

  >> c1.m_p
  (int *) 0x46c5de0

  >> obj2.m_p
  (int *) 0x2503fe0

  >> c1.get()
  (int) 8
  >> 
#+END_SRC

The move assignment operator is called when assigning an l-value object
to a temporary value or r-value. If a move constructor is not defined
or was not created by the compiler, then the copy constructor is invoked
resulting in an expensive deep copy. 

#+BEGIN_SRC cpp 
  >> AClass cx;
   [TRACE] Object created => id = 12 ; *m_p = 0

  // Move assignment operator is called as cx is assigned to a temporary
  // object (R-value)
  // -------------------------------
  >> cx = AClass(4);
   [TRACE] Object created => id = 13 ; *m_p = 4
   [TRACE] Move asn operator invoked. OK. src_id = 13 - dest_id = 12 
   [TRACE] Object destroyed => Dtor called => id = 13 

  >> cx.get()
  (int) 4
  >> 

  // Move assignment operator called as cx is assigned to a R-value 
  >> cx = make_object(3);
   [TRACE] Object created => id = 14 ; *m_p = 4
   [TRACE] FUN = make_object => Created object => id = 14 ; cls.get() = 7
   [TRACE] Move asn operator invoked. OK. src_id = 14 - dest_id = 12 
   [TRACE] Object destroyed => Dtor called => id = 14 
  >> 

  >> cx.get()
  (int) 7
  >> 
#+END_SRC

Force invocation of the move-assignment operator by using std::move
which casts the argument from l-value to r-value: 

#+BEGIN_SRC cpp 
  >> cx = obj1;
   [TRACE] Copy asn. operator invoked. => src_id = 1 - dest_id = 12 

  >> cx = std::move(obj2);
   [TRACE] Move asn operator invoked. OK. src_id = 2 - dest_id = 12 

  >> cx.get()
  (int) 8
#+END_SRC

 *Simplifcation of move member functions* 

The move constructor and assignment operator could be rewritten in a
more concise way by using the std::move and std::swap facilities from
the standard library. 

 + Move constructor:

#+BEGIN_SRC cpp 
    // Move constructor: move resource from a temporary object (RValue) to a new object.
    AClass(AClass&& that): m_id{AClass::make_id()}, m_p{nullptr}
    { 
        std::swap(m_p, that.m_p);
    } 
#+END_SRC

Move assignment operator: 

#+BEGIN_SRC cpp 
    // Move assignment operator: move resource from a temporary object (RValue)
    // to an existing object (this).
    AClass& operator=(AClass&& that)
    {
        std::swap(m_p, that.m_p);
        return *this;
    }
#+END_SRC

Functions std::swap: 

#+BEGIN_SRC cpp 
  >> int xx = 10, yy = 20;

  >> xx
  (int) 10
  >> yy
  (int) 20

  >> std::swap(xx, yy);
  >> xx
  (int) 20
  >> yy
  (int) 10
  >> 
#+END_SRC

*** Move Semantics References from C++ standard 

  + [[https://en.cppreference.com/w/cpp/language/value_category][Value Categories]] 

  + [[https://en.cppreference.com/w/cpp/language/move_constructor][Move constructor]]

  + [[https://en.cppreference.com/w/cpp/language/move_assignment][Move assignment operator]]

  + [[http://www.cplusplus.com/doc/tutorial/classes2/][Special Member Functions]]

  + [[https://en.cppreference.com/w/cpp/algorithm/swap][std::swap]]

  + [[https://en.cppreference.com/w/cpp/utility/move][std::move]]

  + [[https://en.cppreference.com/w/cpp/utility/forward][std::forward]]

*** References and further reading 

 + *Move constructor - cppreference*
   + <https://en.cppreference.com/w/cpp/language/move_constructor>

 + *Move assignment operator - cppreference*
   + <https://en.cppreference.com/w/cpp/language/move_assignment> 

 + *Move Constructor and Move Assignment Operators (C++)* - Microsft
   + <https://docs.microsoft.com/en-us/cpp/cpp/move-constructors-and-move-assignment-operators-cpp?view=vs-2019>

 + *C++11: Move Semantics  - DKFZ*
   + <http://mitk.org/images/c/ca/MoveConstructor.pdf>

 + *C++ Move Semantics Gotchas*
   + <https://web.mst.edu/~nmjxv3/articles/move-gotchas.html>

 + *When C++ does not move*
   + <https://pspdfkit.com/blog/2019/when-cpp-doesnt-move/>

 + *C++ rules for automatic member function generation*
   + <http://www.enyo.de/fw/notes/cpp-auto-members.html>

 + *Copying and assigning objects in C++*
   + <https://www.ics.uci.edu/~thornton/ics46/Notes/MoveSemantics/> 
** Smart Pointers 
*** Problems of Raw Pointer 

 Raw pointers to dynamically allocated objects, (objects allocated with
 _new_ and disposed with _delete_ operator) are responsible for a broad
 range of problems such as memory leaks, double free and dangling
 pointers that affected many old codebases. Some of the problems and
 pontential bugs of raw pointers are: 

  + _memory leak_
    + => The dynamically allocated object was not disposed. For every
      object allocated with _AType* ptr = new AType()_, there should be a
      matching _delete_ operator. A memory leak happens when a call to
      this operator is missing. It can happen due to be hard to keep
      track of the onership of an owning raw pointer in large codebase;
      code refactoring and early return from functions.

  + _dangling pointer_
    + => An owning pointer is still being used after the object has
      been deleted, for instance, _AType* ptr = new AType_, the object is
      deleted, the pointer was not set nullptr and later some part of
      the code calls ptr->MemberFunction().

  + _double free_
    + => The pointer to a dynamically-allocated object was deleted more
      than once and was not set null or nullptr after it was deleted
      at the first time. 

  + _lack of exception safety_
    + => If an exception happens after a heap-allocated object was
      instantiaded, the matching delete operator will not be called,
      therefore a memory leak will happen.

  + _lack of clear ownership_
    + => Ownership is the responbility to dispose a heap-allocated
      object and keep it alive while it is being used. Raw pointers doe
      not provide clear ownership, it is not possible to know if there
      are any other objects still using the pointer and the ones that
      will responsible for disposing the resource.

*** Smart Pointers from standard library 

 Smart pointers are classes that manages the lifetime and ownership of
 heap-allocated objects by wrapping raw pointers and emulating them
 through overloading of dereference operators (*) and (->). They intend
 to solve the raw owning pointers issues by making the ownership clear
 and providing proper resource cleanup ensuring exception safety.

 Note: 

  + Smart pointers should be used for _polymorphic objects_ (objects
    with at least one virtual member function) or large objects that
    cannot fit on the stack.

  + Smart pointers *should* not be used for stack-allocated or static
    objects (global objects). They should only be used with objects
    that would be instantiated with _new_ operator. 

  *Smart Pointers in the C++ Standard*

  * +std::auto_ptr+ - Deprecated (Removed in C++17) => Replace it for
    *std::unique_ptr* 

  * std::unique_ptr
    + predecessor: boost:unique_ptr
    + Features:
      + Single ownership
      + Non-copiable and movable-only.
      + No runtime overhead over raw pointers and costs less than a
        shared_ptr.  
    + Use Cases:
      + PIMPL design pattern
      + Heap-allocated object is refered by a single parent object.
      + Factory functions that instatiates dynamically allocated
        polymorphic objects. In this case, it is recommeded to use
        unique_ptr as it is easier to convert to shared_ptr than the
        other way around. 

  * std::shared_ptr
    + predecessor: boost::shared_ptr
    + Features: Shared ownership with reference counting.
    + Use Case:
      + More than one object need a copy of the pointer to
        polymorphic dynamically allocated object and also need to keep
        the object alive while it is being used.

  * std::weak_ptr
    + predecessor: boost::weak_ptr
    + Feature: No ownership.
    + Use Case:
      + Solves shared_ptr cyclic reference problems.

*** Other Smart Pointer Implementations 

Boost: 

  + [[https://www.boost.org/doc/libs/1_69_0/libs/smart_ptr/doc/html/smart_ptr.html#scoped_ptr][boost::scoped_ptr]] - Similar to unique_ptr, but no-copiable and
    no-copiable.

  + [[https://www.boost.org/doc/libs/1_70_0/libs/smart_ptr/doc/html/smart_ptr.html#intrusive_ptr][Boost.Intrusive_ptr]] - Similar to shared_ptr.

QT Framework:

  + [[https://doc.qt.io/qt-5/qsharedpointer.html][QSharedPointer]] 

  + [[https://doc.qt.io/qt-5/qweakpointer.html][QWeakPointer]] 

  + [[https://doc.qt.io/qt-5/qscopedpointer.html][QScopedPointer]] 

WXWidgets Smart Pointers: 

 + [[https://docs.wxwidgets.org/3.1/group__group__class__smartpointers.html][smart pointers]]

Windows ATL - Active Template Library - COM (Component Object Model)
Smart Pointers

  + [[https://docs.microsoft.com/en-us/cpp/atl/reference/ccomptr-class?view=vs-2017][CComPtr Class]]

  + [[https://docs.microsoft.com/en-us/cpp/atl/reference/ccomqiptr-class?view=vs-2017][CComQIPtr]]

  + [[https://docs.microsoft.com/en-us/cpp/atl/reference/ccomheapptr-class?view=vs-2017][CComHeapPtr]]

  + [[https://docs.microsoft.com/en-us/cpp/atl/reference/ccomgitptr-class?view=vs-2017][CComGITPtr]]

  + [[https://docs.microsoft.com/en-us/cpp/cpp/com-ptr-t-class?view=vs-2017][_com_ptr_t]]

VTK Smart Pointers: 

  + [[https://vtk.org/Wiki/VTK/Tutorials/SmartPointers][Vtk SmartPointers]]

Poco Framework 

  + [[https://pocoproject.org/docs/Poco.SharedPtr.html][Poco.SharedPtr]]

ARM Mbed 

  + [[https://os.mbed.com/docs/mbed-os/v5.13/apis/shared-pointer.html][Shared Pointer]] 

Misc - Found in Github
 
  + [[https://github.com/mariano-perez-rodriguez/value_ptr][value_ptr]] - "A value semantics smart pointer for C++"

  + [[https://github.com/martinmoene/value-ptr-lite][value-ptr-lite]] - "value-ptr-lite - A C++ smart-pointer with value
    semantics for C++98, C++11 and later in a single-file header-only
    library"

  + [[https://github.com/loopperfect/valuable][valuable]] - "A C++ smart-pointer with value-semantics."

  + [[https://github.com/martong/rcu_ptr][rcu_ptr]] - "A special smart pointer to exchange data between
    threads" 

  + [[https://github.com/Corralx/tag_ptr][tag_ptr]] - "This is a simple C++11 implementation of a tagged
    pointer, that allows to use the least significant bits in a
    pointer to save a payload, generally called tag. It does so by
    exploiting the alignment of types in memory."

  + [[https://github.com/scottslacksmith/any_ptr][any_ptr]] - "any_ptr and any_shared_ptr are 2 C++ containers for
    storing pointers to heterogeneous types that, unlike std::any,
    preserves normal pointer behaviour."

  + [[https://github.com/dzitkowskik/CUDA-smart-pointers][CUDA-smart-pointers]]

*** Documentation Links

 Header File: 
  + [[https://en.cppreference.com/w/cpp/memory][<memory>]]

 Smart Pointer Classes: 

   + [[https://en.cppreference.com/w/cpp/memory/unique_ptr][std::unique_ptr]]

   + [[https://en.cppreference.com/w/cpp/memory/shared_ptr][std::shared_ptr]]

   + [[https://en.cppreference.com/w/cpp/memory/weak_ptr][std::weak_ptr]]

 Helper Functions for Smart Pointer Instatitation: 

  + [[https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique][std::make_unique]] - Prefered way of instantiating unique ptr.

  + [[https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared][std::make_shared]] - Function for instantiating shared pointers.

  + [[https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast][Pointer casting function]]
    + Functions:
      + std::static_pointer_cast
      + std::dynamic_pointer_cast
      + std::const_pointer_cast
      + std::reinterpret_pointer_cast 

 Related Concepts: 

  + [[https://en.cppreference.com/w/cpp/language/pimpl][pimpl idiom]]

  + [[https://en.cppreference.com/w/cpp/language/type#Incomplete_type][Incomplete type]]

  + [[https://en.cppreference.com/w/cpp/language/destructor#Virtual_destructors][Virtual Destructors]]

*** std::unique_ptr 

 Single ownership, movable-only and non-copiable smart pointer. 

   + Header file: [[https://en.cppreference.com/w/cpp/memory][<memory>]]
   + Documentation: [[https://en.cppreference.com/w/cpp/memory/unique_ptr][unique_ptr]]

  *Use Cases* 

   + Factory functions that instantiates dynamically allocated
     polymorphic objects.

   + The lifetime of the managed object depends only on the lifetime of
     a single object or only a single objects need a copy of the
     pointer, one to one relationship. 

   + Pimpl design pattern. 


  *Class template declaration* 

 #+BEGIN_SRC cpp 
   template< typename T
            ,typename Deleter = std::default_delete<T>
            >
   class std::unique_ptr; 

   // Array version 
   template< typename T
            ,typename Deleter = std::default_delete<T>
            >
   class std::unique_ptr<T [], Deleter; 
 #+END_SRC

  *Member Function Table* 

 Member functions of ~std::unique_ptr<T, Deleter>~

 |--------------------------------+--------+---------------------------------------------------------------------------------|
 | Function signature             | Return | Description                                                                     |
 | with parameters                | type   |                                                                                 |
 |--------------------------------+--------+---------------------------------------------------------------------------------|
 | *Constructor*                    |        |                                                                                 |
 | unique_ptr() noexcept          | -      | Default constructor                                                             |
 | unique_ptr(nullptr) noexcept   |        |                                                                                 |
 | unique_ptr(T* pointer)         | -      |                                                                                 |
 | ... ... ... ..                 | -      | Many others                                                                     |
 |                                |        |                                                                                 |
 | *Observers*                      |        |                                                                                 |
 |--------------------------------+--------+---------------------------------------------------------------------------------|
 | get() const noexcept           | T*     | Return pointer to managed object or nullptr if it owns no object.               |
 |                                |        |                                                                                 |
 |                                |        |                                                                                 |
 | *Modifiers*                      |        |                                                                                 |
 |--------------------------------+--------+---------------------------------------------------------------------------------|
 | release() noexcept             | T*     | Deletes the managed object, release the memory allocated for it.                |
 | reset(T* ptr)                  | void   | Replaces the managed object by a new one, deleting the old object.              |
 | swap(unique_ptr<T>& other)     | void   | Swaps the managed objects of two unique_ptr's                                   |
 |                                |        |                                                                                 |
 | *Operators*                      |        |                                                                                 |
 |--------------------------------+--------+---------------------------------------------------------------------------------|
 | operator*() const              | T&     | Dereference: Get reference to managed object                                    |
 | operator->() const noexcept    | T*     | Dereference: Access managed object member functions.                            |
 | operator bool() const noexcept | bool   | Returns true if there is a managed object. Used for if(ptr) { ... not null ...} |
 |                                |        |                                                                                 |

 Helper functions (not member Functions): 

 |-----------------------------------------+-------------+---------------------------------------------------|
 | Function signature                      | Return Type | Description                                       |
 |-----------------------------------------+-------------+---------------------------------------------------|
 | std::make_unique<T>(Args ...)           | UP<T>       | Creates a new unique_ptr (preferred.)             |
 | std::allocate_shared                    | -           | Same as make_unique, but with a custom allocator. |
 | std::swap(UP<T>& lhs, UP<T>& rhs)       | void        | Swap managed objects of two unique_ptr's          |
 | operator <<(OS& os, std::unique_ptr<T>) | OS&         | Print managed object to output stream (C++20)     |
 |                                         |             |                                                   |

 Note: The following type synonym were used to describe the signatures
 in a concise way: 

 #+BEGIN_SRC cpp 
   template <typename T> using UP = std::unique_ptr<T>; 
   using OS = std::ostream;
 #+END_SRC


  *Simplified Member Functions Signatures*

#+BEGIN_SRC cpp 
  template< typename T
           ,typename Deleter = std::default_delete<T>
           >
  class unique_ptr
  {
      // Internal raw owning pointer that points to a heap-allocated object.
      T* m_ptr = nullptr;
  public:
      //----- Constructors --------------------------//
      //---------------------------------------------//
      // Default ctor
      unique_ptr();
      // Overload ctor1 - construct from a owning pointer
      unique_ptr(T* ptr);
      // Move ctor
      unique_ptr(unique_ptr&& rhs);
      // Move assignment operator deleted
      unique_ptr& operator=(unique_ptr&& r) noexcept;
      // Copy ctor deleted => Smart pointer non-copiable
      unique_ptr(unique_ptr const& rhs) = delete;
      // Copy assignment operator deleted => Smart pointer non-copiable
      unique_ptr& operator=(unique_ptr const& r) = delete;
      // Destructor
      ~unique_ptr();

      //--- Operator Overloading Member Functions ------//
      //-----------------------------------------------//
      T& operator*()  const;
      T* operator->() const noexcept;
      operator bool() const;

      //---- Ordinary Member Functions -----------------//
      //------------------------------------------------//
      T*   get()                    const noexcept;
      T*   release()                noexcept;
      void reset(T* new_object)     noexcept;
      void swap(unique_ptr<T>& rhs) noexcept;
  };
#+END_SRC

  *Member Functions in Detail*

  + Default constructor - initialized to nullptr. 

 #+BEGIN_SRC cpp 
    std::unique_ptr<Type> ptr;
 #+END_SRC

  + Constructors: 

 #+BEGIN_SRC cpp 
    std::unique_ptr<Type> ptr(new Type{args ...});
 #+END_SRC  

  + *std::make_unique* - alternaitve to constructor
  + Intialization through helper function std::make_unique (C++14)
    + Note: It is not recomended to initialized a smart pointer
      directly through constructor.

 Allocating single object: 

 #+BEGIN_SRC cpp 
    // Args are constructor arguments.
    std::unique_ptr<Type> ptr = std::make_unique<Type>(args, ....);
 #+END_SRC

 Allocating array: 

 #+BEGIN_SRC cpp 
    std::unique_ptr<Type[]> ptr = std::make_unique<Type[]>();
 #+END_SRC


 Or: 

 #+BEGIN_SRC cpp 
    auto ptr = std::make_unique<Type>(args, ....);
 #+END_SRC

 Definition: 

 #+BEGIN_SRC cpp 
   template <typename T, typename... Args>
   std::unique_ptr<T> make_unique(Args &&... args) 
   {
       return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
   }
 #+END_SRC

  + Move constructor: 

 #+BEGIN_SRC cpp 
     std::unique_ptr<Type> old_ptr(new Type{args ...});

     // Move ctor initialized from an old pointer. 
     std::unique_ptr<Type> ptr{std::move(old_ptr)};
 #+END_SRC

  + Move assignment. 

 #+BEGIN_SRC cpp 
     std::unique_ptr<Type> old_ptr(new Type{args ...});

     std::unique_ptr<Type> ptr;
   
     ptr = std::move(old_ptr);
 #+END_SRC

  + Delete pointed object, releasing its memory. 

 #+BEGIN_SRC cpp 
   auto ptr = std::make_unique<Type>(args, ....);   

   ptr.reset(); // Delete heap-allocated object releasing memory and
                // resetting the pointer.
 #+END_SRC

  + Check whether the pointer is null or not. 

 #+BEGIN_SRC cpp 
   auto ptr = std::make_unique<Type>(args, ....);   

   if(ptr) {
      std::puts("Pointer is null");
   } else {
      std::puts("Pointer is not null");
   }

   if(ptr == nullptr) {
      std::puts("Pointer is null");
   } else {
      std::puts("Pointer is not null");
   }
 #+END_SRC
*** std::shared_ptr 

shared_ptr is a smart pointer that provides shared ownership semantics
and memory management through reference counting. This class contains
two parts, a pointer to the managed object (heap-allocated object) and
a heap-allocated control block which is shared by all smart pointers
owning the same object and contains a reference counter. 

Whenever a copy of the smart happens, the reference counter in the
shared control block is incremented by one. Whenever any smart pointer,
that manages a common object, is deleted when it goes out scope, the
reference counter is decremented by one. When reference counter
reaches zero, the owned object and the control block are disposed. 

Use cases: 

  + Emulate the experience of a language with garbage collection.

  + Polymorphic object that will be referred by many other objects, in
    other words, many other objects need a copy of the pointer to the
    polymorphic object.

  + Instantiation of large objects that cannot fit in the stack. 

 *Header* 

  + [[https://en.cppreference.com/w/cpp/memory][<memory>]]

 *Documentation* 

   + [[https://en.cppreference.com/w/cpp/memory/shared_ptr][std::shared_ptr]] (Cppreference)

   + [[https://docs.microsoft.com/en-us/cpp/standard-library/shared-ptr-class?view=vs-2019][std::shared_ptr]] (Microsft)

   + [[https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=vs-2019][How to: Create and Use shared_ptr Instances]] (Microsft)

   + [[https://www.boost.org/doc/libs/1_70_0/libs/smart_ptr/doc/html/smart_ptr.html#shared_ptr][boost:shared_ptr]] (Predecessor, pre-C++11)


  *Simplified Member Functions* of std::shared_ptr<T>

|-----------------------------------------+--------+-----------------------------------------------------------------|
| Member function                         | Return | Description                                                     |
|                                         | type   |                                                                 |
|-----------------------------------------+--------+-----------------------------------------------------------------|
| *Most relevant constructors*              |        |                                                                 |
|-----------------------------------------+--------+-----------------------------------------------------------------|
| shared_ptr()                            |        | Default constructor, initialize with nullptr.                   |
| shared_ptr( std::nullptr_t )            |        |                                                                 |
| shared_ptr(T* )                         |        | Initialize with _new_ keyword.                                    |
| std::shared_ptr(std::unique_ptr<T>&& r) |        | Initialize with a unique_ptr R-value.                           |
|                                         |        |                                                                 |
| *Observers*                               |        |                                                                 |
|-----------------------------------------+--------+-----------------------------------------------------------------|
| get() const                             | T*     | Return pointer to owned object.                                 |
| use_count()                             | long   | Value of reference counter                                      |
|                                         |        |                                                                 |
| operator bool()                         | bool   | Checks whether the pointer is not null. if(ptr) { ... }         |
| operator*() const                       | T&     | Dereference operator. Return reference to owned object.         |
| operator->() const                      | T*     | Dereference operator. Access member function of managed object. |
|                                         |        |                                                                 |
|-----------------------------------------+--------+-----------------------------------------------------------------|
| *Modifier*                                |        |                                                                 |
|-----------------------------------------+--------+-----------------------------------------------------------------|
| reset()                                 | void   | Replace the current managed object by this pointer by nullptr.  |
| reset(T* ptr)                           | void   | Replace the current managed object by this pointer by ptr.      |
|                                         |        |                                                                 |

Note: 

 + use_count() returns the number of shared_ptr managing the same
   heap-allocated object, in other words, it returns the value of the
   reference counter. When it reaches zero, the shared_ptr object owns
   no object or does not manage any object.

 + reset() and reset(T*) members only deletes the current managed
   object, if there are any other std::shared_ptr using it. 


 *Simplified Member Functions Signature* 

#+BEGIN_SRC cpp 
  template<typename T>
  class shared_ptr
  {
      // ..... omit private part  ... //
  public:

      //----- Constructors --------------------------//
      //---------------------------------------------//
      // Default ctor
      shared_ptr();
      // Overload ctor1 - construct from a owning pointer
      shared_ptr(T* ptr);

      // Move ctor
      shared_ptr(shared_ptr&& rhs);
      // Move assignment operator
      shared_ptr& operator=(shared_ptr&& r);
      // Copy ctor
      shared_ptr(shared_ptr const& rhs);
      // Copy assignment operator
      shared_ptr& operator=(shared_ptr const& r);
      // Destructor
      ~shared_ptr();

      //--- Operator Overloading Member Functions ------//
      //-----------------------------------------------//
      T& operator*()  const;
      T* operator->() const noexcept;    
      operator bool() const;

      //---- Ordinary Member Functions -----------------//
      //------------------------------------------------//

      long  use_count()              const noexcept;
      T*    get()                    const noexcept;
      T*    release()                noexcept;
      void  reset(T* new_object)     noexcept;
      void  swap(shared_ptr<T>& rhs) noexcept;
  };
#+END_SRC

 *Non Member Functions* 

#+BEGIN_SRC cpp 
  template< class T, class... Args >
  shared_ptr<T> make_shared( Args&&... args );   // Since C++11 

  template<class T>
  shared_ptr<T> make_shared( std::size_t N );   // Since C++20 

   // ... many other operators ... // 

  template< class T >
  bool operator==( std::nullptr_t lhs, const shared_ptr<T>& rhs ) noexcept;

  template < class T, class U > 
  bool operator==( const shared_ptr<T>& lhs, const shared_ptr<U>& rhs ) noexcept;
#+END_SRC

 *Basics - How it works* 

  + When a shared_ptr owns not object or is default initialized or
    initialized with nullptr, the reference counter is set to zero.

#+BEGIN_SRC cpp 
  // Reference counter is zero 
  std::shared_ptr<AClass> ptr1;
  // .use_counter => Return the value of the reference counter.
  assert(ptr.use_counter() == 0) ; 

  // Reference counter is zero, the ptr2 object owns anything
  std::shared_ptr<AClass> ptr2 = nullptr;
  assert(ptr2.use_counter() == 0) ; 

  // Reference counter is zero 
  std::shared_ptr<AClass> ptr2{nullptr};
  assert(ptr2.use_counter() == 0) ; 
#+END_SRC

  + When a shared_ptr is initialized (not default initialized, copy or
    move initialization) with _new_ keyword or std::make_shared, the
    reference counter is set to 1, the member function _use_count_
    returns 1. 

#+BEGIN_SRC cpp 
  class AClass{ 
  public:
     ... ... ... 
     void method1(){ ... .}
     void method2(){ .... .. }
  }; 

  // Not: recommended (AVOID)
  std::shared_ptr<AClass> cls(new AClass>(arg0, arg1, arg2 ...));
  assert(ptr.use_count() == 1);

  // Call methods just like it would be with an ordinary pointer 
  ptr->method1(); 
  ptr->method2(); 

  // Get a reference to the object: 
  AClass ref& = *ptr;

  // Best 
  std::shared_ptr<AClass> cls =  std::make_shared<AClass>(arg0, arg1, arg2 ...);
  assert(ptr.use_count() == 1);
  
  // Best 
  auto cls =  std::make_shared<AClass>(arg0, arg1, arg2 ...);
  assert(ptr.use_count() == 1);
#+END_SRC

   + When a copy of a shared_ptr object is performed, the reference
     counter is incremented and when a copy object goes out of scope,
     the reference counter is decremented. 

#+BEGIN_SRC cpp 
  std::shared_ptr<AClass> cls =  std::make_shared<AClass>(arg0, arg1, arg2 ...);
  assert(ptr.use_count() == 1);

  cls->CallMethod1OfAClass();

  { 
     // Copy constructor of std::shared_ptr<T> called 
     // => Incremente reference counter by 1 
     auto copy1 =  cls; 
     assert(ptr.use_count() == 2);   
     assert(copy1.use_count() == 2);   

    {
       std::shared_ptr<AClass> copy2; 
       assert(copy2.use_count() == 0);
   
       // Call move assignment operator of std::shared<T> 
       // Increment reference counter. 
       copy2 = cls;
       assert(copy2.use_count() == 3);
    }
    // Object: copy2 => Destroyed here, decremente ref counter by 1 
    assert(cls.use_count() == 2);
  }
  // Object copy1 destroyed here (end of its scope), decremente 
  // counter by one. 
  assert(cls.use_count() == 1);  
   
  // Decremente control block by 1, when it reaches zero, 
  // the control block and the managed object are destroyed.
  cls = nullptr;
  assert(cls.use_count() == 0);  
  // Or: 
  cls.reset(); 
  assert(cls.use_count() == 0);  
#+END_SRC
 
   + The shared managed object and the control block are only disposed
     when the number of shared_ptr objects owning the managed objects
     is zero, in other words, the reference counter equal to zero.

#+BEGIN_SRC cpp 
  auto cls =  std::make_shared<AClass>(arg0, arg1, arg2 ...);
  assert(ptr.use_count() == 1);

  std::shared_ptr<AClass> copy1{cls}; 
  assert(cls.use_count() == 2);
  assert(copy1.use_count() == 2);

  // Reference counter decremented and cls set nullptr. 
  // However, the shared control block and the managed object 
  // were not deleted as they are still used by object 'copy1'. 
  cls = nullptr; 
  assert(cls.use_count() == 0);
  assert(copy1.use_count() == 1);

  // Reference counter decremented, now it reaches zero and both the
  // control block and the managed (heap-allocated) object are deleted
  // as they are no longer used by any other shared_ptr.
  copy1 = nullptr;
  assert(copy.use_count() == 0);
#+END_SRC
*** Best practices and things to avoid for std::shared_ptr

  *Initialization of shared_ptr* 

Instead of: 

#+BEGIN_SRC cpp 
   std::shared_ptr<SomeType> ptr{new SomeType(arg0, arg1, ..., argN)};
#+END_SRC

Better: 

#+BEGIN_SRC cpp 
   std::shared_ptr<SomeType> ptr = std::make_shared<SomeType>(arg0, arg1, ..., argN);
#+END_SRC

Or even better: 

#+BEGIN_SRC cpp 
   auto ptr = std::make_shared<SomeType>(arg0, arg1, ..., argN);
#+END_SRC


  *Polymorphic objects and containers* 

#+BEGIN_SRC cpp 
  class IBase(){
  public:
     virtual void method1() = 0;
     ~IInterface() = default;
  };

  class ClassA: public IBase {
       ... ... 
  }; 

  class ClassB: public IBase {
      .. ... ...
  }; 
     ... ... ... .. 
#+END_SRC
 
Instead of: 

#+BEGIN_SRC cpp 
   std::vector<IBase> dataset { new ClassA(), new ClasB(param0, param1, ...), new Class C, ... };
   dataset.push_back(new ClassA(param0, param1, ..., paramN));
   dataset.push_back(new ClassB(param0, param1, ..., paramN));

  // ········ omit ··· ··· ···· 
  
  // Dispose: 
  for(auto ptr: dataset) { delete ptr; }
#+END_SRC

Better: 

#+BEGIN_SRC cpp 
   std::vector<std::shared_ptr<IBase>> dataset { 
        std::make_shared<ClassA>(), 
        std::make_shared<ClassB>(param0, param1, ...),
        std::make_shared<ClassC>(), 
        ... 
  };
  dataset.push_back(std::make_shared<ClassA>(param0, param1, ..., paramN);
  dataset.push_back(std::make_shared<ClassB>(param0, param1, ..., paramN);

  for(auto cosnt& ptr: dataset){
     // iterate over a container with polymorphic objects ... 
     ... ... ... ... ... 
  }

  // .... Disposed automatically ... 
#+END_SRC

Or simplified with: 

#+BEGIN_SRC cpp 
  // Type alias 
  template<typename T>
  using sh = std::shared_ptr<T>;

  std::vector<sh<IBase>> dataset { 
        std::make_shared<ClassA>(), 
        std::make_shared<ClassB>(param0, param1, ...),
        std::make_shared<ClassC>(), 
        ... 
  }; 
   ... ... ... ... ... 
#+END_SRC

It could also be written as:

#+BEGIN_SRC cpp 
  template<typename T>
  using shared_vector = std::vector<std::shared_ptr<T>>;

  shared_vector<T> dataset { 
        std::make_shared<ClassA>(), 
        std::make_shared<ClassB>(param0, param1, ...),
        std::make_shared<ClassC>(), 
        ... 
  }; 

  // ... ... ... // 
#+END_SRC


  *Free Functions and member parameter passing* 

If the function only needs to query or modify the managed object and
does not need to know anything about the shared_ptr, pass by
reference, const reference or by pointer in the case that null pointer
is acceptable. Functions with those types of arguments will be able to
work with ordinary values, dumb pointers and any type of smart pointers.

#+BEGIN_SRC cpp 
   void someModifierFunction(AType& obj1)
   {
      std::cout << " id = " << obj1.id() << std::endl; 
      obj1.setName(new_name); 
      obj1.display();
   }

   void someConstFunction(AType const& obj1)
   {
      std::cout << " id = " << obj1.id() << std::endl; 
   }

   void somePointerFunction(AType* pobj1)
   {
      if(!pobj1){
          std::cout << " Supplied null pointer"  << std::endl;
          return; 
      }
      std::cout << " id = " << pobj1->id() << std::endl; 
   }

   auto ptr = std::make_shared_ptr<AType>(Arg0, Arg1, ... ArgN); 

   // Passing ptr to functions 
   someModifierFunction(*ptr);
   someConstFunction(*ptr);
   somePointerFunction(ptr,get());
#+END_SRC

Avoid passing the shared pointer by value, if taking ownership, in
other words, storing a copy of the pointer is not needed as the copy
increments the reference counter incurring on a performance overhead. 

#+BEGIN_SRC cpp 
   // AVOID 
   void someFunction(std::shared_ptr<T> ptr)
   {
       // ... incremente atomic reference counter ... 
       // ... . .. // 
   }
#+END_SRC

Only pass by reference to shared_ptr if the function needs to know
about the pointer and does not need to take any ownership (storing a
copy of the pointer for later reference).

#+BEGIN_SRC cpp 
   void function_that_needs_to_know_about_ptr(std::shared_ptr<T> const& ptr)
   {
      std::cout << " Ref count value = " << ptr.use_count() << "\n";
      std::cout << " Address = " << ptr.get() << "\n";
      std::cout << " Value returned by object's member function = " << ptr->memberFunction() << "\n";
   }
#+END_SRC

  *Ownership* 

Avoid: 

 + The following class needs to store a copy of a pointer to polymorphic
   class for later reference and it is responsible for disposing the
   resource during its destruction. In other words, it takes ownership
   of the resource.    

#+BEGIN_SRC cpp 
  class ClassThatTakesOwnership
  {
  private:
     // Pointer to heap-allocated instance of polymorphic class 
     IInterface* m_ptr;

  public: 
     ClassThatTakesOwnership(IInterface* ptr): m_ptr(ptr) {  } 

     ~ClassThatTakesOwnership()
      {
         delete m_ptr; 
         m_ptr = nullptr; 
      }

     void callLater(){ 
        ptr->callMethod(); 
     }      
  };

  ClassThatTakesOwnership cls1{new ImplementationA};

  // NO! BROKEN!
  std::shared_ptr<IInterface> obj = std::make_shared<ImplementationA>(); 
  // NO FLAWED! 
  ClassThatTakesOwnership cls2{obj.get()};
#+END_SRC

Better:

#+BEGIN_SRC cpp 
  class ClassThatTakesOwnership
  {
  private:
     // Pointer to heap-allocated instance of polymorphic class 
     std::shared_ptr<IInterface> m_ptr;

  public: 
     ClassThatTakesOwnership(std::shared_ptr<IInterface> ptr)
       : m_ptr(std::move(ptr)) {  } 

     void callLater(){ 
        ptr->callMethod(); 
     }      
  };

  std::shared_ptr<IInterface> obj = std::make_shared<ImplementationA>(); 
  ClassThatTakesOwnership cls1{obj};

  ClassThatTakesOwnership cls2{std::make_shared<ImplementationB>()};
#+END_SRC

  *Factory functions* 

It is better to return std::unique_ptr from factory functions rather
than shared_ptr as the first is easily turned into the later and
opposite is more difficult. 

#+BEGIN_SRC cpp 
  class IInterface(){
  public:
     virtual void method1() = 0;
     ~IInterface() = default;
  };

  class ImplementationA: public IInterface {
     void method1() override { 
        ... ... .. 
     }
  }; 

  class ImplementationB: public IInterface {
     void method1() override { 
        ... ... .. 
     }
  }; 

  auto factoryFunction(int id) -> std::unique_ptr<IInterface> 
  {
     if(id == 1) { return std::make_unique<ImplementationA>(); }
     if(id == 2) { return std::make_unique<ImplementationB>(); }
     return nullptr;
  }

  // ----------- Usage ----------------------------
  std::shared_ptr<IInterface> p_int1 = factoryFunction(1); 
  std::shared_ptr<IInterface> p_int2 { factoryFunction(1) };
#+END_SRC
  
  *Polymorphism and Casting of Shared Pointers* 

The functions std::static_pointer_cast, std::dynamic_pointer_cast,
std::const_pointer_cast and std::shared_pointer_cast from [[https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast][pointer_cast]]
(cppreference) can be used for downcasting and runtime type
identification of polymorphic objects. 

Consider the hierarchy: 

#+BEGIN_SRC cpp 
  class IBase(){
  public:
     virtual void method1() = 0;
     ~IInterface() = default;
  };

  class ClassA: public IBase {
     void method1() override { 
        ... ... .. 
     }

     void methodExclusiveOfA() { .... }
  }; 

  class ClassB: public IBase {
     void method1() override { 
        ... ... .. 
     }

     void methodExclusiveOfB() { ... }
  }; 
#+END_SRC

Create an instance of class A: 

#+BEGIN_SRC cpp 
   std::shared_ptr<IBase> obj = std::make_shared<ClassA>(obj);
#+END_SRC

 + *Static casting* - Casting at compile time without any runtime
   overhead, however, if the casting is not possible, it results in
   undefined behavior just like what happens with static_cast for
   pointers. 

#+BEGIN_SRC cpp 
   std::shared_ptr<A> ptr_a = std::static_pointer_cast<A>(obj);
   if(ptr_a) {
      ptr_a->method1();
      ptr_a->methodExclusiveofA(); 
   }

   // **** WARNING!! UNDEFINED BEHAVIOR!! *****
   std::shared_ptr<A> ptr_b = std::static_pointer_cast<B>(obj);
#+END_SRC

 + *Dynamic Casting* - RTTI - Runtime Type Identification, if the
   casting fails, the function _std::dynamic_pointer_cast_ returns a
   null pointer just like _dynamic_cast<T>_ operator.

#+BEGIN_SRC cpp 
   // Increment reference counter by 1 if successful 
   std::shared_ptr<A> ptr_a = std::dynamic_pointer_cast<A>(obj);
   assert( ptr_a != nullptr);
   if(ptr_a) {
      ptr_a->method1();
      ptr_a->methodExclusiveofA(); 
   }

   auto ptr_b = std::dynamic_pointer_cast<B>(obj);
   assert( ptr_b == nullptr);
   if(ptr_b){
      ptr_b->method1();
      ptr_b->methodExclusiveofB(); 
   }
#+END_SRC

*** Example: unique_ptr 

 Example: 

  + A car object has  only one engine, multiple cars cannot have the
    same engine and the engine is destroyed when the car object is destroyed.

  + The engine is polymorphic object implementing the interface
    IEngine.

  + The car object can replace the engine at runtime. 

 Full code: 
  + [[file:src/smart_ptr_unique1.cpp][file:src/smart_ptr_unique1.cpp]] 


Headers: 

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

  #include <type_traits>

  // Provide std::unique_ptr and std::shared_ptr
  #include <memory>
#+END_SRC

Interface: IEngine

#+BEGIN_SRC cpp 
  // Car Engine Interface
  class IEngine{
  public:
      virtual std::string type() const = 0;
      virtual void        run()  = 0;
      // virtual void        shutdown() = 0;
      virtual ~IEngine() = default;
  };
#+END_SRC

Class DieselEngine implemeting the interface IEngine.

#+BEGIN_SRC cpp 
  class DieselEngine: public IEngine
  {
  public:
      DieselEngine()
      {
          std::puts(" [INFO] Diesel Engine created.");
      }

      ~DieselEngine()
      {
          std::puts(" [INFO] Diesel Engine deleted.");
      }

      std::string type() const override
      {
          return "diesel engine";
      }

      void run() override
      {
          std::puts(" Running a super powerful diesel Engine!!");
      }
  };
#+END_SRC

Class ElectricEngine implemeting the interface IEngine: 

#+BEGIN_SRC cpp 
  class ElectricEngine: public IEngine
  {
  public:
      ElectricEngine()
      {
          std::puts(" [INFO] Electrict Engine created.");
      }

      ~ElectricEngine()
      {
          std::puts(" [INFO] Electric Engine deleted.");
      }

      std::string type() const override
      {
          return "electric engine";
      }

      void run() override
      {
          std::puts(" =>> Running a silent and clean electric engine!!");
      }
  };
#+END_SRC

Class SomeCar that contains an engine object implemeting the IEngine
interface. 

#+BEGIN_SRC cpp 

  class SomeCar{
  private:
      std::unique_ptr<IEngine> m_engine;
  public:

      SomeCar(): m_engine(nullptr) { }

      // Constructor: Dependency injection
      // => the dependency is supplied and instantiated
      // by an external code rather than being instantiated by this class.
      SomeCar(IEngine* obj): m_engine(obj){ }

      // Unique_ptr cannot be copied, they only can be moved.
      // The std::move, transfers the ownership of the supplied std::unique_ptr
      // to this class.
      SomeCar(std::unique_ptr<IEngine> engine)
          : m_engine(std::move(engine))
      {
      }

      void run_engine(){
          std::puts(" [INFO] Run car engine.");
          // Unique_ptr can be used just as an ordinary pointer
          m_engine->run();
      }

      // Set a new engine.
      void set_engine(IEngine* engine)
      {
          // Disposes the old engine and sets a new one
          m_engine.reset(engine);
      }

      void set_engine(std::unique_ptr<IEngine> engine)
      {
          // Calls move assingment operator disposing the old engine
          m_engine  = std::move(engine);
      }

      std::string engine_type() {
          return m_engine->type();
      }

      void remove_engine() {
          // Delete wrapped heap-allocated object
          m_engine.release();
      }

      // Check if the car has an engine
      bool has_engine(){
          return m_engine != nullptr;
      }

      ~SomeCar(){
          std::puts(" [INFO] object of class SomeCar disposed. OK");
      }

  };
#+END_SRC

Factory function: 

#+BEGIN_SRC cpp 
  std::unique_ptr<IEngine>
  factoryFunction(char code)
  {
      if(code == 'e') { return std::make_unique<ElectricEngine>(); }
      if(code == 'd') { return std::make_unique<DieselEngine>(); }
      return nullptr;
  }
#+END_SRC

 *Main Function* - int main() 

 + Main Function - Experiment 0 

#+BEGIN_SRC cpp 
  std::cout << "\n ***** EXPERIENT 0 === Type Traits *********************\n";
  std::cout << "---------------------------------------------------------------\n";
  std::cout << std::boolalpha;
  {

      std::cout << " is_abstract<IEngine>() = "
                << std::is_abstract<IEngine>() << "\n";

      std::cout << " is_abstract<ElectricEngine>() = "
                << std::is_abstract<ElectricEngine>() << "\n";

      std::cout << " is_fundamental<ElectricEngine>() = "
                << std::is_fundamental<ElectricEngine>() << "\n";

      std::cout << " is_polymorphic<ElectricEngine>() = "
                << std::is_polymorphic<ElectricEngine>() << "\n";

      std::cout << " is_trivially_copiable<ElectricEngine() = "
                << std::is_trivially_copyable<ElectricEngine>() << "\n";

      std::cout << " is_trivially_move_constructible<ElectricEngine() = "
                << std::is_trivially_move_constructible<ElectricEngine>() << "\n";

  }
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ,***** EXPERIENT 0 === Type Traits *********************
   ---------------------------------------------------------------
    is_abstract<IEngine>() = true
    is_abstract<ElectricEngine>() = false
    is_fundamental<ElectricEngine>() = false
    is_polymorphic<ElectricEngine>() = true
    is_trivially_copiable<ElectricEngine() = false
    is_trivially_move_constructible<ElectricEngine() = false
#+END_SRC


 + Main function - Experiment 1 

#+BEGIN_SRC cpp 
  std::cout << "\n ***** EXPERIMENT 1 = Instatiate a car with new operator ****\n ";
  std::cout << "---------------------------------------------------------------\n";
  {
      // Note: note recommended using 'new', instead use std::make_unique
      SomeCar car1(new DieselEngine);
      std::cout << " car1.has_engine() = " << car1.has_engine() << "\n";
      std::cout << " car1.engine_type() = " << car1.engine_type() << "\n";
      car1.run_engine();

      // Car and engine deleted at the end of this scope or at this bracket.
  }
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ,***** EXPERIMENT 1 = Instatiate a car with new operator ****
   ---------------------------------------------------------------
   [INFO] Diesel Engine created.
   car1.has_engine() = true
   car1.engine_type() = diesel engine
   [INFO] Run car engine.
   Running a super powerful diesel Engine!!
   [INFO] object of class SomeCar disposed. OK
   [INFO] Diesel Engine deleted.
#+END_SRC

 + Main function - Experiment 2 

#+BEGIN_SRC cpp 
    std::cout << "\n **** EXPERIMENT 2 = Instatiate a car with an exising unique_ptr ****\n ";
    std::cout << "---------------------------------------------------------------\n";
    {
        // Not recommended using new!
        std::unique_ptr<IEngine> engineA(new ElectricEngine);

        // Note: engineA is not copiable, can only be moved
        SomeCar carA(std::move(engineA));
        std::cout << " carA.has_engine() = " << carA.has_engine() << "\n";
        std::cout << " carA.engine_type() = " << carA.engine_type() << "\n";
        carA.run_engine();

        // Remove engine of carA and sell it at the market
        carA.remove_engine();
        std::cout << " After removal of carA's engine." << "\n";
        std::cout << " car1.has_engine() = " << carA.has_engine() << "\n";

        std::cout << "\n After removing engine of CarA" << "\n";
        carA.set_engine(new DieselEngine);
        std::cout << " carA.engine_type() = " << carA.engine_type() << "\n";
        carA.run_engine();
    }
#+END_SRC

Output: 

#+BEGIN_SRC text 
  ,**** EXPERIMENT 2 = Instatiate a car with an exising unique_ptr ****
   ---------------------------------------------------------------
   [INFO] Electrict Engine created.
   [INFO] Called SomeCar L-value reference constructor
   carA.has_engine() = true
   carA.engine_type() = electric engine
   [INFO] Run car engine.
   =>> Running a silent and clean electric engine!!
   After removal of carA's engine.
   car1.has_engine() = false

   After removing engine of CarA
   [INFO] Diesel Engine created.
   carA.engine_type() = diesel engine
   [INFO] Run car engine.
   Running a super powerful diesel Engine!!
   [INFO] object of class SomeCar disposed. OK
   [INFO] Diesel Engine deleted.
#+END_SRC

 + Main function - Experiment 3 

#+BEGIN_SRC cpp 
    std::cout << "\n **** EXPERIMENT 3 = Using std::make_unique ****\n ";
    std::cout << "---------------------------------------------------------------\n";
    {
        SomeCar carA(std::make_unique<DieselEngine>());
        std::cout << " carA.has_engine() = " << carA.has_engine() << "\n";
        std::cout << " carA.engine_type() = " << carA.engine_type() << "\n";
        carA.run_engine();


        std::cout << "\n [TRACE] After setting a new engine for CarA" << "\n";
        auto engine = std::make_unique<ElectricEngine>();
        std::cout << " ?? engine == nullptr " << (engine == nullptr) << std::endl;

        carA.set_engine(std::move(engine));

        std::cout << " carA.engine_type() = " << carA.engine_type() << "\n";
        carA.run_engine();

        std::cout << "\n [TRACE] After setting a new engine again for CarA" << "\n";
        carA.set_engine( std::make_unique<DieselEngine>() );
        std::cout << " carA.engine_type() = " << carA.engine_type() << "\n";
        carA.run_engine();

    }
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ,**** EXPERIMENT 3 = Using std::make_unique ****
   ---------------------------------------------------------------
   [INFO] Diesel Engine created.
   [INFO] Called SomeCar R-value reference constructor
   carA.has_engine() = true
   carA.engine_type() = diesel engine
   [INFO] Run car engine.
   Running a super powerful diesel Engine!!

   [TRACE] After setting a new engine for CarA
   [INFO] Electrict Engine created.
   ?? engine == nullptr false
   [INFO] Diesel Engine deleted.
   carA.engine_type() = electric engine
   [INFO] Run car engine.
   =>> Running a silent and clean electric engine!!

   [TRACE] After setting a new engine again for CarA
   [INFO] Diesel Engine created.
   [INFO] Electric Engine deleted.
   carA.engine_type() = diesel engine
   [INFO] Run car engine.
   Running a super powerful diesel Engine!!
   [INFO] object of class SomeCar disposed. OK
   [INFO] Diesel Engine deleted.
#+END_SRC

 + Main function - Experiment 4 

#+BEGIN_SRC cpp 
  std::cout << "\n **** EXPERIMENT 4 = Factory Function ****\n ";
  std::cout << "---------------------------------------------------------------\n";
  {
      SomeCar car;
      auto engine1 = factoryFunction('x');

      // If the pointer is not nullptr (null) evalutes to true
      if(engine1){
          std::cout << " Engine created from factory function. Ok. \n";
      } else {
          car.set_engine(std::move(engine1));
      }
      std::cout << " ??? car.has_engine() = " << car.has_engine() << std::endl;

      std::cout << "\n Set engine to DIESEL engine.\n";
      car.set_engine(factoryFunction('d'));
      std::cout << " ??? car.has_engine() = " << car.has_engine() << std::endl;
      std::cout << " Engine type = " << car.engine_type() << "\n";
      car.run_engine();

      std::cout << "\n Set engine to ELECTRIC engine.\n";
      car.set_engine(factoryFunction('e'));
      std::cout << " ??? car.has_engine() = " << car.has_engine() << std::endl;
      std::cout << " Engine type = " << car.engine_type() << "\n";
      car.run_engine();
  }
#+END_SRC

Output: 

#+BEGIN_SRC text 
    ,**** EXPERIMENT 4 = Factory Function ****
    ---------------------------------------------------------------
    ??? car.has_engine() = false

    Set engine to DIESEL engine.
    [INFO] Diesel Engine created.
    ??? car.has_engine() = true
    Engine type = diesel engine
    [INFO] Run car engine.
    Running a super powerful diesel Engine!!

    Set engine to ELECTRIC engine.
    [INFO] Electrict Engine created.
    [INFO] Diesel Engine deleted.
    ??? car.has_engine() = true
    Engine type = electric engine
    [INFO] Run car engine.
    =>> Running a silent and clean electric engine!!
    [INFO] object of class SomeCar disposed. OK
    [INFO] Electric Engine deleted.
#+END_SRC
*** Example: shared_ptr 

Full code: 
 + File:  [[file:src/smart_ptr_shared1.cpp][file:src/smart_ptr_shared1.cpp]]

Build: 

#+BEGIN_SRC sh 
   # Build 
   $ g++ shared_ptr1.cpp -o out.bin -std=c++1z -g -O0 -Wall -Wextra 
   
   # Run 
   ./out.bin 
#+END_SRC

Headers:

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <string>
  #include <vector>
  #include <algorithm>
  #include <iomanip>

  #include <cassert> // assert (assertions)
  #include <memory> // Provide: std::shared_ptr
#+END_SRC

Interface: IMediaAsset

#+BEGIN_SRC cpp 
  // Media asset interface => generic specification for an media asset.
  // Note: A struct is just a class with everything public by default.
  struct IMediaAsset{
      virtual std::string type() const = 0;
      virtual std::string name() const = 0;
      virtual void play()              = 0;

      /** Always add a default destructor. */
      virtual ~IMediaAsset() = default;
  };
#+END_SRC

Class: MusicAsset

#+BEGIN_SRC cpp 

  class MusicAsset: public IMediaAsset
  {
      std::string m_name;
  public:

      MusicAsset(std::string name):
          m_name(std::move(name))
      {
          std::printf(" [TRACE] CTOR - Music object => name = %s created. \n "
                      , m_name.c_str());
      }

      MusicAsset(): MusicAsset("unnamed-music") { }

      ~MusicAsset()
      {
          std::printf(" [TRACE] DTOR - Music object => name = %s destroyed. \n "
                      , m_name.c_str());
      }

      // Override keyword is optional, but it is recommended in C++11
      std::string type() const override
      {
          return "music";
      }

      std::string name() const override
      {
          return m_name;
      }

      void play() override
      {
          std::cout << " [INFO] Playing music: " << m_name << std::endl;
      }

      void setVolumePercent(unsigned int volume) {
          std::cout << " [INFO] Volume of music <"
                    << m_name << "> set to "
                    << volume << "%\n";
      }

  };
#+END_SRC

Class PictureAsset: 

#+BEGIN_SRC cpp 

  class PictureAsset: public IMediaAsset
  {
      std::string m_name;
  public:

      PictureAsset(std::string name):
          m_name(std::move(name))
      {
          std::printf(" [TRACE] CTOR - Picture object => name = %s created. \n "
                     , m_name.c_str());
      }

      PictureAsset(): PictureAsset("unnamed-picture") { }

      ~PictureAsset()
      {
          std::printf(" [TRACE] DTOR - Picture object => name = %s destroyed. \n "
                      , m_name.c_str());
      }

      // Override keyword is optional, but it is recommended in C++11
      std::string type() const override
      {
          return "picture";
      }

      std::string name() const override
      {
          return m_name;
      }

      void play() override
      {
          std::cout << " [INFO] Show picture : " << m_name << std::endl;
      }

      void resizeInPercent(unsigned int percent) {
          std::cout << " [INFO] Picture<"
                    << m_name << "> resized "
                    << percent << "%\n";
      }


  };
#+END_SRC

Shared pointer type alias: 

#+BEGIN_SRC cpp 
  // Type alias for shared_ptr
  template<typename T>
  using sh = std::shared_ptr<T>;
#+END_SRC

Factory function: 

#+BEGIN_SRC cpp 
  /* For the factory function use std::unique_ptr instead of shared_ptr as
   ,* it is easier to convert unique_ptr to shared_ptr than the other way around.
   ,*/
  std::unique_ptr<IMediaAsset>
  factoryFunction(int id)
  {
      if(id == 1) { return std::make_unique<MusicAsset>("Fur Elise"); }
      if(id == 2) { return std::make_unique<PictureAsset>("São Paulo's Skyline"); }
      if(id == 3) { return std::make_unique<MusicAsset>("Baorque music"); }
      if(id == 4) { return std::make_unique<PictureAsset>("Tokyo skyline"); }
      return nullptr;
  }
#+END_SRC

  + main() Function - Experiment 1 

#+BEGIN_SRC cpp 
  std::cout << std::boolalpha;

  //=============== EXPERIMENT 1 ===============================================//
  std::puts("\n ****** =>>>> EXPERIMENT 1 - Reference counter test **************\n");

  // Not recommended using new => Instead use std::make_shared
  // When the object is created, the reference count is set to 1.
  std::shared_ptr<PictureAsset> pic1(new PictureAsset("Desert sunshine"));
  assert( pic1.use_count() == 1);

  std::cout << " => Type of object pic1 = " << pic1->type()
            << "  ; name = " << pic1->name()
            << std::endl;

  std::cout << " => Address of pic1 managed object = " << pic1.get() << std::endl;
  std::cout << " => Value of ref. counter of pic1 = " << pic1.use_count() << std::endl;


  {
      std::puts(" >> [TRACE] Before entering local scope <<=== \n");

      // Increments reference counter by 1 (set to 2) => .use_count() returns 2
      std::shared_ptr<PictureAsset> pic1_copyA = pic1;
      assert(pic1_copyA.use_count() == 2);
      assert(pic1.use_count() == 2);
      std::printf(" [INFO] Reference count of pic1_copyA = %ld \n", pic1_copyA.use_count());
      std::printf(" pic1_copyA->name() = %s \n", pic1_copyA->name().c_str());


      // Increments reference counter by 1 (set to 3)
      auto pic1_copyB = pic1;
      assert(pic1.use_count() == 3);
      assert(pic1_copyB.use_count() == 3);
      // .use_count() returns 3
      std::printf(" [INFO] Reference count of pic1_copyB = %ld \n", pic1_copyA.use_count());
      std::printf(" pic1_copyB->name() = %s \n", pic1_copyB->name().c_str());

      /** Objdcts pic1_copyA and pic1_copyB are destroyed,
       ,* then each one decrements the reference counter by 1
       ,*/
      std::puts(" >> [TRACE] Levaing  local scope <<=== ");
  }

  // .use_count returns 1 as the two copies were destroyed.
  std::printf(" [INFO] Before reset(). Reference count of pic1 = %ld \n", pic1.use_count());

  assert(pic1.use_count() == 1);
  // Decrements reference counter of control block by 1.
  // The owned object and the control block are deleted when the counter is zero.
  // When the counter reaches zero, the internal pointer is set to nullptr.
  pic1.reset();
  assert(pic1.use_count() == 0);

  std::printf(" [INFO] After reset(). Reference count of pic1 = %ld \n", pic1.use_count());

  std::cout << " ?? Is pic1 nullptr => (pic1 == nullptr) : "
            << (pic1  == nullptr)
            << std::endl;

  std::cout << " ?? Does shared_ptr pic1 own an object => (pic1 != nullptr) : "
            << (pic1  != nullptr)
            << std::endl;

#+END_SRC

Output: 

#+BEGIN_SRC text 
  ,****** =>>>> EXPERIMENT 1 - Reference counter test **************

   [TRACE] CTOR - Picture object => name = Desert sunshine created. 
    => Type of object pic1 = picture  ; name = Desert sunshine
   => Address of pic1 managed object = 0x1b73e80
   => Value of ref. counter of pic1 = 1
   >> [TRACE] Before entering local scope <<=== 

   [INFO] Reference count of pic1_copyA = 2 
   pic1_copyA->name() = Desert sunshine 
   [INFO] Reference count of pic1_copyB = 3 
   pic1_copyB->name() = Desert sunshine 
   >> [TRACE] Levaing  local scope <<=== 
   [INFO] Before reset(). Reference count of pic1 = 1 
   [TRACE] DTOR - Picture object => name = Desert sunshine destroyed. 
    [INFO] After reset(). Reference count of pic1 = 0 
   ?? Is pic1 nullptr => (pic1 == nullptr) : true
   ?? Does shared_ptr pic1 own an object => (pic1 != nullptr) : false

#+END_SRC

 + main() Function - Experiment 2 

#+BEGIN_SRC cpp 
  //======= EXPERIMENT 2 ===>> Polymorphism ======================================//
  std::puts("\n ****** =>>>> EXPERIMENT 2 - Polymorphism test **************\n");

  std::printf(" \n --- Experiment 2.A - musicA object \n");

  // Default initialized to nullptr (reference counter is zero).
  std::shared_ptr<IMediaAsset> media1;
  assert(media1.use_count() == 0);

  if(!media1){
      std::cout << " [TRACE] Media pointer owns no object, it is nullptr" << std::endl;
  } else {
      std::cout << " [TRACE] Media pointer owns an object, it is not nullptr" << std::endl;
  }
  std::printf(" [INFO] Ref count of media1 = %ld \n", media1.use_count());

  // Best way to instantiante a polymorphic object
  // Type: std::shared_ptr<MusicAsset>
  auto musicA = std::make_shared<MusicAsset>("Fur Elise");
  std::printf(" [INFO] Ref count of musicA = %ld \n", musicA.use_count());

  // Polymorphism: the pointer to a derived class
  // can be assigned to a pointer of the base class.
  media1 = musicA;
  std::printf(" [INFO] Ref count of musicA = %ld \n", musicA.use_count());
  std::printf(" [INFO] Ref count of medai1 = %ld \n", media1.use_count());

  std::printf(" \n --- Experiment 2.B - pictA object \n");
  {


      // Type: std::shared_ptr<PictureAsset>
      auto pictA = std::make_shared<PictureAsset>("Canyon sunset");
      std::printf(" [INFO] Before assigning: Ref count of pictA = %ld \n"
                  , pictA.use_count());

      std::printf(" => pictA->type() = '%s' - pictA->name() = %s  "
                  , pictA->type().c_str(), pictA->name().c_str() );

      media1 = pictA;
      std::printf(" [INFO] After assigning: Ref count of pictA = %ld \n"
                  , musicA.use_count());

      std::printf(" => media1->type() = '%s' - media1->name() = %s  \n"
                  , media1->type().c_str(), media1->name().c_str() );

      // Object (shared pointer) pictA destroyed here
      // , but not the owned object "Canyon sunset" as it also owned by 'media1' pointer
  }

  std::printf(" \n --- Experiment 2.C - After end of local scope \n");

  std::shared_ptr<IMediaAsset> media2 = media1;
  std::printf(" [INFO] Ref count of media1 = %ld \n", media1.use_count());
  std::printf(" [INFO] Ref count of media1 = %ld \n", media2.use_count());

  media1 = nullptr;
  std::printf(" [INFO] Ater setting media1 to null => Ref count of media1 = %ld \n"
              , media1.use_count());
  std::printf(" [INFO] Ater setting media2 to null => Ref count of media2 = %ld \n"
              , media2.use_count());

  std::printf(" Before setting media2 to nullptr => media2->type() = '%s' - media2->name() = %s  \n"
              , media2->type().c_str(), media2->name().c_str() );

  // Reference count set to zero => The object "Canyon sunset" is destroyed
  // as any pointer no longer owns it.
  media2 = nullptr;

  std::cout << " After setting media2 to nullptr => ?? Is media2 nullptr = "
            << (media2 == nullptr) << std::endl;
#+END_SRC

Output: 

#+BEGIN_SRC text 
   ,****** =>>>> EXPERIMENT 2 - Polymorphism test **************


    --- Experiment 2.A - musicA object 
    [TRACE] Media pointer owns no object, it is nullptr
    [INFO] Ref count of media1 = 0 
    [TRACE] CTOR - Music object => name = Fur Elise created. 
     [INFO] Ref count of musicA = 1 
    [INFO] Ref count of musicA = 2 
    [INFO] Ref count of medai1 = 2 

    --- Experiment 2.B - pictA object 
    [TRACE] CTOR - Picture object => name = Canyon sunset created. 
     [INFO] Before assigning: Ref count of pictA = 1 
    => pictA->type() = 'picture' - pictA->name() = Canyon sunset   [INFO] After assigning: Ref count of pictA = 1 
    => media1->type() = 'picture' - media1->name() = Canyon sunset  

    --- Experiment 2.C - After end of local scope 
    [INFO] Ref count of media1 = 2 
    [INFO] Ref count of media1 = 2 
    [INFO] Ater setting media1 to null => Ref count of media1 = 0 
    [INFO] Ater setting media2 to null => Ref count of media2 = 1 
    Before setting media2 to nullptr => media2->type() = 'picture' - media2->name() = Canyon sunset  
    [TRACE] DTOR - Picture object => name = Canyon sunset destroyed. 
     After setting media2 to nullptr => ?? Is media2 nullptr = true
#+END_SRC

  + Experiment 3 

#+BEGIN_SRC cpp 
  //=============== EXPERIMENT 3 - Polymorphism and pointer casting ===========//
  std::puts("\n ****** =>>>> EXPERIMENT 3 - Polymorphism and casting ***********\n");

  std::shared_ptr<IMediaAsset> asset1 = std::make_shared<MusicAsset>("Blues");


  // Downcast object at runtime (RTTI) checking whetehr it
  // is a Music asset taking its ownership.
  {
      // RTTI Runtime - Type information
      std::shared_ptr<PictureAsset> asset_is_music = std::dynamic_pointer_cast<PictureAsset>(asset1);
      if(asset_is_music){
          std::cout << " =>>> Asset type is music OK" << std::endl;
          std::printf(" Object Type = %s - object name = %s\n"
                      , asset_is_music->type().c_str()
                          , asset_is_music->name().c_str());

      } else {
          std::cout << " =>> Asset type is not music. " << std::endl;
      }

  }

  // Static casting object at runtime => IF the casting is wrong, it results in
  // undefined behavior!!

  std::cout << "\n ---- Before changing pointed object " << std::endl;
  asset1 = factoryFunction(2);
  std::cout << "\n ---- After changing pointed object " << std::endl;

  if(asset1->type() == "picture")
  {
      // Warning: if the casting does not match, results in undefined behavior!!
      auto asset_picture = std::static_pointer_cast<PictureAsset>(asset1);

      std::cout << "\n =>>> Asset type is picture OK" << std::endl;
      std::printf(" Object Type = %s - object name = %s\n"
                  , asset_picture->type().c_str()
                      , asset_picture->name().c_str());

      asset_picture->resizeInPercent(40);
  }

#+END_SRC
 
Output: 

#+BEGIN_SRC text 
   ,****** =>>>> EXPERIMENT 3 - Polymorphism and casting ***********

    [TRACE] CTOR - Music object => name = Blues created. 
     =>> Asset type is not music. 

    ---- Before changing pointed object 
    [TRACE] CTOR - Picture object => name = São Paulo's Skyline created. 
     [TRACE] DTOR - Music object => name = Blues destroyed. 

    ---- After changing pointed object 

    =>>> Asset type is picture OK
    Object Type = picture - object name = São Paulo's Skyline
    [INFO] Picture<São Paulo's Skyline> resized 40%
#+END_SRC

 + Experiment 4 

#+BEGIN_SRC cpp 
  //=============== EXPERIMENT 4 - Polymorphism and containers ================//
  std::puts("\n ****** =>>>> EXPERIMENT 4 - Polymorphioc Objects and Containers *****\n");

  auto objA = std::make_shared<MusicAsset>("Some medieval music");
  std::shared_ptr<IMediaAsset> objB = factoryFunction(2);

  std::cout << "\n --- Before filling 'collection' " << std::endl;

  // Polymorphism
  std::vector<sh<IMediaAsset>> collection =
      {
          std::make_shared<PictureAsset>("Max turbo power diesel engine")
        , std::make_shared<MusicAsset>("Some baroque music")
        , std::make_shared<PictureAsset>("Desert canyon")
        , factoryFunction(1)
      };

  collection.push_back(objA);
  collection.push_back(objB);

  std::cout << " --- After filling 'collection' \n\n";

  std::cout << " Ref counter of objA = " << objA.use_count() << std::endl;

  std::cout << " ==== Print objects in the container ==== " << std::endl;

  for(auto const& ptr: collection){
      std::cout << std::right << std::setw(15) << ptr->type()
                << std::right << "  "
                << std::left  << std::setw(35) << ptr->name()
                << std::endl;
  }
  std::cout << std::right;

  std::cout << "\n ----- Before clearing the vector  ----- " << std::endl;

  collection.clear();

  std::cout << "\n ----- After clearing the vector  ----- " << std::endl;

  objA = nullptr;
  objB.reset();

  std::puts("\n  *********** End of Main() *****************");

  return 0;
#+END_SRC

Output: 

#+BEGIN_SRC text 
  ,****** =>>>> EXPERIMENT 4 - Polymorphioc Objects and Containers *****

   [TRACE] CTOR - Music object => name = Some medieval music created. 
    [TRACE] CTOR - Picture object => name = São Paulo's Skyline created. 

   --- Before filling 'collection' 
   [TRACE] CTOR - Picture object => name = Max turbo power diesel engine created. 
    [TRACE] CTOR - Music object => name = Some baroque music created. 
    [TRACE] CTOR - Picture object => name = Desert canyon created. 
    [TRACE] CTOR - Music object => name = Fur Elise created. 
    --- After filling 'collection' 

   Ref counter of objA = 2
   ==== Print objects in the container ==== 
          picture  Max turbo power diesel engine      
            music  Some baroque music                 
          picture  Desert canyon                      
            music  Fur Elise                          
            music  Some medieval music                
          picture  São Paulo's Skyline               

   ----- Before clearing the vector  ----- 
   [TRACE] DTOR - Picture object => name = Max turbo power diesel engine destroyed. 
    [TRACE] DTOR - Music object => name = Some baroque music destroyed. 
    [TRACE] DTOR - Picture object => name = Desert canyon destroyed. 
    [TRACE] DTOR - Music object => name = Fur Elise destroyed. 

   ----- After clearing the vector  ----- 
   [TRACE] DTOR - Music object => name = Some medieval music destroyed. 
    [TRACE] DTOR - Picture object => name = São Paulo's Skyline destroyed. 

    ,*********** End of Main() *****************
   [TRACE] DTOR - Picture object => name = São Paulo's Skyline destroyed. 
    [TRACE] DTOR - Music object => name = Fur Elise destroyed. 
#+END_SRC
*** Selected Codebases with std::shared_ptr 

Libraries and Applications: 

  + Project: [[https://github.com/LibreOffice/core][LibreOffice]] - Read-only LibreOffice core repo. Note:
    Contains more than 1000 usages of shared_ptr. 
    + [[https://github.com/LibreOffice/core/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://gitlab.com/inkscape/inkscape][inkscape]] - Vector drawing and diagram application similar to Microsft Visio.
    + [[https://gitlab.com/search?utf8=%25E2%259C%2593&search=shared_ptr&group_id=&project_id=3472737&search_code=true&repository_ref=master&nav_source=navbar][std::shared_ptr search]]

  + Project: [[https://github.com/emweb/wt][WT]] C++ Web Toolkit, aka Web Framework.
    + [[https://github.com/emweb/wt/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/BVLC/caffe][caffe]] - Caffe is a deep learning framework made with
    expression, speed, and modularity in mind. It is developed by
    Berkeley AI Research (BAIR)/The Berkeley Vision and Learning
    Center (BVLC) and community contributors.
    + [[https://github.com/BVLC/caffe/search?q=std%253A%253Ashared_ptr&unscoped_q=std%253A%253Ashared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/facebook/rocksdb][rocksdb]] - A Persistent Key-Value Store for Flash and RAM
    Storage (developed by Facebook)
    + [[https://github.com/facebook/rocksdb/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/microsoft/terminal][microsoft/terminal]] - The new Windows Terminal, and the
    original Windows console host -- all in the same place!
    + [[https://github.com/microsoft/terminal/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/skypjack/uvw][uvw]] - Header-only, event based, tiny and easy to use
    libuv wrapper in modern C++. 
    + [[https://github.com/skypjack/uvw/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

Computer Graphics and Game Engines: 

  + Project: [[https://github.com/WolfEngine/Wolf.Engine][Wolf.Engine]] - The Wolf is a comprehensive set of C++ open
    source libraries for realtime rendering, realtime streaming and
    game developing https://WolfEngine.app 
    + [[https://github.com/WolfEngine/Wolf.Engine/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/4ian/GDevelop][GDevelop]] - video_game GDevelop is an open-source,
    cross-platform game engine designed to be used by
    everyone. https://gdevelop-app.com
    + [[https://github.com/4ian/GDevelop/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/SourMesen/Mesen][Mesen]] - Mesen is a cross-platform (Windows & Linux)
    NES/Famicom emulator built in C++ and C# https://www.mesen.ca
    + [[https://github.com/SourMesen/Mesen/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/PCSX2/pcsx2][pcsx2]] - The Playstation 2 Emulator 
    + [[https://github.com/PCSX2/pcsx2/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/Shervanator/Engine][Shervanator/Engine]] - A basic cross-platform (Mac,
    Windows, Linux, HTML5, Android) 3D game engine.
    + [[https://github.com/Shervanator/Engine/search?q=shared_ptr&unscoped_q=shared_ptr][std::shared_ptr search]]

  + Project: [[https://github.com/openscad/openscad][openscad]] - OpenSCAD - The Programmers Solid 3D CAD Modeller
    + [[https://github.com/openscad/openscad/search?q=shared_ptr&unscoped_q=shared_ptr][search std::shared_ptr]]

  + Project: [[https://github.com/jpvanoosten/LearningDirectX12][LearningDirectX12]] - This repository is intended to be
    used as a code repository for learning DirectX 12. The tutorials
    can be found on https://www.3dgep.com. 
    + [[https://github.com/jpvanoosten/LearningDirectX12/search?q=std%253A%253Ashared_ptr&unscoped_q=std%253A%253Ashared_ptr][std::shared_ptr search]]


*** Additional Reading 

 *General:*

  + *Five Popular Miths about C++*
    + <http://www.stroustrup.com/Myths-final.pdf> 

  + StackOverflow - *Why do C++ libraries and frameworks never use smart pointers?*
    + <https://stackoverflow.com/questions/10334511>

  + Boost intrusive_ptr : faster shared pointer
    + <https://baptiste-wicht.com/posts/2011/11/boost-intrusive_ptr.html>

  + Wrapping C++ std::shared_ptr and similar smart pointers
    + <https://discuss.ocaml.org/t/wrapping-c-std-shared-ptr-and-similar-smart-pointers/3582>

  + C++ Gof Design Patterns heavily depends on new or shared_ptr
    + <https://softwareengineering.stackexchange.com/questions/381197>

 *Shared Pointers in Projects and Libraries* 

  + *Boost Shared Pointers* - Inkscape
    + http://wiki.inkscape.org/wiki/index.php/Boost_shared_pointers

  + *Mantid Project - Some C++ Tips*
    + https://www.mantidproject.org/Some_C%2B%2B_Tips

  + *Boost Structures in OMPL - Open Motion Planing*
    + https://www.mantidproject.org/Some_C%2B%2B_Tips

  + *Project Chrono - Shared Pointers*
    + http://api.projectchrono.org/shared_pointers.html
 
** Exceptions and Error Handling 
*** Overview 

 *C++ has several error Handling approaches:*

 + _Exceptions_: - try-catch and throw
   * Benefits:
     + Code Separation:
       + Separation of error handling from the computation logic.
     + Error notification
       + Forces developers to handle the error by ending the the
         program execution when the application is not ready to handle
         the error that caused the exception. 
     + Easier to recover from errors and failures.
     + Stack Traces:
   * Downsides:
     + Increase of executable size - It should not be a concern anymore,
       since hard driver are becoming more cheaper with the passing of
       time.
     + According to many sources, exceptions can be a concern in real
       time embedded systems. 

 + _Error codes in global variables_
   * Many C APIs handle error by setting some global variable that the
     calling code must check for some some error condition. For
     instance, the U*nix C-API indicates error by setting the global
     variable _errno_ that must be checked by the calling code after
     after some operation that may set this flag. The downside of the
     this approach is that if the program doesn't check the global
     error flag, the program may continue its execution without
     notifying the user that something is wrong what can lead to
     runtime bugs hard to trace.

   * Downsides:
     + It is easy to forget handling global variables with error code.
     + May have multi-threading racing conditions issues.
     + Don't notify users that the program cannot handle the runtime
       errors.
     + Hard to trace and debug.

 + _Error codes as return value_:

   * A function can provide error notification by returning an error
     code to the caller. For instance, a function which downloads a
     file could return 1 for successful download, 2 for DNS resolution
     error, 3 for network error and so on.

   * Variations:

     + _Return an error code such as a bitmask or enumeration_. Example:
       HRESULT type is returned type by many Windows COM API for
       indicating error
       + https://en.wikipedia.org/wiki/HRESULT
       + [[https://docs.microsoft.com/en-us/windows/desktop/seccrypto/common-hresult-values][Common HRESULT Values | Microsoft Docs]]
       + [[https://docs.microsoft.com/en-us/windows/desktop/api/unknwn/nf-unknwn-iunknown-queryinterface%28refiid_void%29][IUnknown::QueryInterface(REFIID,void) | Microsoft Docs]]

     + _Return a null pointer_ to indicate failure or the absence of an
       object, that it was no possible to find an object or allocate
       memory. Example: C++ new operator with nothrow,

       + Example:
       + Base* ptr = new (nothrow ) Derived;
       + if(ptr){ .. do something ...} else { std::puts("Error: ... "); )}

     + _Return an error code or error flag from class methods_. This
       approach is used by C++ streams std::iosbase and its derived
       classes, std::cin, std::istream and so on., bool
       std::iosbase.good(), bool std::iosbase.fail().

 + _User supplied callback function_
   + The client code supplies a callback function which is called when
     an error happens.
 
 + _Using 'either' type_
   + See:
     [[https://hackernoon.com/error-handling-in-c-or-why-you-should-use-eithers-in-favor-of-exceptions-and-error-codes-f0640912eb45][Error Handling in C++ or: Why You Should Use Eithers in Favor of Exceptions and Error-codes]]
 
 + _std::optional<T>_ - C++17 Maybe or Optional type. 

 *Exception Headers* 

 + Headers: 
   + [[https://en.cppreference.com/w/cpp/header/stdexcept][<stdexcept>]]
   + [[http://www.cplusplus.com/reference/exception/exception/][<exception>]]

 *Exceptions Good Practices:*
 
 + Assertions: should not be used for argument validation since they
   can be disabled during compilation or on release builds. 

 + Exceptions should be used on objects' constructors in order to avoid
   letting the object in an invalid state. => _Fail Fast principle_.

 + Destructors should not throw exceptions as it invokers terminates()
   shutting down the program. 

 + DO NOT: catch all exceptions. Only exceptions that can be handled
   should be caught. 

 *C++ Stack Terminology*

 + Exception Specification
 + Stack Unwinding
 + Exception-safety
 + RAII - Resource Aquisition is Resource Initialization
 + Smart Pointers 

 *Functions related to exceptions* 

 + [[https://en.cppreference.com/w/cpp/error/current_exception][std::current_exception]]
 + [[https://en.cppreference.com/w/cpp/error/rethrow_exception][std::rethrow_exception]]
 + [[https://en.cppreference.com/w/cpp/error/terminate][std::terminate]]
 + [[https://en.cppreference.com/w/cpp/utility/program/abort][std::abort]]
 + [[https://en.cppreference.com/w/cpp/error/terminate_handler][std::terminate_handler]]
 + [[https://en.cppreference.com/w/cpp/utility/program/exit][std::exit]]

 *Standard Library Exception defined in header file <exception>*

| Exception             | Description                                                                                         |
|-----------------------+-----------------------------------------------------------------------------------------------------|
| ~std::exception~        | An exception and parent class of all the standard C++ exceptions.                                   |
| ~std::runtime_error~    | An exception that theoretically can not be detected by reading the code.                            |
| ~std::logic_error~      | An exception that theoretically can be detected by reading the code.                                |
| ~std::domain_error~     | This is an exception thrown when a mathematically invalid domain is used                            |
| ~std::invalid_argument~ | This is thrown due to invalid arguments.                                                            |
| ~std::bad_alloc~        | This can be thrown by new.                                                                          |
| ~std::bad_cast~         | This can be thrown by dynamic_cast.                                                                 |
| ~std::bad_exception~    | This is useful device to handle unexpected exceptions in a C++ program                              |
| ~std::bad_typeid~       | This can be thrown by typeid.                                                                       |
| ~std::length_error~     | This is thrown when a too big std::string is created                                                |
| ~std::out_of_range~     | This can be thrown by the at method from for example a std::vector and std::bitset<>::operator[](). |
| ~std::overflow_error~   | This is thrown if a mathematical overflow occurs.                                                   |
| ~std::range_error~      | This is occured when you try to store a value which is out of range.                                |
| ~std::underflow_error~  | This is thrown if a mathematical underflow occurs.                                                  |


References: 

C++ Documentation: 
 + [[https://en.cppreference.com/w/cpp/error/exception][std::exception - cppreference.com]]
 + [[https://en.cppreference.com/w/cpp/error/exception/what][std::exception::what - cppreference.com]]
 + [[https://isocpp.org/wiki/faq/exceptions][Exceptions and Error Handling, C++ FAQ]]
 + [[https://wiki.sei.cmu.edu/confluence/display/cplusplus/ERR56-CPP.+Guarantee+exception+safety][ERR56-CPP. Guarantee exception safety - SEI CERT C++ Coding Standard - Confluence]]
 + [[https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/cplr156.htm][IBM Knowledge Center - Exception specifications (C++ only)]]

Misc:
 + [[https://stackoverflow.com/questions/11938979/what-exception-classes-are-in-the-standard-c-library][What exception classes are in the standard C++ library - Stack Overflow]]
 + [[https://en.cppreference.com/w/cpp/language/throw][throw expression - cppreference.com]]
 + [[https://blog.mozilla.org/nnethercote/2011/01/18/the-dangers-of-fno-exceptions/][The dangers of -fno-exceptions | Nicholas Nethercote]]
 + [[https://stackoverflow.com/questions/16182781/how-to-create-exceptions][c++ - How to create exceptions? - Stack Overflow]]
 + [[https://dzone.com/articles/some-useful-facts-to-know-when-using-c-exceptions][Some Useful Facts to Know Before Using C++ Exceptions - DZone Performance]]
 + [[http://www.acodersjourney.com/2016/08/top-15-c-exception-handling-mistakes-avoid/][Top 15 C++ Exception handling mistakes and how to avoid them. - A CODER'S JOURNEY]]

Best: 

 + [[https://blog.plan99.net/what-s-wrong-with-exceptions-nothing-cee2ed0616?gi=33a0310b3ff9][What’s wrong with exceptions? Nothing. – Mike’s blog]]
 + [[https://isocpp.org/wiki/faq/exceptions][Exceptions and Error Handling, C++ FAQ]]
 + [[http://www.learncpp.com/cpp-tutorial/145-exceptions-classes-and-inheritance/][14.5 — Exceptions, classes, and inheritance | Learn C++]]
 + [[https://en.wikibooks.org/wiki/C%2B%2B_Programming/Exception_Handling][C++ Programming/Exception Handling - Wikibooks, open books for an open world]]
 + [[http://rdiez.shoutwiki.com/wiki/Error_Handling_in_General_and_C%2B%2B_Exceptions_in_Particular][Error Handling in General and C++ Exceptions in Particular - rdiez's Personal Wiki]]
*** Exception Basics 

C++ can throw any type as exception: 

#+BEGIN_SRC cpp 
  >> throw 10
  Error in <TRint::HandleTermInput()>: Exception caught!
  >> 
  >> throw "hello world"
  Error in <TRint::HandleTermInput()>: Exception caught!
  >> 
  >> throw 34.212
  Error in <TRint::HandleTermInput()>: Exception caught!
  >> 
  >> throw std::runtime_error("Illegal state exception!")
  Error in <TRint::HandleTermInput()>: std::runtime_error caught: Illegal state exception!

  >> throw std::invalid_argument("Error: number of elements cannot be negative.")
  Error in <TRint::HandleTermInput()>: std::invalid_argument caught: Error: number of elements cannot be negative.
  >> 
  >> throw std::out_of_range("Invalid element index. Aborting operation!")
  Error in <TRint::HandleTermInput()>: std::out_of_range caught: Invalid element index. Aborting operation!

#+END_SRC

Catching exceptions: 

#+BEGIN_SRC cpp 
  void testException(std::function<void ()> action){
       try {
           action();
       }
       // handle of std::invalid_argument
       catch(const std::invalid_argument& ex){
            std::cerr << " [ERROR] {std::invalid_argument} \n => "
                      << ex.what() << "\n";
            return;
       }
       // handle of std::out_of_range
       catch(const std::out_of_range& ex){
            std::cerr << " [ERROR] {std::out_of_range} \n => "
                      << ex.what() << "\n";
            return;
       }
       catch(const std::exception& ex){
            std::cerr << " [ERROR] {std::exception} \n => "
                      << ex.what() << "\n";
            return;
       }
       std::cout << " [INFO] Executed gracefully. OK" << "\n";
  }
#+END_SRC

Running: 

#+BEGIN_SRC cpp 
  >> testException([](){ throw std::runtime_error("Fatal error 0xBAF5F8");})
   [ERROR] {std::exception} 
   => Fatal error 0xBAF5F8

  >> testException([](){ throw std::invalid_argument("Expected x = 10");})
   [ERROR] {std::invalid_argument} 
   => Expected x = 10
  >> 

  >> testException([](){ throw std::out_of_range("Error: given invalid index.");})
   [ERROR] {std::out_of_range} 
   => Error: given invalid index.
  >> 

  // Crash the program as it cannot handle this exception 
  >> testException([](){ throw 10 ;})
  Error in <TRint::HandleTermInput()>: Exception caught!

  // Crash again!
  >> testException([](){ throw "hello world" ;})
  Error in <TRint::HandleTermInput()>: Exception caught!
  >> 

  >> testException([](){ throw std::overflow_error("Number cannot be represented. Overflow error!");})
   [ERROR] {std::exception} 
   => Number cannot be represented. Overflow error!
  >> 
#+END_SRC
 
*** Types of Program termination 

 *Types of program/process termination* 

C++ has two types of process termination, normal and abnormal. 

 + _normal termination_ (aka normal exit)
   + Happens when the main function finishes its execution returning
     an integer status code or the function std::exit(int status) is
     called. When it happens, all objects with automatic (stack
     allocated) and static storage (global objects) are destroyed and
     their destructors called. 

 + _abnormal termination_ (aka abnormal exits)

   + Happens when the function [[https://en.cppreference.com/w/cpp/utility/program/abort][std::abort]] is called raising the
     SIGABRT signal (abort signal). This function terminates the
     program without calling destructors of automatic, thread or
     static storage duration, thefore resources are not cleaned up.

   + The function std::abort is also called when an assertion macro
     fails from [[https://en.cppreference.com/w/cpp/error/assert][<cassert>]] header fails. 

 *Causes of Abnormal Termination* - std::terminate 

When the function [[https://en.cppreference.com/w/cpp/error/terminate][std::terminate]] is called by the C++ runtime, it
calls [[https://en.cppreference.com/w/cpp/error/terminate_handler][std::terminate_handler]] callback function which is set by default
to [[https://en.cppreference.com/w/cpp/utility/program/abort][std::abort]], which abnormally termintes the program. The function called by
std::terminate can be changed with [[https://en.cppreference.com/w/cpp/error/set_terminate][std::set_terminate]] which sets a new
terminate handler(aka callback).  

The functions [[https://en.cppreference.com/w/cpp/error/terminate][std::terminate]] and  [[https://en.cppreference.com/w/cpp/utility/program/abort][std::abort]] are called by the C++
runtime when: 

   * Uncaught exception => A thrown exception is not caught with try
     ... catch block. 

   * Constructor of static (global object) and thread-local objects
     throw exceptions.

   * Noexcept specification is violated: a function or member function
     annotated with noexcept throws an exception.

   * A joinable std::thread (thread that is still running) is
     destroyed or assigned to. 

 *Further Reading* 

 + [[https://wiki.sei.cmu.edu/confluence/display/cplusplus/ERR50-CPP.+Do+not+abruptly+terminate+the+program][ERR50-CPP. Do not abruptly terminate the program - SEI CERT C++ Coding Standard - Confluence]]

 + [[https://blog.mozilla.org/nnethercote/2011/01/18/the-dangers-of-fno-exceptions/][The dangers of -fno-exceptions | Nicholas Nethercote]]

 + [[https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.cbclx01/cplr163.htm][The terminate() function (C++ only)]]

 + [[https://stackoverflow.com/questions/7054685/are-destructors-run-when-calling-exit][c++ - Are destructors run when calling exit()? - Stack Overflow]]

 + [[https://www.quora.com/Does-this-C++-program-using-std-exit-really-invoke-undefined-behavior][Does this C++ program using std::exit really invoke undefined behavior? - Quora]]

*** Overriding std::terminate handler 

This experiment program overrides std::terminate_handler for testing
what happens with the application and destructors in normal and
abnormal terminations.

 + File: [[file:src/test_terminate.cpp][file:src/test_terminate.cpp]]

  *Source Code Listing* 

Class DummayClass: 

#+BEGIN_SRC cpp 
  class DummyClass{
  public:
      DummyClass()
      {
          std::puts(" [INFO] Object ctor => Constructor called.");
      }
      ~DummyClass()
      {
          std::puts(" [INFO] Object dtor => Destructor called.");
      }
  };
#+END_SRC

Function main() part 1: Instantiante a dummy object of class
DummyClass for testing destructor and constructor. 

Function main() part 1: 

#+BEGIN_SRC cpp 
  DummyClass cls;
#+END_SRC

Function main() - part 2 
 + Override [[https://en.cppreference.com/w/cpp/error/terminate_handler][std::terminate_handler]] via std::set_terminate if the
   environment variable named TERMINATE is set to the string "true".

#+BEGIN_SRC cpp 
  const char* option = std::getenv("TERMINATE");
  if(option != nullptr && std::string(option) == "true")
  {

      std::puts(" [TRACE] Override std::terminate handler.");
      // Overrides the function called by std::terminate (std::abort by default).
      //
      // It accepts function pointer or a non-capturing lambda.
      // Override std::termiante setting std::terminate_handler callback
      std::set_terminate([](){
          std::cerr << " [FATAL] std::terminate() called; SIGABRT signal abort sent."
                    << std::endl;
          // terminate current process sending abrt
          std::abort();
      });
  }
#+END_SRC

Function main() - part 3: 
 + Register function to be called when the program is terminated via
   std::atexit. This function accepts function pointer or
   non-capturing lambda. 

#+BEGIN_SRC cpp 
  // Register function to be called when the program exits.
  // Note: It does not override the normal termination behavior.
  std::atexit([](){
      std::cerr  << " [INFO] Normal termination. Ok." << std::endl;
  });
#+END_SRC

Function main() - part 4:  
  + Handle command line arguments. 

#+BEGIN_SRC cpp 
  if(argc < 2) {
      std::puts(" [ERROR] Missing command. Shutdown");
      return 1;
  }
  std::string cmd = argv[1];
#+END_SRC

Function main() - part 5:  
  + Simulate many types of normal and abornal terminations.

#+BEGIN_SRC cpp 
      if(cmd == "terminate_normal1")
      {
          std::puts(" [TRACE] Nothing.");
      }
      else if(cmd == "terminate_normal2")
      {
          std::puts(" [TRACE] Call std::exit(int status_code);");
          std::exit(2);
      }
      else if (cmd == "terminate_except")
      {
          std::puts(" [TRACE] Before throwing exception");
          throw std::runtime_error("Invalid input domain");
          std::puts(" [TRACE] After throwing exception");

      } else if (cmd == "terminate_thread")
      {
          using namespace std::chrono_literals;
          std::puts(" [TRACE] Joinable thread out of scope without calling .join() or detach");

          std::thread th{ [](){
                  while(true) {
                      std::puts(" [TRACE] Thread running ....");
                      std::this_thread::sleep_for(1s);
                  }
          }};

          // Missing thread::join() or thread::detach method call
          // => The runtime calls std::terminate()
      }

      std::cout  << " [TRACE] End of main function" << std::endl;

      return 0;
#+END_SRC

 *Building:*

#+BEGIN_SRC sh 
   $ clang++ test_terminate.cpp -o term -std=c++1z -g -Wall -Wextra -g -lpthread
#+END_SRC

 *Running:*

 + Normal termination: 

Termiante via main() return statement. 

#+BEGIN_SRC sh 
  ./term terminate_normal1
   [INFO] Object ctor => Constructor called.
   [TRACE] Nothing.
   [TRACE] End of main function
   [INFO] Object dtor => Destructor called.
   [INFO] Normal termination. Ok.
#+END_SRC

Terminate with std::exit.

#+BEGIN_SRC sh 
  ./term terminate_normal2
   [INFO] Object ctor => Constructor called.
   [TRACE] Call std::exit(int status_code);
   [INFO] Normal termination. Ok.
#+END_SRC

 + Abornmal termination through uncaught exception 

Run without overriding std::set_terminate 

#+BEGIN_SRC sh 
  $ ./term terminate_except
   [INFO] Object ctor => Constructor called.
   [TRACE] Before throwing exception
  terminate called after throwing an instance of 'std::runtime_error'
    what():  Invalid input domain
  Aborted (core dumped)
#+END_SRC

Run overriding std::terminate_handler handler by setting environment
variable TERMINATE to string 'true'.

#+BEGIN_SRC sh 
  $ env TERMINATE=true ./term terminate_except
   [INFO] Object ctor => Constructor called.
   [TRACE] Override std::terminate handler.
   [TRACE] Before throwing exception
   [FATAL] std::terminate() called; SIGABRT signal abort sent.
  Aborted (core dumped)
#+END_SRC

 + Abornmal termination through joinable std::thread object out of
   scope without calling .join() or .detach().

Run without overriding std::terminate_handler

#+BEGIN_SRC sh 
  $ ./term terminate_thread
   [INFO] Object ctor => Constructor called.
   [TRACE] Joinable thread out of scope without calling .join() or detach
  terminate called without an active exception
   [TRACE] Thread running ....
  Aborted (core dumped)
#+END_SRC

Run without std::terminate_handler: 

#+BEGIN_SRC sh 
  $ env TERMINATE=true ./term terminate_thread
   [INFO] Object ctor => Constructor called.
   [TRACE] Override std::terminate handler.
   [TRACE] Joinable thread out of scope without calling .join() or detach
   [FATAL] std::terminate() called; SIGABRT signal abort sent. [TRACE] Thread running ....

  Aborted (core dumped)
#+END_SRC

*** Custom Exceptions 

Example: 

#+BEGIN_SRC cpp 
  enum class ErrorFlags : unsigned {
      MemoryError     =  0x2A,
      NetWorkFailure  =  0xFA,
      DNSFailure      =  0x50, 
      UnknownError    =  0xAF
  };

  struct DownloadException: public std::exception {
      ErrorFlags errorCode;
      DownloadException(ErrorFlags errorCode)
         :errorCode{errorCode}{}	
      auto what() const throw() -> const char* {
           return "Error: Download failure. See error code. ";
      }
  };

  void testDownloadException(std::function<void ()> action){
      std::exception_ptr p;
      try {
          action();
      } catch(const DownloadException& ex){
          std::cerr << ex.what() << "\n";
          std::cerr << "[FAILURE] Error code = "
                    << std::hex <<  static_cast<unsigned>(ex.errorCode)
                    << std::dec
                    << "\n";
          return;
      } catch(...){
              // Catch all exceptions, log and rethrow		
          std::cerr << "[FAILURE] Unknown exception." << "\n";
          p = std::current_exception();
          std::rethrow_exception( p);		
      }
      std::cout << " [INFO] Download ended gracefully. OK." << "\n";
  }
#+END_SRC

Testing: 

#+BEGIN_SRC cpp
  >> testDownloadException([](){})
   [INFO] Download ended gracefully. OK.

  >> testDownloadException([](){ throw DownloadException(ErrorFlags::NetWorkFailure); })
  Error: Download failure. See error code. 
  [FAILURE] Error code = fa
  >> 
  >> testDownloadException([](){ throw DownloadException(ErrorFlags::DNSFailure); })
  Error: Download failure. See error code. 
  [FAILURE] Error code = 50
  >> 
  >> testDownloadException([](){ throw DownloadException(ErrorFlags::UnknownError); })
  Error: Download failure. See error code. 
  [FAILURE] Error code = af
  >> 

  >> testDownloadException([](){ throw std::runtime_error("Fatal kernel failure!!"); })
  [FAILURE] Unknown exception.
  Error in <TRint::HandleTermInput()>: std::runtime_error caught: Fatal kernel failure!!

  >> testDownloadException([](){ throw std::out_of_range("Invalid index"); })
  [FAILURE] Unknown exception.
  Error in <TRint::HandleTermInput()>: std::out_of_range caught: Invalid index
  >> 
#+END_SRC

*** Example - code 

 File: exceptions.cpp 

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

   struct Error{
   public:
       const char* reason;
       const int errorCode;    
       Error(int errorCode, const char* reason): errorCode(errorCode), reason(reason) {};
       void display(std::ostream& os){
           os << "Error code = " << errorCode << "; reason = " << reason << "\n";
       }
   };

   class NetworkFailure : public std::exception {
   public:
       const char* what () const throw(){
           return " ==> Error: network failure.";
       }
   } networkFailure;

   struct OutOfmemoryError : std::exception {
       const char* what() const throw(){
           return "==> Error: there is no enough memory.";
       }
   };

   struct UnknownError {};

   // Any object, class or type can be thrown like an Exception.
   void exceptionThrower(int code){
       NetworkFailure networkFailure;
       switch(code){
       case 0:
           throw "Error (1) has happened";
           break;
       case 1:
           throw 4090;
           break;
       case 2:
           throw 'x';
           break;
       case 3:
           throw Error(0xffa, "Failure to download update.");
           break;
       case 4:
           throw Error(0xff5, "Invalide input parameters.");
           break;
       case 5:
           throw std::runtime_error("Runtime error happened.");
           break;
       case 6:
           throw std::bad_alloc();
           break;
       case 7:
           throw OutOfmemoryError();
           break;
       case 8:
           throw networkFailure;
           break;  
       default:
           throw UnknownError();
       }
   }

   void handleException(int n){
       try {
           exceptionThrower(n);
       } catch (const char* perror){
           std::cerr << "==> [String] An error of type string happened: " << perror << std::endl;
       } catch (int errorCode){
           std::cerr << "==> [Int   ] Returned error code = " << errorCode << std::endl;       
       } catch (char x){
           std::cerr << "==> [Char  ] Returned char error code = " << x << std::endl;      
       } catch (Error err){
           err.display(std::cerr);
       } catch (const std::exception& ex){
           std::cerr << "Catch an std::exception. = " << ex.what() << std::endl;
       } // Catch all exceptions - Not recommeded. 
       catch (...) {
           std::cerr << "==> Unknown exception." << std::endl;
       }
   }

   int main(){
       handleException(0);
       handleException(1);
       handleException(2);
       handleException(3);
       handleException(4);
       handleException(5);
       handleException(6);
       handleException(7);
       handleException(8);
       handleException(100);
       std::cout << "Finish successfully" << std::endl;    
       return 0;
   }

 #+END_SRC

 Compiling and running:

 #+BEGIN_SRC sh 
   $ clang++ -std=c++11 exceptions.cpp -o out.bin && ./out.bin

   ==> [String] An error of type string happened: Error (1) has happened
   ==> [Int   ] Returned error code = 4090
   ==> [Char  ] Returned char error code = x
   Error code = 4090; reason = Failure to download update.
   Error code = 4085; reason = Invalide input parameters.
   Catch an std::exception. = Runtime error happened.
   Catch an std::exception. = std::bad_alloc
   Catch an std::exception. = ==> Error: there is no enough memory.
   Catch an std::exception. =  ==> Error: network failure.
   ==> Unknown exception.
   Finish successfully

 #+END_SRC

*** Exception Safety Guarantees 

Exception-Safety Concept: 

 + According to [[http://www.stroustrup.com/except.pdf][Stroustrup]], an operation is said to be _exception-safe_
   it it leaves the object in a valid and well-defined state after its
   termination when an exception is thrown.

 + An Exception-Safe code should:

   + Left the the program in a valid state after an exception
     happens.

   + avoid memory leaks => always release the allocated memory when an
     exception happens or no longer needed. 

   + avoid resource leaks => always release acquired resources such as
     socket handlers, file descriptors, database connection handlers,
     locks and so on when an exception happens or no longer needed.

   + not allow data structures being corrupted.


 *Levels of Excpetion-Safety Guarantees* 

Exception-safety guarantees are a set of promises made by class or
library to a client code allowing better reasoning about exceptions. A
library or code can provide the following _exception-safety guarantees_,
aka _levels of exception-safety guarantees_:

 + _basic exception-safety guarantees_ (aka _no-leak guarantee_)

   * No resources are leaked and the invariants of the component are
     preserved.

   * The component must be in a valid state after the exception is
     thrown, but it does not mean that its state was kept.

   * This is the minimum standard that a library, component, container
     or class should implement.

 + _strong exception-safety guarantees_ (aka _commit or rollback semantics_)

   * Some functions from standard library with strong exception safety guarantee:
     * Member functions for several containers: push_back, push_front
       and rehash.

   * The component state is kept the same as it was before the
     operation has been completed successfuly or thrown an exception.

   * Summary: if an operation fails, it has no effects.

 + _no-throw guarantees_ (aka _no-fail_ or _failure transparency_)

   * The operation does not throw an exception and all operations are
     guaranteed to complete successfully with any exception handled
     internally, therefore not affecting any client code.

   * Some functions from standard library with no-throw exception-safe guarantee.
     * Member functions of several containers: erase, pop_back,
       pop_front and clear.
     * Function: _std::swap_ 

   * Functions with no-throw guarantee can be explicitly annotated
     with [[https://en.cppreference.com/w/cpp/language/noexcept_spec][noexcept]] specifier.

   * The *noexcepet* specifier annotation for copy constructor and move
     constructor allows many functions from the C++ standard library
     to choose the most efficient function overloading based on this
     annotation. For instance, if the move constructor of a given type
     *M* is not marked with _noexcept_ specfier, the member function
     push_back of std::vector container will not use this constructor,
     instead it will use the copy constructor incurring on a copy
     overhead and less efficiency. If the annotation is used, the
     push_back member function will use move-constructor which makes
     the operation more efficient.

   * Note: If a function or member function is annotated with
     noexcept and throws any exception, the function std::terminate is
     called terminating the process immediately. 

 + _No exception safety_
   * Non guarantees are provided and the object or container may be in
     a corrupt state. No exception-safety should be avoided.

 + _Exception neutral_ (additional exception-safety level)
   + An exception neutral code does not throw or catch exception. It
     only forwards exceptions thrown in the code that it calls to the
     client code. 


 *Principles for exception-safe code*

 * Avoid resouce leaks and memory leaks. 

 * Always keep an object in valid state when an exception is thrown.

 * Do not destroy a piece of data before its replacement can be
   store. 

 *Language features for exception safety* 

 * try-catch block

 * RAII Idiom - Resource Acquisition Is Initialization technique.

   + Resources, which can be heap-allocated memory, socket handlers,
     file descriptiors, database handlers and so on, are acquired in
     constructor and released at destructor which are determinstic and
     always called when an exception happens.

   + The C++ language guarantees that a destructor always will be
     called at the end of scope where the object is defined or when an
     exception happens.

   + Note: A destructor should always catch all exceptions and never
     allow them to propagate from them, otherwise, the program will be
     terminated immediately.

 * Copy-and-swap idiom

References: 
 
 + *Exception Safety: Concepts and Techniques*  - Bjarne Stroutrup [BEST]
   + <http://www.stroustrup.com/except.pdf>

 + *Progamming with Exceptions* - Bjarne Stroustrup
   + <http://www.informit.com/articles/article.aspx?p=21084> 

 + *Standard Library Exception Safety*  - Bjarne Stroustrup  [BEST]
   + <https://www.cise.ufl.edu/~manuel/stroustrup/ex.pdf> 

 + *Exception Safety in Generic Components* - David Abrahams
   + <https://www.boost.org/community/exception_safety.html>

 + *Exception Safety Analysis* - Andrei Alexandrescu
   + <http://www.drdobbs.com/exception-safety-analysis/184401728>

 + *C++ Core Guidelines: Rules for Error Handling* - Rainer Grimm [BEST]
   + <https://www.modernescpp.com/index.php/c-core-guidelines-rules-to-error-handling>

 + *Design Patterns in C++ - Safety to exceptions* - Giuseppe Lipari [BEST]   
   + <http://retis.sssup.it/~lipari/courses/oosd2010-2/09.exception_safety.pdf>

 + *Using Exception in C++ - a practical guide* - Zibigniew Skowron [BEST]
   + <http://cpp.mimuw.edu.pl/files/Using%20Exceptions%20in%20C++.pdf>

 + *5 Exception Safety - Handling Errors and Exceptions* - University of Hellsinki [BEST]
   + <https://www.cs.helsinki.fi/u/vihavain/s08/cpp/slides/CppCh5_2.pdf>

 + *C++ Exception Safety* - Ali Çehreli [BEST]
   + <http://acehreli.org/turkcecpp/exception_safety.pdf>

 + *Part 9 - Exception Safety*
   + <https://wiki.ifs.hsr.ch/CppAdvanced/files/lecture_09_exception_safety.pdf> 

 + *Make Move Constructor No-Throw*
   + <http://blogs.microsoft.co.il/sasha/2014/08/08/make-move-constructors-no-throw/>

 + *How to: Design for Exception Safety* - Microsoft [BEST]
   + <https://docs.microsoft.com/en-us/cpp/cpp/how-to-design-for-exception-safety?view=vs-2019>

 + *Generic: Change the Way you write Exception-Safe Code - Forever* -
   Andrei Alexandrescu and Petru Marginean
   + <http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758>

 + *Effective C++ item 29: Strive For Exception-safe Code*
   + <http://blog.ycshao.com/2017/11/15/effective-c-item-29-strive-for-exception-safe-code/>

 + *Making Operations on standard library containers strong exception safe*
   + <https://pdfs.semanticscholar.org/2a6a/30b9f7cd82ef29b64fbecae10463d533a6da.pdf>

 + *Exceptions* - CppReference
   + <https://en.cppreference.com/w/cpp/language/exceptions>

 + *ERR56-CPP. Guarantee exception safety*
   + <https://wiki.sei.cmu.edu/confluence/display/cplusplus/ERR56-CPP.+Guarantee+exception+safety>

 + *Exception Safety* - QT Documentation
   + <https://doc.qt.io/qt-5/exceptionsafety.html>

 + Question - *Do you (really) write exception safe code?*
   + <https://stackoverflow.com/questions/1853243/do-you-really-write-exception-safe-code>

 + *Exception Safety* - Wikipedia
   + <https://en.wikipedia.org/wiki/Exception_safety>

 + *Copy-and-Swap Pattern*
   + <https://cpppatterns.com/patterns/copy-and-swap.html> 

** C++11 Tuples 
*** Overview  

Tuples are a generic containers (product type) common in functional
languages for storing heterogeneous types. Some use cases for tuples
are, grouping unrelated types into a single object and returning multiple
values from functions. C++11 provide tuples in the
standard library in the header <tuple>. 

 + [[https://en.cppreference.com/w/cpp/utility/tuple][std::tuple - cppreference.com]]
*** Function std::make_tuple 

Example: 

#+BEGIN_SRC cpp 
  >> auto coord0 = std::make_tuple("Madrid", 40.4168, -3.7038);

  >> std::get<0>(coord0)
  (const char*) "Madrid"
  >> std::get<1>(coord0)
  (double) 40.416800
  >> std::get<2>(coord0)
  (double) -3.7038000
  >> 

  >> coord0
  (std::tuple<const char *, double, double> &) 
  { "Madrid", 40.416800, -3.7038000 }

  >> std::cout << "City = " << std::get<0>(coord0) << "\n";
  City = Madrid

  >> std::cout << "Latitude = " << std::get<1>(coord0) << "\n";
  Latitude = 40.4168

  >> std::cout << "Longitude = " << std::get<2>(coord0) << "\n";
  Longitude = -3.7038
#+END_SRC

*** Example in Cling REPL 

Create database row: 

#+BEGIN_SRC cpp 
 using DbRow = std::tuple<int, double, std::string>;
#+END_SRC

Create an instance of the tuple: 

#+BEGIN_SRC cpp 
  >> DbRow(200, 500.23, "Diesel Power Generator")
  (DbRow) { 200, 500.23000, "Diesel Power Generator" }

  >> DbRow(51300, 1.2, "1 kg Orange")
  (DbRow) { 51300, 1.2000000, "1 kg Orange" }
  >> 
#+END_SRC

Get tuple elements: (std::get<INDEX>)

#+BEGIN_SRC cpp 
  >> auto row = DbRow(51300, 1.2, "1 kg Orange")
  { 51300, 1.2000000, "1 kg Orange" }

  >> std::get<0>(row)
  (int) 51300

  >> std::get<1>(row)
  (double) 1.2000000

  >> std::get<2>(row)
  "1 kg Orange"
  >> 

  >> std::cout << std::get<0>(row) << " / " << std::get<1>(row) << " / " << std::get<2>(row) << "\n\n" ;
  51300 / 1.2 / 1 kg Orange
#+END_SRC


Split tuple elements: (std::tie)

#+BEGIN_SRC cpp 
  >> std::tie(Index, Price, Name) = row
  (std::tuple &) { 51300, 1.2000000, "1 kg Orange" }

  >> Index
  (int) 51300

  >> Price
  (double) 1.2000000

  >> Name
  (std::string &) "1 kg Orange"
  >> 

#+END_SRC

Create function to print tuple:

#+BEGIN_SRC cpp 
  void printTuple(const DbRow& row){
          std::cout << "Id    = " << std::get<0>(row) << "\n";
          std::cout << "Name  = " << std::get<1>(row) << "\n";
          std::cout << "Price = " << std::get<2>(row) << "\n";
  }
#+END_SRC

Pass tuple to function: 

#+BEGIN_SRC cpp 
  >> printTuple(row)
  Id    = 51300
  Name  = 1.2
  Price = 1 kg Orange

  >> printTuple(std::tuple<int, double, std::string>(100, 12.5, "1kg Fresh Bacon"))
  Id    = 100
  Name  = 12.5
  Price = 1kg Fresh Bacon
  >> 
							   
  >> printTuple(DbRow{100, 12.5, "1kg Fresh Bacon"})
  Id    = 100
  Name  = 12.5
  Price = 1kg Fresh Bacon

  >> printTuple({100, 12.5, "1kg Fresh Bacon"})
  Id    = 100
  Name  = 12.5
  Price = 1kg Fresh Bacon
  >> 												   
#+END_SRC

Return tuple from function: 

#+BEGIN_SRC cpp 
  // Profit margin in percent 
  DbRow makeProduct(double profitMargin, int index, double price, const std::string& name){
          double factor = (profitMargin + 100.0) / 100.0; 
          return {index, factor * price, name };
  }

  >> auto p = makeProduct(15.0, 600, 1.5, "Water bottle 1L - Brand XPMFN")
  { 600, 1.7250000, "Water bottle 1L - Brand XPMFN" }
  >> 

  >> std::get<0>(p)
  (int) 600

  >> std::get<1>(p)
  (double) 1.7250000

  >> std::get<2>(p)
  "Water bottle 1L - Brand XPMFN"
#+END_SRC

Change tuple elements: 

#+BEGIN_SRC cpp 
  >> auto r = DbRow{-1, 0, "Dummy Product"}
  { -1, 0.0000000, "Dummy Product" }

  >> std::get<0>(r) 
  (int) -1

  >> std::get<0>(r) = 500
  (int) 500

  >> std::get<1>(r)
  (double) 0.0000000

  >> std::get<1>(r) = 200.0 
  (double) 200.00000

  >> std::get<2>(r)
  "Dummy Product"

  >> std::get<2>(r) = "Super high power diesel"
  "Super high power diesel"

  >> r
  { 500, 200.00000, "Super high power diesel" }
#+END_SRC

*** Example - sample source code

Example: 

 + File: cpp11Tuples.cpp 

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <string>
  #include <sstream>
  #include <vector>
  #include <iomanip>
  #include <tuple>

  // Type synonym 
  using DbRow = std::tuple<int, double, std::string>;

  std::string toString(const DbRow& row){
          std::stringstream ss;
          ss << "id = "       << std::get<0>(row)
             << " ; price = " << std::get<1>(row)
             << "; name = "   << std::get<2>(row)
             << std::endl;
          return ss.str();
  }

  void printInventory(const std::vector<DbRow>& inventory){
          using std::cout;
          using std::endl;
          for(auto &p: inventory){
                  int id;
                  double price;
                  std::string name;
                  std::tie(id, price, name) = p;
                  cout << std::right << std::setw(10) << id
                           << std::right << std::setw(10) << std::setprecision(2) << std::fixed << price
                           << std::right << std::setw(5) << " "
                           << std::left  << std::setw(10) << name
                           << "\n";
          }
  }
      
  int main(){
          using std::cout;
          using std::endl;
          using std::string;

          // Database row 
          std::tuple<int, double, string> row1(412, 200.41, "battery pack");
          DbRow row2(100, 20.5, "something else");
      
          cout << "Product 1 = " << toString(row1) << endl;
          cout << "Product 2 = " << toString(row2) << endl;

          std::vector<DbRow> dataset = {
                  DbRow(100, 2.5,  "apples"),
                  DbRow(200, 1.4,  "oranges"),
                  DbRow(300, 12.4, "sugar"),
                  DbRow(205, 20.5, "coffee")
          };

          printInventory(dataset);         
          return 0;
  }
#+END_SRC

Running: 

#+BEGIN_SRC sh 
  $ g++ cpp11Tuples.cpp -o cpp11Tuples.bin -g -std=c++11 -Wall -Wextra && ./cpp11Tuples.bin
  Product 1 = id = 412 ; price = 200.41; name = battery pack

  Product 2 = id = 100 ; price = 20.5; name = something else

         100      2.50     apples    
         200      1.40     oranges   
         300     12.40     sugar     
         205     20.50     coffee    
#+END_SRC

** Handling Signals 
*** Oveview  

Signals are software interrupts sent to a process by the operating
system. The signals can be generated by memory corruption; user
pressing Ctrl + Z in ther terminal; killing the process on Unix-like
OSes with command $ kill <Process-ID> and so on. 

Headers: 
 + [[https://en.cppreference.com/w/cpp/header/csignal][<csignal>]] Cppreference
 + [[http://www.cplusplus.com/reference/csignal/][<csignal>]] CplusPlus 

More about signals at: 
 + [[https://www.sharcnet.ca/help/index.php/Signal_Handling_and_Checkpointing][Signal Handling and Checkpointing - Documentation]]
 + [[https://en.wikipedia.org/wiki/Signal_(IPC)][Signal (IPC) - Wikipedia]]
 + [[http://www.yolinux.com/TUTORIALS/C++Signals.html][C/C++ signal handling]]
 + [[http://man7.org/linux/man-pages/man7/signal.7.html][signal(7) - Linux manual page]]

#+CAPTION: Listing of signals that can be sent to a process 
|-----------------+-------------------------------+------------------------------------------------------------------|
| Signal Macro    | Name                          | Description                                                      |
|-----------------+-------------------------------+------------------------------------------------------------------|
| SIGINT          | Signal Interrupt              | Generated when user types Ctrl + C                               |
| SIGTSTP (Posix) | Terminal Stop Signal          | Generated when user types Ctrl + Z on any Unix-like OS.          |
| SIGTERM         | Signal Terminal Request       | Signal sent by Unix command $ kill <PID>                         |
| SIGABRT         | Signal Abort                  |                                                                  |
| SIGFPE          | Singla Float-Point Exception  |                                                                  |
| SIGILL          | Signal Illegal Instruction    |                                                                  |
| SIGSEGV         | Signal Segmentation Violation |                                                                  |
| SIGQUIT (Posix) | Signal Quit                   | Terminate program with a core dump (Ctrl + \) Unix-like OS only. |
| SIGHUP (Posix)  | Signal hang-up                | Parent terminal process killed.                                  |
|-----------------+-------------------------------+------------------------------------------------------------------|

 + Additional signals at [[http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html][signals.h]]
 + [[https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html][Terminal Signals - Linux GlibC]]

 *Function Signal:* 

Install signal handler or callback function that is called when a
given signal is sent to the current process. 

Signature: 

#+BEGIN_SRC cpp 
   void signal(int SIGNAL, void (*HANDLER) (int) );

   // Or: 
   void signal( int SIGNAL,            /* Signal */
                void (*HANDLER) (int)  /* Callback (function-pointer) */
              );

  // Or: 
   void signal( int SIGNAL,            /* Signal */
                void HANDLER (int)  /* Callback (function-pointer) */
              );
#+END_SRC
*** Example 

 + File: [[file:src/handle-signal.cpp][file:src/handle-signal.cpp]]

Headers: 

#+BEGIN_SRC cpp 
  #include <iostream>
  #include <map>
  #include <string>
  #include <functional> 
  #include <csignal>
  #include <fstream> 

  // Unix specific (not valid for MS-Windows)
  #include <unistd.h> // Import getpid()
#+END_SRC

Class Dummy used for creating the global static object dummyGlobal:

#+BEGIN_SRC cpp 
  class Dummy{
  public:
      Dummy(){
        std::cerr << " [TRACE] Program initialized OK "  << "\n";
     }
     ~Dummy(){
        std::cerr << " [TRACE] All objects destroyed. Program End OK. "  << "\n";
     }
  };

  Dummy dummyGlobal;
#+END_SRC


Function: signal_handler

#+BEGIN_SRC cpp 
  void signal_handler(int signal)
  {
     // static auto logger = []{
     // 	auto log = std::ofstream("signals.log");
     // 	log << " [INFO] Initialized Logger OK." << std::endl;
     // 	return log;	
     // }();

     auto& logger = std::cerr;

     const static std::map<int, std::string> signalDatabse = {
          {SIGINT,   "SIGINT"}
         ,{SIGABRT,  "SIGABRT"}
         ,{SIGSEGV,  "SIGSEV"}
         ,{SIGFPE,   "SIGFPE"}
         ,{SIGTSTP,  "SIGTSTP"}
         ,{SIGTERM,  "SIGTERM"}
         ,{SIGQUIT,  "SIGQUIT"}
       };

     // std::cin.ignore(1000);
     std::cin.clear();

     std::string sigName;

     auto it = signalDatabse.find(signal);
     if(it != signalDatabse.end())
       sigName = it->second;
     else
       sigName = "UNKNOWN";

     logger << "\n [INFO] " << __FUNCTION__ << "() "
            << " Received signal = {" << sigName << "} => code = " << signal << std::endl;
  }
#+END_SRC

Function main(): 

#+BEGIN_SRC cpp 
     pid_t pid = ::getpid();
     std::cout << " Process ID =  " << pid << "\n";
     std::cout << " Attach to it with $ gdb --tui --pid=" << pid << "\n";

     std::signal(SIGINT,  &signal_handler);
     std::signal(SIGFPE,  &signal_handler);
     std::signal(SIGTERM,  signal_handler);
     std::signal(SIGTSTP,  signal_handler);
     std::signal(SIGQUIT,  signal_handler);

     int n = 0;
     char ch = 0;

     std::string line;

     while(std::cin.good()){
        std::cout << " Variable n = " << n++ << "\n";
        std::cout << " => Input = ";
        std::getline(std::cin, line);

        // Simulate float-point exception 
        if(line == "sigfpe"){
           std::cout << " 10.0 / 0.0 = " << 10.0 / 0.0 << "\n";
        }
     }

     return EXIT_SUCCESS;
#+END_SRC
 
Compiling: 

#+BEGIN_SRC sh 
 $ clang++ handle-signal.cpp -o handle-signal.bin -std=c++1z -g -O0 -Wall 
#+END_SRC

Running: 

#+BEGIN_SRC sh 
  $ ./handle-signal.bin 
   [TRACE] Program initialized OK 
   Process ID =  27650
   Attach to it with $ gdb --tui --pid=27650
   Variable n = 0
   => Input = 
   Variable n = 1
   => Input = 
   Variable n = 2

   # User types Ctrl + C
   => Input = ^C
   [INFO] signal_handler()  Received signal = {SIGINT} => code = 2

   Variable n = 3

   # User types Ctrl + Z 
   => Input = ^Z
   [INFO] signal_handler()  Received signal = {SIGTSTP} => code = 20

   # User types Ctrl + \ 
   Variable n = 4
   => Input = ^\
   [INFO] signal_handler()  Received signal = {SIGQUIT} => code = 3

   # User runs from another terminal $ kill 27650
   Variable n = 5
   => Input = 
   [INFO] signal_handler()  Received signal = {SIGTERM} => code = 15
   [TRACE] All objects destroyed. Program End OK. 
  (base) 
#+END_SRC
** Pointer to Function or Function Pointer  
*** Overview 

In C++, functions pointers are not so common as in C. However, they
are still useful when it is necessary to call a C-library which uses
this type of pointer for callbacks and event handlers.

It is preferrable to use std::function for callbacks and higher order
functions instead of function pointers as std::function can be used
with anything callable, such as function pointers, functors
(function-objects) or C++11 lambdas. 

Use cases of function pointers in C:
 + Callbacks
 + Higher Order Functions
 + Event Handlers 

Use cases of function pointers in C++:
 + Type erasure of functions.
 + Interfacing C-libraries.
 + Creating C++ wrappers for C-libraries.
 + Load functions at runtime from a DLL, shared library on Windows or
   Shared Object on U*nix (Linux, BSD, OSX, ...).

 *Function pointer variable declaration:*

#+BEGIN_SRC cpp 
  ReturnType (* VariableName) (ArgType0, ArgType1, ArgType2 ....);

  // OR -> Intitalized to null 
  ReturnType (* VariableName) (ArgType0, ArgType1, ArgType2 ....) = nullptr;

  // Initialized to the address of some function 
  ReturnType (* VariableName) (ArgType0, ArgType1, ArgType2 ....) = FUNCTION1;
  ReturnType (* VariableName) (ArgType0, ArgType1, ArgType2 ....) = &FUNCTION1;
#+END_SRC 

 *Function pointer Type Synonym - Prior to C++11*

#+BEGIN_SRC cpp 
  typedef ReturnType (* PointerAliasType) (ArgType0, ArgType1, ArgType2 ....);
  PointerAliasType fp = nullptr;
  PointerAliasType fp = &FUNCTION1;
  PointerAliasType fp = FUNCTION1;
 
  // Call 
  ReturnType result = fp(arg0, arg1, arg2, ... argn1);
#+END_SRC

 *Function pointer Type Synonym - C++11* (better and more readable)

#+BEGIN_SRC cpp 
  using PointerAliasType = ReturnType (*) (ArgType0, ArgType1, ArgType2 ....);
  // Or: 
  using PointerAliasType = auto (ArgType0, ArgType1, ArgType2 ....) -> ReturnType;
#+END_SRC

Examples: 

 + =void (* fpointer)(int);=
   - Function pointer taking an integer as paremeter and returns
     nothing, void.

 + =void* (* fp)(double *);=
   - Function pointer that points to a function taking a double
     pointer (double *) and returns a void pointer.

 + =int (* myFunPointer)(int, int);=
   - Function pointer that points to a function that takes two
     integers as parameters and returns an integer.

 + double (* FunPointer) (double) = &sin;
   + Function pointer initialized with the address with of the
     function sin. 

 + double (* FunPointer) (double) = sin;
   + Function pointer initialized with the address with of the
     function sin. 

 + ~int (p2* funcp)(double, double) = NULL~
   - Function pointer initialized to NULL or zero.

 + =void (*p[10]) (void *) ()=
   + Array of 10 pointers to a function that returns void 

*** Function Pointer Declaration 

#+BEGIN_SRC cpp 
  // Declare a function pointer to a function 
  // of type: double => double 
  >> double (* mfunptr) (double) = nullptr;

  >> mfunptr = sin
  (double (*)(double)) Function @0x7ff56aa56f80

  >> mfunptr(M_PI)
  (double) 1.2246468e-16

  >> mfunptr(M_PI_2)
  (double) 1.0000000
  >> 

  >> mfunptr(1)
  (double) 0.0000000
  >> mfunptr(100)
  (double) 2.0000000
  >> mfunptr(1000)
  (double) 3.0000000
  >> 

  // Pass a non-capturing lambda 
  // --------------------------------------------
  >> mfunptr = [](double x){ return 3 * x; }
  (double (*)(double)) Function @0x7ff56bb000c0

  >> mfunptr(3)
  (double) 9.0000000

  >> mfunptr(5)
  (double) 15.000000

  // Pass a capturing lambda => Cannot pass capturing 
  // lambdas to function pointers.
  // --------------------------------------------

  >> double k = 10.0
  (double) 10.000000

  //
  >> mfunptr = [&k](double x){ return 3 * x + k;}
  ROOT_prompt_31:1:13: error: 'k' cannot be captured because it does not have automatic storage duration
  mfunptr = [&k](double x){ return 3 * x + k;}
              ^
  >> mfunptr = [k](double x){ return 3 * x + k;}
  ROOT_prompt_32:1:12: error: 'k' cannot be captured because it does not have automatic storage duration
  mfunptr = [k](double x){ return 3 * x + k;}
             ^
  ROOT_prompt_28:1:8: note: 'k' declared here
  double k = 10.0
#+END_SRC
 
*** Function Pointer Callbacks 

Example 1: 

#+BEGIN_SRC cpp 
  void doTimes(int n, void (* action)(int n)){
       for(int i = 0; i < n; i++)
               action(i);
  }

  void printLine(int i){
       std::cout << "i = " << i << " \n";
  }

  >> doTimes(4, printLine)
  i = 0 
  i = 1 
  i = 2 
  i = 3 

#+END_SRC

Example 2: 

 - Higher order function for tabulating numerical functions
   implemented with function pointers. 

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

  // Alternative 1: 
  void tabulateFun1(double (* MathFunc) (double)){
       std::cout << std::setprecision(3) << std::fixed;
       for(int i = 0; i < 10; i++)
           std::cout << std::setw(5) << i
                     << std::setw(10) << MathFunc(i)
                     << "\n";
  }

  // Alternative 2: 
  void tabulateFun2(double MathFunc (double)){
       std::cout << std::setprecision(3) << std::fixed;
       for(int i = 0; i < 10; i++)
           std::cout << std::setw(5) << i
                     << std::setw(10) << MathFunc(i)
                     << "\n";
  }

  // Syntax 3 (C++11)
  void tabulateFun3(auto MathFunc (double) -> double){
       std::cout << std::setprecision(3) << std::fixed;
       for(int i = 0; i < 10; i++)
           std::cout << std::setw(5) << i
                     << std::setw(10) << MathFunc(i)
                     << "\n";
  }

#+END_SRC

The syntax can be simplified with type synonym using "using" (C++11)
or typedef (old standard).

#+BEGIN_SRC cpp 
  // Type Synonym [1] (C++11)
  using MathFunPtr = double (*) (double);
  // Type Synonym [2] (C++11)
  using MathFunPtr = auto (double) -> double;

  // Type Synonym [3] (Old standards)
  typedef double (* MathFunPtr) (double);

  void tabulateFun4(MathFunPtr MathFunc){
       std::cout << std::setprecision(3) << std::fixed;
       for(int i = 0; i < 10; i++)
           std::cout << std::setw(5) << i
                     << std::setw(10) << MathFunc(i)
                     << "\n";
  }
#+END_SRC

It is not recomended to implement this function using function
pointers. It is better to use the type std::function available in the
header <functional> as it can also work with anything callable such as
C++11 lambdas, functions-objects and function pointers.

 + Better implementation, more C++ friendly using C++11 std::function
   from header <functional>.
 
#+BEGIN_SRC cpp 
  void tabulateFunCPP11(std::function<double (double)> MathFunc){
       std::cout << std::setprecision(3) << std::fixed;
       for(int i = 0; i < 10; i++)
           std::cout << std::setw(5) << i
                     << std::setw(10) << MathFunc(i)
                     << "\n";
  }
#+END_SRC

Running in CLING Repl: 

#+BEGIN_SRC cpp 
  >> tabulateFun1(sin)
      0     0.000
      1     0.841
      2     0.909
      3     0.141
     ... ... .... 

  >> tabulateFun2(log)
      0      -inf
      1     0.000
      2     0.693
      3     1.099
      4     1.386
     ... ... .... 

  >> tabulateFun3(&exp2)
      0     1.000
      1     2.000
      2     4.000
      3     8.000
    ... ... .... 

  >> tabulateFun4(&cos)
      0     1.000
      1     0.540
      2    -0.416
     ... ... .... 
#+END_SRC
** Pointer to Class Member Function 
   :PROPERTIES:
   :ID:       07dc0b5f-0486-4c18-b356-226ec48d4834
   :END:

In addition to ordinary pointers and function pointers, C++ has member
function pointers which can point to a particular class method and be
used for performing indirect method calls. 

Despite member function pointer are much less used than other types of
pointers, they are still useful in lots of use cases such as: 

 + Implementing callbacks => Example: QT Slots and Signals.
 + Creating warappers     => Example: Boost.Python 
 + Reflection 

Pointer to member function declaration: 

  + It declares a pointer-to-member function of the class
    _CLASS_NAME_. The pointer variable  is named pVariable and has the
    type signature:  _(ARG0, ARG1, ... ARGN) => RETURN_TYPE_

#+BEGIN_SRC cpp 
   // Define a pointer to member function named 'pVariable' 
   RETURN_TYPE (CLASS_NAME::* pVariable) (ARG0, ARG1, ..., ARGN-1);

   // Define a pointer to member function 'pVariable' set to null pointer. 
   RETURN_TYPE (CLASS_NAME::* pVariable) (ARG0, ARG1, ..., ARGN-1) = nullptr;

   // Define a pointer to member function named 'pVariable' initialized with the 
   // address of method (member function) member_functionA.
   // Note: The signature of member_functionA is: 
   // RETURN_TYPE CLASS_NAME::member_functionA (ARG0, ARG1, ...)   
   RETURN_TYPE (CLASS_NAME::* pVariable) (ARG0, ARG1, ..., ARGN-1) = &CLASS_NAME::member_functionA;

   // Define a pointer to member function named 'pVariable' initialized with the 
   // address of method (member function) memebr_funnctionA. 
   RETURN_TYPE (CLASS_NAME::* pVariable) (ARG0, ARG1, ..., ARGN-1) = &CLASS_NAME::member_functionB;
#+END_SRC

  + Example: Pointer to any member function taking zero arguments and
    returning a string.

#+BEGIN_SRC cpp 
   std::string (Dummy::* pMemfn) () = nullptr;
#+END_SRC

  + Invoking a pointer to member function. It is necessary an instance
    of the class in order to invoke the member function pointed by the
    pointer.

#+BEGIN_SRC cpp 
   CLASS_TYPE obj;
   pVariable = &CLASS_TYPE::member_function1;
   (obj.*pVariable)(arg0, arg1, arg2, ... argn);
#+END_SRC


  + Type synonym with Typdef 

#+BEGIN_SRC cpp 
   typedef RETURN_TYPE (CLASS_NAME::* pMemberFunction) (ARG0, ARG1, ..., ARGN-1);
   pMemberFunction pvar = &CLASS_NAME::member_functionA;
   CLASS_NAME obj;
   (obj.*pvar)(arg0, arg1, .... argn-1);
#+END_SRC

  + Type synonym with C++11 "using" keyword

#+BEGIN_SRC cpp 
   using pMemberFunction = RETURN_TYPE (CLASS_NAME::*) (ARG0, ARG1, ..., ARGN-1);
   pMemberFunction pvar = &CLASS_NAME::member_functionA;
   CLASS_NAME obj;
   (obj.*pvar)(arg0, arg1, .... argn-1);
#+END_SRC

 *Further Reading:*
 
 + [[https://accu.org/index.php/journals/495][ACCU - An Application of Pointers to Members]]
 + [[http://soggywizards.com/tips/code/c%2B%2B/member-pointers.html][Pointers to C++ Member Functions]]
 + [[https://yosefk.com/c%2B%2Bfqa/function.html][C++ FQA Lite: Pointers to member functions]]
 + [[https://arne-mertz.de/2017/01/decltype-declval/][Modern C++ Features - decltype and std::declval - Simplify C++!]]
 + [[https://isocpp.org/wiki/faq/pointers-to-members][Pointers to Member Functions, C++ FAQ]]
 + [[https://wiki.qt.io/New_Signal_Slot_Syntax][New Signal Slot Syntax - Qt Wiki]]
 + [[https://www.codeguru.com/cpp/cpp/article.php/c17401/C-Tutorial-PointertoMember-Function.htm][C++ Tutorial: Pointer-to-Member Function]]
 + [[https://embeddedartistry.com/blog/2017/1/26/c11-improving-your-callback-game][Improving Your Callback Game — Embedded Artistry]]
 

 *Example*

File: 
  - [[file:src/member-function-pointer.cpp][file:src/member-function-pointer.cpp]]
  - Online compiler: http://rextester.com/WYFC32509

#+BEGIN_SRC cpp :tangle src/member-function-pointer.cpp
  #include <iostream>
  #include <string>
  #include <iomanip>
  #include <deque>
  #include <map>
  #include <cassert>

  class Dummy {
  private:
          std::string _name = "unnamed";
  public:
          Dummy(){}
          Dummy(const std::string& name): _name(name){}
          ~Dummy() = default;
          std::string getName() {
                  return "I am a dummy class named <" + _name + ">";
          }
          std::string getLocation() {
                  return "Unknown location";
          }
          std::string operator()(){
                  return "I am a function-object called: <" + _name + ">";
          }
          auto compute(double x, double y) -> double {
                  return 4 * x + 5 * y;
          }	
  };

  class DummyB{
  public:
          DummyB(){}
          ~DummyB() = default;
          std::string getName() {
                  return "My name is DummyB";
          }
          std::string getLocation() {
                  return "Location of dummyB location";
          }
          std::string operator()(){
                  return "I am the class DummyB";
          }
  };

  // Create type synonym to any member function of Dummy class
  // which takes no parameter and returns a string.
  typedef std::string (Dummy::* pDummyMemFnStr)();

  void invokeMemberFun(Dummy& obj, pDummyMemFnStr pMemfn){
          std::cout << " [1] Method invocation returned value: " << (obj.*pMemfn)() << "\n";
  }

  // Create type synonum with the new "using" C++11 syntax
  using pDummyMemFnStrCPP11 = std::string (Dummy::*)();

  auto invokeMemberFun2(Dummy& obj, pDummyMemFnStrCPP11 pMemfn) -> void {
          std::cout << " [2] Method invocation returned value: " << (obj.*pMemfn)() << "\n";
  }

  template<class T>
  auto invokeMemberFun3(T& obj, std::string (T::* pMemfn)()) -> void{
          std::cout << " [3] Method invocation returned value: " << (obj.*pMemfn)() << "\n";
  }

  template<class T, class R, class ... Args>
  auto invokeMemfn(R (T::* pMemfn) (Args ... args), T& obj, Args ... arglist) -> R{
          return (obj.*pMemfn)(arglist ...);
  }

  int main(){
          const auto nl = std::string("\n");
          const auto nl2 = std::string("\n\n");
          const std::string line = "--------------------------------------------------\n";
	
          std::cout << nl << "=== Experiment 1 ===============" << nl2;
          std::cout << line;
          // Pointer to member function to any member functions
          // (aka method) which takes no argument and returns a string
          // of signature: () => std::string
          //.....................................................
          std::string (Dummy::* pMemfn) () = nullptr;
          // std::string (Dummy::* pMemfn) ();
          if(pMemfn == nullptr)
                  std::cerr << " [INFO] Pointer not initilialized yet." << nl;

          Dummy d("DUMMY");
	
          // Set the function pointer to member function getName().
          pMemfn = &Dummy::getName;
          // Invoke pointer to member function (aka pointer to method)
          std::cout << "Name     = " << (d.*pMemfn)() << nl2;
          assert((d.*pMemfn)() == "I am a dummy class named <DUMMY>");

          if(pMemfn != nullptr)
                  std::cerr << " [INFO] Pointer initilialized OK." << nl;
	
          // Set pointer to Dummy::getLocation
          pMemfn = &Dummy::getLocation;
          std::cout << "Location = " << (d.*pMemfn)() << nl;
          // assert((d.*pMemfn)() == "I am a dummy class named <DUMMY>");	
	
	
          std::cout << nl << "=== Experiment 2 - Using typedef ===============" << nl;
          std::cout << line;
          pDummyMemFnStr pMemfn2 = nullptr;
          pMemfn2 = &Dummy::getName;
          std::cout << "d.getName() == " << (d.*pMemfn2)() << nl;
          assert((d.*pMemfn2)() == "I am a dummy class named <DUMMY>");	

          std::cout << nl << "=== Experiment 3 - Invoking member function with free function =" << nl;
          std::cout << line;
          // execute d.getName() 
          invokeMemberFun(d, &Dummy::getName);
          // execute d.getLocation() 
          invokeMemberFun(d, &Dummy::getLocation);
          // execute d() 
          invokeMemberFun(d, &Dummy::operator());
	
          std::cout << nl << "=== Experiment 4 - Invoking member function with free function C++11" << nl;
          std::cout << line;
          invokeMemberFun2(d, &Dummy::getName);
          invokeMemberFun2(d, &Dummy::getLocation);
          invokeMemberFun2(d, &Dummy::operator());

          std::cout << nl << "=== Experiment 5 - Pointer to member functions in STL deque collection" << nl;
          auto plist = std::deque<pDummyMemFnStrCPP11>();
          plist.push_back(&Dummy::getName);
          plist.push_back(&Dummy::getLocation);
          plist.push_back(&Dummy::operator());
          for(const auto& p: plist)
                  std::cout << " (+) Calll returned = " << (d.*p)() << nl;

          std::cout << nl << "=== Experiment 6 - Pointer to member functions in map collection" << nl;
          auto dict = std::map<std::string, pDummyMemFnStrCPP11>();
          dict["getName"]     = &Dummy::getName;
          dict["getLocation"] = &Dummy::getLocation;
          dict["callme"]      = &Dummy::operator();
          for(const auto& kv: dict)
                  std::cout << std::right << std::setw(20)  << "invoke(object, "
                            << std::setw(15) << kv.first << ")"
                            << " = " << (d.*(kv.second))() << nl;

          std::cout << nl << "=== Experiment 7 - Template " << nl;
          DummyB b;
          invokeMemberFun3(d, &Dummy::getName);
          invokeMemberFun3(b, &DummyB::getName);
          invokeMemberFun3(d, &Dummy::getLocation);
          invokeMemberFun3(b, &DummyB::getLocation);

          std::cout << nl << "=== Experiment 8 - Template " << nl;
          std::cout << line;
          std::cout << "d.getName()         = " << invokeMemfn(&Dummy::getName, d) << nl;
          std::cout << "d.compute(3.0, 4.0) = " << invokeMemfn(&Dummy::compute, d, 3.0, 4.0) << nl;
	
          return 0;
  }

#+END_SRC

Running: 

#+BEGIN_SRC sh 
   $ clang++ member-function-pointer.cpp -o member-function-pointer.bin -std=c++1z -Wall -Wextra  
   $ ./member-function-pointer.bin

   === Experiment 1 ===============

   --------------------------------------------------
    [INFO] Pointer not initilialized yet.
   Name     = I am a dummy class named <DUMMY>

    [INFO] Pointer initilialized OK.
   Location = Unknown location

   === Experiment 2 - Using typedef ===============
   --------------------------------------------------
   d.getName() == I am a dummy class named <DUMMY>

   === Experiment 3 - Invoking member function with free function =
   --------------------------------------------------
    [1] Method invocation returned value: I am a dummy class named <DUMMY>
    [1] Method invocation returned value: Unknown location
    [1] Method invocation returned value: I am a function-object called: <DUMMY>

   === Experiment 4 - Invoking member function with free function C++11
   --------------------------------------------------
    [2] Method invocation returned value: I am a dummy class named <DUMMY>
    [2] Method invocation returned value: Unknown location
    [2] Method invocation returned value: I am a function-object called: <DUMMY>

   === Experiment 5 - Pointer to member functions in STL deque collection
    (+) Calll returned = I am a dummy class named <DUMMY>
    (+) Calll returned = Unknown location
    (+) Calll returned = I am a function-object called: <DUMMY>

   === Experiment 6 - Pointer to member functions in map collection
        invoke(object,          callme) = I am a function-object called: <DUMMY>
        invoke(object,     getLocation) = Unknown location
        invoke(object,         getName) = I am a dummy class named <DUMMY>

   === Experiment 7 - Template 
    [3] Method invocation returned value: I am a dummy class named <DUMMY>
    [3] Method invocation returned value: My name is DummyB
    [3] Method invocation returned value: Unknown location
    [3] Method invocation returned value: Location of dummyB location

   === Experiment 8 - Template 
   --------------------------------------------------
   d.getName()         = I am a dummy class named <DUMMY>
   d.compute(3.0, 4.0) = 32

#+END_SRC
** Pointer to Class Member Variable 
*** Summary  

Pointers to members variables provides an way to access class member
data indirectly. 

Among other things, it has the following use cases:

 + Create setters/getters
 + Serialization 
 + Reflection
 + Indirect Access
 + Security research.
 + Get the member data pointer offset in bytes.

 *Syntax for pointer to member data*

 + Declare a pointer to member of a certain class of an specific
   type. 

#+BEGIN_SRC cpp 
  MEMBER_TYPE  CLASS_NAME::* PointerVariableName;
#+END_SRC

 + Declare a pointer to member intialized to null.

#+BEGIN_SRC cpp 
  MEMBER_TYPE  CLASS_NAME::* PointerVariableName = nulltpr;
#+END_SRC

 + Declare a pointer to member intialized to the address of some
   member variable. 

#+BEGIN_SRC cpp 
  MEMBER_TYPE  CLASS_NAME::* PointerVariableName = &CLASS_NAME::memberVariable;
#+END_SRC

 *Syntax for type alias/synonym of pointer to member data*

 + *Before C++11* - type alias with the typedef keyword. 

#+BEGIN_SRC cpp 
  typedef MEMBER_TYPE CLASS_NAME::* TypeAliasName;
  // Instance declaration: 
  TypeAliasName pointerToMember;
  TypeAliasName pointerToMember = nullptr;
  TypeAliasName pointerToMember = &CLASS_NAME::MemeberVariable;
#+END_SRC

 + *C++11* - type alias with 'using' keyword

#+BEGIN_SRC cpp 
  using TypeAliasName = MEMBER_TYPE CLASS_NAME::*;
  // Instance declaration: 
  TypeAliasName pointerToMember;
  TypeAliasName pointerToMember = nullptr;
  TypeAliasName pointerToMember = &CLASS_NAME::MemeberVariable;
#+END_SRC
*** Example 

#+BEGIN_SRC cpp 
  // It could also be: struct Dummy{ ... }
  class Dummy{
  public:
          double      x;
          double      y;
          int         points;
          std::string name;
          double      z;
          char        ch;
          Dummy(){}
          Dummy(double x, double y, int points, const std::string& name):
                  x(x), y(y), points(points), name(name){}
  };
#+END_SRC

Creating a test object: 

#+BEGIN_SRC cpp 
  >>  auto obj = Dummy(20.2, 9.0, 10, "dummy");
  >> obj.x
  (double) 20.200000
  >> obj.y
  (double) 9.0000000
  >> obj.points
  (int) 10
  >> obj.name
  (std::string &) "dummy"
  >> obj.z
  (double) 0.0000000
  >> obj.ch
  (char) '0x00'

  >> auto obj2 = Dummy(100.0, -10.0, 70, "objectx")
  (Dummy &) @0x7fda2fd33060
  >> 
#+END_SRC

Create an initialized to null pointer to double member data: 

#+BEGIN_SRC cpp 
>> double Dummy::* p_to_member_double = nullptr;
>> 
>> p_to_member_double
(double Dummy::*) @0x43cbed0
#+END_SRC

Set pointer ~p_to_member_double~ to field x.

#+BEGIN_SRC cpp 
  >> p_to_member_double = &Dummy::x
  (double Dummy::*) @0x46bc260
  >> 

  // Acess field x of obj 
  >> obj.* p_to_member_double
  (double) 20.200000
  >> 
  >> obj.* p_to_member_double = -90.2
  (double) -90.200000
  >> obj.* p_to_member_double 
  (double) -90.200000
  >> obj.x
  (double) -90.200000
  >>  

  >> obj2.* p_to_member_double
  (double) 100.00000
  >> 

  >> obj2.* p_to_member_double = 200.0
  (double) 200.00000
  >> obj2.x
  (double) 200.00000
  >> 
#+END_SRC

Set pointer ~p_to_member_double~ to field y.

#+BEGIN_SRC cpp 
  >> p_to_member_double = &Dummy::y;

  >> obj.y
  (double) 9.0000000
  >> 
  >> obj.* p_to_member_double
  (double) 9.0000000
  >> obj.* p_to_member_double = -190.0
  (double) -190.00000
  >> obj.* p_to_member_double
  (double) -190.00000
  >> obj.y
  (double) -190.00000
  >> 
  >>

  >> obj2.y
  (double) -10.000000
  >> obj2.* p_to_member_double
  (double) -10.000000
  >> 
  >> obj2.* p_to_member_double = -900.223
  (double) -900.22300
  >> obj2.* p_to_member_double
  (double) -900.22300
#+END_SRC

Create a type alias to pointer to member of type double.

#+BEGIN_SRC cpp 
  // C++11 => Better!!
  using PointerToMemberDouble = double Dummy::*;
  // Old C++ standards => Cryptic  
  typedef double Dummy::* PointerToMemberDoubleTypedef ; 

  PointerToMemberDouble ptrdouble = &Dummy::z;

  >> obj.* ptrdouble 
  (double) 0.0000000

  >> obj.z
  (double) 0.0000000

  >> obj.* ptrdouble 
  (double) 0.0000000

  >> obj.* ptrdouble = 100.0
  (double) 100.00000

  >> obj.* ptrdouble 
  (double) 100.00000

  >> obj.z
  (double) 100.00000


  >> obj2.z
  (double) 0.0000000

  >> obj2.z = 600.0
  (double) 600.00000

  >> obj2.* ptrdouble 
  (double) 600.00000

  >> obj2.* ptrdouble = -100.0
  (double) -100.00000

  >> obj2.* ptrdouble 
  (double) -100.00000

  >> obj2.z
  (double) -100.00000
  >> 
  >> 

#+END_SRC

Use pointer to member with object pointer. 

#+BEGIN_SRC cpp 
  >> auto pobj1 = &obj
  (Dummy *) @0x7ffd126ee978
 
  >> pobj1->y
  (double) -190.00000
  >> 

  >> PointerToMemberDouble ptom_double = &Dummy::y;
  >> 
  >> pobj1->* ptom_double
  (double) -190.00000
  >> 
  >> pobj1->* ptom_double = -300.0;
  >> 
  >> pobj1->y
  (double) -300.00000
  >> 
#+END_SRC

Get member offset: 

#+BEGIN_SRC cpp 
  template<class Class, class Field>
  size_t getOffset(Field Class::*fieldp) { 
          return size_t(&(static_cast<Class*>(nullptr)->*fieldp));
  }

  >> auto offset_x = getOffset(&Dummy::x)
  (unsigned long) 0

  >> auto offset_y = getOffset(&Dummy::y)
  (unsigned long) 8

  >> auto offset_z = getOffset(&Dummy::z)
  (unsigned long) 56
  >> 
  >> auto offset_name = getOffset(&Dummy::name)
  (unsigned long) 24
  >> auto offset_points = getOffset(&Dummy::points)
  (unsigned long) 16
#+END_SRC

Access class member x using x offset.

#+BEGIN_SRC cpp 
  >> auto p = &obj
  (Dummy *) @0x7ffd126ee978

  >> reinterpret_cast<double*>(((size_t) p) + offset_x)
  (double *) 0x7fda2fd33010

  >> *reinterpret_cast<double*>(((size_t) p) + offset_x)
  (double) -90.200000

  >> *reinterpret_cast<double*>(((size_t) p) + offset_x) = -100.0
  (double) -100.00000

  >> p->x
  (double) -100.00000
  >> 
  >> 
  >> double& xref1 = *reinterpret_cast<double*>(((size_t) p) + offset_x)
  (double) -100.00000
  >> xref1 = 900.0
  (double) 900.00000
  >> p->x
  (double) 900.00000
  >> 


#+END_SRC

Access class member z using z offset.

#+BEGIN_SRC cpp 
  >> p->z
  (double) 100.00000
  >> 

  >> *reinterpret_cast<double*>(((size_t) p) + offset_z)
  (double) 100.00000
  >> 

  >> *reinterpret_cast<double*>(((size_t) p) + offset_z) = -200.0
  (double) -200.00000

  >> p->z
  (double) -200.00000
  >> 

  >> *reinterpret_cast<double*>(((size_t) &obj2) + offset_z)
  (double) -100.00000

  >> *reinterpret_cast<double*>(((size_t) &obj2) + offset_z) = 300.0
  (double) 300.00000

  >> *reinterpret_cast<double*>(((size_t) &obj2) + offset_z) = 300.0;

  >> obj2.z
  (double) 300.00000
  >> 
#+END_SRC

Access field 'name' using its offset.

#+BEGIN_SRC cpp 
   >> obj.name
   (std::string &) "dummy"
   >> 
   >> *reinterpret_cast<std::string*>(((size_t) &obj) + offset_name)
   (std::string &) "dummy"

   >> *reinterpret_cast<std::string*>(((size_t) &obj) + offset_name) = "binary";
   >> obj.name
   (std::string &) "binary"
   >> 

   >> obj.name
   (std::string &) "P0WN3D"
#+END_SRC

Generic solution for dealing with offsets: 

#+BEGIN_SRC cpp 
  template<typename FIELD, typename CLASS>
  FIELD* getFieldPointer(const CLASS& obj, size_t offset ){
          return reinterpret_cast<FIELD*>(((size_t) &obj) + offset);
  }

  template<typename FIELD, typename CLASS>
  FIELD getFieldValue(const CLASS& obj, size_t offset ){
          return *reinterpret_cast<FIELD*>(((size_t) &obj) + offset);
  }
#+END_SRC

Get object's members values by their offset: 

#+BEGIN_SRC cpp 
  >> auto obj3 = Dummy(120.2, -89.0, 143, "blob");
  >> obj3.x
  (double) 120.20000
  >> obj3.y
  (double) -89.000000
  >> obj3.z
  (double) 0.0000000
  >> obj3.z = 45.0;
  >> obj3.name;
  >> 

  >> 
  >> getOffset(&Dummy::x)
  (unsigned long) 0
  >> getOffset(&Dummy::y)
  (unsigned long) 8
  >> getOffset(&Dummy::z)
  (unsigned long) 56
  >> getOffset(&Dummy::name)
  (unsigned long) 24
  >> getOffset(&Dummy::points)
  (unsigned long) 16
  >> 

  >> obj3.x
  (double) 120.20000

  >> getFieldValue<double>(obj3, 0)
  (double) 120.20000
  >> 

  >> obj3.y
  (double) -89.000000

  >> getFieldValue<double>(obj3, 8)
  (double) -89.000000
  >> 

  >> obj3.z
  (double) 0.0000000
  >> obj3.z = 45.0;

  >> getFieldValue<double>(obj3, 56)
  (double) 45.000000
  >> 

  >> obj3.name
  (std::string &) "blob"
  >> 
  >> getFieldValue<std::string>(obj3, 24)
  "blob"
#+END_SRC



   
 
