19 #ifndef TIMPI_STANDARD_TYPE_H    20 #define TIMPI_STANDARD_TYPE_H    24 #include "timpi/timpi_config.h"    33 #endif // TIMPI_HAVE_MPI    36 #ifdef TIMPI_DEFAULT_QUADRUPLE_PRECISION    37 # include <boost/multiprecision/float128.hpp>    48 #include <type_traits>    49 #include <unordered_map>    50 #include <unordered_set>    82 template <
typename T, 
typename Enable>
   100 template <
typename T>
   107 template <
typename T, 
typename A>
   114 template <
typename T, 
typename A>
   121 template <
typename K, 
typename T, 
typename C, 
typename A>
   128 template <
typename K, 
typename T, 
typename C, 
typename A>
   135 template <
typename T, 
typename C, 
typename A>
   142 template <
typename T, 
typename C, 
typename A>
   149 template <
typename K, 
typename T, 
typename C, 
typename A>
   156 template <
typename K, 
typename T, 
typename C, 
typename A>
   163 template <
typename T, 
typename C, 
typename A>
   170 template <
typename T, 
typename C, 
typename A>
   180 template <
typename T>
   193 template <
typename T, 
typename A>
   194 StandardType<typename InnermostType<T>::type>
   197   const T * inner_example = (example && !example->empty()) ? &(*example)[0] : 
nullptr;
   206 #ifdef TIMPI_HAVE_MPI   208 #define TIMPI_STANDARD_TYPE(cxxtype,mpitype)                      \   210   class StandardType<cxxtype> : public DataType                      \   214       StandardType(const cxxtype * = nullptr) : DataType(mpitype) {} \   216     static const bool is_fixed_type = true;                          \   221 #define TIMPI_STANDARD_TYPE(cxxtype,mpitype)               \   223   class StandardType<cxxtype> : public DataType               \   227       StandardType(const cxxtype * = nullptr) : DataType() {} \   229     static const bool is_fixed_type = true;                   \   249 #ifdef TIMPI_HAVE_MPI   259     _type(uncommitted_type) {
   260     MPI_Type_commit (&uncommitted_type);
   264     MPI_Type_free(&
_type);
   273 # ifdef TIMPI_DEFAULT_QUADRUPLE_PRECISION   280         static data_type static_type = MPI_DATATYPE_NULL;
   281         if (static_type == MPI_DATATYPE_NULL)
   283             timpi_call_mpi(MPI_Type_contiguous(2, MPI_DOUBLE, &static_type));
   285               (std::make_unique<ManageType>(static_type));
   287         _datatype = static_type;
   296       _datatype = t._datatype;
   304 # ifdef TIMPI_DEFAULT_QUADRUPLE_PRECISION   312 template<
typename T1, 
typename T2>
   314                    typename std::enable_if<
   315                      StandardType<typename std::remove_const<T1>::type>::is_fixed_type &&
   316                      StandardType<T2>::is_fixed_type>::type> : 
