elowy01
4/17/2019 - 3:49 PM

Cheat sheet on the C++ language

Cheat sheet on the C++ language

// # Environment variables:
CPLUS_INCLUDE_PATH=/opt/gdbm-1.8.3/includ
export CPLUS_INCLUDE_PATH

/ Link path:
LIBRARY_PATH=/opt/gdbm-1.8.3/lib
export LIBRARY_PATH

# C-style guide
http://archive.oreilly.com/oreillyschool/courses/cplusplus1/style.html#functions
//
#STL stands for The C++ Standard Template Library (STL)
//
# installing Boost libraries in MAC
# One way I've found to install it is using:
 brew install boost
/
#After installing we can now where it was installed by doing:
> brew info boost
#We get:
boost: stable 1.70.0 (bottled), HEAD
Collection of portable C++ source libraries
https://www.boost.org/
/usr/local/Cellar/boost/1.70.0 (13,983 files, 511.8MB) *
  Poured from bottle on 2019-06-26 at 12:03:56
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/boost.rb
==> Dependencies
Required: icu4c ✔
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 60,088 (30 days), 177,811 (90 days), 641,141 (365 days)
install_on_request: 20,129 (30 days), 59,918 (90 days), 199,466 (365 days)
build_error: 0 (30 days)
#We can get the location that in my case is:
/usr/local/Cellar/boost/1.70.0
/
#Then we can create a program that uses Boost

#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
    using namespace boost::lambda;
    typedef std::istream_iterator<int> in;

    std::for_each(
        in(std::cin), in(), std::cout << (_1 * 3) << " " );
}
/
#And then we can compile it:
g++ -I /usr/local/Cellar/boost/1.70.0 main.cpp -o boost
//
# A different way of knowing the Boost version. Add this in the code:
std::cout << "Using Boost "     
          << BOOST_VERSION / 100000     << "."  // major version
          << BOOST_VERSION / 100 % 1000 << "."  // minor version
          << BOOST_VERSION % 100                // patch level
          << std::endl;
/
# if we want to have additional info on the compilation steps
(including the include libraries that are included at compile time)
you do:

g++ -v -I /usr/local/Cellar/boost/1.70.0 main.cpp -o boost
//
* Adding more than one folder with -I
g++ -I /usr/local/Cellar/boost/1.70.0 -I /another/dir/ main.cpp -o boost
//
#using Visual Studio Code
#Modifying project configuration on compiling properties:

Go to CPP_PROJECTS--> .vscode


#using Eclipse as IDE:

#Creating a new project:
Go to File->New->C/C++ Project->C++ Managed Build->Hello World C++ Project--> In Toolchain select MacOSX GCC

Then click on Project->Build All
And then click on Run->run

#integer data types:
short	2 bytes	
int 	2 bytes 	Typically 4 bytes on modern architectures
long 	4 bytes 	
long long 8 bytes	C99/C++11 type
//
#uniform initialization (available from C++11):
int width{ 5 }; // brace (uniform) initialization of value 5 into variable width
//
#boolean data type:
bool b1 { true };
bool b2 { false };
b1 = false;
//
# const keyword
It is used to create a constant of a certain data type . It is not a variable and we cannot changes its value in the
program. In order to create for example an integer constanst we do:

const int arraySize = 100;

int age [arraySize]; # and we can use it

for ( i =0; i< arraySize; i++) # another example of its usage
//
#print out something to the screen:

#include <iostream>

int main(int argc, char** argv) {
    std::cout << "Hi!";
    Return 0;
}

--> Put This Into A File Named Hello.Cpp And Compile It By Using:

C++ -g Hello.Cpp

# -g is necessary for debugging

And 

Execute By Doing :
./A.Out
/
#Then, If We want to debug it:
gdb a.out

#we need to create a breakpoint in order to stop at a certain point:
break 42

#then we run again and now it will stop at line 42
gdb run

#then, to get info on the breakpoints:
(gdb)info break 

#then, we can disable a specific breakpoint:
(gdb) disable 2

#continue one step
(gdb) next

#step into a function
(gdb) step

#type the text of the program in the vicinity of where it is presently stopped.
(gdb) list
//
#set a given variable within gdb:
(gdb) set variable a=1
(gdb) print(a)
$10 = 1
//
#Is there a way to jump immediately to that breakpoint without using "next" or "step"
 press c, it will continue execution until the next breakpoint.
//
// How to use command-line arguments when compiling
// Name of program mainreturn.cpp 
#include <iostream> 
using namespace std; 
  
int main(int argc, char** argv) 
{ 
    cout << "You have entered " << argc 
         << " arguments:" << "\n"; 
  
    for (int i = 0; i < argc; ++i) 
        cout << argv[i] << "\n"; 
  
    return 0; 
} 
/Then, we compile it and run it by doing:
$ g++ mainreturn.cpp -o main 
$ ./main geeks for geeks

/You have entered 4 arguments:
./main
geeks
for
geeks
//
#running gdb using command line args:
gdb --args executablename arg1 arg2 arg3
//
#backtrace full
#A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame (frame zero), followed by its caller (frame one), and on up the stack.
(gdb) bt full
//
#if when we try to run gdb we get:

No symbol table is loaded.  Use the "file" command.

#a solution that worked for me is to use the compiler flag: -ggdb and recompile
//
# declaring multiple variables on the same line
int main()
{
	std::string data1,data2,data3;

	data1="a";
	data2="b";
	data3="c";
 
	std::cout<<data1<<std::endl;
	std::cout<<data2<<std::endl;
	std::cout<<data3<<std::endl;

	return 0;
 
}
//
# declaring and initializing (defining) multiple variables at the same time
int column = 0, row = 0, index = 0;
//
#printing more than one thing on the same line:

#include <iostream>
 
int main()
{
    int x = 4;
    std::cout << "x is equal to: " << x;
    return 0;
}
This program prints:

x is equal to: 4
//
#Inserting new lines:

int main()
{
    std::cout << "Hi!" << std::endl;
    std::cout << "My name is Alex." << std::endl;
    return 0;
}
# A second way of inserting new lines that is preferred:
#include <iostream> // for std::cout
 
int main()
{
    int x{ 5 };
    std::cout << "x is equal to: " << x << '\n'; // Using '\n' standalone
    std::cout << "And that's all, folks!\n"; // Using '\n' embedded into a double-quoted piece of text (note: no single quotes when used this way)
    return 0;
}
//
#printing different words on the same line:
#include <iostream> // for std::cout
 
int main()
{
    std::cout << "Hello" << " world!";
    return 0;
}
//
#Read in input from user:
#include <iostream>
 
int main()
{
    std::cout << "Enter a number: "; // ask user for a number
    int x = 0;
    std::cin >> x; // read number from console and store it in x
    std::cout << "You entered " << x << std::endl;
    return 0;
}
//
#Size of the different variables (it can vary depending on your compiler):

#include <iostream>
 
int main()
{
    using namespace std;
    cout << "bool:\t\t" << sizeof(bool) << " bytes" << endl;
    cout << "char:\t\t" << sizeof(char) << " bytes" << endl;
    cout << "wchar_t:\t" << sizeof(wchar_t) << " bytes" << endl;
    cout << "char16_t:\t" << sizeof(char16_t) << " bytes" << endl; // C++11, may not be supported by your compiler
    cout << "char32_t:\t" << sizeof(char32_t) << " bytes" << endl; // C++11, may not be supported by your compiler
    cout << "short:\t\t"#include <iostream>
int value(5); // global variable
 
int main()
{
    int value = 7; // hides the global variable value
    value++; // increments local value, Not Global Value
    ::Value--; // Decrements Global Value, Not local value
 
    Std::Cout << "Global Value: " << ::Value << "\n";
    std::cout << "local value: " << value << "\n";
    return 0;
} // local value is destroyed#include <iostream>
int value(5); // global variable
 
int main()
{
    int value = 7; // hides the global variable value
    value++; // increments local value, not global value
    ::value--; // decrements global value, not local value
 
    std::cout << "global value: " << ::value << "\n";
    std::cout << "local value: " << value << "\n";
    return 0;
} // local value is destroyed << sizeof(short) << " bytes" << endl;
    cout << "int:\t\t" << sizeof(int) << " bytes" << endl;
    cout << "long:\t\t" << sizeof(long) << " bytes" << endl;
    cout << "long long:\t" << sizeof(long long) << " bytes" << endl; // C++11, may not be supported by your compiler
    cout << "float:\t\t" << sizeof(float) << " bytes" << endl;
    cout << "double:\t\t" << sizeof(double) << " bytes" << endl;
    cout << "long double:\t" << sizeof(long double) << " bytes" << endl;
    return 0;
}
//
#Similar to how variables in an inner block with the same name as a variable in an outer block hides the variable in the outer block, local variables with the same name as a global variable hide the global variable inside the block that the local variable is declared in. However, the global scope operator (::) can be used to tell the compiler you mean the global version instead of the local version.

