iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OptionalHelpersImpl.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_CORE_DESIGN_DETAILS_OPTIONALHELPERSIMPL_H_
36 #define INCLUDE_NRT_CORE_DESIGN_DETAILS_OPTIONALHELPERSIMPL_H_
37 
38 #include <assert.h>
39 //! @cond PRIVATE_NEVERDEFINED
40 ///////////////////////////////////////////////////////////////////////////////
41 // BY REFERENCE
42 ///////////////////////////////////////////////////////////////////////////////
43 template <class T> inline
44 nrt::OptionalBase<T, true>::OptionalBase() : itsReference( *reinterpret_cast<T*>( const_cast<StorageType*>( &DefaultValue ) ) ), itsValid( false )
45 { }
46 
47 template <class T> inline
48 nrt::OptionalBase<T, true>::OptionalBase( OptionalBase const & other ) : itsReference( *reinterpret_cast<T*>( const_cast<StorageType*>( &DefaultValue ) ) ), itsValid( false )
49 {
50  if( other )
51  {
52  itsReference = other.itsReference;
53  itsValid = true;
54  }
55  else
56  clear();
57 }
58 
59 template <class T> inline
60 nrt::OptionalBase<T, true>::OptionalBase( OptionalBase && other ) : itsReference( *reinterpret_cast<T*>( const_cast<StorageType*>( &DefaultValue ) ) ), itsValid( false )
61 {
62  if( other )
63  {
64  itsReference = std::move( other.itsReference );
65  itsValid = true;
66  }
67 
68  other.clear();
69 }
70 
71 template <class T> inline
72 nrt::OptionalBase<T, true>::OptionalBase( ActualType otherT ) : itsReference( otherT ), itsValid( true )
73 { }
74 
75 template <class T> inline
77 {
78  clear();
79 }
80 
81 template <class T> inline
82 auto nrt::OptionalBase<T, true>::operator=( OptionalBase const & other ) -> OptionalBase &
83 {
84  if( other )
85  {
86  itsReference = other.itsReference;
87  itsValid = true;
88  }
89  else
90  clear();
91 
92  return *this;
93 }
94 
95 template <class T> inline
96 auto nrt::OptionalBase<T, true>::operator=( OptionalBase && other ) -> OptionalBase &
97 {
98  if( other )
99  {
100  itsReference = std::move( other.itsReference );
101  itsValid = true;
102  other.clear();
103  }
104  else
105  clear();
106 
107  return *this;
108 }
109 
110 template <class T> inline
111 auto nrt::OptionalBase<T, true>::operator=( ActualType otherT ) -> OptionalBase &
112 {
113  itsReference = otherT;
114  itsValid = true;
115 
116  return *this;
117 }
118 
119 template <class T> inline
120 auto nrt::OptionalBase<T, true>::inferType() -> ActualType
121 {
122  assert( false );
123  return itsReference.get();
124 }
125 
126 template <class T> inline
127 auto nrt::OptionalBase<T, true>::inferType() const -> ActualType const
128 {
129  assert( false );
130  return itsReference.get();
131 }
132 
133 template <class T> inline
135 {
136  if( isSet() )
137  {
138  itsReference = *reinterpret_cast<T*>( const_cast<StorageType*>( &DefaultValue ) );
139  itsValid = false;
140  }
141 }
142 
143 template <class T> inline
145 {
146  return itsValid;
147 }
148 
149 template <class T> inline
151 {
152  return isSet();
153 }
154 
155 template <class T> inline
157 {
158  return data();
159 }
160 
161 template <class T> inline
162 T const * nrt::OptionalBase<T, true>::get() const
163 {
164  return data();
165 }
166 
167 template <class T> inline
169 {
170  return get();
171 }
172 
173 template <class T> inline
175 {
176  return get();
177 }
178 
179 template <class T> inline
181 {
182  return *get();
183 }
184 
185 template <class T> inline
187 {
188  return *get();
189 }
190 
191 template <class T> inline
193 {
194  return std::addressof( itsReference.get() );
195 }
196 
197 template <class T> inline
198 T const * nrt::OptionalBase<T, true>::data() const
199 {
200  return std::addressof( itsReference.get() );
201 }
202 
203 // for our static member
204 template <class T>
205 constexpr typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type
207 
208 ///////////////////////////////////////////////////////////////////////////////
209 // BY VALUE
210 ///////////////////////////////////////////////////////////////////////////////
211 template <class T> inline
212 nrt::OptionalBase<T, false>::OptionalBase() : itsValid( false )
213 { }
214 
215 template <class T> inline
216 nrt::OptionalBase<T, false>::OptionalBase( OptionalBase const & other ) : itsValid( false )
217 {
218  if( other )
219  assign( *other );
220 }
221 
222 template <class T> inline
223 nrt::OptionalBase<T, false>::OptionalBase( OptionalBase && other ) : itsValid( false )
224 {
225  if( other )
226  assign( std::move( *other ) );
227  other.clear();
228 }
229 
230 template <class T> inline
231 nrt::OptionalBase<T, false>::OptionalBase( ArgumentTypeCopy otherT ) : itsValid( false )
232 {
233  assign( otherT );
234 }
235 
236 template <class T> inline
237 nrt::OptionalBase<T, false>::OptionalBase( ArgumentTypeMove otherT ) : itsValid( false )
238 {
239  assign( std::move( otherT ) );
240 }
241 
242 template <class T> inline
244 {
245  clear();
246 }
247 
248 template <class T> inline
249 auto nrt::OptionalBase<T, false>::operator=( OptionalBase const & other ) -> OptionalBase &
250 {
251  if( other )
252  assign( *other );
253  else
254  clear();
255 
256  return *this;
257 }
258 
259 template <class T> inline
260 auto nrt::OptionalBase<T, false>::operator=( OptionalBase && other ) -> OptionalBase &
261 {
262  if( other )
263  {
264  assign( std::move( *other ) );
265  other.clear();
266  }
267  else
268  clear();
269 
270  return *this;
271 }
272 
273 template <class T> inline
274 auto nrt::OptionalBase<T, false>::operator=( ArgumentTypeCopy other ) -> OptionalBase &
275 {
276  assign( other );
277  return *this;
278 }
279 
280 template <class T> inline
281 auto nrt::OptionalBase<T, false>::operator=( ArgumentTypeMove other ) -> OptionalBase &
282 {
283  assign( std::move( other ) );
284  return *this;
285 }
286 
287 template <class T> inline
289 {
290  if( isSet() )
291  {
292  data()->~T();
293  itsValid = false;
294  }
295 }
296 
297 template <class T> inline
299 {
300  return itsValid;
301 }
302 
303 template <class T> inline
305 {
306  return isSet();
307 }
308 
309 template <class T> inline
311 {
312  assert( false );
313  return *( (T*)nullptr );
314 }
315 
316 template <class T> inline
318 {
319  assert( false );
320  return *( (T*)nullptr );
321 }
322 
323 template <class T> inline
325 {
326  return data();
327 }
328 
329 template <class T> inline
330 T const * nrt::OptionalBase<T, false>::get() const
331 {
332  return data();
333 }
334 
335 template <class T> inline
337 {
338  return get();
339 }
340 
341 template <class T> inline
343 {
344  return get();
345 }
346 
347 template <class T> inline
349 {
350  return *get();
351 }
352 
353 template <class T> inline
355 {
356  return *get();
357 }
358 
359 template <class T> inline
361 {
362  return reinterpret_cast<T*>( &itsData );
363 }
364 
365 template <class T> inline
366 T const * nrt::OptionalBase<T, false>::data() const
367 {
368  return reinterpret_cast<T const*>( &itsData );
369 }
370 
371 template <class T>
372 template <typename U> inline
373 typename std::enable_if<nrt_optional_impl::IsCopyConstructibleNonRef<U>::Value && nrt_optional_impl::IsCopyAssignableNonRef<U>::Value>::type
374 nrt::OptionalBase<T, false>::assign( T const & by_copy )
375 {
376  if( isSet() )
377  *data() = by_copy;
378  else
379  {
380  ::new( data() ) T( by_copy );
381  itsValid = true;
382  }
383 }
384 
385 template <class T>
386 template <typename U> inline
387 typename std::enable_if<nrt_optional_impl::IsCopyConstructibleNonRef<U>::Value && !nrt_optional_impl::IsCopyAssignableNonRef<U>::Value>::type
388 nrt::OptionalBase<T, false>::assign( T const & by_copy )
389 {
390  if( isSet() )
391  clear();
392 
393  ::new( data() ) T( by_copy );
394  itsValid = true;
395 }
396 
397 template <class T>
398 template <typename U> inline
399 typename std::enable_if<!nrt_optional_impl::IsCopyConstructibleNonRef<U>::Value && nrt_optional_impl::IsCopyAssignableNonRef<U>::Value>::type
400 nrt::OptionalBase<T, false>::assign( T const & by_copy )
401 {
402  if( !isSet() )
403  {
404  ::new( data() ) T;
405  itsValid = true;
406  }
407 
408  *data() = by_copy;
409 }
410 
411 template <class T>
412 template <typename U> inline
413 typename std::enable_if<nrt_optional_impl::IsMoveConstructibleNonRef<U>::Value && nrt_optional_impl::IsMoveAssignableNonRef<U>::Value>::type
414 nrt::OptionalBase<T, false>::assign( T && by_move )
415 {
416  if( isSet() )
417  *data() = std::move( by_move );
418  else
419  {
420  ::new( data() ) T( std::move( by_move ) );
421  itsValid = true;
422  }
423 }
424 
425 template <class T>
426 template <typename U> inline
427 typename std::enable_if<nrt_optional_impl::IsMoveConstructibleNonRef<U>::Value && !nrt_optional_impl::IsMoveAssignableNonRef<U>::Value>::type
428 nrt::OptionalBase<T, false>::assign( T && by_move )
429 {
430  if( isSet() )
431  clear();
432 
433  ::new( data() ) T( std::move( by_move ) );
434  itsValid = true;
435 }
436 
437 template <class T>
438 template <typename U> inline
439 typename std::enable_if<!nrt_optional_impl::IsMoveConstructibleNonRef<U>::Value && nrt_optional_impl::IsMoveAssignableNonRef<U>::Value>::type
440 nrt::OptionalBase<T, false>::assign( T && by_move )
441 {
442  if( !isSet() )
443  {
444  ::new( data() ) T;
445  itsValid = true;
446  }
447 
448  *data() = std::move( by_move );
449 }
450 //! @endcond
451 #endif // INCLUDE_NRT_CORE_DESIGN_DETAILS_OPTIONALHELPERSIMPL_H_