• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SERIALIZE_ARENA_PTR_H_
16 #define SERIALIZE_ARENA_PTR_H_
17 
18 #include <google/protobuf/arena.h>
19 #include <memory>
20 
21 namespace iorap {
22 namespace serialize {
23 
24 /**
25  * @file
26  *
27  * Helpers for protobuf arena allocators. We use smart pointers
28  * with an arena embedded inside of them to avoid caring about the
29  * arena in other parts of libiorap.
30  */
31 
32 // Arena-managed objects must not be deleted manually.
33 // When the Arena goes out of scope, it cleans everything up itself.
34 template <typename T>
DoNotDelete(T *)35 void DoNotDelete(T*) {}
36 
37 template <typename T, typename Base = std::unique_ptr<T, decltype(&DoNotDelete<T>)>>
38 struct ArenaPtr : public Base {
39   template <typename... Args>
MakeArenaPtr40   static ArenaPtr<T> Make(Args&& ... args) {
41     ArenaPtr<T> arena_ptr(nullptr);
42     arena_ptr.reset(google::protobuf::Arena::Create<T>(arena_ptr.arena_.get(),
43                                                        std::forward<Args>(args)...));
44     return arena_ptr;
45   }
46 
ArenaPtrArenaPtr47   ArenaPtr(std::nullptr_t) : Base(nullptr, &DoNotDelete<T>) {}  // NOLINT explicit.
48 
49  private:
50   // Use a unique_ptr because Arena doesn't support move semantics.
51   std::unique_ptr<google::protobuf::Arena> arena_{new google::protobuf::Arena{}};
52 };
53 
54 template <typename T, typename Base = std::shared_ptr<T>>
55 struct ArenaSharedPtr : public Base {
56   template <typename... Args>
MakeArenaSharedPtr57   static ArenaSharedPtr<T> Make(Args&& ... args) {
58     ArenaSharedPtr<T> arena_ptr(nullptr, &DoNotDelete<T>);
59     arena_ptr.reset(google::protobuf::Arena::Create<T>(arena_ptr.arena_.get(),
60                                                        std::forward<Args>(args)...));
61     return arena_ptr;
62   }
63 
64   ArenaSharedPtr() = default;
65   template <typename Deleter>
ArenaSharedPtrArenaSharedPtr66   ArenaSharedPtr(std::nullptr_t, Deleter d) : Base(nullptr, d) {}  // NOLINT explicit.
67 
68  private:
69   std::shared_ptr<google::protobuf::Arena> arena_{new google::protobuf::Arena{}};
70 };
71 
72 }  // namespace serialize
73 }  // namespace iorap
74 
75 #endif
76 
77