#include <iostream>
int value(5); // global variable
 
int main()
{
    int value = 7; // hides the global variable value
    value++; // increments local value, not global value
    ::value--; // decrements global value, not local value
 
    std::cout << "global value: " << ::value << "\n";
    std::cout << "local value: " << value << "\n";
    return 0;
} // local value is destroyed
#
#Internal and external variables:
A variable with internal linkage is called an internal variable (or static variable). Variables with internal linkage can be used anywhere within the file they are defined in, but can not be referenced outside the file they exist in.

A variable with external linkage is called an external variable. Variables with external linkage can be used both in the file they are defined in, as well as in other files.

If we want to make a global variable internal (able to be used only within a single file), we can use the static keyword to do so:

static int g_x; // g_x is static, and can only be used within this file
 
int main()
{
    return 0;
}
//
#strings in C++

#include <string>
#include <iostream>

/*
 * 
 */
int main(int argc, char** argv) {
    std::string myName;
    myName="Jose";
    std::cout << myName;
    return 0;
}
/
*The same can be achieved by doing:
using namespace std;

int main(int argc, char** argv) {
    string myName;
    myName="Jose";
    cout << myName;
    return 0;
}
//
#several conditions with if and else:

if(boolean_expression 1) {
   // Executes when the boolean expression 1 is true
} else if( boolean_expression 2) {
   // Executes when the boolean expression 2 is true
} else if( boolean_expression 3) {
   // Executes when the boolean expression 3 is true
} else {
   // executes when the none of the above condition is true.
}

//
#appending (concatenating) strings:
int main()
{
    std::string a("45");
    std::string b("11");
 
    std::cout << a + b << "\n"; // a and b will be appended, not added
    a += " volts";
    std::cout << a;
 
    return 0;
}
/
# a second example:
#include <iostream>

int main()
{
	std::string s = "Hello";
	std::string greet = s + " World"; //concatenation easy!

	std::cout << greet << "\n";
}

//
#String length

#include <string>
#include <iostream>
int main()
 
{
    std::string myName("Alex");
    std::cout << myName << " has " << myName.length() << " characters\n";
    return 0;
}
//
#Shorter way of initializing structs:
struct Employee
{
    short id;
    int age;
    double wage;
};
 
Employee joe = { 1, 32, 60000.0 }; // joe.id = 1, joe.age = 32, joe.wage = 60000.0
//
# Length of an array

int main()
{
	int arr[]={1,2,3,4,5};

	int len = sizeof(arr) / sizeof(int);

	std::cout << "Len is:" << len << std::endl;
}

//
# sorting an array
#include <iostream>
#include <algorithm> // for std::sort

int main()
{
   const int length=5;

   int array[length]= { 10,20,5,15,10};

   std::sort(array, array+length);

   for (int i=0; i < length; ++i) {
	   std::cout << array[i] << ' ';
   }

    return 0;
	
}

//
#Dynamic arrays:
The length of a dynamic array can be set at runtime, and their length can be changed.
/
#Initializing an array:
int prime[5] = { 2, 3, 5, 7, 11 }; // use initializer list to initialize the fixed array
/
#The size of the array is not necessary if using an initializer list:
int array[] = { 0, 1, 2, 3, 4 }; // let initializer list set size of the array
/
#Arrays and enums:
#Enums will allow to distinguish each of the array indexes with a name:
enum StudentNames
{
    KENNY, // 0
    KYLE, // 1
    STAN, // 2
    BUTTERS, // 3
    CARTMAN, // 4
    MAX_STUDENTS // 5
};
 
int main()
{
    int testScores[MAX_STUDENTS]; // allocate 5 integers
    testScores[STAN] = 76;
 
    return 0;
}
//
#iterating over an array
#include <array>
#include <iostream>

/*
 * 
 */

int main(int argc, char** argv) {
    int array[] = { 0, 1, 2, 3, 4, 5};
    
    const int numElems = sizeof(array) / sizeof(array[0]);
    
    for(int i=0; i<numElems; i++) {
        std::cout<< "Elem:" << array[i] << "\n"; 
    }
    
    return 0;
}

//
#std::array
This is a better library for dealing with arrays:
/
#include <array>
std::array<int, 5> myarray = { 9, 7, 5, 3, 1 }; // initialization list
//this initializes an array of integers
/
#2nd way of initializing, that performs a bound checking:
#include <array>
std::array<int, 5> myarray { 9, 7, 5, 3, 1 };
myarray.at(1) = 6; // array element 1 valid, sets array element 1 to value 6
myarray.at(9) = 10; // array element 9 is invalid, will throw error
/
#Calculating the size of an array:
#include <array>
std::array<double, 5> myarray { 9.0, 7.2, 5.4, 3.6, 1.8 };
std::cout << "size: " << myarray.size();
/
#iterating over an array:
#include <array>
std::array<int, 5> myarray { 9, 7, 5, 3, 1 };
 
for (auto &element : myarray)
    std::cout << element << ' ';

/
#sort an array:
#include <iostream>
#include <array>
#include <algorithm> // for std::sort
 
int main()
{
    std::array<int, 5> myarray { 7, 3, 1, 9, 5 };
    std::sort(myarray.begin(), myarray.end()); // sort the array forwards
//    std::sort(myarray.rbegin(), myarray.rend()); // sort the array backwards
 
    for (const auto &element : myarray)
        std::cout << element << ' ';
 
    return 0;
}
//
#std::vector. Lives in the <vector> header
Provides dynamic array functionality that handles its own memory management. This means you can create arrays that have their length set at runtime, without having to explicitly allocate and deallocate memory using new and delete.
/
std::vector<int> array2 = { 9, 7, 5, 3, 1 }; 
/
Just like std::array, accessing array elements can be done via the [] operator (which does no bounds checking) or the at() function (which does bounds checking):

array[2] = 2;
array.at(3) = 3;
/
Resizing an array

Resizing a built-in dynamically allocated array is complicated. Resizing a std::vector is as simple as calling the resize() function:

#include <vector>
#include <iostream>
 
int main()
{
    std::vector<int> array { 0, 1, 2 };
    array.resize(5); // set size to 5
 
    std::cout << "The size is: " << array.size() << '\n';
 
    for (auto const &element: array)
        std::cout << element << ' ';
 
    return 0;
};
/
#adding elements to std::vector and printing its contents:
#include <iostream>
#include <vector>

int main()
{
	std::vector<int> myvector;

	myvector.push_back (100);
	myvector.push_back (200);
	myvector.push_back (300);

	for (int i = 0; i<myvector.size(); i++) {
		std::cout << myvector.at(i) << ' ';
	}
}
//
* std::set is an associative container
* It’s doesn’t allow duplicate elements i.e. it only contains unique elements.
* Std::set can contain element of any specified type in template argument i.e.
std::set<int> // contains only int elements.
class Sample;
std::set<Sample> // contains only Sample class objects.
// example
#include<iostream>
#include<set>
#include<string>
int main()
{
	std::set<std::string> setOfNumbers;

	// Lets insert four elements
	setOfNumbers.insert("first");
	setOfNumbers.insert("second");
	setOfNumbers.insert("third");
	setOfNumbers.insert("first");

	// Only 3 elements will be inserted
	std::cout<<"Set Size = "<<setOfNumbers.size()<<std::endl;

	// Iterate through all the elements in a set and display the value.
	for (std::set<std::string>::iterator it=setOfNumbers.begin(); it!=setOfNumbers.end(); ++it)
	    std::cout << ' ' << *it;
	    std::cout<<"\n";
	    return 0;
}
/
#checking if an element is in std::set
const bool is_in = setName.find(5) != setName.end();
//
#creating a function
// function example
#include <iostream>
using namespace std;

