Point Cloud Library (PCL) 1.12.0
Loading...
Searching...
No Matches
type_traits.h
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 * Copyright (c) 2020-, Open Perception, Inc.
6 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * * Neither the name of the copyright holder(s) nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38#pragma once
39
40#include <pcl/point_struct_traits.h> // for pcl::traits::POD, pcl::traits::name, pcl::traits::datatype, pcl::traits::offset
41
42#include <cstddef> // for std::size_t
43#include <cstdint> // for std::uint8_t
44
45#include <functional> // for std::function, needed till C++17
46#include <string> // for std::string
47#include <type_traits> // for std::false_type, std::true_type
48
49namespace pcl
50{
51 namespace deprecated
52 {
53 /** \class DeprecatedType
54 * \brief A dummy type to aid in template parameter deprecation
55 */
56 struct T {};
57 }
58
59 namespace fields
60 {
61 // Tag types get put in this namespace
62 }
63
64 namespace traits
65 {
66 namespace detail {
67 /**
68 * \brief Enumeration for different numerical types
69 *
70 * \details struct used to enable scope and implicit conversion to int
71 */
73 static const std::uint8_t INT8 = 1, UINT8 = 2,
74 INT16 = 3, UINT16 = 4,
75 INT32 = 5, UINT32 = 6,
76 FLOAT32 = 7, FLOAT64 = 8;
77 };
78 }
79
80 // Metafunction to return enum value representing a type
81 template<typename T> struct asEnum {};
82 template<> struct asEnum<std::int8_t> { static const std::uint8_t value = detail::PointFieldTypes::INT8; };
83 template<> struct asEnum<std::uint8_t> { static const std::uint8_t value = detail::PointFieldTypes::UINT8; };
84 template<> struct asEnum<std::int16_t> { static const std::uint8_t value = detail::PointFieldTypes::INT16; };
85 template<> struct asEnum<std::uint16_t> { static const std::uint8_t value = detail::PointFieldTypes::UINT16; };
86 template<> struct asEnum<std::int32_t> { static const std::uint8_t value = detail::PointFieldTypes::INT32; };
87 template<> struct asEnum<std::uint32_t> { static const std::uint8_t value = detail::PointFieldTypes::UINT32; };
88 template<> struct asEnum<float> { static const std::uint8_t value = detail::PointFieldTypes::FLOAT32; };
89 template<> struct asEnum<double> { static const std::uint8_t value = detail::PointFieldTypes::FLOAT64; };
90
91 template<typename T>
92 static constexpr std::uint8_t asEnum_v = asEnum<T>::value;
93
94 // Metafunction to return type of enum value
95 template<int> struct asType {};
96 template<> struct asType<detail::PointFieldTypes::INT8> { using type = std::int8_t; };
97 template<> struct asType<detail::PointFieldTypes::UINT8> { using type = std::uint8_t; };
98 template<> struct asType<detail::PointFieldTypes::INT16> { using type = std::int16_t; };
99 template<> struct asType<detail::PointFieldTypes::UINT16> { using type = std::uint16_t; };
100 template<> struct asType<detail::PointFieldTypes::INT32> { using type = std::int32_t; };
101 template<> struct asType<detail::PointFieldTypes::UINT32> { using type = std::uint32_t; };
102 template<> struct asType<detail::PointFieldTypes::FLOAT32> { using type = float; };
103 template<> struct asType<detail::PointFieldTypes::FLOAT64> { using type = double; };
104
105 template<int index>
107
108 } // namespace traits
109
110 /** \brief A helper functor that can copy a specific value if the given field exists.
111 *
112 * \note In order to actually copy the value an instance of this functor should be passed
113 * to a pcl::for_each_type loop. See the example below.
114 *
115 * \code
116 * PointInT p;
117 * bool exists;
118 * float value;
119 * using FieldList = typename pcl::traits::fieldList<PointInT>::type;
120 * pcl::for_each_type<FieldList> (pcl::CopyIfFieldExists<PointT, float> (p, "intensity", exists, value));
121 * \endcode
122 */
123 template <typename PointInT, typename OutT>
125 {
126 using Pod = typename traits::POD<PointInT>::type;
127
128 /** \brief Constructor.
129 * \param[in] pt the input point
130 * \param[in] field the name of the field
131 * \param[out] exists set to true if the field exists, false otherwise
132 * \param[out] value the copied field value
133 */
134 CopyIfFieldExists (const PointInT &pt,
135 const std::string &field,
136 bool &exists,
137 OutT &value)
138 : pt_ (reinterpret_cast<const Pod&>(pt)), name_ (field), exists_ (exists), value_ (value)
139 {
140 exists_ = false;
141 }
142
143 /** \brief Constructor.
144 * \param[in] pt the input point
145 * \param[in] field the name of the field
146 * \param[out] value the copied field value
147 */
148 CopyIfFieldExists (const PointInT &pt,
149 const std::string &field,
150 OutT &value)
151 : pt_ (reinterpret_cast<const Pod&>(pt)), name_ (field), exists_ (exists_tmp_), value_ (value)
152 {
153 }
154
155 /** \brief Operator. Data copy happens here. */
156 template <typename Key> inline void
158 {
159 if (name_ == pcl::traits::name<PointInT, Key>::value)
160 {
161 exists_ = true;
162 using T = typename pcl::traits::datatype<PointInT, Key>::type;
163 const std::uint8_t* data_ptr = reinterpret_cast<const std::uint8_t*>(&pt_) + pcl::traits::offset<PointInT, Key>::value;
164 value_ = static_cast<OutT> (*reinterpret_cast<const T*>(data_ptr));
165 }
166 }
167
168 private:
169 const Pod &pt_;
170 const std::string &name_;
171 bool &exists_;
172 // Bogus entry
173 bool exists_tmp_;
174 OutT &value_;
175 };
176
177 /** \brief A helper functor that can set a specific value in a field if the field exists.
178 *
179 * \note In order to actually set the value an instance of this functor should be passed
180 * to a pcl::for_each_type loop. See the example below.
181 *
182 * \code
183 * PointT p;
184 * using FieldList = typename pcl::traits::fieldList<PointT>::type;
185 * pcl::for_each_type<FieldList> (pcl::SetIfFieldExists<PointT, float> (p, "intensity", 42.0f));
186 * \endcode
187 */
188 template <typename PointOutT, typename InT>
190 {
191 using Pod = typename traits::POD<PointOutT>::type;
192
193 /** \brief Constructor.
194 * \param[in] pt the input point
195 * \param[in] field the name of the field
196 * \param[out] value the value to set
197 */
198 SetIfFieldExists (PointOutT &pt,
199 const std::string &field,
200 const InT &value)
201 : pt_ (reinterpret_cast<Pod&>(pt)), name_ (field), value_ (value)
202 {
203 }
204
205 /** \brief Operator. Data copy happens here. */
206 template <typename Key> inline void
208 {
209 if (name_ == pcl::traits::name<PointOutT, Key>::value)
210 {
211 using T = typename pcl::traits::datatype<PointOutT, Key>::type;
212 std::uint8_t* data_ptr = reinterpret_cast<std::uint8_t*>(&pt_) + pcl::traits::offset<PointOutT, Key>::value;
213 *reinterpret_cast<T*>(data_ptr) = static_cast<T> (value_);
214 }
215 }
216
217 private:
218 Pod &pt_;
219 const std::string &name_;
220 const InT &value_;
221 };
222
223 /** \brief Set the value at a specified field in a point
224 * \param[out] pt the point to set the value to
225 * \param[in] field_offset the offset of the field
226 * \param[in] value the value to set
227 */
228 template <typename PointT, typename ValT> inline void
229 setFieldValue (PointT &pt, std::size_t field_offset, const ValT &value)
230 {
231 std::uint8_t* data_ptr = reinterpret_cast<std::uint8_t*>(&pt) + field_offset;
232 *reinterpret_cast<ValT*>(data_ptr) = value;
233 }
234
235 /** \brief Get the value at a specified field in a point
236 * \param[in] pt the point to get the value from
237 * \param[in] field_offset the offset of the field
238 * \param[out] value the value to retrieve
239 */
240 template <typename PointT, typename ValT> inline void
241 getFieldValue (const PointT &pt, std::size_t field_offset, ValT &value)
242 {
243 const std::uint8_t* data_ptr = reinterpret_cast<const std::uint8_t*>(&pt) + field_offset;
244 value = *reinterpret_cast<const ValT*>(data_ptr);
245 }
246
247 template <typename ...> using void_t = void; // part of std in c++17
248
249#ifdef DOXYGEN_ONLY
250
251 /**
252 * \brief Tests at compile time if type T has a custom allocator
253 *
254 * \see pcl::make_shared, PCL_MAKE_ALIGNED_OPERATOR_NEW
255 * \tparam T Type of the object to test
256 */
257 template <typename T> struct has_custom_allocator;
258
259#else
260
261 template <typename, typename = void_t<>> struct has_custom_allocator : std::false_type {};
262 template <typename T> struct has_custom_allocator<T, void_t<typename T::_custom_allocator_type_trait>> : std::true_type {};
263
264#endif
265
266 /**
267 * \todo: Remove in C++17
268 */
269#ifndef __cpp_lib_is_invocable
270 // Implementation taken from: https://stackoverflow.com/a/51188325
271 template <typename F, typename... Args>
272 constexpr bool is_invocable_v =
273 std::is_constructible<std::function<void(Args...)>,
274 std::reference_wrapper<std::remove_reference_t<F>>>::value;
275
276 template <typename R, typename F, typename... Args>
277 constexpr bool is_invocable_r_v =
278 std::is_constructible<std::function<R(Args...)>,
279 std::reference_wrapper<std::remove_reference_t<F>>>::value;
280#else
281 using std::is_invocable_v;
282 using std::is_invocable_r_v;
283#endif
284
285 /**
286 * \todo: Remove in C++17
287 */
288#ifndef __cpp_lib_remove_cvref
289 template <typename T>
290 using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
291#else
292 using std::remove_cvref_t;
293#endif
294}
typename asType< index >::type asType_t
static constexpr std::uint8_t asEnum_v
Definition type_traits.h:92
void setFieldValue(PointT &pt, std::size_t field_offset, const ValT &value)
Set the value at a specified field in a point.
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
constexpr bool is_invocable_v
void getFieldValue(const PointT &pt, std::size_t field_offset, ValT &value)
Get the value at a specified field in a point.
void void_t
constexpr bool is_invocable_r_v
A helper functor that can copy a specific value if the given field exists.
CopyIfFieldExists(const PointInT &pt, const std::string &field, OutT &value)
Constructor.
CopyIfFieldExists(const PointInT &pt, const std::string &field, bool &exists, OutT &value)
Constructor.
void operator()()
Operator.
typename traits::POD< PointInT >::type Pod
A point structure representing Euclidean xyz coordinates, and the RGB color.
A helper functor that can set a specific value in a field if the field exists.
SetIfFieldExists(PointOutT &pt, const std::string &field, const InT &value)
Constructor.
typename traits::POD< PointOutT >::type Pod
void operator()()
Operator.
Tests at compile time if type T has a custom allocator.
Enumeration for different numerical types.
Definition type_traits.h:72
static const std::uint8_t INT16
Definition type_traits.h:74
static const std::uint8_t FLOAT64
Definition type_traits.h:76
static const std::uint8_t UINT8
Definition type_traits.h:73
static const std::uint8_t UINT32
Definition type_traits.h:75
static const std::uint8_t FLOAT32
Definition type_traits.h:76
static const std::uint8_t INT32
Definition type_traits.h:75
static const std::uint8_t UINT16
Definition type_traits.h:74
static const std::uint8_t INT8
Definition type_traits.h:73