Skip to content

Commit

Permalink
changes to type and type traits
Browse files Browse the repository at this point in the history
  • Loading branch information
patflick committed Aug 19, 2016
1 parent 87af3ea commit f1f338c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 28 deletions.
44 changes: 21 additions & 23 deletions include/mxx/datatypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,9 @@ class value_datatype_builder : public datatype_builder_base<T, value_datatype_bu
};

// determine the offset of a `pointer to member` type without instantiation
template <typename T, typename M>
size_t offset_of(M T::* m) {
template <typename T, typename Base, typename M>
typename std::enable_if<std::is_base_of<Base, T>::value, size_t>::type
offset_of(M Base::* m) {
return reinterpret_cast<size_t>(&(((T*)nullptr)->*m));
}

Expand All @@ -593,19 +594,16 @@ class static_datatype_builder : public datatype_builder_base<T, static_datatype_
// add members via "pointer to member" types
template <typename M>
void add_member(M T::*m) {
this->template add_member_by_offset<M>(offset_of(m));
this->template add_member_by_offset<M>(offset_of<T, T, M>(m));
}
};


// non-static datatype construction using variadic templates and only a subset of members
template <typename T, typename... Args>
datatype built_custom_datatype(T* val, Args&...args) {
value_datatype_builder<T> builder(*val);
builder.add_members(args...);
return builder.get_datatype();
}

// support adding members of base classes
template <typename Base, typename M>
typename std::enable_if<std::is_base_of<Base, T>::value, void>::type
add_member(M Base::*m) {
this->template add_member_by_offset<M>(offset_of<T, Base, M>(m));
}
};


/*
Expand Down Expand Up @@ -674,7 +672,7 @@ struct is_trivial_type<T, typename std::enable_if<


template <typename T>
typename std::enable_if<has_static_member_datatype<T, void(static_datatype_builder<T>&)>::value, datatype>::type
inline typename std::enable_if<has_static_member_datatype<T, void(static_datatype_builder<T>&)>::value, datatype>::type
build_datatype() {
//static_assert(!has_static_member_datatype<T, void(mxx::value_datatype_builder<T>&)>::value, "needs static datatype() function");
//T val;
Expand All @@ -684,7 +682,7 @@ build_datatype() {
}

template <typename T>
typename std::enable_if<
inline typename std::enable_if<
!has_static_member_datatype<T, void(static_datatype_builder<T>&)>::value
&& has_member_datatype<T, void(value_datatype_builder<T>&)>::value
, datatype>::type
Expand All @@ -695,42 +693,42 @@ build_datatype() {
return builder.get_datatype();
}

// TODO: enable_if specializations for this function
template <typename T>
datatype build_datatype(const T&) {
inline datatype build_datatype(const T&) {
datatype dt(datatype_builder<T>::get_type(), is_builtin_type<T>::value);
return dt;
}

// TODO: use is_builtin etc instead of `has_builder` after removing the custom `datatype_builder`
// specializations
// if datatype_builder<T> exists:
template <typename T>
typename std::enable_if<has_builder<T>::value, datatype>::type
inline typename std::enable_if<has_builder<T>::value, datatype>::type
build_datatype() {
datatype dt(datatype_builder<T>::get_type(), is_builtin_type<T>::value);
return dt;
}

template <typename T>
typename std::enable_if<!is_trivial_type<T>::value, datatype>::type
inline typename std::enable_if<!is_trivial_type<T>::value, datatype>::type
build_datatype() {
// static assert the opposite to trigger the static assertion failure
static_assert(is_trivial_type<T>::value,
"Type `T` is not a `trivial` type and is thus not supported for mxx send/recv operations. "
"This type needs one of the following to be supported as trivial datatype: "
"custom datatype builder, member function `datatype` or global function `make_datatype(Layout& l, T&)`");
"specialized build_datatype<T>, a member function `datatype`, or global function `make_datatype(Layout& l, T&)`");

return datatype();
}


template <typename T>
datatype get_datatype() {
inline datatype get_datatype() {
// TODO: retrieve cached datatype
return build_datatype<T>();
}

template <typename T>
datatype get_datatype(const T& t) {
inline datatype get_datatype(const T& t) {
// TODO: retrieve cached datatype
return build_datatype(t);
}
Expand Down
8 changes: 3 additions & 5 deletions include/mxx/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <vector>
#include <string>

//namespace mxx {
namespace mxx {

// source for testing if member functions are available: http:https://stackoverflow.com/a/16824239/4639394
#define MXX_DEFINE_HAS_MEMBER(member) \
Expand All @@ -22,7 +22,7 @@ private: \
decltype( std::declval<T>(). member ( std::declval<Args>()... ) ), \
Ret /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ \
>::type; /* attempt to call it and see if the return type is correct */ \
template<typename> \
template <typename> \
static constexpr std::false_type check(...); \
typedef decltype(check<C>(0)) type; \
public: \
Expand Down Expand Up @@ -95,11 +95,9 @@ MXX_DEFINE_HAS_STATIC_MEMBER(datatype)
MXX_DEFINE_HAS_MEMBER(datatype)


namespace mxx {
// TODO: build this into the mxx/datatype structures
template <typename T, typename Enable = void>
struct has_datatype : std::false_type {};
}



Expand Down Expand Up @@ -178,6 +176,6 @@ template <typename C, typename Enable = void>
struct is_flat_type : std::integral_constant<bool,
is_contiguous_container<C>::value> {};

//} // namespace mxx
} // namespace mxx

#endif // MXX_TYPE_TRAITS

0 comments on commit f1f338c

Please sign in to comment.