| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | #ifndef GOOGLE_PROTOBUF_ARENA_H__
|
| | #define GOOGLE_PROTOBUF_ARENA_H__
|
| |
|
| | #include <limits>
|
| | #ifdef max
|
| | #undef max
|
| | #endif
|
| | #if LANG_CXX11
|
| | #include <google/protobuf/stubs/type_traits.h>
|
| | #endif
|
| | #if defined(_MSC_VER) && !_HAS_EXCEPTIONS
|
| |
|
| | #include <exception>
|
| | #include <typeinfo>
|
| | namespace std {
|
| | using type_info = ::type_info;
|
| | }
|
| | #else
|
| | #include <typeinfo>
|
| | #endif
|
| |
|
| | #include <google/protobuf/arena_impl.h>
|
| | #include <google/protobuf/stubs/port.h>
|
| |
|
| | namespace google {
|
| | namespace protobuf {
|
| |
|
| | class Arena;
|
| | class Message;
|
| |
|
| | namespace internal {
|
| | struct ArenaStringPtr;
|
| | class LazyField;
|
| |
|
| | template<typename Type>
|
| | class GenericTypeHandler;
|
| |
|
| |
|
| | template<typename T> void arena_destruct_object(void* object) {
|
| | reinterpret_cast<T*>(object)->~T();
|
| | }
|
| | template<typename T> void arena_delete_object(void* object) {
|
| | delete reinterpret_cast<T*>(object);
|
| | }
|
| | inline void arena_free(void* object, size_t size) {
|
| | #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
|
| | ::operator delete(object, size);
|
| | #else
|
| | (void)size;
|
| | ::operator delete(object);
|
| | #endif
|
| | }
|
| |
|
| | }
|
| |
|
| |
|
| |
|
| | struct ArenaOptions {
|
| |
|
| |
|
| | size_t start_block_size;
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | size_t max_block_size;
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | char* initial_block;
|
| |
|
| |
|
| | size_t initial_block_size;
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | void* (*block_alloc)(size_t);
|
| |
|
| |
|
| |
|
| | void (*block_dealloc)(void*, size_t);
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | void* (*on_arena_init)(Arena* arena);
|
| | void (*on_arena_reset)(Arena* arena, void* cookie, uint64 space_used);
|
| | void (*on_arena_destruction)(Arena* arena, void* cookie, uint64 space_used);
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | void (*on_arena_allocation)(const std::type_info* allocated_type,
|
| | uint64 alloc_size, void* cookie);
|
| |
|
| | ArenaOptions()
|
| | : start_block_size(kDefaultStartBlockSize),
|
| | max_block_size(kDefaultMaxBlockSize),
|
| | initial_block(NULL),
|
| | initial_block_size(0),
|
| | block_alloc(&::operator new),
|
| | block_dealloc(&internal::arena_free),
|
| | on_arena_init(NULL),
|
| | on_arena_reset(NULL),
|
| | on_arena_destruction(NULL),
|
| | on_arena_allocation(NULL) {}
|
| |
|
| | private:
|
| |
|
| |
|
| | static const size_t kDefaultStartBlockSize = 256;
|
| | static const size_t kDefaultMaxBlockSize = 8192;
|
| | };
|
| |
|
| |
|
| |
|
| | #ifndef GOOGLE_PROTOBUF_NO_RTTI
|
| | #define RTTI_TYPE_ID(type) (&typeid(type))
|
| | #else
|
| | #define RTTI_TYPE_ID(type) (NULL)
|
| | #endif
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | class LIBPROTOBUF_EXPORT Arena {
|
| | public:
|
| |
|
| |
|
| | explicit Arena(const ArenaOptions& options) : impl_(options) {
|
| | Init(options);
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | static const size_t kBlockOverhead = internal::ArenaImpl::kHeaderSize;
|
| |
|
| |
|
| |
|
| | Arena() : impl_(ArenaOptions()) { Init(ArenaOptions()); }
|
| |
|
| | ~Arena() {
|
| | if (on_arena_reset_ != NULL || on_arena_destruction_ != NULL) {
|
| | CallDestructorHooks();
|
| | }
|
| | }
|
| |
|
| | void Init(const ArenaOptions& options) {
|
| | on_arena_allocation_ = options.on_arena_allocation;
|
| | on_arena_reset_ = options.on_arena_reset;
|
| | on_arena_destruction_ = options.on_arena_destruction;
|
| |
|
| | if (options.on_arena_init != NULL) {
|
| | hooks_cookie_ = options.on_arena_init(this);
|
| | } else {
|
| | hooks_cookie_ = NULL;
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | #if LANG_CXX11
|
| | template <typename T, typename... Args>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* CreateMessage(
|
| | ::google::protobuf::Arena* arena, Args&&... args) {
|
| | static_assert(
|
| | InternalHelper<T>::is_arena_constructable::value,
|
| | "CreateMessage can only construct types that are ArenaConstructable");
|
| | if (arena == NULL) {
|
| | return new T(NULL, std::forward<Args>(args)...);
|
| | } else {
|
| | return arena->CreateMessageInternal<T>(std::forward<Args>(args)...);
|
| | }
|
| | }
|
| | #endif
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* CreateMessage(::google::protobuf::Arena* arena) {
|
| | #if LANG_CXX11
|
| | static_assert(
|
| | InternalHelper<T>::is_arena_constructable::value,
|
| | "CreateMessage can only construct types that are ArenaConstructable");
|
| | #endif
|
| | if (arena == NULL) {
|
| | return new T;
|
| | } else {
|
| | return arena->CreateMessageInternal<T>();
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| | template <typename T, typename Arg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* CreateMessage(::google::protobuf::Arena* arena, const Arg& arg) {
|
| | #if LANG_CXX11
|
| | static_assert(
|
| | InternalHelper<T>::is_arena_constructable::value,
|
| | "CreateMessage can only construct types that are ArenaConstructable");
|
| | #endif
|
| | if (arena == NULL) {
|
| | return new T(NULL, arg);
|
| | } else {
|
| | return arena->CreateMessageInternal<T>(arg);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| | template <typename T, typename Arg1, typename Arg2>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* CreateMessage(::google::protobuf::Arena* arena,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2) {
|
| | #if LANG_CXX11
|
| | static_assert(
|
| | InternalHelper<T>::is_arena_constructable::value,
|
| | "CreateMessage can only construct types that are ArenaConstructable");
|
| | #endif
|
| | if (arena == NULL) {
|
| | return new T(NULL, arg1, arg2);
|
| | } else {
|
| | return arena->CreateMessageInternal<T>(arg1, arg2);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | #if LANG_CXX11
|
| | template <typename T, typename... Args>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena, Args&&... args) {
|
| | if (arena == NULL) {
|
| | return new T(std::forward<Args>(args)...);
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | std::forward<Args>(args)...);
|
| | }
|
| | }
|
| | #endif
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena) {
|
| | if (arena == NULL) {
|
| | return new T();
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value);
|
| | }
|
| | }
|
| |
|
| |
|
| | template <typename T, typename Arg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena, const Arg& arg) {
|
| | if (arena == NULL) {
|
| | return new T(arg);
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | arg);
|
| | }
|
| | }
|
| |
|
| |
|
| | template <typename T, typename Arg1, typename Arg2>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena, const Arg1& arg1, const Arg2& arg2) {
|
| | if (arena == NULL) {
|
| | return new T(arg1, arg2);
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | arg1, arg2);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2,
|
| | const Arg3& arg3) {
|
| | if (arena == NULL) {
|
| | return new T(arg1, arg2, arg3);
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | arg1, arg2, arg3);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena,
|
| | const Arg1& arg1, const Arg2& arg2,
|
| | const Arg3& arg3, const Arg4& arg4) {
|
| | if (arena == NULL) {
|
| | return new T(arg1, arg2, arg3, arg4);
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | arg1, arg2, arg3, arg4);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4, typename Arg5>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena,
|
| | const Arg1& arg1, const Arg2& arg2,
|
| | const Arg3& arg3, const Arg4& arg4,
|
| | const Arg5& arg5) {
|
| | if (arena == NULL) {
|
| | return new T(arg1, arg2, arg3, arg4, arg5);
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | arg1, arg2, arg3, arg4, arg5);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4, typename Arg5, typename Arg6>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena,
|
| | const Arg1& arg1, const Arg2& arg2,
|
| | const Arg3& arg3, const Arg4& arg4,
|
| | const Arg5& arg5, const Arg6& arg6) {
|
| | if (arena == NULL) {
|
| | return new T(arg1, arg2, arg3, arg4, arg5, arg6);
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | arg1, arg2, arg3, arg4, arg5, arg6);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4, typename Arg5, typename Arg6, typename Arg7>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena,
|
| | const Arg1& arg1, const Arg2& arg2,
|
| | const Arg3& arg3, const Arg4& arg4,
|
| | const Arg5& arg5, const Arg6& arg6,
|
| | const Arg7& arg7) {
|
| | if (arena == NULL) {
|
| | return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
| | } else {
|
| | return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4, typename Arg5, typename Arg6, typename Arg7,
|
| | typename Arg8>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* Create(::google::protobuf::Arena* arena,
|
| | const Arg1& arg1, const Arg2& arg2,
|
| | const Arg3& arg3, const Arg4& arg4,
|
| | const Arg5& arg5, const Arg6& arg6,
|
| | const Arg7& arg7, const Arg8& arg8) {
|
| | if (arena == NULL) {
|
| | return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
| | } else {
|
| | return arena->CreateInternal<T>(
|
| | google::protobuf::internal::has_trivial_destructor<T>::value,
|
| | arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* CreateArray(::google::protobuf::Arena* arena, size_t num_elements) {
|
| | GOOGLE_CHECK_LE(num_elements,
|
| | std::numeric_limits<size_t>::max() / sizeof(T))
|
| | << "Requested size is too large to fit into size_t.";
|
| | if (arena == NULL) {
|
| | return static_cast<T*>(::operator new[](num_elements * sizeof(T)));
|
| | } else {
|
| | return arena->CreateInternalRawArray<T>(num_elements);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| | uint64 SpaceAllocated() const { return impl_.SpaceAllocated(); }
|
| |
|
| |
|
| |
|
| |
|
| | uint64 SpaceUsed() const { return impl_.SpaceUsed(); }
|
| |
|
| |
|
| |
|
| |
|
| | std::pair<uint64, uint64> SpaceAllocatedAndUsed() const {
|
| | return std::make_pair(SpaceAllocated(), SpaceUsed());
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE uint64 Reset() {
|
| |
|
| | if (on_arena_reset_ != NULL) {
|
| | on_arena_reset_(this, hooks_cookie_, impl_.SpaceAllocated());
|
| | }
|
| | return impl_.Reset();
|
| | }
|
| |
|
| |
|
| |
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
|
| | void Own(T* object) {
|
| | OwnInternal(object, google::protobuf::internal::is_convertible<T*, ::google::protobuf::Message*>());
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
|
| | void OwnDestructor(T* object) {
|
| | if (object != NULL) {
|
| | impl_.AddCleanup(object, &internal::arena_destruct_object<T>);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void OwnCustomDestructor(
|
| | void* object, void (*destruct)(void*)) {
|
| | impl_.AddCleanup(object, destruct);
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static ::google::protobuf::Arena* GetArena(const T* value) {
|
| | return GetArenaInternal(value, is_arena_constructable<T>());
|
| | }
|
| |
|
| | template <typename T>
|
| | class InternalHelper {
|
| | template <typename U>
|
| | static char DestructorSkippable(const typename U::DestructorSkippable_*);
|
| | template <typename U>
|
| | static double DestructorSkippable(...);
|
| |
|
| | typedef google::protobuf::internal::integral_constant<
|
| | bool, sizeof(DestructorSkippable<T>(static_cast<const T*>(0))) ==
|
| | sizeof(char) ||
|
| | google::protobuf::internal::has_trivial_destructor<T>::value>
|
| | is_destructor_skippable;
|
| |
|
| | template<typename U>
|
| | static char ArenaConstructable(
|
| | const typename U::InternalArenaConstructable_*);
|
| | template<typename U>
|
| | static double ArenaConstructable(...);
|
| |
|
| | typedef google::protobuf::internal::integral_constant<bool, sizeof(ArenaConstructable<T>(
|
| | static_cast<const T*>(0))) ==
|
| | sizeof(char)>
|
| | is_arena_constructable;
|
| |
|
| | #if LANG_CXX11
|
| | template <typename... Args>
|
| | static T* Construct(void* ptr, Args&&... args) {
|
| | return new (ptr) T(std::forward<Args>(args)...);
|
| | }
|
| | #else
|
| | template <typename Arg1>
|
| | static T* Construct(void* ptr, const Arg1& arg1) {
|
| | return new (ptr) T(arg1);
|
| | }
|
| | template <typename Arg1, typename Arg2>
|
| | static T* Construct(void* ptr, const Arg1& arg1, const Arg2& arg2) {
|
| | return new (ptr) T(arg1, arg2);
|
| | }
|
| | template <typename Arg1, typename Arg2, typename Arg3>
|
| | static T* Construct(void* ptr, const Arg1& arg1,
|
| | const Arg2& arg2, const Arg3& arg3) {
|
| | return new (ptr) T(arg1, arg2, arg3);
|
| | }
|
| | #endif
|
| |
|
| | static Arena* GetArena(const T* p) { return p->GetArenaNoVirtual(); }
|
| |
|
| | friend class Arena;
|
| | };
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | template <typename T>
|
| | struct is_arena_constructable : InternalHelper<T>::is_arena_constructable {};
|
| |
|
| | private:
|
| | void CallDestructorHooks();
|
| | void OnArenaAllocation(const std::type_info* allocated_type, size_t n) const;
|
| | inline void AllocHook(const std::type_info* allocated_type, size_t n) const {
|
| | if (GOOGLE_PREDICT_FALSE(hooks_cookie_ != NULL)) {
|
| | OnArenaAllocation(allocated_type, n);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| | template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | void* AllocateInternal(bool skip_explicit_ownership) {
|
| | const size_t n = internal::AlignUpTo8(sizeof(T));
|
| | AllocHook(RTTI_TYPE_ID(T), n);
|
| |
|
| | if (skip_explicit_ownership) {
|
| | return impl_.AllocateAligned(n);
|
| | } else {
|
| | return impl_.AllocateAlignedAndAddCleanup(
|
| | n, &internal::arena_destruct_object<T>);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | template <typename Msg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static Msg* CreateMaybeMessage(Arena* arena, google::protobuf::internal::true_type) {
|
| | return CreateMessage<Msg>(arena);
|
| | }
|
| |
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* CreateMaybeMessage(Arena* arena, google::protobuf::internal::false_type) {
|
| | return Create<T>(arena);
|
| | }
|
| |
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static T* CreateMaybeMessage(Arena* arena) {
|
| | return CreateMaybeMessage<T>(arena, is_arena_constructable<T>());
|
| | }
|
| |
|
| |
|
| |
|
| | template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternalRawArray(size_t num_elements) {
|
| | GOOGLE_CHECK_LE(num_elements,
|
| | std::numeric_limits<size_t>::max() / sizeof(T))
|
| | << "Requested size is too large to fit into size_t.";
|
| | const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements);
|
| |
|
| | AllocHook(RTTI_TYPE_ID(T), n);
|
| | return static_cast<T*>(impl_.AllocateAligned(n));
|
| | }
|
| |
|
| | #if LANG_CXX11
|
| | template <typename T, typename... Args>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership, Args&&... args) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership))
|
| | T(std::forward<Args>(args)...);
|
| | }
|
| | #else
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership)) T();
|
| | }
|
| |
|
| | template <typename T, typename Arg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership, const Arg& arg) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg);
|
| | }
|
| |
|
| | template <typename T, typename Arg1, typename Arg2>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2);
|
| | }
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2,
|
| | const Arg3& arg3) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership))
|
| | T(arg1, arg2, arg3);
|
| | }
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2,
|
| | const Arg3& arg3,
|
| | const Arg4& arg4) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership))
|
| | T(arg1, arg2, arg3, arg4);
|
| | }
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4, typename Arg5>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2,
|
| | const Arg3& arg3,
|
| | const Arg4& arg4,
|
| | const Arg5& arg5) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership))
|
| | T(arg1, arg2, arg3, arg4, arg5);
|
| | }
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4, typename Arg5, typename Arg6>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2,
|
| | const Arg3& arg3,
|
| | const Arg4& arg4,
|
| | const Arg5& arg5,
|
| | const Arg6& arg6) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership))
|
| | T(arg1, arg2, arg3, arg4, arg5, arg6);
|
| | }
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4, typename Arg5, typename Arg6, typename Arg7>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2,
|
| | const Arg3& arg3,
|
| | const Arg4& arg4,
|
| | const Arg5& arg5,
|
| | const Arg6& arg6,
|
| | const Arg7& arg7) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership))
|
| | T(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
| | }
|
| |
|
| | template <typename T, typename Arg1, typename Arg2, typename Arg3,
|
| | typename Arg4, typename Arg5, typename Arg6, typename Arg7,
|
| | typename Arg8>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateInternal(bool skip_explicit_ownership,
|
| | const Arg1& arg1,
|
| | const Arg2& arg2,
|
| | const Arg3& arg3,
|
| | const Arg4& arg4,
|
| | const Arg5& arg5,
|
| | const Arg6& arg6,
|
| | const Arg7& arg7,
|
| | const Arg8& arg8) {
|
| | return new (AllocateInternal<T>(skip_explicit_ownership))
|
| | T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
| | }
|
| | #endif
|
| | #if LANG_CXX11
|
| | template <typename T, typename... Args>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal(
|
| | Args&&... args) {
|
| | return InternalHelper<T>::Construct(
|
| | AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value),
|
| | this, std::forward<Args>(args)...);
|
| | }
|
| | #endif
|
| | template <typename T>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal() {
|
| | return InternalHelper<T>::Construct(
|
| | AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value),
|
| | this);
|
| | }
|
| |
|
| | template <typename T, typename Arg> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateMessageInternal(const Arg& arg) {
|
| | return InternalHelper<T>::Construct(
|
| | AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value),
|
| | this, arg);
|
| | }
|
| |
|
| | template <typename T, typename Arg1, typename Arg2>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | T* CreateMessageInternal(const Arg1& arg1, const Arg2& arg2) {
|
| | return InternalHelper<T>::Construct(
|
| | AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value),
|
| | this, arg1, arg2);
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| | template <typename T>
|
| | static void CreateInArenaStorage(T* ptr, Arena* arena) {
|
| | CreateInArenaStorageInternal(ptr, arena,
|
| | typename is_arena_constructable<T>::type());
|
| | RegisterDestructorInternal(
|
| | ptr, arena,
|
| | typename InternalHelper<T>::is_destructor_skippable::type());
|
| | }
|
| |
|
| | template <typename T>
|
| | static void CreateInArenaStorageInternal(
|
| | T* ptr, Arena* arena, google::protobuf::internal::true_type) {
|
| | InternalHelper<T>::Construct(ptr, arena);
|
| | }
|
| | template <typename T>
|
| | static void CreateInArenaStorageInternal(
|
| | T* ptr, Arena* , google::protobuf::internal::false_type) {
|
| | new (ptr) T();
|
| | }
|
| |
|
| | template <typename T>
|
| | static void RegisterDestructorInternal(
|
| | T* , Arena* , google::protobuf::internal::true_type) {}
|
| | template <typename T>
|
| | static void RegisterDestructorInternal(
|
| | T* ptr, Arena* arena, google::protobuf::internal::false_type) {
|
| | arena->OwnDestructor(ptr);
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | void OwnInternal(T* object, google::protobuf::internal::true_type) {
|
| | if (object != NULL) {
|
| | impl_.AddCleanup(object,
|
| | &internal::arena_delete_object< ::google::protobuf::Message>);
|
| | }
|
| | }
|
| | template<typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | void OwnInternal(T* object, google::protobuf::internal::false_type) {
|
| | if (object != NULL) {
|
| | impl_.AddCleanup(object, &internal::arena_delete_object<T>);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| | template <typename T> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static ::google::protobuf::Arena* GetArenaInternal(
|
| | const T* value, google::protobuf::internal::true_type) {
|
| | return InternalHelper<T>::GetArena(value);
|
| | }
|
| |
|
| | template <typename T>
|
| | GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
|
| | static ::google::protobuf::Arena* GetArenaInternal(
|
| | const T* , google::protobuf::internal::false_type) {
|
| | return NULL;
|
| | }
|
| |
|
| |
|
| | void* AllocateAligned(size_t n) {
|
| | AllocHook(NULL, n);
|
| | return impl_.AllocateAligned(internal::AlignUpTo8(n));
|
| | }
|
| |
|
| | internal::ArenaImpl impl_;
|
| |
|
| | void* (*on_arena_init_)(Arena* arena);
|
| | void (*on_arena_allocation_)(const std::type_info* allocated_type,
|
| | uint64 alloc_size, void* cookie);
|
| | void (*on_arena_reset_)(Arena* arena, void* cookie, uint64 space_used);
|
| | void (*on_arena_destruction_)(Arena* arena, void* cookie, uint64 space_used);
|
| |
|
| |
|
| |
|
| | void* hooks_cookie_;
|
| |
|
| | template <typename Type>
|
| | friend class ::google::protobuf::internal::GenericTypeHandler;
|
| | friend struct internal::ArenaStringPtr;
|
| | friend class internal::LazyField;
|
| | template <typename Key, typename T>
|
| | friend class Map;
|
| | };
|
| |
|
| |
|
| | #undef RTTI_TYPE_ID
|
| |
|
| | }
|
| |
|
| | }
|
| | #endif
|
| |
|