Point Cloud Library (PCL)  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
point_traits.h
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2011, Willow Garage, Inc.
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of Willow Garage, Inc. nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * $Id: point_traits.h 3564 2011-12-16 06:11:13Z rusu $
00037  *
00038  */
00039 
00040 #ifndef PCL_POINT_TRAITS_H_
00041 #define PCL_POINT_TRAITS_H_
00042 
00043 #include <sensor_msgs/PointField.h>
00044 #include <boost/type_traits/remove_all_extents.hpp>
00045 #include <boost/type_traits/is_same.hpp>
00046 #include <boost/mpl/assert.hpp>
00047 
00048 namespace pcl 
00049 {
00050 
00051   namespace fields
00052   {
00053     // Tag types get put in this namespace
00054   }
00055 
00056   namespace traits
00057   {
00058     // Metafunction to return enum value representing a type
00059     template<typename T> struct asEnum {};
00060     template<> struct asEnum<int8_t>   { static const uint8_t value = sensor_msgs::PointField::INT8;    };
00061     template<> struct asEnum<uint8_t>  { static const uint8_t value = sensor_msgs::PointField::UINT8;   };
00062     template<> struct asEnum<int16_t>  { static const uint8_t value = sensor_msgs::PointField::INT16;   };
00063     template<> struct asEnum<uint16_t> { static const uint8_t value = sensor_msgs::PointField::UINT16;  };
00064     template<> struct asEnum<int32_t>  { static const uint8_t value = sensor_msgs::PointField::INT32;   };
00065     template<> struct asEnum<uint32_t> { static const uint8_t value = sensor_msgs::PointField::UINT32;  };
00066     template<> struct asEnum<float>    { static const uint8_t value = sensor_msgs::PointField::FLOAT32; };
00067     template<> struct asEnum<double>   { static const uint8_t value = sensor_msgs::PointField::FLOAT64; };
00068 
00069     // Metafunction to return type of enum value 
00070     template<int> struct asType {};
00071     template<> struct asType<sensor_msgs::PointField::INT8>    { typedef int8_t   type; };
00072     template<> struct asType<sensor_msgs::PointField::UINT8>   { typedef uint8_t  type; };
00073     template<> struct asType<sensor_msgs::PointField::INT16>   { typedef int16_t  type; };
00074     template<> struct asType<sensor_msgs::PointField::UINT16>  { typedef uint16_t type; };
00075     template<> struct asType<sensor_msgs::PointField::INT32>   { typedef int32_t  type; };
00076     template<> struct asType<sensor_msgs::PointField::UINT32>  { typedef uint32_t type; };
00077     template<> struct asType<sensor_msgs::PointField::FLOAT32> { typedef float    type; };
00078     template<> struct asType<sensor_msgs::PointField::FLOAT64> { typedef double   type; };
00079 
00080     // Metafunction to decompose a type (possibly of array of any number of dimensions) into
00081     // its scalar type and total number of elements.
00082     template<typename T> struct decomposeArray
00083     {
00084       typedef typename boost::remove_all_extents<T>::type type;
00085       static const uint32_t value = sizeof(T) / sizeof(type);
00086     };
00087 
00088     // For non-POD point types, this is specialized to return the corresponding POD type.
00089     template<typename PointT> struct POD
00090     {
00091       typedef PointT type;
00092     };
00093 
00094     // name
00095     /* This really only depends on Tag, but we go through some gymnastics to avoid ODR violations.
00096        We template it on the point type PointT to avoid ODR violations when registering multiple
00097        point types with shared tags.
00098        The dummy parameter is so we can partially specialize name on PointT and Tag but leave it
00099        templated on dummy. Each specialization declares a static char array containing the tag
00100        name. The definition of the static member would conflict when linking multiple translation
00101        units that include the point type registration. But when the static member definition is
00102        templated (on dummy), we sidestep the ODR issue.
00103     */
00104     template<class PointT, typename Tag, int dummy = 0>
00105     struct name : name<typename POD<PointT>::type, Tag, dummy>
00106     {
00107       // Contents of specialization:
00108       // static const char value[];
00109       
00110       // Avoid infinite compile-time recursion
00111       BOOST_MPL_ASSERT_MSG((!boost::is_same<PointT, typename POD<PointT>::type>::value),
00112                            POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
00113     };
00114 
00115     // offset
00116     template<class PointT, typename Tag>
00117     struct offset : offset<typename POD<PointT>::type, Tag>
00118     {
00119       // Contents of specialization:
00120       // static const size_t value;
00121       
00122       // Avoid infinite compile-time recursion
00123       BOOST_MPL_ASSERT_MSG((!boost::is_same<PointT, typename POD<PointT>::type>::value),
00124                            POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
00125     };
00126 
00127     // datatype
00128     template<class PointT, typename Tag>
00129     struct datatype : datatype<typename POD<PointT>::type, Tag>
00130     {
00131       // Contents of specialization:
00132       // typedef ... type;
00133       // static const uint8_t value;
00134       // static const uint32_t size;
00135       
00136       // Avoid infinite compile-time recursion
00137       BOOST_MPL_ASSERT_MSG((!boost::is_same<PointT, typename POD<PointT>::type>::value),
00138                            POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
00139     };
00140 
00141     // fields
00142     template<typename PointT>
00143     struct fieldList : fieldList<typename POD<PointT>::type>
00144     {
00145       // Contents of specialization:
00146       // typedef boost::mpl::vector<...> type;
00147       
00148       // Avoid infinite compile-time recursion
00149       BOOST_MPL_ASSERT_MSG((!boost::is_same<PointT, typename POD<PointT>::type>::value),
00150                            POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
00151     };
00152 
00153   } //namespace traits
00154 }
00155 
00156 #endif  //#ifndef PCL_POINT_TRAITS_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines