Arena type traits standardization.
This is adapted from the branch of @xfxyjwf at:
494716a682
and should solve the protobuf compilation problem against nvcc.
Tested against nvcc 6.5 and 7.0.
This commit is contained in:
parent
b1b9c254e2
commit
bbf64cee3d
@ -490,27 +490,29 @@ class LIBPROTOBUF_EXPORT Arena {
|
|||||||
return GetArenaInternal(value, static_cast<T*>(0));
|
return GetArenaInternal(value, static_cast<T*>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper typetrait that indicates support for arenas in a type T at compile
|
private:
|
||||||
// time. This is public only to allow construction of higher-level templated
|
struct InternalIsArenaConstructableHelper {
|
||||||
// utilities. is_arena_constructable<T>::value is an instance of
|
|
||||||
// google::protobuf::internal::true_type if the message type T has arena support enabled, and
|
|
||||||
// google::protobuf::internal::false_type otherwise.
|
|
||||||
//
|
|
||||||
// This is inside Arena because only Arena has the friend relationships
|
|
||||||
// necessary to see the underlying generated code traits.
|
|
||||||
template<typename T>
|
|
||||||
struct is_arena_constructable {
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
static char ArenaConstructable(
|
static char ArenaConstructable(
|
||||||
const typename U::InternalArenaConstructable_*);
|
const typename U::InternalArenaConstructable_*);
|
||||||
template<typename U>
|
template<typename U>
|
||||||
static double ArenaConstructable(...);
|
static double ArenaConstructable(...);
|
||||||
|
};
|
||||||
|
|
||||||
// This will resolve to either google::protobuf::internal::true_type or google::protobuf::internal::false_type.
|
public:
|
||||||
typedef google::protobuf::internal::integral_constant<bool,
|
// Helper typetrait that indicates support for arenas in a type T at compile
|
||||||
sizeof(ArenaConstructable<const T>(static_cast<const T*>(0))) ==
|
// time. This is public only to allow construction of higher-level templated
|
||||||
sizeof(char)> type;
|
// utilities. is_arena_constructable<T>::value is true if the message type T
|
||||||
static const type value;
|
// has arena support enabled, and false otherwise.
|
||||||
|
//
|
||||||
|
// This is inside Arena because only Arena has the friend relationships
|
||||||
|
// necessary to see the underlying generated code traits.
|
||||||
|
template<typename T>
|
||||||
|
struct is_arena_constructable :
|
||||||
|
public google::protobuf::internal::integral_constant<bool,
|
||||||
|
sizeof(InternalIsArenaConstructableHelper::ArenaConstructable<
|
||||||
|
const T>(static_cast<const T*>(0))) ==
|
||||||
|
sizeof(char)> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -572,32 +574,28 @@ class LIBPROTOBUF_EXPORT Arena {
|
|||||||
return google::protobuf::internal::has_trivial_destructor<T>::value;
|
return google::protobuf::internal::has_trivial_destructor<T>::value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper typetrait that indicates whether the desctructor of type T should be
|
struct InternalIsDestructorSkippableHelper {
|
||||||
// called when arena is destroyed at compile time. This is only to allow
|
|
||||||
// construction of higher-level templated utilities.
|
|
||||||
// is_destructor_skippable<T>::value is an instance of google::protobuf::internal::true_type if the
|
|
||||||
// destructor of the message type T should not be called when arena is
|
|
||||||
// destroyed or google::protobuf::internal::has_trivial_destructor<T>::value == true, and
|
|
||||||
// google::protobuf::internal::false_type otherwise.
|
|
||||||
//
|
|
||||||
// This is inside Arena because only Arena has the friend relationships
|
|
||||||
// necessary to see the underlying generated code traits.
|
|
||||||
template<typename T>
|
|
||||||
struct is_destructor_skippable {
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
static char DestructorSkippable(
|
static char DestructorSkippable(
|
||||||
const typename U::DestructorSkippable_*);
|
const typename U::DestructorSkippable_*);
|
||||||
template<typename U>
|
template<typename U>
|
||||||
static double DestructorSkippable(...);
|
static double DestructorSkippable(...);
|
||||||
|
};
|
||||||
|
|
||||||
// The raw_skippable_value const bool variable is separated from the typedef
|
// Helper typetrait that indicates whether the desctructor of type T should be
|
||||||
// line below as a work-around of an NVCC 7.0 (and earlier) compiler bug.
|
// called when arena is destroyed at compile time. This is only to allow
|
||||||
static const bool raw_skippable_value =
|
// construction of higher-level templated utilities.
|
||||||
sizeof(DestructorSkippable<const T>(static_cast<const T*>(0))) ==
|
// is_destructor_skippable<T>::value is true if the destructor of the message
|
||||||
sizeof(char) || google::protobuf::internal::has_trivial_destructor<T>::value == true;
|
// type T should not be called when arena is destroyed or false otherwise.
|
||||||
// This will resolve to either google::protobuf::internal::true_type or google::protobuf::internal::false_type.
|
// This is inside Arena because only Arena has the friend relationships
|
||||||
typedef google::protobuf::internal::integral_constant<bool, raw_skippable_value> type;
|
// necessary to see the underlying generated code traits.
|
||||||
static const type value;
|
template<typename T>
|
||||||
|
struct is_destructor_skippable :
|
||||||
|
public google::protobuf::internal::integral_constant<bool,
|
||||||
|
sizeof(InternalIsDestructorSkippableHelper::DestructorSkippable<
|
||||||
|
const T>(static_cast<const T*>(0))) ==
|
||||||
|
sizeof(char) ||
|
||||||
|
google::protobuf::internal::has_trivial_destructor<T>::value> {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -780,8 +778,10 @@ class LIBPROTOBUF_EXPORT Arena {
|
|||||||
// which needs to declare google::protobuf::Map as friend of generated message.
|
// which needs to declare google::protobuf::Map as friend of generated message.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void CreateInArenaStorage(T* ptr, Arena* arena) {
|
static void CreateInArenaStorage(T* ptr, Arena* arena) {
|
||||||
CreateInArenaStorageInternal(ptr, arena, is_arena_constructable<T>::value);
|
CreateInArenaStorageInternal(
|
||||||
RegisterDestructorInternal(ptr, arena, is_destructor_skippable<T>::value);
|
ptr, arena, typename is_arena_constructable<T>::type());
|
||||||
|
RegisterDestructorInternal(
|
||||||
|
ptr, arena, typename is_destructor_skippable<T>::type());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -910,16 +910,6 @@ class LIBPROTOBUF_EXPORT Arena {
|
|||||||
// Defined above for supporting environments without RTTI.
|
// Defined above for supporting environments without RTTI.
|
||||||
#undef RTTI_TYPE_ID
|
#undef RTTI_TYPE_ID
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const typename Arena::is_arena_constructable<T>::type
|
|
||||||
Arena::is_arena_constructable<T>::value =
|
|
||||||
typename Arena::is_arena_constructable<T>::type();
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const typename Arena::is_destructor_skippable<T>::type
|
|
||||||
Arena::is_destructor_skippable<T>::value =
|
|
||||||
typename Arena::is_destructor_skippable<T>::type();
|
|
||||||
|
|
||||||
} // namespace protobuf
|
} // namespace protobuf
|
||||||
|
|
||||||
} // namespace google
|
} // namespace google
|
||||||
|
Loading…
Reference in New Issue
Block a user