Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
register_point_struct.h
Go to the documentation of this file.
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  *
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 Willow Garage, Inc. 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  * $Id: register_point_struct.h 6126 2012-07-03 20:19:58Z aichim $
37  *
38  */
39 
40 #ifndef PCL_REGISTER_POINT_STRUCT_H_
41 #define PCL_REGISTER_POINT_STRUCT_H_
42 
43 #include <pcl/point_traits.h>
44 
45 #include <boost/mpl/vector.hpp>
46 #include <boost/mpl/for_each.hpp>
47 #include <boost/mpl/assert.hpp>
48 #include <boost/preprocessor/seq/enum.hpp>
49 #include <boost/preprocessor/seq/for_each.hpp>
50 #include <boost/preprocessor/seq/transform.hpp>
51 #include <boost/preprocessor/cat.hpp>
52 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
53 #include <boost/type_traits/is_pod.hpp>
54 #include <stddef.h> //offsetof
55 
56 // Must be used in global namespace with name fully qualified
57 #define POINT_CLOUD_REGISTER_POINT_STRUCT(name, fseq) \
58  POINT_CLOUD_REGISTER_POINT_STRUCT_I(name, \
59  BOOST_PP_CAT(POINT_CLOUD_REGISTER_POINT_STRUCT_X fseq, 0)) \
60  /***/
61 
62 #define POINT_CLOUD_REGISTER_POINT_WRAPPER(wrapper, pod) \
63  BOOST_MPL_ASSERT_MSG(sizeof(wrapper) == sizeof(pod), POINT_WRAPPER_AND_POD_TYPES_HAVE_DIFFERENT_SIZES, (wrapper&, pod&)); \
64  namespace pcl { \
65  namespace traits { \
66  template<> struct POD<wrapper> { typedef pod type; }; \
67  } \
68  } \
69  /***/
70 
71 // These macros help transform the unusual data structure (type, name, tag)(type, name, tag)...
72 // into a proper preprocessor sequence of 3-tuples ((type, name, tag))((type, name, tag))...
73 #define POINT_CLOUD_REGISTER_POINT_STRUCT_X(type, name, tag) \
74  ((type, name, tag)) POINT_CLOUD_REGISTER_POINT_STRUCT_Y
75 #define POINT_CLOUD_REGISTER_POINT_STRUCT_Y(type, name, tag) \
76  ((type, name, tag)) POINT_CLOUD_REGISTER_POINT_STRUCT_X
77 #define POINT_CLOUD_REGISTER_POINT_STRUCT_X0
78 #define POINT_CLOUD_REGISTER_POINT_STRUCT_Y0
79 
80 // Construct type traits given full sequence of (type, name, tag) triples
81 // BOOST_MPL_ASSERT_MSG(boost::is_pod<name>::value,
82 // REGISTERED_POINT_TYPE_MUST_BE_PLAIN_OLD_DATA, (name));
83 #define POINT_CLOUD_REGISTER_POINT_STRUCT_I(name, seq) \
84  namespace pcl \
85  { \
86  namespace fields \
87  { \
88  BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_TAG, name, seq) \
89  } \
90  namespace traits \
91  { \
92  BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_NAME, name, seq) \
93  BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_OFFSET, name, seq) \
94  BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_DATATYPE, name, seq) \
95  POINT_CLOUD_REGISTER_POINT_FIELD_LIST(name, POINT_CLOUD_EXTRACT_TAGS(seq)) \
96  } \
97  } \
98  /***/
99 
100 #define POINT_CLOUD_REGISTER_FIELD_TAG(r, name, elem) \
101  struct BOOST_PP_TUPLE_ELEM(3, 2, elem); \
102  /***/
103 
104 #define POINT_CLOUD_REGISTER_FIELD_NAME(r, point, elem) \
105  template<int dummy> \
106  struct name<point, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem), dummy> \
107  { \
108  static const char value[]; \
109  }; \
110  \
111  template<int dummy> \
112  const char name<point, \
113  pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem), \
114  dummy>::value[] = \
115  BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(3, 2, elem)); \
116  /***/
117 
118 #define POINT_CLOUD_REGISTER_FIELD_OFFSET(r, name, elem) \
119  template<> struct offset<name, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)> \
120  { \
121  static const size_t value = offsetof(name, BOOST_PP_TUPLE_ELEM(3, 1, elem)); \
122  }; \
123  /***/
124 
125 // \note: the mpl::identity weirdness is to support array types without requiring the
126 // user to wrap them. The basic problem is:
127 // typedef float[81] type; // SYNTAX ERROR!
128 // typedef float type[81]; // OK, can now use "type" as a synonym for float[81]
129 #define POINT_CLOUD_REGISTER_FIELD_DATATYPE(r, name, elem) \
130  template<> struct datatype<name, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)> \
131  { \
132  typedef boost::mpl::identity<BOOST_PP_TUPLE_ELEM(3, 0, elem)>::type type; \
133  typedef decomposeArray<type> decomposed; \
134  static const uint8_t value = asEnum<decomposed::type>::value; \
135  static const uint32_t size = decomposed::value; \
136  }; \
137  /***/
138 
139 #define POINT_CLOUD_TAG_OP(s, data, elem) pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)
140 
141 #define POINT_CLOUD_EXTRACT_TAGS(seq) BOOST_PP_SEQ_TRANSFORM(POINT_CLOUD_TAG_OP, _, seq)
142 
143 #define POINT_CLOUD_REGISTER_POINT_FIELD_LIST(name, seq) \
144  template<> struct fieldList<name> \
145  { \
146  typedef boost::mpl::vector<BOOST_PP_SEQ_ENUM(seq)> type; \
147  }; \
148  /***/
149 
150 // Disabling barely-used Fusion registration of point types for now.
151 #if 0
152 #define POINT_CLOUD_EXPAND_TAG_OP(s, data, elem) \
153  (boost::mpl::identity<BOOST_PP_TUPLE_ELEM(3, 0, elem)>::type, \
154  BOOST_PP_TUPLE_ELEM(3, 1, elem), \
155  pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)) \
156  /***/
157 
158 #define POINT_CLOUD_EXPAND_TAGS(seq) BOOST_PP_SEQ_TRANSFORM(POINT_CLOUD_EXPAND_TAG_OP, _, seq)
159 
160 #define POINT_CLOUD_REGISTER_WITH_FUSION(name, seq) \
161  BOOST_FUSION_ADAPT_ASSOC_STRUCT_I(name, POINT_CLOUD_EXPAND_TAGS(seq)) \
162  /***/
163 #endif
164 
165 #endif //#ifndef PCL_REGISTER_POINT_STRUCT_H_