Point Cloud Library (PCL)  1.3.1
register_point_struct.h
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id: register_point_struct.h 1380 2011-06-19 11:34:29Z bouffa $
00035  *
00036  */
00037 
00038 #ifndef PCL_REGISTER_POINT_STRUCT_H_
00039 #define PCL_REGISTER_POINT_STRUCT_H_
00040 
00041 #include "pcl/ros/point_traits.h"
00042 
00043 #include <boost/mpl/vector.hpp>
00044 #include <boost/mpl/for_each.hpp>
00045 #include <boost/mpl/assert.hpp>
00046 #include <boost/preprocessor/seq/enum.hpp>
00047 #include <boost/preprocessor/seq/for_each.hpp>
00048 #include <boost/preprocessor/seq/transform.hpp>
00049 #include <boost/preprocessor/cat.hpp>
00050 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
00051 #include <boost/type_traits/is_pod.hpp>
00052 #include <stddef.h> //offsetof
00053 
00054 // Must be used in global namespace with name fully qualified
00055 #define POINT_CLOUD_REGISTER_POINT_STRUCT(name, fseq)               \
00056   POINT_CLOUD_REGISTER_POINT_STRUCT_I(name,                         \
00057     BOOST_PP_CAT(POINT_CLOUD_REGISTER_POINT_STRUCT_X fseq, 0))      \
00058   /***/
00059 
00060 #define POINT_CLOUD_REGISTER_POINT_WRAPPER(wrapper, pod)    \
00061   BOOST_MPL_ASSERT_MSG(sizeof(wrapper) == sizeof(pod), POINT_WRAPPER_AND_POD_TYPES_HAVE_DIFFERENT_SIZES, (wrapper&, pod&)); \
00062   namespace pcl {                                           \
00063     namespace traits {                                      \
00064       template<> struct POD<wrapper> { typedef pod type; }; \
00065     }                                                       \
00066   }                                                         \
00067   /***/
00068 
00069 // These macros help transform the unusual data structure (type, name, tag)(type, name, tag)...
00070 // into a proper preprocessor sequence of 3-tuples ((type, name, tag))((type, name, tag))...
00071 #define POINT_CLOUD_REGISTER_POINT_STRUCT_X(type, name, tag)            \
00072   ((type, name, tag)) POINT_CLOUD_REGISTER_POINT_STRUCT_Y
00073 #define POINT_CLOUD_REGISTER_POINT_STRUCT_Y(type, name, tag)            \
00074   ((type, name, tag)) POINT_CLOUD_REGISTER_POINT_STRUCT_X
00075 #define POINT_CLOUD_REGISTER_POINT_STRUCT_X0
00076 #define POINT_CLOUD_REGISTER_POINT_STRUCT_Y0
00077 
00078 // Construct type traits given full sequence of (type, name, tag) triples
00079 //  BOOST_MPL_ASSERT_MSG(boost::is_pod<name>::value,                    
00080 //                       REGISTERED_POINT_TYPE_MUST_BE_PLAIN_OLD_DATA, (name)); 
00081 #define POINT_CLOUD_REGISTER_POINT_STRUCT_I(name, seq)                           \
00082   namespace pcl                                                                  \
00083   {                                                                              \
00084     namespace fields                                                             \
00085     {                                                                            \
00086       BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_TAG, name, seq)           \
00087     }                                                                            \
00088     namespace traits                                                             \
00089     {                                                                            \
00090       BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_NAME, name, seq)          \
00091       BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_OFFSET, name, seq)        \
00092       BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_DATATYPE, name, seq)      \
00093       POINT_CLOUD_REGISTER_POINT_FIELD_LIST(name, POINT_CLOUD_EXTRACT_TAGS(seq)) \
00094     }                                                                            \
00095   }                                                                              \
00096   /***/
00097 
00098 #define POINT_CLOUD_REGISTER_FIELD_TAG(r, name, elem)   \
00099   struct BOOST_PP_TUPLE_ELEM(3, 2, elem);               \
00100   /***/
00101 
00102 #define POINT_CLOUD_REGISTER_FIELD_NAME(r, point, elem)                 \
00103   template<int dummy>                                                   \
00104   struct name<point, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem), dummy> \
00105   {                                                                     \
00106     static const char value[];                                          \
00107   };                                                                    \
00108                                                                         \
00109   template<int dummy>                                                   \
00110   const char name<point,                                                \
00111                   pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem),         \
00112                   dummy>::value[] =                                     \
00113     BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(3, 2, elem));                \
00114   /***/
00115 
00116 #define POINT_CLOUD_REGISTER_FIELD_OFFSET(r, name, elem)                \
00117   template<> struct offset<name, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)> \
00118   {                                                                     \
00119     static const size_t value = offsetof(name, BOOST_PP_TUPLE_ELEM(3, 1, elem)); \
00120   };                                                                    \
00121   /***/
00122 
00123 // \note: the mpl::identity weirdness is to support array types without requiring the
00124 // user to wrap them. The basic problem is:
00125 // typedef float[81] type; // SYNTAX ERROR!
00126 // typedef float type[81]; // OK, can now use "type" as a synonym for float[81]
00127 #define POINT_CLOUD_REGISTER_FIELD_DATATYPE(r, name, elem)              \
00128   template<> struct datatype<name, pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)> \
00129   {                                                                     \
00130     typedef boost::mpl::identity<BOOST_PP_TUPLE_ELEM(3, 0, elem)>::type type; \
00131     typedef decomposeArray<type> decomposed;                            \
00132     static const uint8_t value = asEnum<decomposed::type>::value;       \
00133     static const uint32_t size = decomposed::value;                     \
00134   };                                                                    \
00135   /***/
00136 
00137 #define POINT_CLOUD_TAG_OP(s, data, elem) pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)
00138 
00139 #define POINT_CLOUD_EXTRACT_TAGS(seq) BOOST_PP_SEQ_TRANSFORM(POINT_CLOUD_TAG_OP, _, seq)
00140 
00141 #define POINT_CLOUD_REGISTER_POINT_FIELD_LIST(name, seq)        \
00142   template<> struct fieldList<name>                             \
00143   {                                                             \
00144     typedef boost::mpl::vector<BOOST_PP_SEQ_ENUM(seq)> type;    \
00145   };                                                            \
00146   /***/
00147 
00148 // Disabling barely-used Fusion registration of point types for now.
00149 #if 0
00150 #define POINT_CLOUD_EXPAND_TAG_OP(s, data, elem)                \
00151   (boost::mpl::identity<BOOST_PP_TUPLE_ELEM(3, 0, elem)>::type, \
00152    BOOST_PP_TUPLE_ELEM(3, 1, elem),                             \
00153    pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem))                \
00154   /***/
00155 
00156 #define POINT_CLOUD_EXPAND_TAGS(seq) BOOST_PP_SEQ_TRANSFORM(POINT_CLOUD_EXPAND_TAG_OP, _, seq)
00157 
00158 #define POINT_CLOUD_REGISTER_WITH_FUSION(name, seq)                     \
00159   BOOST_FUSION_ADAPT_ASSOC_STRUCT_I(name, POINT_CLOUD_EXPAND_TAGS(seq)) \
00160   /***/
00161 #endif
00162 
00163 #endif  //#ifndef PCL_REGISTER_POINT_STRUCT_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines