rclcpp  master
C++ ROS Client Library API
allocator_common.hpp
Go to the documentation of this file.
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_COMMON_HPP_
16 #define RCLCPP__ALLOCATOR__ALLOCATOR_COMMON_HPP_
17 
18 #include <memory>
19 
20 #include "rcl/allocator.h"
21 
23 
24 namespace rclcpp
25 {
26 namespace allocator
27 {
28 
29 template<typename T, typename Alloc>
30 using AllocRebind = typename std::allocator_traits<Alloc>::template rebind_traits<T>;
31 
32 template<typename Alloc>
33 void * retyped_allocate(size_t size, void * untyped_allocator)
34 {
35  auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
36  if (!typed_allocator) {
37  throw std::runtime_error("Received incorrect allocator type");
38  }
39  return std::allocator_traits<Alloc>::allocate(*typed_allocator, size);
40 }
41 
42 template<typename T, typename Alloc>
43 void retyped_deallocate(void * untyped_pointer, void * untyped_allocator)
44 {
45  auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
46  if (!typed_allocator) {
47  throw std::runtime_error("Received incorrect allocator type");
48  }
49  auto typed_ptr = static_cast<T *>(untyped_pointer);
50  std::allocator_traits<Alloc>::deallocate(*typed_allocator, typed_ptr, 1);
51 }
52 
53 template<typename T, typename Alloc>
54 void * retyped_reallocate(void * untyped_pointer, size_t size, void * untyped_allocator)
55 {
56  auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
57  if (!typed_allocator) {
58  throw std::runtime_error("Received incorrect allocator type");
59  }
60  auto typed_ptr = static_cast<T *>(untyped_pointer);
61  std::allocator_traits<Alloc>::deallocate(*typed_allocator, typed_ptr, 1);
62  return std::allocator_traits<Alloc>::allocate(*typed_allocator, size);
63 }
64 
65 
66 // Convert a std::allocator_traits-formatted Allocator into an rcl allocator
67 template<typename T, typename Alloc,
68 typename std::enable_if<!std::is_same<Alloc, std::allocator<void>>::value>::type * = nullptr>
70 {
72 #ifndef _WIN32
73  rcl_allocator.allocate = &retyped_allocate<Alloc>;
74  rcl_allocator.deallocate = &retyped_deallocate<T, Alloc>;
75  rcl_allocator.reallocate = &retyped_reallocate<T, Alloc>;
76  rcl_allocator.state = &allocator;
77 #else
78  (void)allocator; // Remove warning
79 #endif
80  return rcl_allocator;
81 }
82 
83 // TODO(jacquelinekay) Workaround for an incomplete implementation of std::allocator<void>
84 template<typename T, typename Alloc,
85 typename std::enable_if<std::is_same<Alloc, std::allocator<void>>::value>::type * = nullptr>
86 rcl_allocator_t get_rcl_allocator(Alloc & allocator)
87 {
88  (void)allocator;
90 }
91 
92 } // namespace allocator
93 } // namespace rclcpp
94 
95 #endif // RCLCPP__ALLOCATOR__ALLOCATOR_COMMON_HPP_
void retyped_deallocate(void *untyped_pointer, void *untyped_allocator)
Definition: allocator_common.hpp:43
void *(* reallocate)(void *pointer, size_t size, void *state)
Definition: allocator_common.hpp:24
void *(* allocate)(size_t size, void *state)
typename std::allocator_traits< Alloc >::template rebind_traits< T > AllocRebind
Definition: allocator_common.hpp:30
void * retyped_allocate(size_t size, void *untyped_allocator)
Definition: allocator_common.hpp:33
void * retyped_reallocate(void *untyped_pointer, size_t size, void *untyped_allocator)
Definition: allocator_common.hpp:54
rcl_allocator_t get_rcl_allocator(Alloc &allocator)
Definition: allocator_common.hpp:69
void(* deallocate)(void *pointer, void *state)
#define rcl_get_default_allocator