diff --git a/gtsam/base/boost_variant_with_workaround.h b/gtsam/base/boost_variant_with_workaround.h new file mode 100644 index 000000000..9b989cf8d --- /dev/null +++ b/gtsam/base/boost_variant_with_workaround.h @@ -0,0 +1,95 @@ +/* ---------------------------------------------------------------------------- + + * 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 boost_variant_with_workaround.h + * @brief Includes boost/variant.hpp with a workaround for a variant/boost graph conflict, by defining the variant 'get' function in a new variant_workaround namespace. + * @author Richard Roberts + */ + +#pragma once + +#include +#include + +namespace variant_workaround { + + /* ************************************************************************* */ + // The following functions are pasted from boost/variant/get.hpp, but with + // explicit argument types to avoid a conflict with 'get' in the boost graph + // library that exists in boost < 1.47. +#if BOOST_VERSION >= 104700 + using boost::get; +#else + template + inline + typename boost::add_pointer::type + get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) + { + typedef typename boost::add_pointer::type U_ptr; + if (!operand) return static_cast(0); + + boost::detail::variant::get_visitor v; + return operand->apply_visitor(v); + } + + template + inline + typename boost::add_pointer::type + get( + const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) + { + typedef typename boost::add_pointer::type U_ptr; + if (!operand) return static_cast(0); + + boost::detail::variant::get_visitor v; + return operand->apply_visitor(v); + } + + template + inline + typename boost::add_reference::type + get( + boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) + { + typedef typename boost::add_pointer::type U_ptr; + U_ptr result = variant_workaround::get(&operand); + + if (!result) + throw boost::bad_get(); + return *result; + } + + template + inline + typename boost::add_reference::type + get( + const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand + BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) + ) + { + typedef typename boost::add_pointer::type U_ptr; + U_ptr result = variant_workaround::get(&operand); + + if (!result) + throw boost::bad_get(); + return *result; + } +#endif + +} diff --git a/gtsam/nonlinear/ISAM2-inl.h b/gtsam/nonlinear/ISAM2-inl.h index a8c76392c..85bd7aeb8 100644 --- a/gtsam/nonlinear/ISAM2-inl.h +++ b/gtsam/nonlinear/ISAM2-inl.h @@ -30,6 +30,7 @@ using namespace boost::assign; #include #include + namespace gtsam { using namespace std; @@ -43,16 +44,18 @@ static const bool structuralLast = false; template ISAM2::ISAM2(const ISAM2Params& params): delta_(Permutation(), deltaUnpermuted_), params_(params) { + // See note in gtsam/base/boost_variant_with_workaround.h if(params_.optimizationParams.type() == typeid(ISAM2DoglegParams)) - doglegDelta_ = boost::get(params_.optimizationParams).initialDelta; + doglegDelta_ = variant_workaround::get(params_.optimizationParams).initialDelta; } /* ************************************************************************* */ template ISAM2::ISAM2(): delta_(Permutation(), deltaUnpermuted_) { + // See note in gtsam/base/boost_variant_with_workaround.h if(params_.optimizationParams.type() == typeid(ISAM2DoglegParams)) - doglegDelta_ = boost::get(params_.optimizationParams).initialDelta; + doglegDelta_ = variant_workaround::get(params_.optimizationParams).initialDelta; } /* ************************************************************************* */ @@ -528,7 +531,9 @@ ISAM2Result ISAM2::update( tic(9,"solve"); // 9. Solve if(params_.optimizationParams.type() == typeid(ISAM2GaussNewtonParams)) { - const ISAM2GaussNewtonParams& gaussNewtonParams = boost::get(params_.optimizationParams); + // See note in gtsam/base/boost_variant_with_workaround.h + const ISAM2GaussNewtonParams& gaussNewtonParams = + variant_workaround::get(params_.optimizationParams); if (gaussNewtonParams.wildfireThreshold <= 0.0 || disableReordering) { VectorValues newDelta(theta_.dims(ordering_)); optimize2(this->root(), newDelta); @@ -550,7 +555,9 @@ ISAM2Result ISAM2::update( #endif } } else if(params_.optimizationParams.type() == typeid(ISAM2DoglegParams)) { - const ISAM2DoglegParams& doglegParams = boost::get(params_.optimizationParams); + // See note in gtsam/base/boost_variant_with_workaround.h + const ISAM2DoglegParams& doglegParams = + variant_workaround::get(params_.optimizationParams); // Do one Dogleg iteration DoglegOptimizerImpl::IterationResult doglegResult = DoglegOptimizerImpl::Iterate( *doglegDelta_, doglegParams.adaptationMode, *this, nonlinearFactors_, theta_, ordering_, nonlinearFactors_.error(theta_), doglegParams.verbose); diff --git a/gtsam/nonlinear/ISAM2.h b/gtsam/nonlinear/ISAM2.h index aed6b4ebf..2007ba79e 100644 --- a/gtsam/nonlinear/ISAM2.h +++ b/gtsam/nonlinear/ISAM2.h @@ -23,7 +23,8 @@ #include #include -#include +// Workaround for boost < 1.47, see note in file +#include namespace gtsam {