iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PointHelpers.H
Go to the documentation of this file.
1 /*! @file
2  @author Shane Grant
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 #ifndef INCLUDE_NRT_POINTCLOUD2_DETAILS_POINTHELPERS_H
36 #define INCLUDE_NRT_POINTCLOUD2_DETAILS_POINTHELPERS_H
37 
39 #include <array>
40 
41 namespace nrt
42 {
43  // A helper struct for manipulating features regardless of their type
44  /* This struct allows you to manipulate members of a feature as if they supported array
45  access and iterators. The only requirement for features is that they actually do have
46  iterator support if their dimensionality is greater than one.
47 
48  Array style access is slower than iterator access since it uses iterators to get to
49  specific elements. Since we can't make assumptions about the type of iterator, this is
50  an O(n) operation where n is dimensionality of the feature.
51 
52  This struct should only be used for implementation specific details since users should have
53  full knowledge of the types they use. */
54  template <class FeatureType, bool IsScalar = std::is_scalar<FeatureType>::value>
55  struct PointHelpers;
56 
57  // break into is non scalar version (which we assume we can iterate on) and
58  // a scalar version
59 
60  // feature type is not a scalar, so assume we can iterate over it somehow
61  template <class FeatureType>
62  struct PointHelpers<FeatureType, false>
63  {
64  // Fills an already existing std::array with the feature contents
65  template <class U, size_t Dimension>
66  static void toArray( FeatureType const & feature, typename std::array<U, Dimension>::iterator dest )
67  {
68  for( auto & i : feature )
69  *dest++ = clamped_convert<U>( i );
70  }
71 
72  // Fills an already existing C style array with the feature contents
73  template <class U>
74  static void toArray( FeatureType const & feature, U * dest )
75  {
76  int index = 0;
77 
78  for( auto & i : feature )
79  dest[index++] = clamped_convert<U>(*i);
80  }
81 
82  // Gets a specific index from the feature
83  template <class U>
84  static bool getIndex( FeatureType const & feature, size_t index, U & value )
85  {
86  size_t j = 0;
87 
88  for( auto & i : feature )
89  {
90  if ( index == j )
91  {
92  value = clamped_convert<U>( i );
93  return true;
94  }
95 
96  ++j;
97  }
98 
99  return false;
100  }
101 
102  // Sets a specific index from the feature
103  template <class U>
104  static bool setIndex( FeatureType & feature, int index, U value )
105  {
106  int j = 0;
107  for( auto & i : feature )
108  {
109  if ( index == j )
110  {
111  *i = value;
112  return true;
113  }
114 
115  ++j;
116  }
117 
118  return false;
119  }
120 
121  // This is just a workaround to let the compiler know that the following two functions
122  // are distinct... see Boost enable_if pages
123  template<int>
124  struct dummy
125  {
126  dummy(int) {}
127  };
128 
129  // Returns an iterator to the beginning of the feature
130  // class version
131  static auto begin( FeatureType & feature, dummy<0> = 0 ) -> typename std::enable_if<std::is_class<FeatureType>::value, decltype( feature.begin() )>
132  {
133  return feature.begin();
134  }
135 
136  // Returns an iterator to the beginning of the feature
137  // array version
138  static typename std::enable_if<!std::is_class<FeatureType>::value, FeatureType *>
139  begin( FeatureType & feature, dummy<1> = 1 )
140  {
141  return &feature;
142  }
143 
144  // Returns an iterator to the end of the feature
145  // class version
146  static auto end( FeatureType & feature, dummy<0> = 0 ) -> typename std::enable_if<std::is_class<FeatureType>::value, decltype( feature.end() )>
147  {
148  return feature.end();
149  }
150 
151  // Returns an iterator to the end of the feature
152  // array version
153  static typename std::enable_if<!std::is_class<FeatureType>::value, FeatureType *>
154  end( FeatureType && feature, dummy<1> = 1 )
155  {
156  return &feature + std::extent<FeatureType>::value;
157  }
158 
159  static auto dimension( FeatureType & feature, dummy<0> = 0 ) -> typename std::enable_if<std::is_class<FeatureType>::value, size_t>
160  {
161  return std::distance( feature.begin(), feature.end() );
162  }
163 
164  static auto dimension( FeatureType &/* feature */, dummy<1> = 1 ) -> typename std::enable_if<!std::is_class<FeatureType>::value, size_t>
165  {
166  return std::extent<FeatureType>::value;
167  }
168  };
169 
170  // object is a scalar, so iterating wouldn't make sense - we'll give results to emulate an iterator
171  template <class FeatureType>
172  struct PointHelpers<FeatureType, true>
173  {
174  // This is just a workaround to let the compiler know that the following two functions
175  // are distinct... see Boost enable_if pages
176  template<int>
177  struct dummy
178  {
179  dummy(int) {}
180  };
181 
182  // Fills an already existing std::array with the feature contents
183  template <class U, size_t Dimension>
184  static void toArray( FeatureType const & feature, typename std::array<U, Dimension>::iterator dest )
185  {
186  dest = clamped_convert<U>( feature );
187  }
188 
189  // Fills an already existing C style array with the feature contents
190  template <class U>
191  static void toArray( FeatureType const & feature, U * dest )
192  {
193  *dest = clamped_convert<U>( feature );
194  }
195 
196  // Gets a specific index from the feature
197  template <class U>
198  static bool getIndex( FeatureType const & feature, size_t index, U & value )
199  {
200  if( index != 0 )
201  return false;
202 
203  value = clamped_convert<U>( feature );
204 
205  return true;
206  }
207 
208  // Sets a specific index from the feature
209  template <class U>
210  static bool setIndex( FeatureType & feature, int index, U value )
211  {
212  if( index != 0 )
213  return false;
214 
215  feature = value;
216 
217  return true;
218  }
219 
220  static auto begin( FeatureType & feature ) -> FeatureType *
221  {
222  return &feature;
223  }
224 
225  static auto end( FeatureType & feature ) -> FeatureType *
226  {
227  return &feature + 1;
228  }
229 
230  static auto dimension( FeatureType & feature ) -> size_t
231  {
232  return 1;
233  }
234  };
235 } // namespace nrt
236 
237 #endif // INCLUDE_NRT_POINTCLOUD2_DETAILS_POINTHELPERS_H