Point Cloud Library (PCL)  1.5.1
 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-2012, 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 4302 2012-02-07 23:14:39Z 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> 
00090     struct POD
00091     {
00092       typedef PointT type;
00093     };
00094 
00095     // name
00096     /* This really only depends on Tag, but we go through some gymnastics to avoid ODR violations.
00097        We template it on the point type PointT to avoid ODR violations when registering multiple
00098        point types with shared tags.
00099        The dummy parameter is so we can partially specialize name on PointT and Tag but leave it
00100        templated on dummy. Each specialization declares a static char array containing the tag
00101        name. The definition of the static member would conflict when linking multiple translation
00102        units that include the point type registration. But when the static member definition is
00103        templated (on dummy), we sidestep the ODR issue.
00104     */
00105     template<class PointT, typename Tag, int dummy = 0>
00106     struct name : name<typename POD<PointT>::type, Tag, dummy>
00107     {
00108       // Contents of specialization:
00109       // static const char value[];
00110       
00111       // Avoid infinite compile-time recursion
00112       BOOST_MPL_ASSERT_MSG((!boost::is_same<PointT, typename POD<PointT>::type>::value),
00113                            POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
00114     };
00115 
00116     // offset
00117     template<class PointT, typename Tag>
00118     struct offset : offset<typename POD<PointT>::type, Tag>
00119     {
00120       // Contents of specialization:
00121       // static const size_t value;
00122       
00123       // Avoid infinite compile-time recursion
00124       BOOST_MPL_ASSERT_MSG((!boost::is_same<PointT, typename POD<PointT>::type>::value),
00125                            POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
00126     };
00127 
00128     // datatype
00129     template<class PointT, typename Tag>
00130     struct datatype : datatype<typename POD<PointT>::type, Tag>
00131     {
00132       // Contents of specialization:
00133       // typedef ... type;
00134       // static const uint8_t value;
00135       // static const uint32_t size;
00136       
00137       // Avoid infinite compile-time recursion
00138       BOOST_MPL_ASSERT_MSG((!boost::is_same<PointT, typename POD<PointT>::type>::value),
00139                            POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
00140     };
00141 
00142     // fields
00143     template<typename PointT>
00144     struct fieldList : fieldList<typename POD<PointT>::type>
00145     {
00146       // Contents of specialization:
00147       // typedef boost::mpl::vector<...> type;
00148       
00149       // Avoid infinite compile-time recursion
00150       BOOST_MPL_ASSERT_MSG((!boost::is_same<PointT, typename POD<PointT>::type>::value),
00151                            POINT_TYPE_NOT_PROPERLY_REGISTERED, (PointT&));
00152     };
00153 
00154   } //namespace traits
00155 
00156 
00158   template <typename PointInT, typename OutT>
00159   struct CopyIfFieldExists 
00160   {
00161     typedef typename traits::POD<PointInT>::type Pod;
00162 
00169     CopyIfFieldExists (const PointInT &pt, 
00170                        const std::string &field, 
00171                        bool &exists, 
00172                        OutT &value)
00173       : pt_ (reinterpret_cast<const Pod&>(pt)), name_ (field), exists_ (exists), value_ (value)
00174     {
00175       exists_ = false;
00176     }
00177 
00183     CopyIfFieldExists (const PointInT &pt, 
00184                        const std::string &field, 
00185                        OutT &value)
00186       : pt_ (reinterpret_cast<const Pod&>(pt)), name_ (field), exists_ (exists_tmp_), value_ (value)
00187     {
00188     }
00189 
00191     template <typename Key> inline void
00192     operator() ()
00193     {
00194       if (name_ == pcl::traits::name<PointInT, Key>::value)
00195       {
00196         exists_ = true;
00197         typedef typename pcl::traits::datatype<PointInT, Key>::type T;
00198         const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(&pt_) + pcl::traits::offset<PointInT, Key>::value;
00199         value_ = *reinterpret_cast<const T*>(data_ptr);
00200       }
00201     }
00202 
00203     private:
00204       const Pod &pt_;
00205       const std::string &name_;
00206       bool &exists_;
00207       // Bogus entry
00208       bool exists_tmp_;
00209       OutT &value_;
00210   };
00211 }
00212 
00213 #endif  //#ifndef PCL_POINT_TRAITS_H_