#include <iostream>
#include <typeinfo>
#include <utility>
// for demangle:
#include <cxxabi.h>
#include <string>
#include <memory>
#include <cstdlib>


template<template<class T, T...> class Container, typename T, T... t, T... s>
constexpr Container<T, t..., s...>
concat_arglists(Container<T, t...>, Container<T, s...>) {
	return {};
}

// swap_pairs: Пустой лист
template <template<class T, T...> class Container, typename T>
constexpr Container<T> swap_pairs(Container<T>) { return {}; }

// swap_pairs: Лист из 1 элемента
template <template<class T, T...> class Container, typename T, T t>
constexpr Container<T, t> swap_pairs(Container<T, t>) { return {}; }

// swap_pairs: Лист из 2  более элементов
template <template<class T, T...> class Container, typename T, T t1, T t2, T... ts>
constexpr auto
swap_pairs(Container<T, t1, t2, ts...>) {
	using head = Container<T, t2, t1>;
	using tail = decltype(swap_pairs(Container<T, ts...>{}));
	using list = decltype(concat_arglists(head{}, tail{}));
	return list{};
}

std::string demangle(const char* mangled)
{
      int status;
      std::unique_ptr<char[], void (*)(void*)> result(
        abi::__cxa_demangle(mangled, 0, 0, &status), std::free);
      return result.get() ? std::string(result.get()) : "error occurred";
}

int main() {
	std::integer_sequence<int, 2, 1, 4, 3> a;
	std::integer_sequence<int, 4, 5, 2, 3, 1> b;
	auto c = concat_arglists(a, b);
	auto d = swap_pairs(c);
	std::cout << "a = " << demangle( typeid(a).name() ) << std::endl;
	std::cout << "b = " << demangle( typeid(b).name() ) << std::endl;
	std::cout << "c = " << demangle( typeid(c).name() ) << std::endl;
	std::cout << "d = " << demangle( typeid(d).name() ) << std::endl;
	return 0;
}
