GenericValue.h copied from DerivedValue.h
							parent
							
								
									c1c6a30e50
								
							
						
					
					
						commit
						95827dd4d8
					
				|  | @ -0,0 +1,143 @@ | |||
| /* ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | ||||
|  * Atlanta, Georgia 30332-0415 | ||||
|  * All Rights Reserved | ||||
|  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | ||||
| 
 | ||||
|  * See LICENSE for the license information | ||||
| 
 | ||||
|  * -------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| /*
 | ||||
|  * @file DerivedValue.h | ||||
|  * @date Jan 26, 2012 | ||||
|  * @author Duy Nguyen Ta | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <gtsam/base/Value.h> | ||||
| #include <boost/make_shared.hpp> | ||||
| 
 | ||||
| //////////////////
 | ||||
| // The following includes windows.h in some MSVC versions, so we undef min, max, and ERROR
 | ||||
| #include <boost/pool/singleton_pool.hpp> | ||||
| 
 | ||||
| #ifdef min | ||||
| #undef min | ||||
| #endif | ||||
| 
 | ||||
| #ifdef max | ||||
| #undef max | ||||
| #endif | ||||
| 
 | ||||
| #ifdef ERROR | ||||
| #undef ERROR | ||||
| #endif | ||||
| //////////////////
 | ||||
| 
 | ||||
| 
 | ||||
| namespace gtsam { | ||||
| 
 | ||||
| template<class DERIVED> | ||||
| class DerivedValue : public Value { | ||||
| 
 | ||||
| protected: | ||||
|   DerivedValue() {} | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|   virtual ~DerivedValue() {} | ||||
| 
 | ||||
|   /**
 | ||||
|    * Create a duplicate object returned as a pointer to the generic Value interface. | ||||
|    * For the sake of performance, this function use singleton pool allocator instead of the normal heap allocator. | ||||
|    * The result must be deleted with Value::deallocate_, not with the 'delete' operator. | ||||
|    */ | ||||
|   virtual Value* clone_() const { | ||||
|     void *place = boost::singleton_pool<PoolTag, sizeof(DERIVED)>::malloc(); | ||||
|     DERIVED* ptr = new(place) DERIVED(static_cast<const DERIVED&>(*this)); | ||||
|     return ptr; | ||||
|   } | ||||
| 
 | ||||
|   /**
 | ||||
|    * Destroy and deallocate this object, only if it was originally allocated using clone_(). | ||||
|    */ | ||||
|   virtual void deallocate_() const { | ||||
|     this->~DerivedValue(); // Virtual destructor cleans up the derived object
 | ||||
|     boost::singleton_pool<PoolTag, sizeof(DERIVED)>::free((void*)this); // Release memory from pool
 | ||||
|   } | ||||
| 
 | ||||
|   /**
 | ||||
|    * Clone this value (normal clone on the heap, delete with 'delete' operator) | ||||
|    */ | ||||
|   virtual boost::shared_ptr<Value> clone() const { | ||||
|     return boost::make_shared<DERIVED>(static_cast<const DERIVED&>(*this)); | ||||
|   } | ||||
| 
 | ||||
|   /// equals implementing generic Value interface
 | ||||
|   virtual bool equals_(const Value& p, double tol = 1e-9) const { | ||||
|     // Cast the base class Value pointer to a derived class pointer
 | ||||
|     const DERIVED& derivedValue2 = dynamic_cast<const DERIVED&>(p); | ||||
| 
 | ||||
|     // Return the result of calling equals on the derived class
 | ||||
|     return (static_cast<const DERIVED*>(this))->equals(derivedValue2, tol); | ||||
|   } | ||||
| 
 | ||||
|   /// Generic Value interface version of retract
 | ||||
|   virtual Value* retract_(const Vector& delta) const { | ||||
|     // Call retract on the derived class
 | ||||
|     const DERIVED retractResult = (static_cast<const DERIVED*>(this))->retract(delta); | ||||
| 
 | ||||
|     // Create a Value pointer copy of the result
 | ||||
|     void* resultAsValuePlace = boost::singleton_pool<PoolTag, sizeof(DERIVED)>::malloc(); | ||||
|     Value* resultAsValue = new(resultAsValuePlace) DERIVED(retractResult); | ||||
| 
 | ||||
|     // Return the pointer to the Value base class
 | ||||
|     return resultAsValue; | ||||
|   } | ||||
| 
 | ||||
|   /// Generic Value interface version of localCoordinates
 | ||||
|   virtual Vector localCoordinates_(const Value& value2) const { | ||||
|     // Cast the base class Value pointer to a derived class pointer
 | ||||
|     const DERIVED& derivedValue2 = dynamic_cast<const DERIVED&>(value2); | ||||
| 
 | ||||
|     // Return the result of calling localCoordinates on the derived class
 | ||||
|     return (static_cast<const DERIVED*>(this))->localCoordinates(derivedValue2); | ||||
|   } | ||||
| 
 | ||||
|   /// Assignment operator
 | ||||
|   virtual Value& operator=(const Value& rhs) { | ||||
|     // Cast the base class Value pointer to a derived class pointer
 | ||||
|     const DERIVED& derivedRhs = dynamic_cast<const DERIVED&>(rhs); | ||||
| 
 | ||||
|     // Do the assignment and return the result
 | ||||
|     return (static_cast<DERIVED*>(this))->operator=(derivedRhs); | ||||
|   } | ||||
| 
 | ||||
|   /// Conversion to the derived class
 | ||||
|   operator const DERIVED& () const { | ||||
|     return static_cast<const DERIVED&>(*this); | ||||
|   } | ||||
| 
 | ||||
|   /// Conversion to the derived class
 | ||||
|   operator DERIVED& () { | ||||
|     return static_cast<DERIVED&>(*this); | ||||
|   } | ||||
| 
 | ||||
| protected: | ||||
|   /// Assignment operator, protected because only the Value or DERIVED
 | ||||
|   /// assignment operators should be used.
 | ||||
|   DerivedValue<DERIVED>& operator=(const DerivedValue<DERIVED>& rhs) { | ||||
|     // Nothing to do, do not call base class assignment operator
 | ||||
|     return *this; | ||||
|   } | ||||
| 
 | ||||
| private: | ||||
|   /// Fake Tag struct for singleton pool allocator. In fact, it is never used!
 | ||||
|   struct PoolTag { }; | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| } /* namespace gtsam */ | ||||
		Loading…
	
		Reference in New Issue