STL containers#
Sends and receives STL containers.
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <vector>
#include <list>
#include <map>
#include <string>
#include <utility>
#include <cmath>
#include <mpl/mpl.hpp>
// print elements of a pair
template<typename ch, typename tr, typename T1, typename T2>
std::basic_ostream<ch, tr> &operator<<(std::basic_ostream<ch, tr> &out,
const std::pair<T1, T2> &p) {
return out << '(' << p.first << ',' << p.second << ')';
}
// print all elements of a container
template<typename ch, typename tr, typename C>
std::basic_ostream<ch, tr> &print_container(std::basic_ostream<ch, tr> &out, const C &c) {
out << '(';
for (auto i{std::begin(c)}; i != std::end(c); ++i) {
out << (*i);
if (std::next(i) != std::end(c))
out << ',';
}
return out << ')';
}
// print all elements of a vector
template<typename ch, typename tr, typename T, typename A>
std::basic_ostream<ch, tr> &operator<<(std::basic_ostream<ch, tr> &out,
const std::vector<T, A> &v) {
return print_container(out, v);
}
// print all elements of a list
template<typename ch, typename tr, typename T, typename A>
std::basic_ostream<ch, tr> &operator<<(std::basic_ostream<ch, tr> &out,
const std::list<T, A> &l) {
return print_container(out, l);
}
// print all elements of a map
template<typename ch, typename tr, typename K, typename C, typename A>
std::basic_ostream<ch, tr> &operator<<(std::basic_ostream<ch, tr> &out,
const std::map<K, C, A> &m) {
return print_container(out, m);
}
// print all elements of a map
template<typename ch, typename tr, typename T>
std::basic_ostream<ch, tr> &operator<<(std::basic_ostream<ch, tr> &out,
const std::valarray<T> &v) {
return print_container(out, v);
}
// send an STL container
template<typename T>
void send(const mpl::communicator &comm, const T &x) {
comm.send(x, 1);
}
// send an STL container
template<typename T>
void isend(const mpl::communicator &comm, const T &x) {
mpl::irequest r{comm.isend(x, 1)};
r.wait();
}
// receive an STL container
template<typename T>
void recv(const mpl::communicator &comm) {
using value_type = mpl::detail::remove_const_from_members_t<typename T::value_type>;
T x;
auto s{comm.recv(x, 0)};
std::cout << "x = " << x << " with " << s.template get_count<value_type>() << " elements\n";
}
// receive an STL container
template<typename T>
void irecv(const mpl::communicator &comm) {
using value_type = mpl::detail::remove_const_from_members_t<typename T::value_type>;
T x;
mpl::irequest r{comm.irecv(x, 0)};
mpl::status_t s{r.wait()};
std::cout << "x = " << x << " with " << s.template get_count<value_type>() << " elements\n";
}
int main() {
const mpl::communicator &comm_world{mpl::environment::comm_world()};
// run the program with two or more processes
if (comm_world.size() < 2)
comm_world.abort(EXIT_FAILURE);
// process 0 sends
if (comm_world.rank() == 0) {
std::string t_1{"Hello World!"};
send(comm_world, t_1);
isend(comm_world, t_1);
std::vector<int> t_2{0, 1, 2, 3, 4, 5, 6, 77, 42};
send(comm_world, t_2);
isend(comm_world, t_2);
std::vector<std::tuple<int, double>> t_3{{0, 0.0}, {1, 0.1}, {2, 0.2}, {3, 0.3}, {4, 0.4}};
send(comm_world, t_3);
isend(comm_world, t_3);
std::vector<bool> t_4{false, true, false, true, true};
send(comm_world, t_4);
isend(comm_world, t_4);
std::valarray<double> t_5{1, 2, 3, 4, 42, 4 * std::atan(1.0)};
send(comm_world, t_5);
isend(comm_world, t_5);
}
// process 1 receives
if (comm_world.rank() == 1) {
recv<std::string>(comm_world);
irecv<std::string>(comm_world);
recv<std::list<int>>(comm_world);
irecv<std::list<int>>(comm_world);
recv<std::map<int, double>>(comm_world);
irecv<std::map<int, double>>(comm_world);
recv<std::vector<bool>>(comm_world);
irecv<std::vector<bool>>(comm_world);
recv<std::valarray<double>>(comm_world);
irecv<std::valarray<double>>(comm_world);
}
return EXIT_SUCCESS;
}