ROS 2 rclcpp + rcl - rolling  rolling-a919a6e5
ROS 2 C++ Client Library with ROS Client Library
allocator_deleter.hpp
1 // Copyright 2015 Open Source Robotics Foundation, Inc.
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 RCLCPP__ALLOCATOR__ALLOCATOR_DELETER_HPP_
16 #define RCLCPP__ALLOCATOR__ALLOCATOR_DELETER_HPP_
17 
18 #include <memory>
19 #include <stdexcept>
20 
21 namespace rclcpp
22 {
23 namespace allocator
24 {
25 
26 template<typename Allocator>
28 {
29  template<typename T>
30  using AllocRebind = typename std::allocator_traits<Allocator>::template rebind_alloc<T>;
31 
32 public:
34  : allocator_(nullptr)
35  {
36  }
37 
38  explicit AllocatorDeleter(Allocator * a)
39  : allocator_(a)
40  {
41  }
42 
43  template<typename T>
44  explicit AllocatorDeleter(const AllocatorDeleter<T> & a)
45  {
46  allocator_ = a.get_allocator();
47  }
48 
49  template<typename T>
50  void operator()(T * ptr)
51  {
52  std::allocator_traits<AllocRebind<T>>::destroy(*allocator_, ptr);
53  std::allocator_traits<AllocRebind<T>>::deallocate(*allocator_, ptr, 1);
54  ptr = nullptr;
55  }
56 
57  Allocator * get_allocator() const
58  {
59  return allocator_;
60  }
61 
62  void set_allocator(Allocator * alloc)
63  {
64  allocator_ = alloc;
65  }
66 
67 private:
68  Allocator * allocator_;
69 };
70 
71 template<typename Alloc, typename T, typename D>
72 void set_allocator_for_deleter([[maybe_unused]] D * deleter, [[maybe_unused]] Alloc * alloc)
73 {
74  throw std::runtime_error("Reached unexpected template specialization");
75 }
76 
77 template<typename T, typename U>
78 void set_allocator_for_deleter(
79  [[maybe_unused]] std::default_delete<T> * deleter,
80  [[maybe_unused]] std::allocator<U> * alloc)
81 {
82  // This function is intentionally left empty.
83 }
84 
85 template<typename Alloc, typename T>
86 void set_allocator_for_deleter(AllocatorDeleter<T> * deleter, Alloc * alloc)
87 {
88  if (!deleter || !alloc) {
89  throw std::invalid_argument("Argument was NULL to set_allocator_for_deleter");
90  }
91  deleter->set_allocator(alloc);
92 }
93 
94 template<typename Alloc, typename T>
95 using Deleter = typename std::conditional<
96  std::is_same<typename std::allocator_traits<Alloc>::template rebind_alloc<T>,
97  std::allocator<T>>::value,
98  std::default_delete<T>,
99  AllocatorDeleter<Alloc>
100  >::type;
101 } // namespace allocator
102 } // namespace rclcpp
103 
104 #endif // RCLCPP__ALLOCATOR__ALLOCATOR_DELETER_HPP_
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.