int addition (int a, int b)
{
  int r;
  r=a+b;
  return r;
}

int main ()
{
  int z;
  z = addition (5,3);
  cout << "The result is " << z;
}
The result is 8
//
//reading from a file

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
  string line;
  ifstream myfile ("example.txt");
  if (myfile.is_open())
    {
      while ( getline (myfile,line) )
        {
          cout << line << '\n';
        }
      myfile.close();
    }

  else cout << "Unable to open file";

  return 0;
}
/
#Reading from a file (another different way):

#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib> // for exit()
 
int main()
{
    using namespace std;
 
    // ifstream is used for reading files
    // We'll read from a file called Sample.dat
    ifstream inf("Sample.dat");
 
    // If we couldn't open the input file stream for reading
    if (!inf)
    {
        // Print an error and exit
        cerr << "Uh oh, Sample.dat could not be opened for reading!" << endl;
        exit(1);
    }
 
    // While there's still stuff left to read
    while (inf)
    {
        // read stuff from the file into a string and print it
        std::string strInput;
        getline(inf, strInput);
        cout << strInput << endl;
    }
    
    return 0;
	
    // When inf goes out of scope, the ifstream
    // destructor will close the file
}



// writing on a text file
#include <iostream>
#include <fstream>
using namespace std;

int main () {
  ofstream myfile ("example.txt");
  if (myfile.is_open())
  {
    myfile << "This is a line.\n";
    myfile << "This is another line.\n";
    myfile.close();
  }
  else cout << "Unable to open file";
  return 0;
}
//
#appending content to a file:
#include <cstdlib> // for exit()
#include <iostream>
#include <fstream>
 
int main()
{
    using namespace std;
 
    // We'll pass the ios:app flag to tell the ofstream to append
    // rather than rewrite the file.  We do not need to pass in ios::out
    // because ofstream defaults to ios::out
    ofstream outf("Sample.dat", ios::app);
 
    // If we couldn't open the output file stream for writing
    if (!outf)
    {
        // Print an error and exit
        cerr << "Uh oh, Sample.dat could not be opened for writing!" << endl;
        exit(1);
    }
 
    outf << "This is line 3" << endl;
    outf << "This is line 4" << endl;
    
    return 0;
    // When outf goes out of scope, the ofstream
    // destructor will close the file
}

//
*Multi-line comment:
/**
here
goes
the
comment
**/
//
* Compiling for c++11:

c++ -std=c++11 test.cpp -o test.o
//
*Header files:
A header file is a file containing C declarations and macro definitions (see Macros) to be shared between several source files. You request the use of a header file in your program by including it, with the C preprocessing directive ' #include '.
//
*Including functions declared in different files:

Example:

*We have a main.cpp file like (containing the declaration of the add function):

#include <iostream>

int add(int x, int y); // forward declaration using function prototype

int main()
{
  std::cout << "The sum of 3 and 4 is " << add(3, 4) << std::endl;
  return 0;
}

* We have the add.cpp function:

int add(int x, int y)
{
  return x + y;
}

* Then, we compile it with:
c++ add.cpp main.cpp -o main.o
/
* If we want to avoid the declaration of add in main.cpp. We can use a header file like this:
add.h will be:

// This is start of the header guard.  ADD_H can be any unique name.  By convention, we use the name of the header file.
#ifndef ADD_H
#define ADD_H

// This is the content of the .h file, which is where the declarations go
int add(int x, int y); // function prototype for add.h -- don't forget the semicolon!

// This is the end of the header guard
#endif

* Then, main.cpp will be mutated into:

#include <iostream>
#include "add.h"

int main()
{
  std::cout << "The sum of 3 and 4 is " << add(3, 4) << std::endl;
  return 0;
}

*That can be compiled by doing in the same way than before:
c++ add.cpp main.cpp -o main.o
//
# More on header guards:
(See http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node90.html)
#
The basic structure of the guards are:
#ifndef MY_SYMBOL_H
and is followed immediately by the line
#define MY_SYMBOL_H
The line
#endif /* MY_SYMBOL_H */
is placed at the end of the file.

The symbol used is not crucial, but it must be unique. It is traditional to 
use all capital letters for the symbol. Only letters, numbers and the 
underscore character can be used in the symbols. No other punctuation is 
allowed. A very common symbol is to use the name of the header file, 
converting the .h suffix to a _H.
The C style comment after the #endif directive is not mandatory, 
but it is considered good style.

//
* Parsing command line args:

int main(int argc, char* argv[])
{
    if (argc < 3) { // We expect 3 arguments: the program name, the source path and the destination path
        std::cerr << "Usage: " << argv[0] << "SOURCE DESTINATION" << std::endl;
        return 1;
    }
//
* Parsing command line args:

#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
  if (argc < 3) { // We expect 3 arguments: the program name, the source path and the destination path
    std::cerr << "Usage: " << argv[0] << " <SOURCE> <DESTINATION>" << std::endl;
    return 1;
  }
  std::cerr << "Arg 1 is: " << argv[1] << "." << std::endl;
  std::cerr << "Arg 2 is: " << argv[2] << "." << std::endl;
  std::cerr << "Arg 3 is: " << argv[3] << "." << std::endl;
}
//
* String comparison using strcmp:
// C program to illustrate
// strcmp() function
#include<stdio.h>
#include<string.h>
 
int main()
{ 
     
    char leftStr[] = "g f g";
    char rightStr[] = "g f g";
     
    // Using strcmp()
    int res = strcmp(leftStr, rightStr);
     
    if (res==0)
        printf("Strings are equal");
    else
        printf("Strings are unequal");
     
    printf("\nValue returned by strcmp() is:  %d" , res);
    return 0;
}
//
#comparing 2 strings in cpp:
int main ()
{
  std::string str1 ("green apple");
  std::string str2 ("red apple");

  if (str1.compare(str2) != 0)
    std::cout << str1 << " is not " << str2 << '\n';

  if (str1.compare(6,5,"apple") == 0)
    std::cout << "still, " << str1 << " is an apple\n";

  if (str2.compare(str2.size()-5,5,"apple") == 0)
    std::cout << "and " << str2 << " is also an apple\n";

  if (str1.compare(6,5,str2,4,5) == 0)
    std::cout << "therefore, both are apples\n";

  return 0;

//
* object oriented programming (OOP):
* creating a class

#include <iostream>

using namespace std;

class Box {
   public:
      double length;   // Length of a box
      double breadth;  // Breadth of a box
      double height;   // Height of a box
};

int main() {
   Box Box1;        // Declare Box1 of type Box
   Box Box2;        // Declare Box2 of type Box
   double volume = 0.0;     // Store the volume of a box here
 
   // box 1 specification
   Box1.height = 5.0; 
   Box1.length = 6.0; 
   Box1.breadth = 7.0;

   // box 2 specification
   Box2.height = 10.0;
   Box2.length = 12.0;
   Box2.breadth = 13.0;
   
   // volume of box 1
   volume = Box1.height * Box1.length * Box1.breadth;
   cout << "Volume of Box1 : " << volume <<endl;

   // volume of box 2
   volume = Box2.height * Box2.length * Box2.breadth;
   cout << "Volume of Box2 : " << volume <<endl;
   return 0;
}
//
*Now, write a class and implement the methods and add a constructor and a destructor

#include <iostream>
 
using namespace std;
class Line {
   public:
      void setLength( double len );
      double getLength( void );
      Line();   // This is the constructor declaration
      ~Line();  // This is the destructor: declaration
 
   private:
      double length;
};
 
// Member functions definitions including constructor
Line::Line(void) {
   cout << "Object is being created" << endl;
}
Line::~Line(void) {
   cout << "Object is being deleted" << endl;
}
void Line::setLength( double len ) {
   length = len;
}
double Line::getLength( void ) {
   return length;
}

// Main function for the program
int main() {
   Line line;
 
   // set line length
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   return 0;
}

When we run this:
Object is being created
Length of line : 6
Object is being deleted
//
#constructor with parameters and a default value
class Dual
{
    public:
    int a;
    Dual(int x=0)
    {
        a = x;
    }
};

int main()
{
    Dual obj1;
    Dual obj2(10)
}
//
* s.c_str(): A common use of c_str (from std::string) is precisely to convert a C++ std::string to a const char* C string, which is required by many many low level C functions

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
  string s = "hello";
  printf( "your string:%s", s.c_str() );
}
//
#printing a float:
printf ("The sine of %f degrees is %f\n" , n, m)
//
#convert string to double
string value="0.01";
double p0 = atof(value.c_str());	
printf ("The result of this conversion is %f \n" , p0)
//
#adding a newline at the end
std::cout << myName <<std::endl;
//
#Unordered Map:
Unordered maps are associative containers that store elements formed by the combination of a key value and a mapped value, and which allows for fast retrieval of individual elements based on their keys.
//
#good to understand what the include directive is for:
https://en.wikipedia.org/wiki/Include_directive
/
#the convention is that "", for example:
#include "ga.h" is used for local files. <> is user for system files. For example:
#include <ga.h>. The compiler uses to look for header directories in like /usr/include
Additional directories can be used by compiling and adding the additional dirs using the -I option
 /
