essay on programming languages, computer science, information techonlogies and all.

Sunday, March 10, 2019

C++ Pointer

Here you can refresh your memory about pointer.

Pointer and Reference

Pretty basic, Right ?

int a = 1234;
int *pa = &a;    // pa is pointer of a
*pa = 1111;      // assignment on *pa will change a also

int &ra = a;     // ra is reference of a
ra = 4321;       // assignment on ra will change a also

Function return value using reference or pointer

Which do you prefer ? * or & ?

int AddAndMultiply(int a, int b, int& mult)
{
  mult = a * b;
  return a + b;   
}

int AddAndMultiplyV3(int a, int b, int* mult)
{
  *mult = a * b;
  return a + b;
}

int mult = 0;
int sum = AddAndMultiply(1, 2, mult);
sum = AddAndMultiplyV3(1, 2, &mult);

Function return struct

I can read this easily. But isn't struct make code slow by copying memory ? Are you sure ?

struct AddMult
{
  int Add;
  int Mult;
};

AddMult AddAndMultiplyV3(int a, int b)
{
  AddMult r;
  r.Add = a + b;
  r.Mult = a * b;
  return r;
}

AddMult r = AddAndMultiplyV3(1, 2);
sum = r.Add;
mult = r.Mult;

const at before or after


const int* cpa = &a;
*cpa = 42;           // compile error : cpa is pointing a constant variable, so you can't change the value
cpa = &b;            // but you can make it points other variable

const int& cra = a;
cra = 42;            // compile error : cra is referencing a constant variable, so you can't change the value

int* const pca = &a; 
*pca = 42;           // no problem : pca is constantly pointing a variable, and you can change the value of variable.
*pca = &b;           // compile error : but pca can't pointing to other variable.

mutable can be changed on const method

Then what's the point of const if there is mutable ?

struct AddData
{
  int A, B;
  mutable int C = 0;  // ok to be changed on const method.

  int AddAll() const  // This isn't supposed to change member variable. 
  {
    if (C == 0) { C = A + B; }
    return C;
  }
};

Endianess

big-endian puts significant bytes at lower address, while little-endian puts significant bytes at higher address.

uint32_t *pa = new uint32_t[4];
pa[0] = 0x12345678;     // note the little-endian
pa[1] = 0x87654321;
pa[2] = 0x10101010;
pa[3] = 0xCAFEBEEF;

*pa = 0xFFFFFFFF;
*(pa + 1) = 0xEEEEEEEE;

delete[] pa;

64 bit ponter

Each pointer is 64bits.

Packing at struct

Do you know how variable is packed in a struct ?

struct Foo
{
  uint32_t a;     // 4 Bytes
  char b;         // 2 Bytes
  uint16_t c;     // 2 Bytes
  bool d;         // 4 Bytes
  const char * e; // 4 Bytes
};

Foo foo;
Foo* pfoo = &foo;
foo = { 0x12345678, 'a', 0xCAFE, true, nullptr };

Function pointer

This syntax of putting type name in between retrun type and argument type and *, (, ). Can you remember it ?

int TestBar(char a) {  return a + 42;  }
int TestToo(char a) {  return a + 22;  }

typedef int(*FooFn)(char);  // Here you go!

FooFn f = TestBar;
int ret = f('a');
f = TestToo;
ret = f('b');

STL function pointer

Or how about STL style ?

int TestBar(char a) {  return a + 42;  }
int TestToo(char a) {  return a + 22;  }

using FooFn = std::function< int(char) >;  // Here you go again !

FooFn fn = TestBar;
int ret = fn('a');
fn = TestToo;
ret = fn('b');

Wednesday, June 13, 2018

C++ thread

std::thread with static function


#include 

void called_from_static_fn( const std::string& arg )
{
  // ...
}

std::thread t1(called_from_static_fn, "static");
// ...
t1.join();

std::thread with member fn


class Foo
{
public:
	void Bar( const string& arg)
	{
		// ...
	}
};

Foo foo;
thread t1(&Foo::Bar, &foo, "member");
// ...
t1.join();

std::thread with lambda


int ret = 0;
thread t( [ &ret ](int m, int n) { ret = m + n; }, 2, 4 );
t.join();

std::thread in array


static int twice(int m) { return 2 * m; }

vector< thread > threads;
for (int i = 0; i < 10; ++i)
{
  threads.push_back( thread(twice, i));
}

for (auto& t : threads)
{
  t.join();
}

catch exception in a thread


static int DoNotTryAtHome()
{
  throw exception("I said NO");
}

thread t1(DoNotTryAtHomeNoThrow);
t1.join();

use mutex on shared variable


class Foo 
{
	int m_Bar = 0;
	mutex m_LockBar;
public:
	void AddBarSafe(int add)
	{
		lock_guard< mutex > guard(m_LockBar);
		int temp = m_Bar;
		this_thread::sleep_for(chrono::milliseconds(10));
		m_Bar = temp + add;
	}
};

{
	Foo foo;
	vector ts;
	ts.emplace_back(thread{ &Foo::AddBarSafe, &foo, 2 });
	ts.emplace_back(thread{ &Foo::AddBarSafe, &foo, 3 });
	ts.emplace_back(thread{ &Foo::AddBarSafe, &foo, 4 });

	for (auto& t : ts) {  t.join(); }
}

std::thread on class operator()


struct funcCount
{
	int &i;
	funcCount(int& i_) : i(i_) {}
	void operator()()
	{
		for (unsigned j = 0; j < 1000; ++j)
		{
			++i;
			this_thread::sleep_for(chrono::milliseconds(1));
		}
	}
};

{
	int some_local_state = 0;
	funcCount my_func(some_local_state);
	std::thread my_thread(my_func);
	// my_thread.detach();				// undefined behaviour
	my_thread.join();
}

thread_guard


class thread_guard
{
	std::thread& t;
public:
	explicit thread_guard(std::thread& t_) : t(t_) {}
	~thread_guard() 
	{ 
		if (t.joinable()) t.join(); 
	}

	thread_guard(thread_guard const&) = delete;
	thread_guard operator = (thread_guard const &) = delete;
};

void do_something_stupid()
{
	for (int i = 1; i < 10; ++i)
	{
		if (i % 5 == 0)
		{
			throw std::exception("ooops");
		}
	}
}

{
	int some_local_state = 0;
	try
	{
		funcCount my_func(some_local_state);
		std::thread t(my_func);
		thread_guard g(t);
		do_something_stupid();
	}
	catch (...)
	{
	}
}

move around thread


{
	std::thread t1(called_from_static_fn, "static");
	std::thread t2 = std::move(t1);
	t1 = std::thread(&TestMultiThread::called_from_member_fn, this, "static");
	std::thread t3;
	t3 = std::move(t2);
	// t1 = std::move(t3);   //  terminate

	t1.join();
	t3.join();
}

async


{
	future result(async(called_from_static_fn, "static"));
	result.get();
}

{
	Foo foo;
	future result(async(&Foo::Bar, &foo, "member"));
	result.get();
}

{
	future result(async([](int m, int n) { return m + n; }, 2, 4));
	int ret = result.get();
}

{
	vector< future< int > > futures;
	for (int i = 0; i < 10; ++i)
	{
		futures.push_back(async(twice, i));
	}

	for (auto& e : futures)
	{
		cout << e.get() << endl;
	}
}

async will throw exception at convenient time


{
	future result(async(DoNotTryAtHome));
		
	try
	{
		int ret = result.get();
	}
	catch (exception& ex)
	{
		printf("exception caught : %s", ex.what());
	}
}

wait for future


{
	future f = async( [](){ cout << "bar" << endl; } );
		
	if (f.wait_for(chrono::milliseconds(0)) == future_status::deferred)
	{
		cout << "foo and wait for bar" << endl;
		f.get();
	}
	else
	{
		while (f.wait_for(chrono::milliseconds(10)) != future_status::ready)
		{
			cout << "foo waiting ... " << endl;
		}

		cout << "foo" << endl;
	}
}

condition_variable


{
	mutex m_LockReadyProcess;
	condition_variable m_Condition;
	string m_Log;
	bool m_Ready = false;
	bool m_Processed = false;
}

void worker_thread()
{
	unique_lock lock(m_LockReadyProcess);
	m_Condition.wait(lock, [=]{return m_Ready; });

	cout << "Worker thread is processing data\n";
	m_Log += " after processing";

	m_Processed = true;
	cout << "Worker thread signals data processing completed\n";

	lock.unlock();
	m_Condition.notify_one();
}

{
	thread worker( &TestMultiThread::worker_thread, this);

	m_Log = "Example data";

	{
		lock_guard guard(m_LockReadyProcess);
		m_Ready = true;
		cout << "main() signals data ready for processing\n";
	}
	m_Condition.notify_one();

	{
		unique_lock lock(m_LockReadyProcess);
		m_Condition.wait(lock, [=]{return m_Processed; });
	}
	cout << "Back in main(), data = " << m_Log << '\n';

	worker.join();
}

Wednesday, June 6, 2018

Cryptography tutorial using Poco

Poco has crypto module and here is a tutorial of cryptography using Poco. Symmetric encryption is encrypt and decrypt using a key known by two player. Simple but hard to make key to be safe.

#include "Poco/Crypto/Cipher.h"
#include "Poco/Crypto/CipherKey.h"
#include "Poco/Crypto/CipherFactory.h"

auto& factory = CipherFactory::defaultFactory();
string transmission;

{
  Cipher* alice = factory.createCipher( CipherKey( 
    "aes-256-ecb", "open sesame"));
  transmission = alice->encryptString( 
    "Tall tree, Spy-glass shoulder, ... Skeleton Island ESE and by E");
}

{
  Cipher* bob = factory.createCipher( CipherKey( 
    "aes-256-ecb", "open sesame"));
  string decrypted = bob->decryptString(transmission);
  assert(decrypted == 
    "Tall tree, Spy-glass shoulder, ... Skeleton Island ESE and by E");
}
To remove this unsafe key, asymmetric encryption can be used. To do it, first priavate and public key should be generated. OpenSSL can be used like below.


>openssl.exe genrsa -des3 -out private_bob.pem 2048
Generating RSA private key, 2048 bit long modulus
...................+++
.................................................................+++
unable to write 'random state'
e is 65537 (0x10001)
Enter pass phrase for private_bob.pem:
Verifying - Enter pass phrase for private_bob.pem:


>openssl.exe rsa -in private_bob.pem -outform PEM -pubout -out public_bob.pem
Enter pass phrase for private_bob.pem:
writing RSA key

Then Alice can encode message using Bob's public key. Then only Bob can decode it using his private key.

#include "Poco/Crypto/RSAKey.h"
#include "Poco/Crypto/RSADigestEngine.h“

auto& factory = CipherFactory::defaultFactory();
string transmission;

{
  Cipher* alice = factory.createCipher(RSAKey( "public_bob.pem"));
  transmission = alice->encryptString(
    "Tall tree, Spy-glass shoulder, ... Skeleton Island ESE and by E");
}

{
  Cipher* bob = factory.createCipher(RSAKey( "", "private_bob.pem", "bobbob"));
  string decrypted = bob->decryptString(transmission);
  assert(decrypted == "Tall tree, Spy-glass shoulder, ... Skeleton Island ESE and by E");
}
The assymetric encryption can be extended to make contract between two players which is called digital signature.
Here, Alice can verify Bob's digital signature with the contract he promised.

// Poco::DigestEngine::Digest is std::vector 
tuple transmission;

{
  string contract = 
    "Alice will give Bob $100 and Bob will give Alice two magic mushrooms";
  RSADigestEngine bob(RSAKey("", "private_bob.pem", "bobbob"));
  bob.update(contract);
  transmission = make_tuple(contract, bob.signature());
}

{
  RSADigestEngine alice(RSAKey("public_bob.pem"));
  alice.update(get<0>(transmission));
  bool isValid = alice.verify(get<1>(transmission));
  assert(isValid == true);
}

Imagine, Alice get greedy and forged the contract, then Bob's signature doesn't work anymore.

// Poco::DigestEngine::Digest is std::vector 
tuple transmission;

{
  string contract = 
    "Alice will give Bob $100 and Bob will give Alice two magic mushrooms";
  RSADigestEngine bob(RSAKey("", "private_bob.pem", "bobbob"));
  bob.update(contract);
  transmission = make_tuple(contract, bob.signature());
}

{
  RSADigestEngine alice(RSAKey("public_bob.pem"));
  alice.update(
    "Alice will give Bob $100 and Bob will give Alice three magic mushrooms");
  bool isValid = alice.verify(get<1>(transmission));
  assert(isValid == false);
}
This digital signature can be extended further to digital coin. First chained transaction should be established. Here is a diagram from Satoshi Nakamoto's paper which shows the concept.

Here, Queen generate coin and give it to Alice; Queen use Alice's public key to generate transaction hash and sign the hash using majesty private key.

struct Transaction
{
  string Hash;
  vector Signature;
};

Transaction queenToAlice;
{
  // Queen
  RSAKey alicePublic("public_alice.pem");
  stringstream alicePublickey;
  alicePublic.save(&alicePublickey);

  Crypto::DigestEngine hasher("SHA256");
  hasher.update("Queen's own right to create coin");
  hasher.update(alicePublickey.str());
  string hash = Crypto::DigestEngine::digestToHex(
  hasher.digest());

  RSADigestEngine queen(RSAKey("", "private_queen.pem", "queenqueen"));
  queen.update(hash);

  queenToAlice = Transaction{ hash, queen.signature() };
}
Now, Alice can verify Queen's benevolence using Queen's public key.

{
  // Alice
  RSADigestEngine alice(RSAKey("public_queen.pem"));
  alice.update( queenToAlice.Hash );
  assert( true == alice.verify(queenToAlice.Signature));
}
Then Alice send the coin to Bob; Update the transaction 's hash with Bob's public key and sign it with Alice's private key.

Transaction aliceToBob;
{
  // Alice
  RSAKey bobPublic("public_bob.pem");
  stringstream bobPublickey;
  bobPublic.save(&bobPublickey);

  Crypto::DigestEngine hasher("SHA256");
  hasher.update(queenToAlice.Hash);
  hasher.update(queenToAlice.Signature.data(), 
  queenToAlice.Signature.size());
  hasher.update(bobPublickey.str());
  string hash = Crypto::DigestEngine::digestToHex(
  hasher.digest());

  RSADigestEngine alice(RSAKey("", 
    "private_alice.pem", "alicealice"));
  alice.update(hash);

  aliceToBob = Transaction{ hash, alice.signature() };
}
And Bob can verfiy Alice's coin given to himself.

{
  // Bob
  RSADigestEngine bob(RSAKey("public_alice.pem"));
  bob.update(aliceToBob.Hash);
  assert(true == bob.verify(aliceToBob.Signature));
}
The genuine idea of Bitcoin is BlockChain which verify the transaction in decentralized way. Here is another excerpt from the paper.
It says there should be proof-of-work ; which is basically finding a additional string - nounce - that make hash to start with number of '0' characters. Finding nounce is hard but verifying it is easy. Here is how to verify nounce.

struct Transaction {  string Hash, Signature; };

struct Block {
  string PrevHash, Nounce;
  vector Transactions;
};

Block t0 = {
  "Hello, world!", "4250",  { Transaction{ "", "" } }
};


// verfiy t0 block's transactions and proof-of-work
hasher.update(t0.PrevHash);
for (auto tx : t0.Transactions) {
  hasher.update(tx.Hash); hasher.update(tx.Signature);
}
hasher.update(t0.Nounce);

t1.PrevHash = Crypto::DigestEngine::digestToHex(hasher.digest());
assert(t1.PrevHash.substr(0, 4) == "0000");
Here is a way to finding nounce by brute-force.

// gather transactions
t1.Transactions = { 
  Transaction{ "ab", "cd" }, 
  Transaction{ "12", "34" }, 
  Transaction{ "56", "78" } };

// race for the nounce
for (int nounce = 0;; ++nounce)
{
  hasher.reset();
  hasher.update(t1.PrevHash);
  for (auto tx : t1.Transactions) {
    hasher.update(tx.Hash); hasher.update(tx.Signature);
  }
  hasher.update(to_string(nounce));

  string hash = Crypto::DigestEngine::digestToHex(hasher.digest());
  if (hash.substr(0, 4) == "0000") {
    t1.Nounce = to_string(nounce);
    break;
  }
}

// broadcast t1 block to world 

Saturday, May 19, 2018

Using .NET assembly in C++ via COM Interoperability

.NET assembly can be exposed as COM and C++ import it using ATL COM interface. Data should be marshalled to / from .NET Here is a IFoo declared using C# and its usage in C++ using ATL COM.

