#include <string>
#include <iostream>
#include <array>
#include <utility>
#include <unordered_map>
using namespace std;

class my_class
{
	bool empty = false;
	public:
	my_class(int)		{	cerr << "c'tor\n";	}
	my_class()					{	cerr << "default c'tor\n";	}
	my_class(const my_class&)	{	cerr << "copy c'tor\n";	}
	my_class(my_class&& o)		{	cerr << "move c'tor\n";	o.empty = true;}
	~my_class()					{	cerr << (empty ? "Empty": "Filled") << " d'tor\n";	}
	
}; 


int main ( int  , char *[])
{

	const string key{"key"};


	// OK
	{
		unordered_map<string, std::array<my_class, 2>> contig_sizes;
		std::cerr << "Precreated value\n";
		array<my_class, 2> value{1, 2};
		std::cerr << "Now emplace:\n";
		contig_sizes.emplace(key, value);
		std::cerr << "Done:\n";
	}

	// OK
	{
		unordered_map<string, std::array<my_class, 2>> contig_sizes;
		std::cerr << "\nEmplace key, casted value:\n";
		contig_sizes.emplace(key, std::array<my_class, 2>{1, 2});
		std::cerr << "Done:\n";
	}

	// OK use Very inefficient insert
	{
		unordered_map<string, std::array<my_class, 2>> contig_sizes;
		std::cerr << "\nVery inefficient insert:\n";
        contig_sizes.insert({key, {1,2}});
		std::cerr << "Done:\n";
	}

	// OK use inefficient insert
	{
		unordered_map<string, std::array<my_class, 2>> contig_sizes;
		std::cerr << "\nInefficient insert:\n";
        contig_sizes.insert({key, std::array<my_class, 2>{1,2}});
		std::cerr << "Done:\n";
	}

    // OK use ugly insert
	{
		unordered_map<string, std::array<my_class, 2>> contig_sizes;
		std::cerr << "\nUgly insert:\n";
        contig_sizes.insert(pair<const string, array<my_class, 2>>{key, array<my_class, 2>{1, 2}});
		//contig_sizes.insert(make_pair(key, array<my_class, 2>{1, 2}));
		std::cerr << "Done:\n";
	}
	
	// OK emplace with the correct pair type (typedef)
	{
		typedef pair<const string, array<my_class, 2>> pair_type;
		unordered_map<string, std::array<my_class, 2>> contig_sizes;
		//std::cerr << "\nPieceswise construct with pair typedef:\n";
		//pair_type p{std::piecewise_construct, 
		//			std::forward_as_tuple(string(key)), 
		//			std::forward_as_tuple(std::array<my_class, 2>({1, 2}))};
		std::cerr << "\nEmplace with pair typedef:\n";
        // c'tor removed with extra cast
        contig_sizes.emplace(pair_type{key, {1, 2}});
		std::cerr << "Done:\n";
	}
	
	// OK ugly emplace with the correct pair type (typedef)
	{
		typedef pair<const string, array<my_class, 2>> pair_type;
		unordered_map<string, std::array<my_class, 2>> contig_sizes;
		std::cerr << "\nUgly Emplace with pair typedef:\n";
        // c'tor removed with extra cast
        contig_sizes.emplace(pair_type{key, std::array<my_class, 2>{1, 2}});
		std::cerr << "Done:\n";
	}
        

	// compile error
	//contig_sizes.emplace(key, {{1,2}});
}