public DataType   323 #ifdef TIMPI_HAVE_MPI   324     static data_type static_type = MPI_DATATYPE_NULL;
   325     if (static_type == MPI_DATATYPE_NULL)
   328         static const std::pair<T1, T2> p;
   335           d1(
const_cast<typename std::remove_const<T1>::type *
>   340         int blocklengths[] = {1,1};
   341         MPI_Aint displs[2], start;
   344           (MPI_Get_address (
const_cast<std::pair<T1,T2> *
>(example),
   347           (MPI_Get_address (const_cast<T1*>(&example->first),
   350           (MPI_Get_address (const_cast<T2*>(&example->second),
   356         MPI_Datatype tmptype;
   358           (MPI_Type_create_struct (2, blocklengths, displs, types,
   361           (MPI_Type_commit (&tmptype));
   365           (MPI_Type_create_resized (tmptype, 0,
   366                                     sizeof(std::pair<T1,T2>),
   369           (MPI_Type_free (&tmptype));
   372           (std::make_unique<ManageType>(static_type));
   374     _datatype = static_type;
   377 #endif // TIMPI_HAVE_MPI   388     _datatype = t._datatype;
   397 template<
typename T, std::
size_t N>
   399                    typename std::enable_if<
   400                      StandardType<T>::is_fixed_type>::type> : 
public DataType   407 #ifdef TIMPI_HAVE_MPI   408     static data_type static_type = MPI_DATATYPE_NULL;
   409     if (static_type == MPI_DATATYPE_NULL)
   412         std::array<T, N> * ex;
   413         std::unique_ptr<std::array<T, N>> temp;
   415           ex = 
const_cast<std::array<T, N> *
>(example);
   418             temp.reset(
new std::array<T, N>());
   422         static_assert(N > 0, 
"Zero-length std::array is not supported by TIMPI");
   426         MPI_Aint displs, start;
   427         MPI_Datatype tmptype, type = T_type;
   430           (MPI_Get_address (ex, &start));
   432           (MPI_Get_address (&((*ex)[0]), &displs));
   439           (MPI_Type_create_struct (1, &blocklength, &displs, &type,
   442           (MPI_Type_commit (&tmptype));
   446           (MPI_Type_create_resized (tmptype, 0, 
sizeof(std::array<T,N>),
   450           (MPI_Type_free (&tmptype));
   453           (std::make_unique<ManageType>(static_type));
   455     _datatype = static_type;
   456 #else // #ifdef TIMPI_HAVE_MPI   469     _datatype = t._datatype;
   480 template<std::
size_t n_minus_i>
   483   template<
typename... Types>
   484   static void build(std::vector<std::unique_ptr<DataType>> & out_vec,
   485                     const std::tuple<Types...> & example);
   491   template<
typename... Types>
   492   static void build(std::vector<std::unique_ptr<DataType>> & ,
   493                     const std::tuple<Types...> & ) {}
   496 template<std::
size_t n_minus_i>
   497 template<
typename... Types>
   499   (std::vector<std::unique_ptr<DataType>> & out_vec,
   500    const std::tuple<Types...> & example)
   503     std::tuple_element<
sizeof...(Types)-n_minus_i, std::tuple<Types...>>::type
   508      (&std::get<
sizeof...(Types)-n_minus_i>(example)));
   514 template<std::
size_t n_minus_i>
   517   template <
typename OutArray, 
class... Types>
   518   static void fill(OutArray & out,
   519                    const std::tuple<Types...> & example);
   525   template <
typename OutArray, 
typename... Types>
   527                    const std::tuple<Types...> & ) {}
   531 template<std::
size_t n_minus_i>
   532 template<
typename OutArray, 
typename... Types>
   535    const std::tuple<Types...> & example)
   539       (&std::get<
sizeof...(Types)-n_minus_i>(example),
   540        &out_vec[
sizeof...(Types)-n_minus_i]));
   546 template <
typename Head, 
typename... Tail>
   553 template <
typename Head>
   559 template<
typename... Types>
   561                    typename std::enable_if<
   562                      CheckAllFixedTypes<Types...>::is_fixed_type>::type> : 
public DataType   569 #ifdef TIMPI_HAVE_MPI   570     static data_type static_type = MPI_DATATYPE_NULL;
   571     if (static_type == MPI_DATATYPE_NULL)
   574         static const std::tuple<Types...> t;
   581           (MPI_Get_address (example, &start));
   583         const std::size_t tuplesize = 
sizeof...(Types);
   585         std::vector<std::unique_ptr<DataType>> subtypes;
   588         std::array<MPI_Aint, 
sizeof...(Types)> displs;
   591         std::array<MPI_Datatype, 
sizeof...(Types)> types;
   592         std::array<int, 
sizeof...(Types)> blocklengths;
   594         for (std::size_t i = 0; i != tuplesize; ++i)
   602         MPI_Datatype tmptype;
   604           (MPI_Type_create_struct (tuplesize, blocklengths.data(), displs.data(), types.data(),
   607           (MPI_Type_commit (&tmptype));
   611           (MPI_Type_create_resized (tmptype, 0,
   612                                     sizeof(std::tuple<Types...>),
   615           (MPI_Type_free (&tmptype));
   618           (std::make_unique<ManageType>(static_type));
   620     _datatype = static_type;
   621 #else // #ifdef TIMPI_HAVE_MPI   623 #endif // TIMPI_HAVE_MPI   634     _datatype = t._datatype;
   657 #endif // TIMPI_STANDARD_TYPE_H InnermostType< T >::type type
ManageType(data_type uncommitted_type)
InnermostType< T >::type type
MPI_Datatype data_type
Data types for communication. 
InnermostType< std::pair< const K, T > >::type type
StandardType(const std::complex< T > *=nullptr)
StandardType & operator=(StandardType &t)
static void build(std::vector< std::unique_ptr< DataType >> &, const std::tuple< Types... > &)
InnermostType< T >::type type
StandardType(const StandardType< TIMPI_DEFAULT_SCALAR_TYPE > &t)
Encapsulates the MPI_Datatype. 
InnermostType< T >::type type
Templated class to provide the appropriate MPI datatype for use with built-in C types or simple C++ c...
StandardType(const T *example=nullptr)
StandardType< T > build_standard_type(const T *example=nullptr)
virtual ~ManageType() override
static void build(std::vector< std::unique_ptr< DataType >> &out_vec, const std::tuple< Types... > &example)
StandardType & operator=(StandardType &t)
static const bool is_fixed_type
StandardType(const std::tuple< Types... > *example=nullptr)
static void fill(OutArray &out, const std::tuple< Types... > &example)
StandardType(const StandardType< std::array< T, N >> &t)
StandardType<T>'s which do not define a way to MPI_Type T should inherit from this class...
InnermostType< T >::type type
InnermostType< std::pair< const K, T > >::type type
StandardType & operator=(StandardType &t)
static void fill(OutArray &, const std::tuple< Types... > &)
The SemiPermanent "class" is basically just a place for a destructor vtable. 
InnermostType< std::pair< const K, T > >::type type
static const bool is_fixed_type
static void add(std::unique_ptr< SemiPermanent > obj)
void timpi_ignore(const Args &...)
StandardType(const TIMPI_DEFAULT_SCALAR_TYPE *=nullptr)
StandardType(const StandardType< std::pair< T1, T2 >> &t)
StandardType(const std::array< T, N > *example=nullptr)
InnermostType< std::pair< const K, T > >::type type
StandardType(const std::pair< T1, T2 > *example=nullptr)
InnermostType< T >::type type
StandardType(const StandardType< std::tuple< Types... >> &t)
StandardType & operator=(StandardType &t)
TIMPI_STANDARD_TYPE(char, MPI_CHAR)