Point Cloud Library (PCL)  1.11.1
point_struct_traits.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2012, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #pragma once
39 
40 // https://bugreports.qt-project.org/browse/QTBUG-22829
41 #ifndef Q_MOC_RUN
42 #include <boost/mpl/assert.hpp> // for BOOST_MPL_ASSERT_MSG
43 #include <boost/mpl/identity.hpp> // for boost::mpl::identity
44 
45 #include <boost/mpl/vector.hpp> // for boost::mpl::vector
46 #include <boost/preprocessor/seq/enum.hpp> // for BOOST_PP_SEQ_ENUM
47 #include <boost/preprocessor/tuple/elem.hpp> // for BOOST_PP_TUPLE_ELEM
48 #include <boost/preprocessor/stringize.hpp> // for BOOST_PP_STRINGIZE
49 #endif
50 
51 // This is required for the workaround at line 84
52 #ifdef _MSC_VER
53 #include <Eigen/Core>
54 #include <Eigen/src/StlSupport/details.h>
55 #endif
56 
57 #include <cstddef> // for std::size_t, offsetof
58 #include <cstdint> // for std::int8_t, std::uint8_t, std::int16_t, std::uint16_t, std::int32_t, std::uint32_t
59 #include <type_traits> // for std::is_same, std::remove_all_extents_t
60 
61 namespace pcl
62 {
63 namespace traits
64 {
65 
66 // forward declaration
67 template<typename T> struct asEnum;
68 
69 // Metafunction to decompose a type (possibly of array of any number of dimensions) into
70 // its scalar type and total number of elements.
71 template<typename T> struct decomposeArray
72 {
73  using type = std::remove_all_extents_t<T>;
74  static const std::uint32_t value = sizeof (T) / sizeof (type);
75 };
76 
77 // For non-POD point types, this is specialized to return the corresponding POD type.
78 template<typename PointT>
79 struct POD
80 {
81  using type = PointT;
82 };
83 
84 #ifdef _MSC_VER
85 /* Sometimes when calling functions like `copyPoint()` or `copyPointCloud`
86  * without explicitly specifying point types, MSVC deduces them to be e.g.
87  * `Eigen::internal::workaround_msvc_stl_support<pcl::PointXYZ>` instead of
88  * plain `pcl::PointXYZ`. Subsequently these types are passed to meta-
89  * functions like `has_field` or `fieldList` and make them choke. This hack
90  * makes use of the fact that internally `fieldList` always applies `POD` to
91  * its argument type. This specialization therefore allows to unwrap the
92  * contained point type. */
93 template<typename PointT>
94 struct POD<Eigen::internal::workaround_msvc_stl_support<PointT> >
95 {
96  using type = PointT;
97 };
98 #endif
99 
100 // name
101 /* This really only depends on Tag, but we go through some gymnastics to avoid ODR violations.
102  We template it on the point type PointT to avoid ODR violations when registering multiple
103  point types with shared tags.
104  The dummy parameter is so we can partially specialize name on PointT and Tag but leave it
105  templated on dummy. Each specialization declares a static char array containing the tag
106  name. The definition of the static member would conflict when linking multiple translation
107  units that include the point type registration. But when the static member definition is
108  templated (on dummy), we sidestep the ODR issue.
109 */
110 template<class PointT, typename Tag, int dummy = 0>
111 struct name /** \cond NO_WARN_RECURSIVE */ : name<typename POD<PointT>::type, Tag, dummy> /** \endcond */
112 { /** \cond NO_WARN_RECURSIVE */
113  // Contents of specialization:
114  // static const char value[];
115 
116  // Avoid infinite compile-time recursion
117  BOOST_MPL_ASSERT_MSG((!std::is_same<PointT, typename POD<PointT>::type>::value),
118  POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
119 };
120 } // namespace traits
121 } // namespace pcl
122 
123 #define POINT_CLOUD_REGISTER_FIELD_NAME(r, point, elem) \
124  template<int dummy> \
125  struct name<point, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem), dummy> \
126  { /** \endcond */ \
127  static const char value[]; \
128  }; \
129  \
130  template<int dummy> \
131  const char name<point, \
132  pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem), \
133  dummy>::value[] = \
134  BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(3, 2, elem)); \
135 
136 
137 namespace pcl
138 {
139 namespace traits
140 {
141 // offset
142 template<class PointT, typename Tag>
143 struct offset /** \cond NO_WARN_RECURSIVE */ : offset<typename POD<PointT>::type, Tag> /** \endcond */
144 { /** \cond NO_WARN_RECURSIVE */
145  // Contents of specialization:
146  // static const std::size_t value;
147 
148  // Avoid infinite compile-time recursion
149  BOOST_MPL_ASSERT_MSG((!std::is_same<PointT, typename POD<PointT>::type>::value),
150  POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
151 };
152 } // namespace traits
153 } // namespace pcl
154 
155 #define POINT_CLOUD_REGISTER_FIELD_OFFSET(r, name, elem) \
156  template<> struct offset<name, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)> \
157  { /** \endcond */ \
158  static const std::size_t value = offsetof(name, BOOST_PP_TUPLE_ELEM(3, 1, elem)); \
159  }; \
160 
161 
162 namespace pcl
163 {
164 namespace traits
165 {
166  // datatype
167  template<class PointT, typename Tag>
168  struct datatype /** \cond NO_WARN_RECURSIVE */ : datatype<typename POD<PointT>::type, Tag> /** \endcond */
169  { /** \cond NO_WARN_RECURSIVE */
170  // Contents of specialization:
171  // using type = ...;
172  // static const std::uint8_t value;
173  // static const std::uint32_t size;
174 
175  // Avoid infinite compile-time recursion
176  BOOST_MPL_ASSERT_MSG((!std::is_same<PointT, typename POD<PointT>::type>::value),
177  POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
178  };
179  } // namespace traits
180  } // namespace pcl
181 
182 #define POINT_CLOUD_REGISTER_FIELD_DATATYPE(r, name, elem) \
183  template<> struct datatype<name, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)> \
184  { /** \endcond */ \
185  using type = boost::mpl::identity<BOOST_PP_TUPLE_ELEM(3, 0, elem)>::type; \
186  using decomposed = decomposeArray<type>; \
187  static const std::uint8_t value = asEnum<decomposed::type>::value; \
188  static const std::uint32_t size = decomposed::value; \
189  }; \
190 
191 
192 namespace pcl
193 {
194 namespace traits
195 {
196 // fields
197 template<typename PointT>
198 struct fieldList /** \cond NO_WARN_RECURSIVE */ : fieldList<typename POD<PointT>::type> /** \endcond */
199 { /** \cond NO_WARN_RECURSIVE */
200  // Contents of specialization:
201  // using type = boost::mpl::vector<...>;
202 
203  // Avoid infinite compile-time recursion
204  BOOST_MPL_ASSERT_MSG((!std::is_same<PointT, typename POD<PointT>::type>::value),
205  POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
206 };
207 } // namespace traits
208 } // namespace pcl
209 
210 #define POINT_CLOUD_REGISTER_POINT_FIELD_LIST(name, seq) \
211  template<> struct fieldList<name> \
212  { /** \endcond */ \
213  using type = boost::mpl::vector<BOOST_PP_SEQ_ENUM(seq)>; \
214  };
pcl
Definition: convolution.h:46
pcl::uint32_t
std::uint32_t uint32_t
Definition: types.h:58
Eigen
Definition: bfgs.h:10
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition: point_types.hpp:629