+class Datatype : public F2C, public Keyval{
+ char* name_ = nullptr;
+ /* The id here is the (unique) datatype id used for this datastructure.
+ * It's default value is set to -1 since some code expects this return value
+ * when no other id has been assigned
+ */
+ std::string id = "-1";
+ size_t size_;
+ MPI_Aint lb_;
+ MPI_Aint ub_;
+ int flags_;
+ int refcount_ = 1;
+
+public:
+ static std::unordered_map<int, smpi_key_elem> keyvals_;
+ static int keyval_id_;
+ Datatype_contents* contents_ = nullptr;
+
+ Datatype(int id, int size, MPI_Aint lb, MPI_Aint ub, int flags);
+ Datatype(char* name, int id, int size, MPI_Aint lb, MPI_Aint ub, int flags);
+ Datatype(int size, MPI_Aint lb, MPI_Aint ub, int flags);
+ Datatype(char* name, int size, MPI_Aint lb, MPI_Aint ub, int flags);
+ Datatype(Datatype* datatype, int* ret);
+ Datatype(const Datatype&) = delete;
+ Datatype& operator=(const Datatype&) = delete;
+ virtual ~Datatype();
+
+ char* name() { return name_; }
+ size_t size() { return size_; }
+ MPI_Aint lb() { return lb_; }
+ MPI_Aint ub() { return ub_; }
+ int flags() { return flags_; }
+ int refcount() { return refcount_; }
+
+ void ref();
+ static void unref(MPI_Datatype datatype);
+ void commit();
+ bool is_valid();
+ bool is_basic();
+ static const char* encode(const Datatype* dt) { return dt->id.c_str(); }
+ static MPI_Datatype decode(const std::string& datatype_id);
+ bool is_replayable();
+ void addflag(int flag);
+ int extent(MPI_Aint* lb, MPI_Aint* extent);
+ MPI_Aint get_extent() { return ub_ - lb_; };
+ void get_name(char* name, int* length);
+ void set_name(const char* name);
+ static int copy(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
+ MPI_Datatype recvtype);
+ virtual void serialize(const void* noncontiguous, void* contiguous, int count);
+ virtual void unserialize(const void* contiguous, void* noncontiguous, int count, MPI_Op op);
+ static int keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
+ void* extra_state);
+ static int keyval_free(int* keyval);
+ int pack(const void* inbuf, int incount, void* outbuf, int outcount, int* position, const Comm* comm);
+ int unpack(const void* inbuf, int insize, int* position, void* outbuf, int outcount, const Comm* comm);
+ int get_contents(int max_integers, int max_addresses,
+ int max_datatypes, int* array_of_integers, MPI_Aint* array_of_addresses,
+ MPI_Datatype *array_of_datatypes);
+ int get_envelope(int* num_integers, int* num_addresses,
+ int* num_datatypes, int* combiner);
+ static int create_contiguous(int count, MPI_Datatype old_type, MPI_Aint lb, MPI_Datatype* new_type);
+ static int create_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type);
+ static int create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type);
+ static int create_indexed(int count, const int* blocklens, const int* indices, MPI_Datatype old_type, MPI_Datatype* new_type);
+ static int create_hindexed(int count, const int* blocklens, const MPI_Aint* indices, MPI_Datatype old_type,
+ MPI_Datatype* new_type);
+ static int create_struct(int count, const int* blocklens, const MPI_Aint* indices, const MPI_Datatype* old_types,
+ MPI_Datatype* new_type);
+ static int create_subarray(int ndims, const int* array_of_sizes,
+ const int* array_of_subsizes, const int* array_of_starts,
+ int order, MPI_Datatype oldtype, MPI_Datatype *newtype);
+ static int create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent,
+ MPI_Datatype *newtype);
+ static Datatype* f2c(int id);