Commit 9cbf4087 authored by Feng Xiao's avatar Feng Xiao

Merge pull request #1025 from Yangqing/master

Arena type traits standardization.
parents 723010dc 031558bd
...@@ -490,27 +490,28 @@ class LIBPROTOBUF_EXPORT Arena { ...@@ -490,27 +490,28 @@ 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 +573,30 @@ class LIBPROTOBUF_EXPORT Arena { ...@@ -572,32 +573,30 @@ 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 private:
// called when arena is destroyed at compile time. This is only to allow struct InternalIsDestructorSkippableHelper {
// 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 public:
// line below as a work-around of an NVCC 7.0 (and earlier) compiler bug. // Helper typetrait that indicates whether the desctructor of type T should be
static const bool raw_skippable_value = // called when arena is destroyed at compile time. This is only to allow
sizeof(DestructorSkippable<const T>(static_cast<const T*>(0))) == // construction of higher-level templated utilities.
sizeof(char) || google::protobuf::internal::has_trivial_destructor<T>::value == true; // is_destructor_skippable<T>::value is true if the destructor of the message
// This will resolve to either google::protobuf::internal::true_type or google::protobuf::internal::false_type. // type T should not be called when arena is destroyed or false otherwise.
typedef google::protobuf::internal::integral_constant<bool, raw_skippable_value> type; // This is inside Arena because only Arena has the friend relationships
static const type value; // necessary to see the underlying generated code traits.
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 +779,10 @@ class LIBPROTOBUF_EXPORT Arena { ...@@ -780,8 +779,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(ptr, arena,
RegisterDestructorInternal(ptr, arena, is_destructor_skippable<T>::value); typename is_arena_constructable<T>::type());
RegisterDestructorInternal(ptr, arena,
typename is_destructor_skippable<T>::type());
} }
template <typename T> template <typename T>
...@@ -910,16 +911,6 @@ class LIBPROTOBUF_EXPORT Arena { ...@@ -910,16 +911,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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment