// Copyright (C) 2017 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SERIALIZE_ARENA_PTR_H_ #define SERIALIZE_ARENA_PTR_H_ #include #include namespace iorap { namespace serialize { /** * @file * * Helpers for protobuf arena allocators. We use smart pointers * with an arena embedded inside of them to avoid caring about the * arena in other parts of libiorap. */ // Arena-managed objects must not be deleted manually. // When the Arena goes out of scope, it cleans everything up itself. template void DoNotDelete(T*) {} template )>> struct ArenaPtr : public Base { template static ArenaPtr Make(Args&& ... args) { ArenaPtr arena_ptr(nullptr); arena_ptr.reset(google::protobuf::Arena::Create(arena_ptr.arena_.get(), std::forward(args)...)); return arena_ptr; } ArenaPtr(std::nullptr_t) : Base(nullptr, &DoNotDelete) {} // NOLINT explicit. private: // Use a unique_ptr because Arena doesn't support move semantics. std::unique_ptr arena_{new google::protobuf::Arena{}}; }; template > struct ArenaSharedPtr : public Base { template static ArenaSharedPtr Make(Args&& ... args) { ArenaSharedPtr arena_ptr(nullptr, &DoNotDelete); arena_ptr.reset(google::protobuf::Arena::Create(arena_ptr.arena_.get(), std::forward(args)...)); return arena_ptr; } ArenaSharedPtr() = default; template ArenaSharedPtr(std::nullptr_t, Deleter d) : Base(nullptr, d) {} // NOLINT explicit. private: std::shared_ptr arena_{new google::protobuf::Arena{}}; }; } // namespace serialize } // namespace iorap #endif