
On 26 Jul 2010, at 12:41, Robert Ramey wrote:
Matthias Troyer wrote:
On 25 Jul 2010, at 23:56, Robert Ramey wrote:
Matthias Troyer wrote:
Yes, what is missing is the list of special types and their interface. In the past they were all STRONG_TYPEDEF, and the semantics of STRONG_TYPEDEF was the same as that of the underlying integral type. That has changed and broken some code.
The basic issue is that an archive deriving from detail::common_[io]archive has to support the fundamental C++ types, std:: string, and that collection of special types. In order to serialize those special types I need to be able to know something about them! The specific list of concepts they model is less important than that list being stable (as long as serialization can be implemented efficiently). Besides the default constructor it would be good to have a type member specifying the (current) implementation type:
#define BOOST_ARCHIVE_STRONG_TYPEDEF(T, D) \ class D : public T { \ public: \ typedef T implementation_type; \ explicit D(const T t) : T(t){} \ D() : T() {} \ }; \
A month or so ago I had most of these types implemented with STRONG_TYPEDEF. In addition to these I had a few implemented "by hand": tracking_type, class_name_type. So moving a few from the STRONG_TYPEDEF column to the "hand rolled" column didn't raise any red flags. I found that I had to add the following operations to these types:
For T T:base_type // where base_type is some integer supported by binary_primitive and text_primitive. convertable to T::base_type & convertable to const T::base_type operator == operator<
This was totally ad hoc- I was just "making things work" Of course STRONG_TYPEDEF supports all of these except base_type which could easily be added to it at no cost. Soooooo we could define such a concept and that would solve the current dilema, avoid future problems, and make mpi_archives easier to write and more robust. In principle I see this as an improvement. Of course the devil is in the details.
I see the utility of augmenting STRONG_TYPEDEF but I wonder about it. if you have code T:base_type and T is not one of the types we're using - it won't have this available - compiler error. Wouldn't it be better to specify the implicit requirements as above and just know that T will be converted to what one wants? and sizeof(T) can be applied to both the (now) more elaborate types as well as C++ primitives.
The only problem I see with sizeof(T) is that it cannot tell me about signedness. Otherwise I could hack it from sizeof(T)
and also use the implementation_type member in the other special classes. That way you could change those integer types at any time without causing any breakage in Boost.MPI. Right now I have to manually set these types:
BOOST_MPI_DATATYPE(boost::archive::class_id_optional_type, get_mpi_datatype(int_least16_t()), integer);
Though it's off topic at this point, I've never understood what this macro is for. why do these special types need handling different than any other common c++ primitive types like integers. Wasn't it enough for these types to be convertable to integers and references to integers?
This macro specializes the get_mpi_datatype() function for the type boost::archive::class_id_optional_type and implements it to return the appropriate MPI Datatype, which here is the same as that of an int_least16_t. Do you have a way how I can class_id_optional_type to an integer, without knowing what integer type to use? Matthias