namespace MyCompany.Lib
{
    [ComVisible(true)]
    [Guid("71D1B3CD-3CE8-46B8-BF36-329543717F03")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IFoo
    {
        int Bar(int arg);
    }

    [ComVisible(true)]
    [Guid("6F1C4CFC-4BBF-46A1-A9DD-98A4D83691D1")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("MyCompany.Lib.Foo")]
    public class Foo : IFoo
    {
        public int Bar(int arg)
        {
            return 42 + arg;
        }
    }
}

#include < atlbase.h >
#include < atlcom.h >
#include < atlstr.h >

#import "...\MyCompany.Lib.tlb" named_guids

{
  using namespace MyCompany_Lib;
  IFooPtr foo(__uuidof(Foo));
  long ret = foo->Bar(42);
  assert(ret == 84);
}
In C++ project, there will be tlb which has GUID of IFoo and Foo class.

namespace MyCompany.Lib {

struct __declspec(uuid("71d1b3cd-3ce8-46b8-bf36-329543717f03")) IFoo;

_COM_SMARTPTR_TYPEDEF(IFoo, __uuidof(IFoo));

struct __declspec(uuid("71d1b3cd-3ce8-46b8-bf36-329543717f03"))
IFoo : IDispatch
{
    long Bar (long arg );

    virtual HRESULT __stdcall raw_Bar ( long arg, long * pRetVal ) = 0;
}

struct __declspec(uuid("6f1c4cfc-4bbf-46a1-a9dd-98a4d83691d1")) Foo;

#include "...\MyCompany.Lib.tli"

And tli file that has helper method that deals with COM boundary - HRESULT and exception handling.

inline long IFoo::Bar ( long arg ) {
    long _result = 0;
    HRESULT _hr = raw_Bar(arg, &_result);
    if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
    return _result;
}
Note that C# project should register the .NET assembly. Or tlbimp.exe should be used. Also before deloy the .NET assembly, it should be signed so that it can be registerd and exposed to COM framework of Windows.
At C#, there can be numer of different ComInterfaceType which are mapped to different interface.

...
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFoo
{
...

...
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IFoo
{
...

...
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IFoo
...


class IUnknown {
  virtual HRESULT QueryInterface( REFIID riid, __RPC_FAR *ppvObject) = 0;
  virtual ULONG AddRef( void) = 0;
  virtual ULONG Release( void) = 0;
}

class IDispatch : public IUnknown {
  virtual HRESULT GetTypeInfoCount(UINT *pctinfo) = 0;        
  virtual HRESULT GetTypeInfo( ...) = 0;
  virtual HRESULT GetIDsOfNames( ... ) = 0;
  virtual HRESULT Invoke( ... ) = 0;
} 


// tlb
IFoo : IUnknown
{

IFoo : IDispatch
{

IFoo : IDispatch
{

There is ClassInterfaceType. 'AutoDual' add interface method of C# Object class.

[ClassInterface(ClassInterfaceType.None)]
public class Foo : IFoo
{
...


[ClassInterface(ClassInterfaceType.AutoDual)]
public class ProgressBase
{


// tlb

struct __declspec(uuid("6f1c4cfc-4bbf-46a1-a9dd-98a4d83691d1"))
Foo;



struct __declspec(uuid("97754ee6-048b-3d1d-a477-deb25d4bc983"))
_ProgressBase : IDispatch
{
    __declspec(property(get=GetToString))
    _bstr_t ToString;

    _bstr_t GetToString ( );
    VARIANT_BOOL Equals ( const _variant_t & obj );
    long GetHashCode ( );
    _TypePtr GetType ( );

...

Property of C# can be access using Getxxx(), Putxxx(). Or it can be directly accessed like member variable.


    public interface IFoo
    {
        int Koo { get; set; }
    }

    public class Foo : IFoo
    {
        public int Koo
        {
            get;
            set;
        }
    }


IFooPtr foo(__uuidof(Foo));

foo->PutKoo(42);
ret = foo->GetKoo();
assert(ret == 42);

foo->Koo = 11;
assert(foo->Koo == 11);
ret = foo->GetKoo();
assert(ret == 11);
C# Exception will cause HRESULT to be retured as FAIL and will be rethrown as com_error at tli code.

    public class Foo : IFoo
    {
        public int Bar(int arg)
        {
            if( arg != 42 )
            {
                throw new ArgumentException(
                   "Only 42 allowed");
            }

            return 42 + arg;
        }
    }

IFooPtr foo(__uuidof(Foo));

try
{
  ret = foo->Bar(43);
}
catch (_com_error& ex)
{
  cout << ex.Source() << " ," << ex.Description() << endl;
}


> MyCompany.Lib , Only 42 allowed
ProgId can be declared and used instead of GUID to locate specific COM object.

namespace MyCompany.Lib
{
    [ComVisible(true)]
    [Guid("71D1B3CD-3CE8-46B8-BF36-329543717F03")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IFoo
    {
        int Bar(int arg);
    }

    [ComVisible(true)]
    [Guid("6F1C4CFC-4BBF-46A1-A9DD-98A4D83691D1")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("MyCompany.Lib.Foo")]
    public class Foo : IFoo
    {
        public int Bar(int arg)
        {
            return 42 + arg;
        }
    }
}

IFooPtr foo = IFooPtr(L"MyCompany.Lib.Foo");
ret = foo->Bar(42);
assert(ret == 84);

Copy data between C# and C++, marshalling should handled. In here, C++ call CreateImage with image pointer. Then C# marshall the image data to .NET space and then wrap it up to another interface and return it to C++ like a handle.

[ComVisible(true)]
[Guid("6A56D671-70DA-481A-AA9C-080B97D016D6")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IImage
{
    byte[] Data { get; }
    int Width { get; }
    int Height { get; }
    byte GetPixel(int x, int y);
}

internal class ImageBase : IImage
{
    public byte[] Data { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public byte GetPixel(int x, int y)
    {
        return Data[y * Width + x];
    }
}

[ComVisible(true)]
[Guid("9B5F50F0-66AB-40E1-8150-3E3688D297A7")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IImageFactory
{
    IImage CreateImage(
      IntPtr data, int width, int height);
}


[ComVisible(true)]
[Guid("9B5F50F0-66AB-40E1-8150-3E3688D297A7")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IImageFactory
{
    IImage CreateImage(
      IntPtr data, int width, int height);
}

[ComVisible(true)]
[Guid("8F5BB630-4736-4099-8F93-B23AFDC2AF2D")]
[ClassInterface(ClassInterfaceType.None)]
public class ImageFactory : IImageFactory
{
     public IImage CreateImage(
        IntPtr data, int width, int height )
     {
        int size = width * height;
        byte[] managedData = new byte[size];
        Marshal.Copy(data, managedData, 0, size);
        return new ImageBase { 
           Data = managedData, 
           Width = width, 
           Height = height 
        };
    }
}


vector m(320 * 240, 0);
m[24 + 42 * 320] = 0x42;

IImageFactoryPtr fab(__uuidof(ImageFactory));
IImagePtr image = fab->CreateImage_2( 
   (LONG)m.data(), 320, 240);

uint8_t pixelValue = image->GetPixel(24, 42);
assert(pixelValue == 0x42);
C# enum go through barrier by tli which declare C++ enum - weak type - with a unique underscored name.

[ComVisible(true)]
[Guid("DD6EF614-CA16-43C1-9FD8-CBA386FD43C1")]
public enum AlgorithmTarget
{
    General = 0,
    Scratch = 1,
    Brightness = 2,
    Focus = 3,
}

[ComVisible(true)]
[Guid("FDE54767-12B4-4084-8868-F0033CE9ABD5")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAlgorithm
{
    AlgorithmTarget Target { get; }
}

[ComVisible(true)]
[Guid("24A6E633-5911-4948-866A-CAF357D22BE2")]
[ClassInterface(ClassInterfaceType.None)]
public class ThresholdAlgorithm : IAlgorithm
{
    public AlgorithmTarget Target {
        get {
            return AlgorithmTarget.Brightness;
        }
    }
}


// tlb
enum __declspec(uuid("dd6ef614-ca16-43c1-9fd8-cba386fd43c1"))
AlgorithmTarget
{
    AlgorithmTarget_General = 0,
    AlgorithmTarget_Scratch = 1,
    AlgorithmTarget_Brightness = 2,
    AlgorithmTarget_Focus = 3
};


// cpp
IAlgorithmPtr algo(__uuidof(ThresholdAlgorithm));
assert(algo->Target == AlgorithmTarget_Brightness);
C# Struct maps to C++ struct by tlb. Note 'int' is changed to 'long'.

[ComVisible(true)]
[Guid("2672A17B-0D1A-4C8C-9922-D7E78A746D8E")]
public struct Defect
{
    public int X;
    public int Y;
    public int Area;
}

...
public interface IAlgorithm
{
    int GetDefectCount();
    void FillDefect(int index, ref Defect d);
    Defect GetDefect(int index);
}

...
public class ThresholdAlgorithm : IAlgorithm
{
    public int GetDefectCount() { return 2; }
    public Defect GetDefect(int index)
    {
        return new Defect { X = 3, Y = 2, Area = 1 };
    }
    public void FillDefect(int index, ref Defect d)
    {
        d.X = 1;
        d.Y = 2;
        d.Area = 3;
    }
}


// tlb
#pragma pack(push, 4)
struct __declspec
(uuid("2672a17b-0d1a-4c8c-9922-d7e78a746d8e"))
Defect
{
    long x;
    long y;
    long Area;
};



IAlgorithmPtr algo(__uuidof(ThresholdAlgorithm));
assert(algo->GetDefectCount() == 2);

Defect d = algo->GetDefect(0);
assert(d.x == 3);
assert(d.y == 2);
assert(d.Area == 1);

algo->FillDefect(0, &d);
assert(d.x == 1);
assert(d.y == 2);
assert(d.Area == 3);
IEnumerable is mapped to IEnumVARIANTPtr. C++ part can be bit strong to swallow though.

...
public interface IAlgorithm
{
    void SetImage(int index, IImage image);

    [ComVisible(false)]
    IEnumerable Images { get; }

    System.Collections.IEnumerator GetImageEnumerator();
}

...
public class ThresholdAlgorithm : IAlgorithm
{
    IDictionary IndexedImages = 
       new Dictionary();

    public void SetImage(int index, IImage image)
    {
        if( IndexedImages.ContainsKey(index)) {
            IndexedImages[index] = image;
        } else {
            IndexedImages.Add(index, image);
        }
    }

    public IEnumerable Images { 
        get { return IndexedImages.Values; }
    }

    public IEnumerator GetImageEnumerator() {
        return IndexedImages.Values.GetEnumerator();
    }


IAlgorithmPtr algo(__uuidof(ThresholdAlgorithm));

IImageFactoryPtr fab(__uuidof(ImageFactory));
algo->SetImage(0, fab->CreateImage_3(320, 240, 8, 42));
algo->SetImage(1, fab->CreateImage_3(64, 128, 8, 255));

IEnumVARIANTPtr I = algo->GetImageEnumerator();
for (;;)
{
    _variant_t v;
    ULONG count = 0;
    if (FAILED(I->Next(1, &v, &count)) || count != 1)
        break;

    IImagePtr image(v.punkVal);
    uint8_t pixelValue = image->GetPixel(0, 0);
    if (image->Width == 320) {
        assert(pixelValue == 42);
    } else {
        assert(pixelValue == 255);
    }
}
Callback can be tricky. Here is example code that can log using ATL IDispEventImpl

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("A7673505-60FA-4DDA-91D8-A2CB609C19A1")]
public interface IProgress
{
    [DispId(1)] void Info(string msg);

    [DispId(2)] void Warn(string msg);
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComSourceInterfaces(typeof(IProgress))]
[Guid("3F8748C9-659D-4012-9467-CD49BCD39516")]
public class ProgressBase
{
    [ComVisible(false)]
    public delegate void LogFn(string msg);

    public event LogFn Info;
    public event LogFn Warn;

    protected void FireInfo(string msg)
    {
        if (Info == null) return;
        Info(msg);
    }

    protected void FireWarn(string msg)
    {
        if (Warn == null) return;
        Warn(msg);
    }
}

...
public interface IAlgorithm
{
    void Run(string arg);
}

...
public class ThresholdAlgorithm : 
  ProgressBase, IAlgorithm
{
  public void Run(string arg)
  {   
    if( arg == "bar")
    {
      FireWarn(
        "Warning:This algo does work well with bar");
    }

    FireInfo( string.Format(
      "Starting Algorithm with {0}", arg ));

...
            
    FireInfo( string.Format( 
      "Stopped Algorithm with {0}", arg ));
  }
}


#import 
  "C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb" 
  named_guids no_namespace rename("_Module", "_NETModule")

#import "...\MyCompany.Lib.tlb" named_guids

_ATL_FUNC_INFO LogFnInfo = 
  { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };

class LogSink : public IDispEventImpl< 
  1, LogSink, &MyCompany_Lib::DIID_IProgress>
{
public:
  BEGIN_SINK_MAP(LogSink)
    SINK_ENTRY_INFO(1, MyCompany_Lib::DIID_IProgress, 
      1, OnInfo, &LogFnInfo)
    SINK_ENTRY_INFO(1, MyCompany_Lib::DIID_IProgress, 
      2, OnWarn, &LogFnInfo)
  END_SINK_MAP()

  LogSink(MyCompany_Lib::_ProgressBase* pbase)
  {
    m_ProgressBase = pbase;
    m_ProgressBase->AddRef();
    DispEventAdvise(m_ProgressBase);
  }

  ~LogSink()
  {
    m_ProgressBase->Release();
    DispEventUnadvise(m_ProgressBase);
   }

  void __stdcall OnInfo(BSTR msg)
  {
    _bstr_t bmsg(msg,false);
    cout << "Info : " << bmsg << endl;
   }

  void __stdcall OnWarn(BSTR msg)
  {
    _bstr_t bmsg(msg, false);
    cout << "Warn : " << bmsg << endl;
  }

private:
  MyCompany_Lib::_ProgressBase* m_ProgressBase;
};

using namespace MyCompany_Lib;
IAlgorithmPtr algo(__uuidof(ThresholdAlgorithm));
LogSink logger((_ProgressBase*)(IAlgorithm *)algo);

algo->Run(_bstr_t("foo"));
algo->Run(_bstr_t("bar"));


Info : Starting Algorithm with foo
Info : Stopped Algorithm with foo
Warn : Warning : This algo does work well with bar
Info : Starting Algorithm with bar
Info : Stopped Algorithm with bar

Thursday, May 10, 2018

C++/CLI to expose C++ code to C#

Define interface with C#. And also base class if needed.

    // IFoo.cs
    public interface IFoo
    {
        string Bar(int arg1, string arg2);
    }

    // FooBase.cs 
    public abstract class FooBase : IFoo
    {
        public virtual string Bar(int arg1, string arg2)
        {
            return arg1.ToString() + arg2;
        }
    }
Now C++/CLI code. First make Native C++ class - NativeFoo - that suit whatever need. Then define managed class Foo that sit between C++ and C# code. Note how the Foo::Bar() convert C# String to C++ std::string and vice versa.

// Foo.hpp
#include 

class NativeFoo
{
public:
	std::string Bar(int arg1, const std::string& arg2)
	{
		return arg2 + std::to_string(arg1);
	}
};

public ref class Foo : public FooBase
{
private:
	NativeFoo* m_Native;

public:
	Foo() 
		: m_Native( new NativeFoo )  
	{}

	~Foo()  
	{
		delete m_Native;
	}

	String^ Bar(int arg1, String^ arg2) override
	{
		std::string sarg2 = msclr::interop::marshal_as< std::string >(arg2);
		std::string bared = m_Native->Bar(arg1, sarg2);
		String^ ret = msclr::interop::marshal_as< String^ >(bared);
		return ret;
	}
};
Then the managed Foo can be created and Bar() can be used like any C# class.

  IFoo f = new Foo();
  string ret = f.Bar(42, "The answer is ");


Now callback from C++ to C#. First define callback in C# using delegate - OnFooFn.

    public delegate void OnFooFn(IFoo foo, string msg);

    public interface IFoo
    {
        OnFooFn OnFoo
        {
            get;
            set;
        }
    }
Then FooBase has a helper to call callback - FireOnFoo()

    public abstract class FooBase : IFoo
    {
...
        public OnFooFn OnFoo { get; set; }

        public void FireOnFoo( string msg)
        {
            if (OnFoo != null)
            {
                OnFoo( this, msg);
            }
        }
    }
Now native C++ class has a callback fn that will callback whatever call Bar().

class NativeFoo
{
public:
	std::string Bar(int arg1, const std::string& arg2)
	{
		m_FooFn("What is the question ?");
		return arg2 + std::to_string(arg1);
	}

	using CallbackFooFn = std::function< void(std::string) >;
	void SetCallbackFoo(CallbackFooFn fn) { m_FooFn = fn; }

private:
	CallbackFooFn m_FooFn = [](const std::string& arg) {};  // default dummy callback
};
Managed class can't set the above callback directly. It needs a bridge - CallbackBridgeFoo. Using this class, the C++ callback can be made through C#.

class CallbackBridgeFoo
{
private:
	NativeFoo* m_Native;
	gcroot< FooBase^ > m_CLR;  // FooBase has FireOnFoo()

public:
	CallbackBridgeFoo(NativeFoo* native, FooBase^ clr)
	{
		m_Native = native;
		m_CLR = clr;

		m_Native->SetCallbackFoo([this](const std::string& msg)
		{
			String^ smsg = msclr::interop::marshal_as< String^ >(msg);
			this->m_CLR->FireOnFoo(smsg);
		});
	}
};

public ref class Foo : public FooBase
{
private:
	NativeFoo* m_Native;
	CallbackBridgeFoo* m_Bridge;

public:
	Foo() 
		: m_Native( new NativeFoo )  
	{
		m_Bridge = new CallbackBridgeFoo(m_Native, this);
	}

	~Foo()  
	{
		delete m_Bridge;
		delete m_Native;
	}
...
};

Finally, C# can enjoy the C++ callback.

            IFoo f = new Foo();
            f.OnFoo = (sender, msg) => { Console.WriteLine(msg); }; 
            string ret = f.Bar(42, "The answer is ");   

Thursday, April 19, 2018

C++ template tutorial with code example

Parameterized Type


template < typename T >
class Vector 
{
private:
  T* elem;
  int sz;

public:
  explicit Vector(int s) 
  {
    elem = new T[s];
    sz = s;
  }

  T& operator[](int i) 
  {
    if (i < 0 || i >= size()) throw out_of_range("[i] is out of bound");
    return elem[i]; 
  }
};

{
  Vector< int > vi(200);
  vi[0] = 123;
  assert(vi[0] == 123);
}

{
  Vector< string > vs(17);
  vs[3] = "Hello";
  assert(vs[3] == "Hello");
}

{
  Vector< vector < int > > vli(45);
  vli[4] = vector({ 1, 2, 3 });
  assert(vli[4][1] == 2);
}

Function Template


template< typename T >
class Vector {
  // ...

  T* begin() const { return size() ? elem : nullptr; }
  T* end() const { return begin() + size(); }
};

template< typename Container, typename Value >
Value sum(const Container& c, Value v)
{
  for (auto x : c) v += x;
  return v;
}

{
  Vector< int > vi(4);
  vi[0] = 0; vi[1] = 1; vi[2] = 2; vi[3] = 3;
  double ds = sum(vi, 0.0);  // summation to double
  assert(ds == 6.0);

  int is = sum(vi, 0);  // summation to int
  assert(is == 6);
}

{
  list< double > ld;
  ld.push_back(3.0); ld.push_back(4.0);

  double ds = sum(ld, 0.0);
  assert(ds == 7.0);
}

Function Object


class Shape 
{
public:
  virtual void draw() = 0;
  virtual void rotate( double degree ) = 0;
};

class Rect : public Shape 
{
public:
  void draw() { cout << "rect"; }
  void rotate(double degree) { cout << "rotate"; }
};

class Circle : public Shape 
{
public:
  void draw() { cout << "circle"; }
  void rotate(double degree) {}
};

template< typename C, typename Oper >
void for_all(C& c, Oper op)
{
  for (auto& x : c) op(x);
}

vector< unique_ptr< Shape > > v;
v.push_back(make_unique< Rect >());
v.push_back(make_unique< Circle >());

for_all(v, [](unique_ptr< Shape >& s){ s->draw(); });
for_all(v, [](unique_ptr< Shape >& s){ s->rotate(45); });

Variadic Templates


void foo() { cout << endl; }

template< typename T >
void bar(T x) { cout << x << " "; }

template < typename T, typename ...Tail >
void foo(T head, Tail... tail) 
{
  bar(head);
  foo(tail...);
}

foo(1, 2, 2, "Hello");
foo(0.2, 'c', "World!", 0, 1, 2);

Function Specialization


template < class T>
T MyMax(T a, T b) 
{  
  return a > b ? a : b; 
}

template < >
const char* MyMax(const char* a, const char* b)
{
  return strlen(a) > strlen(b) ? a : b;
}


assert(MyMax(1, 2) == 2);
assert(MyMax("Morning", "Afternoon") == "Afternoon");

Function Specialization - Example


struct IO {
  int addr; 
  bool state;
};

struct Servo {
  int axis;
  double position;
};

struct Verify {
  template< typename T >
  static void Equal( T arg ) { throw exception("Should specialize"); }

  static void Equal(IO io) {
    cout << "check addr " << io.addr << " to be " << io.state << endl;
  }

  static void Equal(Servo s) {
    cout << "check axis " << s.axis << " position is at " << s.position << endl;
  }
};

Verify::Equal(IO{ 41, true });
Verify::Equal(Servo{ 3, 3.141592 });

Template Class Specialization - CompileTimeAssert


template< bool > struct CompileTimeAssert;
template< > struct CompileTimeAssert< true > {};

// CompileTimeAssert< sizeof(uint32_t) == 2  >();
CompileTimeAssert< sizeof(uint32_t) == 4 >();

// CompileTimeAssert< std::is_base_of::value >();
CompileTimeAssert< std::is_base_of::value >();

static_assert(std::is_base_of< Shape, Rect >::value, “Rect is a Shape");

Template Class Specialization - TypeTrait


template< typename T >
  struct IsVoid {
  static const bool value = false;
};

template< >
  struct IsVoid< void >{
  static const bool value = true;
};

template< typename T >
  struct IsPointer{
  static const bool value = false;
};

template< typename T >
  struct IsPointer< T* >{
  static const bool value = true;
};

CompileTimeAssert< IsVoid< void >::value >();
// CompileTimeAssert< IsVoid< int >::value >();

CompileTimeAssert< IsPointer< Shape* >::value >();
// CompileTimeAssert< IsPointer< Shape >::value >();

static_assert( is_pointer< Shape* >::value, "Shape* should be a pointer");

smart pointer to release resource automatically


class FILEReleasePolicy
{
public:
 static void release(FILE* fp) { fclose(fp); }
};

using FILEPtr = Poco::SharedPtr;
{
  FILEPtr fp = fopen("temp.txt", "wt");
  fprintf(fp, "hello world");
}

Sunday, April 1, 2018

C++11,14 tutorial with code example

Initializer with default constructor

 struct Foo {
  int Bar; string Too;
 };

 Foo a = { 1234, "Hello" };
 // Foo b( 1234, "Hello" );   // compile error

 vector c = {
  { 1234, "Hello" },
  { 4321, "World" },
  { 1111, "Good Morning" }
 };
When defined a constructor, the default constructor can't be used.

 struct Foo {
  int Bar; string Too;
  Foo(int bar) : Bar(bar) {}
 };

 // Foo a = { 1234, "Hello" };   // compile error
 Foo b{ 1234 };   
 Foo c(1234);
std::initializer usage

 struct Foo {
  int sum(const std::initializer_list< int >& list) {
   int total = 0;
   for (auto& e : list) {
    total += e;
   }
   return total;
  }
 };
 Foo foo;

 auto list = { 1, 2, 3 };
 assert(foo.sum(list) == 6);
 assert(foo.sum({ 1, 2, 3 }) == 6);
 assert(foo.sum({}) == 0);
lvalue and rvalue

 int a = 42;
 int b = 43;

 // a and b are both l-values:
 a = b; // ok
 b = a; // ok
 a = a * b; // ok

 // a * b is an rvalue:
 int c = a * b; // ok, rvalue on right hand side of assignment
 // a * b = 42; // error C2106: '=' : left operand must be l-value
Function return is rvalue but can be lvalue if reference returned.

 int someValue = { 1212 };
 int& foo() { return someValue; }
 int foobar() { return someValue; }

 // lvalues:
 int i = 42;
 i = 43; // ok, i is an lvalue
 int* p = &i; // ok, i is an lvalue
 foo() = 42; // ok, foo() is an lvalue
 int* p1 = &foo(); // ok, foo() is an lvalue

 // rvalues:
 int j = 0;
 j = foobar(); // ok, foobar() is an rvalue
//  int* p2 = &foobar(); // error C2102: '&' requires l-value
 j = 1234; // ok, 42 is an rvalue
Resolving function when argument is reference and universal reference.

 struct FooA { int X = 1234; };
 FooA RunFooA(const FooA& a) { FooA temp = a; temp.X = 4321; return temp; }
 FooA RunFooA(FooA&& a) { a.X = 4321; return a; }


 FooA a;
 FooA b = RunFooA(a);
 FooA c = RunFooA(FooA());
 FooA d = RunFooA(std::move(a));
transfer ownership of std::unique_ptr using std::move

 std::unique_ptr p1{ new int };
// std::unique_ptr p2 = p1; // error -- cannot copy unique pointers
 std::unique_ptr p3 = std::move(p1); // move `p1` into `p2`
       // now unsafe to dereference object held by `p1`
auto type resolution

 auto a = 3.14; // double
 auto b = 1; // int
 auto& c = b; // int&
 auto d = { 0 }; // std::initializer_list
 auto&& e = 1; // int&&
 auto&& f = b; // int&
 auto g = new auto(123); // int*
 delete g;
 const auto h = 1; // const int
 auto i = 1, j = 2, k = 3; // int, int, int
 // auto l = 1, m = true, n = 1.61; // error -- `l` deduced to be int, `m` is bool
 // auto o; // error -- `o` requires initializer
no more typing iterator type

 std::vector v = { 1, 2, 3, 4 };
 std::vector::const_iterator cit1 = v.cbegin();
 auto cit2 = v.cbegin();
auto return type using decltype

 template 
 auto AddAnyTwo(X x, Y y) -> decltype(x + y) {
  return x + y;
 }


 assert(AddAnyTwo(1, 2) == 3);
 assert(AddAnyTwo(1, 2.0) == 3.0);
 assert(AddAnyTwo(1.5, 1.5) == 3.0);
lambda

 int LBar = 1;

 auto getLBar = [=]{ return LBar; };
 assert(getLBar() == 1);

 auto addLBar = [=](int y) { return LBar + y; };
 assert(addLBar(1) == 2);

 auto getLBarRef = [&]() -> int& { return LBar; };
 getLBarRef() = 2;
 assert(LBar == 2);
lambda capture - reference or not

 int x = 1;
 auto f1 = [&x] { x = 2; }; // OK: x is a reference and modifies the original
 f1();

 // auto f2 = [x] { x = 2; }; // ERROR: the lambda can only perform const-operations on the captured value
 auto f3 = [x]() mutable { x = 2; }; // OK: the lambda can perform any operations on the captured value
 f3();
using as alias

 template  using Vec = std::vector;

 Vec v{}; // std::vector

 using String = std::string;
 String s{ "foo" };
nullptr

 struct Foo
 {
  void Bar(int) {}
  void Bar(char*) {}
 };

 Foo foo;
 foo.Bar(NULL);  // should throw error but not with VS2013
 foo.Bar(nullptr);
unspecified enum is just a number

 enum Week { Monday = 0, Tuesday, Thursday };
 enum Month { January = 0, Feburary,  };

 Month m = January;

 if (m == Monday)
 {
  // danger !!!
  m = Feburary;
 }

// Specifying underlying type as `unsigned int`
 enum class Color : unsigned int { Red = 0xff0000, Green = 0xff00, Blue = 0xff };
  
 // `Red`/`Green` in `Alert` don't conflict with `Color`
 enum class Alert : bool { Red = false, Green };
  
 Color redColor = Color::Red;
 Alert redAlert = Alert::Red;

 // bool isSame = (redColor == redAlert); 
 // error C2678: binary '==' : no operator found which takes a left-hand operand of type 'CPPTest::testStrongTypedEnum::Color' 
 // (or there is no acceptable conversion)

delegating constructor

 struct Foo {
  int foo;
  Foo(int foo) : foo(foo) {}
  Foo() : Foo(1) {}
 };

 Foo foo{};
 assert( foo.foo == 1 );
be more explicit on function overriding

 struct A {
  virtual void foo() {}
  void bar() {}
 };

 struct B : A {
  void foo() override {};  // correct -- B::foo overrides A::foo
  // void bar() override {}; // error C3668 : 'CPPTest::testOverrides::B::bar' : method with override specifier 'override' did not override any base class methods
  // void baz() override {}; // error C3668 : 'CPPTest::testOverrides::B::baz' : method with override specifier 'override' did not override any base class methods
 };
say final to stop overriding

 struct A {
  virtual void foo() {}
 };

 struct B : A {
  virtual void foo() final {}
 };

 struct C : B {
  // virtual void foo() {} // error C3248: 'CPPTest::testFinal::B::foo': function declared as 'final' cannot be overridden by 'CPPTest::testFinal::C::foo'
 };
say final to stop inheritance

 struct A final {};

 // error C3246: 'CPPTest::testFinal1::B' : cannot inherit from 'CPPTest::testFinal1::A' as it has been declared as 'final'
 // struct B : A {};
delete to stop compiler generating default methods

#pragma warning( push )
#pragma warning( disable : 4822)

 class A {
  int x;

 public:
  A(int x) : x(x) {};
  A(const A&) = delete;
  A& operator=(const A&) = delete;
 };

 A x{ 123 };
 // A y = x; // error C2280: 'CPPTest::testDeletedFunction::A::testDeletedFunction::A(const CPPTest::testDeletedFunction::A &)' : attempting to reference a deleted function
 // y = x; // error -- operator= deleted

#pragma warning( pop )
range based iteration

 std::vector a{ 1, 2, 3, 4, 5 };
 for (int& x : a) 
 { 
  x *= 2; 
 }
 // a == { 2, 4, 6, 8, 10 }

 for (int x : a) 
 {
  x *= 2;
 }
 // a == { 2, 4, 6, 8, 10 }

 int b[] = { 5, 4, 3, 2, 1 };
 for (int& x : b)
 {
  x *= 3;
 }
std::to_string

 assertEqual("123", std::to_string(123));
 assertEqual("1.200000", std::to_string(1.2));
std::unique_ptr

 
 {
  std::unique_ptr p1{ new int };
  *p1 = 1234;
  assert(*p1 == 1234);
 }

 {
  int *p1 = new int;
  *p1 = 1234;
  assert(*p1 == 1234);
  delete p1;
 }
std::unique_ptr and struct

 
 struct Foo { int Bar; string Too; };
 std::unique_ptr p1{ new Foo };
 p1->Bar = 1234;
 p1->Too = "hello";

 assert(p1->Bar == 1234);
 assert(p1->Too == "hello");
std::make_unique

 struct Foo {
  Foo(int bar, string too) : Bar(bar), Too(too){}
  int Bar; string Too;
 };
 std::unique_ptr p1;

 if (p1 == nullptr)
 {
  // p1 = new Foo;  // compile error 
  p1 = std::unique_ptr(new Foo(1234, "Hello"));
  p1 = std::make_unique(1234, "Hello");
 }
unique_ptr to vector

 struct Foo {
  Foo(int bar, string too) : Bar(bar), Too(too){}
  int Bar; string Too;
 };
 vector< std::unique_ptr > Foos;
 Foos.push_back(std::unique_ptr(new Foo(1234, "Hello")));
 Foos.push_back(std::make_unique(4321, "World"));
 Foos.push_back(std::make_unique(1111, "Good Morning"));
std::shared_ptr

 struct Foo { int Bar = 1234; string Too = "Hello"; };
 std::shared_ptr p1{ new Foo };
 p1->Bar = 4321;

 std::shared_ptr p2 = p1;
 p2->Too = "World";

 assertEqual("World", p1->Too);

 auto p3 = make_shared();
 assertEqual(1234, p3->Bar);

 p1 = p3;
unique_ptr to shared_ptr

 struct Foo { int Bar = 1234; string Too = "Hello"; };
 std::unique_ptr p1( new Foo );

 // std::shared_ptr p2 = p1; 
 // error C2440 : 'initializing' : cannot convert from 'std::unique_ptr< CPPTest::testSharedPtr1::Foo,std::default_delete <_Ty> >' 
 // to 'std::shared_ptr'

 std::shared_ptr p3 = std::move(p1); 

 // p1 is dangling now
tuple

 // `playerProfile` has type `std::tuple`.
 auto playerProfile = std::make_tuple(51, "Frans Nielsen", "NYI");
 assertEqual( 51, std::get<0>(playerProfile)); 
 assertEqual( "Frans Nielsen", std::get<1>(playerProfile));
 assertEqual( "NYI", std::get<2>(playerProfile)); 
tie

// With tuples...
 std::string playerName;
 std::tie(std::ignore, playerName, std::ignore) = std::make_tuple(91, "John Tavares", "NYI");
 assertEqual("John Tavares", playerName);

 // With pairs...
 std::string yes, no;
 std::tie(yes, no) = std::make_pair("yes", "no");
 assertEqual("yes", yes);
 assertEqual("no", no);