iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
test-GenericBag.C
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 
37 #include <nrt/Core/Debugging/Log.H>
38 
39 
40 template <class T>
41 struct AddFunctor
42 {
43  AddFunctor( T val ) : itsVal( val ) {}
44 
45  template <class U>
46  U operator()( U const & val ) const
47  {
48  return val + itsVal;
49  }
50 
51  const T itsVal;
52 };
53 
54 template <class T>
55 struct InPlaceAdd
56 {
57  InPlaceAdd( T val ) : itsVal( val ) {}
58 
59  template <class U>
60  void operator()( U & val ) const
61  {
62  val += itsVal;
63  }
64 
65  const T itsVal;
66 };
67 
68 struct DereferenceFunctor
69 {
70  template <class T> inline
71  T & operator()( T * ptr ) const
72  {
73  return *ptr;
74  }
75 };
76 
77 using namespace nrt;
78 
79 #define BOOST_TEST_DYN_LINK
80 #define BOOST_TEST_MODULE GenericBagTest
81 #include <boost/test/unit_test.hpp>
82 
83 typedef GenericBag<int, bool> BagT1;
84 typedef GenericBag<float, int, double> BagT2;
85 typedef GenericBag<bool, int> BagT3;
86 
87 typedef StreamableGenericBag<int, bool> SBagT1;
88 typedef StreamableGenericBag<float, int, double> SBagT2;
89 
90 // ######################################################################
91 BOOST_AUTO_TEST_CASE( BasicGenericBagUse )
92 {
93  BagT1 bag1;
94  BagT2 bag2( 3.4f, 7, 8.3234 );
95  BagT3 bag3( true, 0 );
96 
97  bag1.get<int>() = 4;
98  bag1.get<bool>() = false;
99 
100  // Test type access
101  BOOST_CHECK_EQUAL( bag1.get<int>(), 4 );
102  BOOST_CHECK_EQUAL( bag1.get<bool>(), false );
103 
104  // Test index access
105  BOOST_CHECK_EQUAL( bag1.get<0>(), 4 );
106  BOOST_CHECK_EQUAL( bag1.get<1>(), false );
107 
108  // Basic assignment
109  bag1 = BagT1( bag2 );
110  BOOST_CHECK_EQUAL( bag1.get<int>(), 7 );
111 
112  bag2 = bag3;
113  BOOST_CHECK_EQUAL( bag2.get<int>(), 0 );
114 
115  bag1 = bag3;
116  BOOST_CHECK_EQUAL( bag1.get<bool>(), true );
117  BOOST_CHECK_EQUAL( bag1.get<int>(), 0 );
118 
119  BOOST_CHECK_EQUAL( bag1.hasType<int>(), true );
120  BOOST_CHECK_EQUAL( bag1.hasType<float>(), false );
121 
122  bool caught = false;
123  try
124  {
125  BOOST_CHECK_EQUAL( bag2.tryGet<float>(), 3.4f );
126  bag2.tryGet<bool>();
127  caught = false;
128  }
130  {
131  caught = true;
132  }
133 
134  BOOST_CHECK_EQUAL( caught, true );
135 }
136 
137 // ######################################################################
138 BOOST_AUTO_TEST_CASE( StreamableGenericBagGeneral )
139 {
140  BagT1 bag1( 3, true );
141  SBagT1 sbag1( bag1 );
142  SBagT2 sbag2( 3.0f, 2, 4.5 );
143 
144  std::ostringstream stream;
145 
146  BOOST_CHECK_EQUAL( sbag1.get<int>(), 3 );
147 
148  stream << sbag1;
149  BOOST_CHECK_EQUAL( stream.str(), "3; 1" );
150 
151  stream.clear(); stream.str("");
152  stream << sbag2;
153  BOOST_CHECK_EQUAL( stream.str(), "3; 2; 4.5" );
154 
155  bag1 = sbag1;
156  BOOST_CHECK_EQUAL( bag1.get<int>(), 3 );
157  BOOST_CHECK_EQUAL( bag1.get<bool>(), true );
158 
159  BagT1 temp1( sbag1 );
160  BOOST_CHECK_EQUAL( temp1.get<int>(), 3 );
161  BOOST_CHECK_EQUAL( temp1.get<bool>(), true );
162 
163  SBagT1 temp2( sbag1 );
164  stream.clear(); stream.str("");
165  stream << temp2;
166  BOOST_CHECK_EQUAL( stream.str(), "3; 1" );
167 
168  SBagT1 temp3( sbag2 );
169  stream.clear(); stream.str("");
170  stream << temp3;
171  BOOST_CHECK_EQUAL( stream.str(), "2; 0" );
172 
173  SBagT1 temp4( std::move( bag1 ) );
174  stream.clear(); stream.str("");
175  stream << temp4;
176  BOOST_CHECK_EQUAL( stream.str(), "3; 1" );
177 
178  SBagT1 temp5;
179  stream.clear(); stream.str("");
180  stream << temp5;
181  BOOST_CHECK_EQUAL( stream.str(), "0; 0" );
182 
183  SBagT1 temp6;
184  BOOST_CHECK_EQUAL( temp6.get<int>(), 0 );
185  BOOST_CHECK_EQUAL( temp6.get<bool>(), 0 );
186 
187  sbag1 = sbag1;
188  BOOST_CHECK_EQUAL( sbag1.get<int>(), 3 );
189  BOOST_CHECK_EQUAL( sbag1.get<bool>(), true );
190 
191  sbag1 = SBagT1( sbag2 );
192  BOOST_CHECK_EQUAL( sbag1.get<int>(), 2 );
193  BOOST_CHECK_EQUAL( sbag1.get<bool>(), false );
194 
195  sbag1 = SBagT1( sbag1 );
196  BOOST_CHECK_EQUAL( sbag1.get<int>(), 2 );
197  BOOST_CHECK_EQUAL( sbag1.get<bool>(), false );
198 
199  BagT3 bag3( true, 0 );
200  sbag1 = bag3;
201  BOOST_CHECK_EQUAL( sbag1.get<int>(), 0 );
202  BOOST_CHECK_EQUAL( sbag1.get<bool>(), true );
203 
204  sbag2 = sbag1;
205  stream.clear(); stream.str("");
206  stream << sbag2;
207  BOOST_CHECK_EQUAL( stream.str(), "3; 0; 4.5" );
208 
209  std::istringstream is("3.9; 45; 524.234");
210  is >> sbag2;
211  stream.clear(); stream.str("");
212  stream << sbag2;
213  BOOST_CHECK_EQUAL( stream.str(), "3.9; 45; 524.234" );
214 }
215 
216 // ######################################################################
217 BOOST_AUTO_TEST_CASE( ReferenceTypeTest )
218 {
219  typedef typename getReferenceType<int, int, const bool, float>::type intRef;
220  typedef typename getReferenceType<const int, int, const bool, float>::type intRef2;
221  typedef typename getReferenceType<bool, int, const bool, float>::type boolRef;
222  typedef typename getReferenceType<char, int, const bool, float>::type notFoundRef;
223  typedef typename getReferenceType<double, const double &>::type doubleRef;
224 
225  BOOST_CHECK_EQUAL( (std::is_same<intRef, int&>::value), 1 );
226  BOOST_CHECK_EQUAL( (std::is_same<intRef2, int&>::value), 1 );
227  BOOST_CHECK_EQUAL( (std::is_same<boolRef, bool&>::value), 0 );
228  BOOST_CHECK_EQUAL( (std::is_same<boolRef, const bool&>::value), 1 );
229  BOOST_CHECK_EQUAL( (std::is_same<doubleRef, const double&>::value), 1 );
230  BOOST_CHECK_EQUAL( (std::is_reference<notFoundRef>::value), 0 );
231 }
232 
233 // ######################################################################
234 BOOST_AUTO_TEST_CASE( TypeTestsGenericBag )
235 {
236  // Testing references
237  int testInt = 3;
238  GenericBag<int &> testBag( testInt );
239 
240  BOOST_CHECK_EQUAL( testInt, testBag.get<int>() );
241 
242  testBag.get<int>() = 7;
243  BOOST_CHECK_EQUAL( testInt, testBag.get<int>() );
244  BOOST_CHECK_EQUAL( testInt, 7 );
245 
246  testBag.get<int&>() = 6;
247  BOOST_CHECK_EQUAL( testInt, testBag.get<int>() );
248  BOOST_CHECK_EQUAL( testInt, 6 );
249 
250  testBag.get<int &&>() = 5;
251  BOOST_CHECK_EQUAL( testInt, testBag.get<int>() );
252  BOOST_CHECK_EQUAL( testInt, 5 );
253 
254  GenericBag<int> testBagNoRef( 2 );
255  BOOST_CHECK_EQUAL( testBagNoRef.get<int>(), 2 );
256  BOOST_CHECK_EQUAL( testBagNoRef.get<int&>(), 2 );
257  BOOST_CHECK_EQUAL( testBagNoRef.get<const int>(), 2 );
258  BOOST_CHECK_EQUAL( testBagNoRef.get<const int &>(), 2 );
259 
260  testBagNoRef = testBag;
261  BOOST_CHECK_EQUAL( testBagNoRef.get<int>(), testBag.get<int>() );
262  testBagNoRef.get<int>() = 3;
263  testBag.get<int>() = 4;
264 
265  BOOST_CHECK_EQUAL( testBagNoRef.get<int>(), 3 );
266  BOOST_CHECK_EQUAL( testBag.get<int>(), 4 );
267 
268  testBag = testBagNoRef;
269  BOOST_CHECK_EQUAL( testInt, testBag.get<int>() );
270  BOOST_CHECK_EQUAL( testInt, testBagNoRef.get<int>() );
271 
272  // Test const stuff
273  GenericBag<int> nonConstBag( 3 );
274  GenericBag<const int> constBag( 4 );
275 
276  //constBag = nonConstBag; // Not allowed!
277  //constBag.get<int>() = 3; // not allowed!
278  //constBag.get<const int>() = 3; // not allowed!
279  //constBag.get<const int &>() = 3; // not allowed!
280 
281  nonConstBag = constBag;
282  BOOST_CHECK_EQUAL( nonConstBag.get<0>(), constBag.get<const int>() );
283 
284  GenericBag<const int> constBag2( constBag );
285  BOOST_CHECK_EQUAL( constBag2.get<int>(), constBag.get<int>() );
286 
287  GenericBag<const int> constBag3( GenericBag<int, const bool>( 3, true ) );
288  BOOST_CHECK_EQUAL( constBag3.get<int>(), 3 );
289 
290  // Try creating ref bags from other bags
291  StreamableGenericBag<int, double> streamBag( 42, 4.2 );
292  GenericBag<int &, const double &> refBag( streamBag );
293 
294  BOOST_CHECK_EQUAL( streamBag.get<double>(), refBag.get<double>() );
295 
296  //refBag.get<double>() = 4.234; // not allowed
297  streamBag.get<double>() = 3.9;
298  BOOST_CHECK_EQUAL( refBag.get<double>(), 3.9 );
299 
300  refBag.get<int>() = 32;
301  BOOST_CHECK_EQUAL( streamBag.get<int>(), 32 );
302 
303  // the following won't compile because we don't have a match for one of the refs
304  // GenericBag<int &, const double &, char &> refBagError( streamBag ); // not allowed!
305 }
306 
307 // ######################################################################
308 BOOST_AUTO_TEST_CASE( MoveTesting )
309 {
310  GenericBag<int> myBag( 3 );
311  GenericBag<int, double> myOtherBag( std::move( myBag ) );
312 
313  BOOST_CHECK_EQUAL( myOtherBag.get<double>(), 0 );
314  BOOST_CHECK_EQUAL( myOtherBag.get<int>(), 3 );
315 
316  StreamableGenericBag<double> streamableBag( GenericBag<char, double>( 'a', 3.2 ) );
317  BOOST_CHECK_EQUAL( streamableBag.get<double>(), 3.2 );
318 
319  //GenericBag<int &> bagRef( GenericBag<int>( 3 ) ); // should not compile
320  GenericBag<int const &> bagRef( GenericBag<int>( 3 ) ); // OK since C++ allows const & to temporaries for whatever reason
321 
322  GenericBag<int> bagFromEmpty( GenericBag<>{} );
323  StreamableGenericBag<int> bagFromEmpty2( GenericBag<>{} );
324 
325  BOOST_CHECK_EQUAL( bagFromEmpty.get<int>(), 0 );
326  BOOST_CHECK_EQUAL( bagFromEmpty2.get<int>(), 0 );
327 
328  int x = 3;
329  GenericBag<int&> bagMoveRef(x);
330  bagMoveRef = GenericBag<int>(4);
331 
332  BOOST_CHECK_EQUAL( bagMoveRef.get<int>(), 4 );
333 }
334 
335 // ######################################################################
336 BOOST_AUTO_TEST_CASE( FunctionTesting )
337 {
338  AddFunctor<int> myFunctor( 3 );
339  GenericBag<int, double> fbag( 3, 3.4 );
340  StreamableGenericBag<int,double> result;
341 
342  result = fbag.applyFunction<int, double>( myFunctor );
343  BOOST_CHECK_EQUAL( fbag.get<int>() + 3, result.get<int>() );
344 
345  result.applyFunctionInPlace( InPlaceAdd<int>( 3 ) );
346  BOOST_CHECK_EQUAL( fbag.get<int>() + 6, result.get<int>() );
347 
348  int testX;
349  bool testY;
350 
351  GenericBag<int *, bool *> testPtr( &testX, &testY );
352 
353  auto testRefBag = testPtr.applyFunction<int&, bool&>( DereferenceFunctor() );
354 
355  testY = true;
356  testRefBag.get<int>() = 3;
357 
358  BOOST_CHECK_EQUAL( testRefBag.get<bool>(), true );
359  BOOST_CHECK_EQUAL( testRefBag.get<int>(), 3 );
360  BOOST_CHECK_EQUAL( testX, 3 );
361  BOOST_CHECK_EQUAL( testY, true );
362 }