218 lines
6.3 KiB
C++
218 lines
6.3 KiB
C++
/* ----------------------------------------------------------------------------
|
|
|
|
* 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 GenericValue.h
|
|
* @brief Wraps any type T so it can play as a Value
|
|
* @date October, 2014
|
|
* @author Michael Bosse, Abel Gawel, Renaud Dube
|
|
* based on DerivedValue.h by Duy Nguyen Ta
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <gtsam/base/Manifold.h>
|
|
#include <gtsam/base/types.h>
|
|
#include <gtsam/base/Value.h>
|
|
|
|
#include <boost/make_shared.hpp>
|
|
#include <boost/pool/pool_alloc.hpp>
|
|
|
|
#include <cmath>
|
|
#include <iostream>
|
|
#include <typeinfo> // operator typeid
|
|
|
|
#ifdef _WIN32
|
|
#define GENERICVALUE_VISIBILITY
|
|
#else
|
|
// This will trigger a LNKxxxx on MSVC, so disable for MSVC build
|
|
// Please refer to https://github.com/borglab/gtsam/blob/develop/Using-GTSAM-EXPORT.md
|
|
#define GENERICVALUE_VISIBILITY GTSAM_EXPORT
|
|
#endif
|
|
|
|
namespace gtsam {
|
|
|
|
/**
|
|
* Wraps any type T so it can play as a Value
|
|
*/
|
|
template<class T>
|
|
class GenericValue: public Value {
|
|
|
|
public:
|
|
|
|
typedef T type;
|
|
|
|
protected:
|
|
|
|
T value_; ///< The wrapped value
|
|
|
|
public:
|
|
// Only needed for serialization.
|
|
GenericValue(){}
|
|
|
|
/// Construct from value
|
|
GenericValue(const T& value) :
|
|
value_(value) {
|
|
}
|
|
|
|
/// Return a constant value
|
|
const T& value() const {
|
|
return value_;
|
|
}
|
|
|
|
/// Return the value
|
|
T& value() {
|
|
return value_;
|
|
}
|
|
|
|
/// Destructor
|
|
virtual ~GenericValue() {
|
|
}
|
|
|
|
/// equals implementing generic Value interface
|
|
bool equals_(const Value& p, double tol = 1e-9) const override {
|
|
// Cast the base class Value pointer to a templated generic class pointer
|
|
const GenericValue& genericValue2 = static_cast<const GenericValue&>(p);
|
|
// Return the result of using the equals traits for the derived class
|
|
return traits<T>::Equals(this->value_, genericValue2.value_, tol);
|
|
}
|
|
|
|
/// non virtual equals function, uses traits
|
|
bool equals(const GenericValue &other, double tol = 1e-9) const {
|
|
return traits<T>::Equals(this->value(), other.value(), tol);
|
|
}
|
|
|
|
/// Virtual print function, uses traits
|
|
void print(const std::string& str) const override {
|
|
std::cout << "(" << demangle(typeid(T).name()) << ")\n";
|
|
traits<T>::Print(value_, str);
|
|
}
|
|
|
|
/**
|
|
* Create a duplicate object returned as a pointer to the generic Value interface.
|
|
*/
|
|
Value* clone_() const override {
|
|
GenericValue* ptr = new GenericValue(*this); // calls copy constructor to fill in
|
|
return ptr;
|
|
}
|
|
|
|
/**
|
|
* Destroy and deallocate this object, only if it was originally allocated using clone_().
|
|
*/
|
|
void deallocate_() const override {
|
|
delete this;
|
|
}
|
|
|
|
/**
|
|
* Clone this value (normal clone on the heap, delete with 'delete' operator)
|
|
*/
|
|
boost::shared_ptr<Value> clone() const override {
|
|
return boost::allocate_shared<GenericValue>(Eigen::aligned_allocator<GenericValue>(), *this);
|
|
}
|
|
|
|
/// Generic Value interface version of retract
|
|
Value* retract_(const Vector& delta) const override {
|
|
// Call retract on the derived class using the retract trait function
|
|
const T retractResult = traits<T>::Retract(GenericValue<T>::value(), delta);
|
|
|
|
Value* resultAsValue = new GenericValue(retractResult);
|
|
|
|
// Return the pointer to the Value base class
|
|
return resultAsValue;
|
|
}
|
|
|
|
/// Generic Value interface version of localCoordinates
|
|
Vector localCoordinates_(const Value& value2) const override {
|
|
// Cast the base class Value pointer to a templated generic class pointer
|
|
const GenericValue<T>& genericValue2 =
|
|
static_cast<const GenericValue<T>&>(value2);
|
|
|
|
// Return the result of calling localCoordinates trait on the derived class
|
|
return traits<T>::Local(GenericValue<T>::value(), genericValue2.value());
|
|
}
|
|
|
|
/// Non-virtual version of retract
|
|
GenericValue retract(const Vector& delta) const {
|
|
return GenericValue(traits<T>::Retract(GenericValue<T>::value(), delta));
|
|
}
|
|
|
|
/// Non-virtual version of localCoordinates
|
|
Vector localCoordinates(const GenericValue& value2) const {
|
|
return localCoordinates_(value2);
|
|
}
|
|
|
|
/// Return run-time dimensionality
|
|
size_t dim() const override {
|
|
return traits<T>::GetDimension(value_);
|
|
}
|
|
|
|
/// Assignment operator
|
|
Value& operator=(const Value& rhs) override {
|
|
// Cast the base class Value pointer to a derived class pointer
|
|
const GenericValue& derivedRhs = static_cast<const GenericValue&>(rhs);
|
|
|
|
// Do the assignment and return the result
|
|
*this = GenericValue(derivedRhs); // calls copy constructor
|
|
return *this;
|
|
}
|
|
|
|
protected:
|
|
|
|
/// Assignment operator, protected because only the Value or DERIVED
|
|
/// assignment operators should be used.
|
|
GenericValue<T>& operator=(const GenericValue<T>& rhs) {
|
|
Value::operator=(static_cast<Value const&>(rhs));
|
|
value_ = rhs.value_;
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
|
|
/** Serialization function */
|
|
friend class boost::serialization::access;
|
|
template<class ARCHIVE>
|
|
void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
|
|
ar & boost::serialization::make_nvp("GenericValue",
|
|
boost::serialization::base_object<Value>(*this));
|
|
ar & boost::serialization::make_nvp("value", value_);
|
|
}
|
|
|
|
|
|
// Alignment, see https://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html
|
|
enum { NeedsToAlign = (sizeof(T) % 16) == 0 };
|
|
public:
|
|
GTSAM_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
|
|
};
|
|
|
|
/// use this macro instead of BOOST_CLASS_EXPORT for GenericValues
|
|
#define GTSAM_VALUE_EXPORT(Type) BOOST_CLASS_EXPORT(gtsam::GenericValue<Type>)
|
|
|
|
// traits
|
|
template <typename ValueType>
|
|
struct traits<GenericValue<ValueType> >
|
|
: public Testable<GenericValue<ValueType> > {};
|
|
|
|
// define Value::cast here since now GenericValue has been declared
|
|
template<typename ValueType>
|
|
const ValueType& Value::cast() const {
|
|
return dynamic_cast<const GenericValue<ValueType>&>(*this).value();
|
|
}
|
|
|
|
/** Functional constructor of GenericValue<T> so T can be automatically deduced
|
|
*/
|
|
template<class T>
|
|
GenericValue<T> genericValue(const T& v) {
|
|
return GenericValue<T>(v);
|
|
}
|
|
|
|
|
|
} /* namespace gtsam */
|