#if when compiling you get the following error:

fatal error: 'tr1/unordered_map' file not found. Explanation of this error is at: https://stackoverflow.com/questions/42030598/mac-c-compiler-not-finding-tr1-unordered-map

It can be solved by doing:
clang++ with -stdlib=libstdc++
//
#compilation process:

The compilation of a C++ program involves three steps:

Preprocessing: the preprocessor takes a C++ source code file and deals with the #includes, #defines and other preprocessor directives. The output of this step is a "pure" C++ file without pre-processor directives.
Compilation: the compiler takes the pre-processor's output and produces an object file from it.
Linking: the linker takes the object files produced by the compiler and produces either a library or an executable file.

-Preprocessing

The preprocessor handles the preprocessor directives, like #include and #define. It is agnostic of the syntax of C++, which is why it must be used with care.
It works on one C++ source file at a time by replacing #include directives with the content of the respective files (which is usually just declarations), doing replacement of macros (#define), and selecting different portions of text depending of #if, #ifdef and #ifndef directives.
The preprocessor works on a stream of preprocessing tokens. Macro substitution is defined as replacing tokens with other tokens (the operator ## enables merging two tokens when it makes sense).
After all this, the preprocessor produces a single output that is a stream of tokens resulting from the transformations described above. It also adds some special markers that tell the compiler where each line came from so that it can use those to produce sensible error messages.
Some errors can be produced at this stage with clever use of the #if and #error directives.

-Compilation

The compilation step is performed on each output of the preprocessor. The compiler parses the pure C++ source code (now without any preprocessor directives) and converts it into assembly code. Then invokes underlying back-end(assembler in toolchain) that assembles that code into machine code producing actual binary file in some format(ELF, COFF, a.out, ...). This object file contains the compiled code (in binary form) of the symbols defined in the input. Symbols in object files are referred to by name.
Object files can refer to symbols that are not defined. This is the case when you use a declaration, and don't provide a definition for it. The compiler doesn't mind this, and will happily produce the object file as long as the source code is well-formed.
Compilers usually let you stop compilation at this point. This is very useful because with it you can compile each source code file separately. The advantage this provides is that you don't need to recompile everything if you only change a single file.
The produced object files can be put in special archives called static libraries, for easier reusing later on.
It's at this stage that "regular" compiler errors, like syntax errors or failed overload resolution errors, are reported.

-Linking

The linker is what produces the final compilation output from the object files the compiler produced. This output can be either a shared (or dynamic) library (and while the name is similar, they haven't got much in common with static libraries mentioned earlier) or an executable.
It links all the object files by replacing the references to undefined symbols with the correct addresses. Each of these symbols can be defined in other object files or in libraries. If they are defined in libraries other than the standard library, you need to tell the linker about them.
At this stage the most common errors are missing definitions or duplicate definitions. The former means that either the definitions don't exist (i.e. they are not written), or that the object files or libraries where they reside were not given to the linker. The latter is obvious: the same symbol was defined in two different object files or libraries.

//
* Compiling a program that makes use of the boost/Boost library:
clang++ -I ~/lib/CPP/boost_1_66_0/ test.cpp
* with -I you add a directory to the include search path
//
# Compiling a program setting the name of the compiled output file
clang++ test.cpp -o test.out
//
# Linker flags. 
(see useful post from https://stackoverflow.com/questions/519342/what-is-the-difference-between-i-and-l-in-makefile)
If we want to add to the linking phase of the compiler a folder with libraries we can use:
-L /dir/with/libraries/

If we want to add the name of the library you want to link to.
For instance, if you want to link to the library ~/libs/libabc.a you'd add:
-L$(HOME)/libs -labc

Example in a Makefile:
# LDFLAGS contains flags passed to the compiler for use during linking
LDFLAGS = -Wl,--hash-style=both
# LIBS contains libraries to link with
LIBS = -L$(HOME)/libs -labc
program: a.o b.o c.o
//
* LD_LIBRARY_PATH
Useful post at : https://stackoverflow.com/questions/7148036/what-is-ld-library-path-and-how-to-use-it

LD_LIBRARY_PATH is the predefined environmental variable in Linux/Unix which sets the path which the linker
should look in to while linking dynamic libraries/shared libraries.

LD_LIBRARY_PATH contains a colon separated list of paths and the linker gives priority to these 
paths over the standard library paths /lib and /usr/lib. The standard paths will still be searched, 
but only after the list of paths in LD_LIBRARY_PATH has been exhausted.

The best way to use LD_LIBRARY_PATH is to set it on the command line or script immediately before 
executing the program. This way the new LD_LIBRARY_PATH isolated from the rest of your system.

Example Usage:

$ export LD_LIBRARY_PATH="/list/of/library/paths:/another/path"
$ ./program
//
#multiline comment
/*
this
is
*/

or these comments can also be commented as:
/* This is a multi-line comment.
 * the matching asterisks to the left
 * can make this easier to read
 */

//
# if you get the following error:
use of undeclared identifier 'cout'; did you mean 'count'?

Then, you need to include the following directive:
#include <iostream>
//
# split a tab delimited string

#include <iostream>
#include <string>
#include <boost/algorithm/string.hpp>

using namespace std;

int main()
{

  string line("test\ttest2\ttest3");
  vector<string> strs;
  boost::split(strs,line,boost::is_any_of("\t"));

  std::cout << "* size of the vector: " << strs.size() << endl;
  for (size_t i = 0; i < strs.size(); i++)
    std::cout << strs[i] << endl;

  return 0;

}
//
#script that parse a file and split by tab the different lines:

#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <boost/algorithm/string.hpp>

using namespace std;

int main () {

  string line;
  ifstream myfile ("text.txt");

  if (myfile.is_open())
    {
      while ( getline (myfile,line) )
        {
	  vector<string> strs;
	    boost::split(strs,line,boost::is_any_of("\t"));

	      for (size_t i = 0; i < strs.size(); i++)
	          std::cout << strs[i] << endl;
        }
      myfile.close();
    }

  else cout << "Unable to open file";

  return 0;
}
//
#Checking if a line starts with a certain character:

#include <iostream>
#include <string>
#include <boost/algorithm/string.hpp>


using namespace std;

int main()
{

  std::string mainStr = "This is the sample string";
  std::string toMatch = "This";

  // Test case-sensitive implementation of startsWith function
  bool result = boost::algorithm::starts_with(mainStr , toMatch);

  std::cout<<result<<std::endl;

  // Test case-insensitive implementation of startsWith function
  result = boost::algorithm::istarts_with(mainStr, "this");

  std::cout<<result<<std::endl;
}
//
#continue statement
// continue loop example
#include <iostream>
using namespace std;

int main ()
{
  for (int n=10; n>0; n--) {
    if (n==5) continue;
    cout << n << ", ";
  }
  cout << "liftoff!\n";
}
//
# convert a single character string to char:

int main () {
  string astring="hello";
  assert(astring.size() == 1); //check if the string has exactly one character
  char acharacter = astring[0];

}
//
#For-each loop
#include <iostream>
 
int main()
{
    int fibonacci[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
    for (int number : fibonacci) // iterate over array fibonacci
       std::cout << number << ' '; // we access the array element for this iteration through variable number
 
    return 0;
}
//
#for loop

int main()
{
   const int length=5;

   int array[length]= { 10,20,5,15,10};

   for (int i=0; i < length; ++i) {
	   std::cout << array[i] << ' ';
   }

    return 0;
	
}
//
#Typdefs
Typedefs allow for creating new names (think of them as aliases) for existing types. Following is the simple syntax to define a new type using typedef:

typedef int counter;
counter tick_c = 100;  // tick_c is a valid integer variable
//
#Multi-file project and how to compile it:
#We have a file named main.cpp:
#include <iostream>
 
int add(int x, int y); // needed so main.cpp knows that add() is a function declared elsewhere
 
int main()
{
    std::cout << "The sum of 3 and 4 is: " << add(3, 4) << '\n';
    return 0;
}

# We have also a file named add.cpp:
int add(int x, int y)
{
    return x + y;
}
# And in order to compile it:
g++ main.cpp add.cpp -o hello_world
//
#associative container that store elements in key-value pair.
std::map
/
#include <iostream>
#include <map>
#include <string>
#include <iterator>
 
int main()
{
    std::map<std::string, int> mapOfWords;
    // Inserting data in std::map
    mapOfWords.insert(std::make_pair("earth", 1));
    mapOfWords.insert(std::make_pair("moon", 2));
    mapOfWords["sun"] = 3;
    // Will replace the value of already added key i.e. earth
    mapOfWords["earth"] = 4;
    // Iterate through all elements in std::map
    std::map<std::string, int>::iterator it = mapOfWords.begin();
    while(it != mapOfWords.end())
    {
        std::cout<<it->first<<" :: "<<it->second<<std::endl;
        it++;
    }
    // Check if insertion is successful or not
    if(mapOfWords.insert(std::make_pair("earth", 1)).second == false)
    {
        std::cout<<"Element with key 'earth' not inserted because already existed"<<std::endl;
    }
    // Searching element in std::map by key.
    if(mapOfWords.find("sun") != mapOfWords.end())
        std::cout<<"word 'sun' found"<<std::endl;
    if(mapOfWords.find("mars") == mapOfWords.end())
        std::cout<<"word 'mars' not found"<<std::endl;
    return 0;
}
//
# checking if a certain key exists in a std::map
#include <iostream>
#include <map>
using namespace std;

int main()
{
    map<string, string> m;
    m.insert(make_pair("f","++--"));
    if ( m.find("f") == m.end() ) {
        // not found
        std::cout<<"Not found!" <<std::endl;
    } else {
        // found
        std::cout<<"Found!" <<std::endl;
    }
    return 0;
}
//
#function to split a string on a certain character

#include <string>
#include <vector>
#include <sstream>
#include <iostream>

/*
std::string split implementation by using delimiter as a character.
*/
std::vector<std::string> split(std::string strToSplit, char delimeter)
{
	std::stringstream ss(strToSplit);
	std::string item;
	std::vector<std::string> splittedStrings;
	while (std::getline(ss, item, delimeter))
	{
		splittedStrings.push_back(item);
	}
	return splittedStrings;
}

int main()
{
	std::string Names="Jose\tPepe";

	std::vector<std::string> splitted_names;
	splitted_names=split(Names,'\t');

	for (int i = 0; i<splitted_names.size(); i++) {
		std::cout << splitted_names.at(i) << '\n';
	}
}
//
# With boost::icontains we can check if a sub string exists in a given string i.e.

#include <iostream>
#include <string>
#include <boost/algorithm/string.hpp>
 
int main()
{
	std::string data = "Hi this is a sample string";
 
	// Case Insensitive Sub String Search
	bool result = boost::icontains(data, "SAMPLE");
 
	if(result)
		std::cout<<"'SAMPLE' is Present in ---"<<data<<std::endl;
	else
		std::cout<<"'SAMPLE' is Not Present in ---"<<data<<std::endl;
}
#But we can not find out the position of substring with it 
//
# substr funciton to remove bits or parts of a string:
#include <iostream>

int main( int argc, char **argv ){

    std::string test="hello";
    std::cout << test.substr(2) << std::endl;

    return 0;
}
# This will print out:
llo
//
# find a character in a string, usage of find in string
#include <iostream>
#include <bitset>
#include <string>
 
int main()
{
    // string search functions return npos if nothing is found
    std::string s = "test";
    if(s.find('a') == std::string::npos)
    std::cout << "no 'a' in 'test'\n";

    return 0;
}
//
#checking if a string is empty

#include <iostream>
#include <string>
 
int main()
{
    // string search functions return npos if nothing is found
    std::string s = "test";
    if(s.empty()) {
        std::cout << "Is empty!" <<std::endl;
    } else {
        std::cout << "Not empty!" <<std::endl;
    }
    return 0;
}
//
# Implement a letter counter

#include <iostream>
#include <string>
 
using namespace std;
 
int main()
{
    string str = "anyString";
    int cnt = 0;
    for(int i=0; str[i]; i++)
        cnt++;
    cout << cnt << endl;
    return 0;
}
//
# Nucleotide counter
#include <iostream>
#include <string>
 
using namespace std;
 
int main()
{
    string str = "AACCTT";
    int A_cnt = 0;
    int C_cnt = 0;
    int T_cnt = 0;
    int G_cnt = 0;
    for(int i=0; str[i]; i++)
        if (str[i]=='A') {
            A_cnt++;
        } else if (str[i]=='C') {
            C_cnt++;
        } else if (str[i]=='T') {
            T_cnt++;
        } else if (str[i]=='G') {
            G_cnt++;
        }
    cout << "A:" << A_cnt << endl;
    cout << "G:" << G_cnt << endl;
    cout << "C:" << C_cnt << endl;
    cout << "T:" << T_cnt << endl;
    return 0;
}
//
# word counter

#include <iostream>
#include <map>
#include <string>
#include <iterator>
#include <vector>

using namespace std;
int main()
{

    std::map<std::string, int> countOfWords;
    // Inserting data in std::map
    std::vector<string> array1 = { "dog", "cat", "dog", "hamster" };
    for (auto const &element: array1)
        ++countOfWords[element];

    // Iterate through all elements in std::map
    std::map<std::string, int>::iterator it = countOfWords.begin();
    while(it != countOfWords.end())
    {
        std::cout<<it->first<<" :: "<<it->second<<std::endl;
        it++;
    }

    return 0;
}
//
# checking if a boolean variable is true or false:
 if (validate == true)
   {
       //do something
   }
   else
   {
       //do something different
   }
//
(OOP) using different classes in multiple files:
We have a File named cat.h
// cat.h
#ifndef ____2_cat_implementation__Cat__
#define ____2_cat_implementation__Cat__

#include <iostream>
using namespace std;
class Cat
{
    public:
        Cat (int initialAge);
        ~Cat();
        int GetAge();              
        void SetAge (int age);      
        void Meow();        
    private: int itsAge;
};

#endif /* defined(____2_cat_implementation__Cat__) */ 
/
#We have another file named: cat.cpp
// cat.cpp
#include <iostream>
#include "Cat.h"
using namespace std;

Cat::Cat(int initialAge) 
{
    itsAge = initialAge;
}

Cat::~Cat() 
{

}

int Cat::GetAge() { return itsAge;}              
void Cat::SetAge (int age) { itsAge = age;}      
void Cat::Meow() { cout << "Meow.\n";}        
/ Finally, we have the main.cpp file:
#include <iostream>
#include "Cat.h"
using namespace std;

int main()
{
    Cat Frisky(5);
    Frisky.Meow();
    cout << "Frisky is a cat who is ";
    cout << Frisky.GetAge() << " years old.\n";
    Frisky.Meow();
    Frisky.SetAge(7);
    cout << "Now Frisky is " ;
    cout << Frisky.GetAge() << " years old.\n";
    return 0;
}
/
This can be compiled by:
g++ -I /folder/with/Cat.h/ cat.cpp main.cpp -o out.exe
#Note that the -I should point to the folder containing the header file
//
###cmake sintax:
/
cmake_minimum_required(VERSION 3.14)
project(cmake_testapp)

set(CMAKE_CXX_STANDARD 14)

add_executable(cmake_testapp main.cpp add.cpp include/add.h)
# The header file will be within the include folder
/
#Adding dependency in cmake to a library (xtensor in this case)
cmake_minimum_required(VERSION 3.14)
project(example_tensor)

set(CMAKE_CXX_STANDARD 14)

find_package(xtl REQUIRED)
find_package(xtensor REQUIRED)
# if xtensor was built with xsimd support:
# find_package(xsimd REQUIRED)

add_executable(example_tensor main.cpp)

/
# Example of how to use cmake from (https://stackoverflow.com/questions/39598323/how-to-properly-link-libraries-with-cmake)
# Say you have file1.cpp, file2.cpp, main.cpp. You add them to your project with:
ADD_LIBRARY(LibsModule 
    file1.cpp
    file2.cpp
)
#Now you added them to a module called LibsModule. Keep that in mind. Say you want to link to pthread 
for example that's already in the system. You can combine it with LibsModule using the command:
target_link_libraries(LibsModule -lpthread)

#And if you want to link a static library to that too, you do this:
target_link_libraries(LibsModule liblapack.a)

#And if you want to add a directory where any of these libraries are located, you do this:
target_link_libraries(LibsModule -L/home/user/libs/somelibpath/)

#Now you add an executable, and you link it with your main file:
ADD_EXECUTABLE(MyProgramExecBlaBla main.cpp)

#(I added BlaBla just to make it clear that the name is custom). And then you link
LibsModule with your executable module MyProgramExecBlaBla
target_link_libraries(MyProgramExecBlaBla LibsModule)

//
#exit from a loop
if(comphealth <= 0 || yourhealth <= 0)
  break;
//
#const functions (see https://www.geeksforgeeks.org/const-member-functions-c/)
#
# This ex below declares the getValue as const, this allows to use this function on any type of object. 
Non-const functions can only be called by non-const objects. So the example below works:

#include<iostream> 
using namespace std; 
  
class Test { 
    int value; 
public: 
    Test(int v = 0) {value = v;} 
      
    // We get compiler error if we add a line like "value = 100;" 
    // in this function. 
    int getValue() const {return value;}   
}; 
  
int main() { 
    Test t(20); 
    cout<<t.getValue(); 
    return 0; 
} 

# But if we try to use the following code:
#include<iostream> 
using namespace std; 
  
class Test { 
    int value; 
public: 
    Test(int v = 0) {value = v;} 
    int getValue() {return value;} 
}; 
  
int main() { 
    const Test t; 
    cout << t.getValue(); 
    return 0; 
} 
# it will give an error
//
# (cast) convert string to numbers

// A program to demonstrate the use of stringstream 
#include <iostream> 
#include <sstream> 
using namespace std; 
  
int main() 
{ 
    string s = "12345"; 
  
    // object from the class stringstream 
    stringstream geek(s); 
  
    // The object has the value 12345 and stream 
    // it to the integer x 
    int x = 0; 
    geek >> x; 
  
    // Now the variable x holds the value 12345 
    cout << "Value of x : " << x; 
  
    return 0; 
}
//
# calculating the average of a list of numbers:
#include <iostream>

using namespace std; 

int main() {
   int n, i;
   float sum = 0.0, avg;
   float num[] = {12, 76, 23, 9, 5}; 
   n = sizeof(num) / sizeof(num[0]);
   for(i = 0; i < n; i++)
      sum += num[i];
   avg = sum / n;
   cout<<"Average of all array elements is "<<avg;
   return 0;
 }
//
# Initializing a pointer with the NULL value (means that the pointer is not pointing to anything). There are several ways
to achieve this:
float *ptr { 0 };  // ptr is now a null pointer

or:

#include <cstddef> // for NULL
 
double *ptr { NULL }; // ptr is a null pointer
//
# getopt.h (getopt)
Example of its usage (obtained from https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html)

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (int argc, char **argv)
{
  int aflag = 0;
  int bflag = 0;
  char *cvalue = NULL;
  int index;
  int c;

  opterr = 0;

  while ((c = getopt (argc, argv, "abc:")) != -1)
    switch (c)
      {
      case 'a':
        aflag = 1;
        break;
      case 'b':
        bflag = 1;
        break;
      case 'c':
        cvalue = optarg;
        break;
      case '?':
        if (optopt == 'c')
          fprintf (stderr, "Option -%c requires an argument.\n", optopt);
        else if (isprint (optopt))
          fprintf (stderr, "Unknown option `-%c'.\n", optopt);
        else
          fprintf (stderr,
                   "Unknown option character `\\x%x'.\n",
                   optopt);
        return 1;
      default:
        abort ();
      }

  printf ("aflag = %d, bflag = %d, cvalue = %s\n",
          aflag, bflag, cvalue);

  for (index = optind; index < argc; index++)
    printf ("Non-option argument %s\n", argv[index]);
    
  return 0;
}

Example of its usage:
% testopt
aflag = 0, bflag = 0, cvalue = (null)

% testopt -a -b
aflag = 1, bflag = 1, cvalue = (null)

% testopt -ab
aflag = 1, bflag = 1, cvalue = (null)

% testopt -c foo
aflag = 0, bflag = 0, cvalue = foo

% testopt -cfoo
aflag = 0, bflag = 0, cvalue = foo

% testopt arg1
aflag = 0, bflag = 0, cvalue = (null)
Non-option argument arg1

% testopt -a arg1
aflag = 1, bflag = 0, cvalue = (null)
Non-option argument arg1

% testopt -c foo arg1
aflag = 0, bflag = 0, cvalue = foo
Non-option argument arg1

% testopt -a -- -b
aflag = 1, bflag = 0, cvalue = (null)
Non-option argument -b

% testopt -a -
aflag = 1, bflag = 0, cvalue = (null)
Non-option argument -
//
#Difference between Header file and Library

Header Files : The files that tell the compiler how to call some functionality (without knowing how the functionality actually works) 
are called header files. They contain the function prototypes. They also contain Data types and constants used with the libraries. 
We use #include to use these header files in programs. These files end with .h extension.
Library : Library is the place where the actual functionality is implemented i.e. they contain function body. 
Libraries have mainly two categories :

Static
Shared or Dynamic
Static : Static libraries contains object code linked with an end user application and then they 
become the part of the executable. These libraries are specifically used at compile time which means 
the library should be present in correct location when user wants to compile his/her C or C++ program. 
In windows they end with .lib extension and with .a for MacOS.

Shared or Dynamic : These libraries are only required at run-time i.e, user can compile his/her code 
without using these libraries. In short these libraries are linked against at compile time to resolve 
undefined references and then its distributed to the application so that application can load it at
run time. For example, when we open our game folders we can find many .dll(dynamic link libraries) 
files. As these libraries can be shared by multiple programs, they are also called as shared libraries.
These files end with .dll or .lib extensions. In windows they end with .dll extension.
//
#Good tutorial on how to create your namespace:
https://www.geeksforgeeks.org/namespace-in-c/
//
# What do 'statically linked' and 'dynamically linked' mean?
Usesful post in https://stackoverflow.com/questions/311882/what-do-statically-linked-and-dynamically-linked-mean
This contains:

There are (in most cases, discounting interpreted code) two stages in getting from source code (what you write) to executable code (what you run).

The first is compilation which turns source code into object modules.

The second, linking, is what combines object modules together to form an executable.

The distinction is made for, among other things, allowing third party libraries to be included in your
executable without you seeing their source code (such as libraries for database access, network 
communications and graphical user interfaces), or for compiling code in different languages
(C and assembly code for example) and then linking them all together.

When you statically link a file into an executable, the contents of that file are included at link time. In other words, the contents of the file are physically inserted into the executable that you will run.

When you link dynamically, a pointer to the file being linked in (the file name of the file, for example) is included in the executable and the contents of said file are not included at link time. It's only when you later run the executable that these dynamically linked files are bought in and they're only bought into the in-memory copy of the executable, not the one on disk.

It's basically a method of deferred linking. There's an even more deferred method (called late binding on some systems) that won't bring in the dynamically linked file until you actually try to call a function within it.

Statically-linked files are 'locked' to the executable at link time so they never change. A dynamically linked file referenced by an executable can change just by replacing the file on the disk.

This allows updates to functionality without having to re-link the code; the loader re-links every time you run it.

This is both good and bad - on one hand, it allows easier updates and bug fixes, on the other it can lead to programs ceasing to work if the updates are incompatible - this is sometimes responsible for the dreaded "DLL hell" that some people mention in that applications can be broken if you replace a dynamically linked library with one that's not compatible 
(developers who do this should expect to be hunted down and punished severely, by the way).
//
# Using boost::iostream and dinamically linking it:
 g++ -o something.o -lboost_iostreams main.cpp
//
#Using Boost to read a compressed (with gzip or gz or .gz) file and
#copy its contents to a new file

#include <fstream>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>

int main()
{
    std::string inf="/Users/ernesto/lib/CPP/test_boost_compression/in.txt";
    std::string outf="/Users/ernesto/lib/CPP/test_boost_compression/out.gz";
    std::ifstream inStream(inf, std::ios_base::in);
    std::ofstream outStream(outf, std::ios_base::out);
    boost::iostreams::filtering_streambuf< boost::iostreams::input> in;
    in.push( boost::iostreams::gzip_compressor());
    in.push( inStream );
    boost::iostreams::copy(in, outStream);
}

And the accompanying Cmake file:

cmake_minimum_required(VERSION 3.14)
project(test_boost_compression)

set(CMAKE_CXX_STANDARD 17)

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

find_package(Boost REQUIRED COMPONENTS iostreams)

if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS})
    add_executable(test_boost_compression main.cpp)
    target_link_libraries(test_boost_compression ${Boost_LIBRARIES})
endif()
//
# C++: Iterating lines in a GZ file using boost::iostreams

/**
 * myzcat.cpp
 * A zcat replacement, for educational purpose.
 * Uses boost::iostream and zlib.
 * 
 * Compile like this:
 *   clang++ -o myzcat myzcat.cpp -lz -lboost_iostreams
 * 
 * This code is published as public domain.
#include <fstream>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/filter/gzip.hpp>

int main(int argc, char** argv) {
    if(argc < 2) {
        std::cerr << "Usage: " << argv[0] << " <gzipped input file>" << std::endl;
    }
    //Read from the first command line argument, assume it's gzipped
    std::ifstream file(argv[1], std::ios_base::in | std::ios_base::binary);
    boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
    inbuf.push(boost::iostreams::gzip_decompressor());
    inbuf.push(file);
    //Convert streambuf to istream
    std::istream instream(&inbuf);
    //Iterate lines
    std::string line;
    while(std::getline(instream, line)) {
        std::cout << line << std::endl;
    }
    //Cleanup
    file.close();
}
////
// Adding a string to a compressed file
/*
Compile on Fedora 16 Linux:
g++ -O2 -Wall -g -o boostgz boostgz.cc -lboost_iostreams-mt
  */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>

using namespace std;

static int read_file(std::string& buf, const char *fn)
{
    ifstream file(fn, ios_base::in | ios_base::binary);
    boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
    in.push(boost::iostreams::gzip_decompressor());
    in.push(file);

    std::istream inf(&in);

    while (inf.good()) {
        char tmpbuf[8192];

        inf.read(tmpbuf, sizeof(tmpbuf));
        buf.append(tmpbuf, inf.gcount());
    }

    return 0;
}

static void add_data(std::string& buf, const char *data)
{
    buf += data;
    buf += "\n";
}

static void write_file(std::string& buf, const char *fn)
{
    ofstream file(fn, ios_base::out | ios_base::binary | ios_base::trunc);
    boost::iostreams::filtering_streambuf<boost::iostreams::output> out;
    out.push(boost::iostreams::gzip_compressor());
    out.push(file);

    std::ostream outf(&out);

    outf.write(buf.c_str(), buf.size());
}

int main(int argc, char *argv[])
{
    if (argc != 3) {
        fprintf(stderr, "usage: %s [string to add] [file.gz]\n",
                argv[0]);
        return 1;
    }

    const char *data = argv[1];
    const char *fn = argv[2];

    std::string buf;

    read_file(buf, fn);
    add_data(buf, data);
    write_file(buf, fn);

    return 0;
}
////////
Example extracted from https://www.geeksforgeeks.org/access-modifiers-in-c/
/
# Access Modifiers:
# Public:
// C++ program to demonstrate public 
// access modifier 
  
#include<iostream> 
using namespace std; 
  
// class definition 
class Circle 
{ 
    public:  
        double radius; 
          
        double  compute_area() 
        { 
            return 3.14*radius*radius; 
        } 
      
}; 
  
// main function 
int main() 
{ 
    Circle obj; 
      
    // accessing public datamember outside class 
    obj.radius = 5.5; 
      
    cout << "Radius is: " << obj.radius << "\n"; 
    cout << "Area is: " << obj.compute_area(); 
    return 0; 
} 

Output:

Radius is: 5.5
Area is: 94.985

#Private:
// C++ program to demonstrate private 
// access modifier 
  
#include<iostream> 
using namespace std; 
  
class Circle 
{    
    // private data member 
    private:  
        double radius; 
       
    // public member function     
    public:     
        double  compute_area() 
        {   // member function can access private  
            // data member radius 
            return 3.14*radius*radius; 
        } 
      
}; 
  
// main function 
int main() 
{    
    // creating object of the class 
    Circle obj; 
      
    // trying to access private data member 
    // directly outside the class 
    obj.radius = 1.5; 
      
    cout << "Area is:" << obj.compute_area(); 
    return 0; 
}

Output:

 In function 'int main()':
11:16: error: 'double Circle::radius' is private
         double radius;
                ^
31:9: error: within this context
     obj.radius = 1.5;
         ^
///////////////
# string manipulators:
Manipulators are functions specifically designed to be used in conjunction with the insertion
(<<) and extraction (>>) operators on stream objects, for example:
 
cout << boolalpha;
//
# Vector of structs initialization

struct subject {
    string name;
    int marks;
    int credits;
};


int main() {
    vector<subject> sub;

    //Push back new subject created with default constructor.
    sub.push_back(subject());

    //Vector now has 1 element @ index 0, so modify it.
    sub[0].name = "english";

    //Add a new element if you want another:
    sub.push_back(subject());

    //Modify its name and marks.
    sub[1].name = "math";
    sub[1].marks = 90;
}
//
# std::count()
# std::count() returns number of occurrences of an 
element in a given range. Returns the number of elements in the range [first,last)
that compare equal to val.
Read post at: https://www.geeksforgeeks.org/std-count-cpp-stl/
//
Example extracted from (https://www.geeksforgeeks.org/pair-in-cpp-stl/)

# Pair in C++ Standard Template Library (STL)
The pair container is a simple container defined in <utility> header consisting of two data elements or objects.

The first element is referenced as ‘first’ and the second element as ‘second’ and the order is fixed (first, second).
Pair is used to combine together two values which may be different in type. Pair provides a way to store two heterogeneous objects as a single unit.
Pair can be assigned, copied and compared. The array of objects allocated in a map or hash_map are of type ‘pair’ by default in which all the ‘first’ elements are unique keys associated with their ‘second’ value objects.
To access the elements, we use variable name followed by dot operator followed by the keyword first or second.

//CPP program to illustrate pair STL 
#include <iostream> 
#include <utility> 
using namespace std; 
  
int main() 
{ 
    pair <int, char> PAIR1 ; 
  
    PAIR1.first = 100; 
    PAIR1.second = 'G' ; 
  
    cout << PAIR1.first << " " ; 
    cout << PAIR1.second << endl ; 
  
    return 0; 
}
//
# conditional operator (a.k.a. ternary operator)
condition ? result_if_true : result_if_false

For example:
int qempty()
{
    return (f == r ? 1 : 0);
}

Which is the same than:
int qempty()
{ 
  if(f == r)
  {
      return 1;
  } 
  else 
  {
      return 0;
  }
}
//
# Templates
# Useful article from https://www.geeksforgeeks.org/templates-cpp/
//
# REGEX
// C++ program to demonstrate working of regex_match()
#include <iostream>
#include <regex>

using namespace std;
int main()
{
    string a = "GeeksForGeeks";

    // Here b is an object of regex (regular expression)
    regex b("(Geek)(.*)"); // Geeks followed by any character

    // regex_match function matches string a against regex b
    if ( regex_match(a, b) )
        cout << "String 'a' matches regular expression 'b' \n";
    
    return 0;
}
//
# reading in certain columns from a file
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;
int main()
{
    ifstream file("/Users/ernesto/CLionProjects/test_scripts/file.dat");
    string line;

    while (getline(file,line))
    {
        istringstream ss(line);

        // possibly you will want some other types here.
        string col2;
        string col4;

        ss >> col2;    // extracts 1st col.
        ss >> col2;    // extracts 2nd col.

        ss >> col4;    // extracts 3rd col.
        ss >> col4;    // extracts 4th col.

        // Now you can something with col2 and col4
        cout << col2 << " " << col4 << endl;

    }
    return 0;
}
//
// Another way of achieving the same (in more compact way)
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;
int main()
{
    ifstream file("/Users/ernesto/CLionProjects/test_scripts/file.dat");
    string line;

    while (std::getline(file, line)) {
        if (line.empty()) continue;     // skips empty lines
        std::istringstream is(line);    // construct temporary istringstream
        std::string col1, col2, col3;
        if (is >> col1 >> col2 >> col3) {
            std::cout << "column 1: " << col1 << " column 3: " << col3 << std::endl;
        }
        else {
            std::cout << "This line didn't meet the expected format." << std::endl;
        }
    }
    return 0;
}
//
// atoi is the old C function that receives a null-terminated char* pointer and 
// returns the int equivalent to the char representing an int. c_str() returns a null-
// terminated char* pointer from a string 

#include<stdlib.h>
string a = "10";
int b=atoi(a.c_str());
/
// In C++11, there is an alternative std::stoi() function that takes a std::string as an argument:
#include <iostream>
#include <string>

int main()
{
    std::string a = "10";
    int b = std::stoi(a);
    std::cout << b << "\n";
    return 0;
}
//
#example on how to use Getopt Long:
#include <iostream>
#include <getopt.h>
#include <stdlib.h>

using namespace std;

void printSummary(char** argv) {
    cerr << "usage: " << argv[0] << " [options] [file]" << endl
         << endl
         << "options:" << endl
         << "    -f, --reference REF     Use this reference when decomposing samples." << endl
         << "    -p, --prefix PREFIX     Affix this output prefix to each file, none by default" << endl
         << "    -P, --default-ploidy N  Set a default ploidy for samples which do not have information in the first record (2)." << endl
         << endl
         << "Outputs sample_seq:N.fa for each sample, reference sequence, and chromosomal copy N in [0,1... ploidy]." << endl
         << "Each sequence in the fasta file is named using the same pattern used for the file name, allowing them to be combined." << endl;
    //<< "Impossible regions of haplotypes are noted with an error message.  The corresponding" << endl
    //<< "regions of the output FASTA files will be marked as N." << endl
    exit(0);
}


int main(int argc, char** argv)
{

    string fastaFileName;
    int defaultPloidy;
    string outputPrefix;
    string nullAlleleString;

    int c;
    while (true) {
        static struct option long_options[] =
                {
                        /* These options set a flag. */
                        // required_argument means that if for example -f or --reference is passed
                        // then an argument is required: For example: --reference file.fa
                        {"help", no_argument, 0, 'h'},
                        {"reference", required_argument, 0, 'f'},
                        {"prefix", required_argument, 0, 'p'},
                        {"default-ploidy", required_argument, 0, 'P'},
                        {"no-call-string", required_argument, 0, 'n'},
                        {0, 0, 0, 0}
                };
        /* getopt_long stores the option index here. */
        int option_index = 0;

        c = getopt_long (argc, argv, "hmf:p:P:n:",
                         long_options, &option_index);

        // if user does not provide option than c will be -1
        if (c == -1)
            break;

        switch (c) {

            case 'f':
                fastaFileName = optarg;
                break;

            case 'h':
                printSummary(argv);
                break;

            case 'p':
                outputPrefix = optarg;
                break;

            case 'P':
                defaultPloidy = atoi(optarg);
                break;

            case 'n':
                nullAlleleString = optarg;
                break;
                
            // this option will be run when invalid option was selected    
            case '?':
                printSummary(argv);
                exit(1);
                break;

            default:
                abort ();
        }
    }

    return 0;
}
//
# Nested std::map example: Inserting and fetching values
# In this case, I created a map (string, map(int,int))

#include <iostream>
#include <map>

int main(int argc, char** argv)
{

    typedef std::map< int, int > Ints;
    typedef std::map< std::string, Ints > String2Ints;

    String2Ints example;
    std::string word="hello";
    example[word][1] = 2;

    String2Ints::iterator it = example.find( word );
    if( it != example.end() ) {
        Ints &innerMap = it->second;
        Ints::iterator innerit = innerMap.find( 1 );
        if( innerit != innerMap.end() )
            std::cout << "found value for word " << word << " 1 - " << innerit->second << std::endl;
    }

    return 0;
//
# default constructor for class
# thanks to default, we can instantiate
# an A object without arguments

class A
{
public:
    A(int a){};
    A() = default;
};


int main(int argc, char** argv)
{
    A a(2);
    A b;
    return 0;
}
//
# getter and setter
#include <iostream>

using namespace std;

class Movie{
    private:
        string rating;
    public:
        string title;
        string director;
        Movie(string atitle, string adirector, string arating)
        {
            title=atitle;
            director=adirector;
            rating=arating;
        }

        void setRating(string arating) {
            if (arating=="PG" || arating=="U")
            {
                rating=arating;
            }
        }

        string getRating() {
            return rating;
        }
};


int main(int argc, char** argv)
{

    Movie m("Star-Wars","George Lucas","U");

    //using getRating
    std::cout<< m.getRating() <<endl;

    //setting rating to invalid value, so rating is not changed
    m.setRating("invalid");
    std::cout<< m.getRating() <<endl;

    //setting rating to valid value, so rating is changed
    m.setRating("PG");
    std::cout<< m.getRating() <<endl;
    return 0;
}
//
# Calling a C function from within C++

You have a C file named somecode.c:

#include <stdio.h>

void foo()
{
  printf("I am foo written in C! How are you doing?");
}

We have the C header for this function:

#ifndef SOMECODE_H_
#define SOMECODE_H_

void foo();

#endif
/
#Then we have the C++ code:

extern "C" {
#include "somecode.h"
}

#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
  foo();
  return 0;
}
/
#Then we compile somecode.c and and othercode.cpp:
gcc -c -o somecode.o somecode.c

g++ -c -o othercode.o othercode.cpp

We link both together:
g++ -o yourprogram somecode.o othercode.o
//
#Passing arguments (args) to functions by value or by reference
/
#By value (a copy of argument is passed to function):
#include <iostream>

using namespace std;

void doubleNumber(int a)
{
    a*=2;
}

int main(int argc, char *argv[])
{
    int x=3;
    doubleNumber(x);
    std::cout<< "Value after function:"<< x << endl;
    return 0;
}
# The value of x is not modified inside function
So it returns 3
/
##By reference (The value of x is modified inside function):
#include <iostream>

using namespace std;

void doubleNumber(int& a)
{
    a*=2;
}

int main(int argc, char *argv[])
{
    int x=3;
    doubleNumber(x);
    std::cout<< "Value after function:"<< x << endl;
    return 0;
}
/
So it returns 6
//
// string::back (reference to the last character of the string)
#include <iostream>
#include <string>

int main ()
{
    std::string str ("hello world.");
    str.back() = '!';
    std::cout << str << '\n';
    return 0;
}
//
/ replace a bit of a string by empty string
#include <string>

int main ()
{
    std::string line="chr1\t110000\tkljlkjlj";
    line.replace(0,3,"");
    
    return 0;
}
 This will print out:
 1	110000	kljlkjlj