diff --git a/sophus/ceres_local_parameterization.hpp b/sophus/ceres_local_parameterization.hpp index d924af9c4..215916412 100644 --- a/sophus/ceres_local_parameterization.hpp +++ b/sophus/ceres_local_parameterization.hpp @@ -1,30 +1,31 @@ #ifndef SOPHUS_CERES_LOCAL_PARAMETERIZATION_HPP #define SOPHUS_CERES_LOCAL_PARAMETERIZATION_HPP +#include + namespace Sophus { +template +constexpr std::true_type complete(T*); +constexpr std::false_type complete(...); + +template +using IsSpecialized = decltype(complete(std::declval())); + /// Type trait used to distinguish mappable vector types from scalars +/// /// We use this class to distinguish Sophus::Vector from Scalar types /// in LieGroup::Tangent /// -/// Fortunately, ceres::Jet is not mappable -template -struct is_mappable_type_t { - template - using EigenTraits = Eigen::internal::traits; - // Eigen::Map requires Eigen::internal::traits type to be complete - template - static auto map_test(U*) - -> std::integral_constant) == - sizeof(EigenTraits)>; - static auto map_test(...) -> std::false_type; - - using type = decltype(map_test((T*)nullptr)); - static constexpr bool value = type::value; -}; +/// Having Eigen::internal::traits specialized for T is a prerequisite for +/// constructing Eigen::Map (we will call such T "mappable" type) +/// +/// Fortunately, ceres::Jet is not a mappable type +template +using HasEigenTraits = IsSpecialized>>; -template -constexpr bool is_mappable_type_v = is_mappable_type_t::value; +template +constexpr bool HasEigenTraitsV = HasEigenTraits::value; /// Helper for mapping tangent vectors (scalars) over pointers to data template @@ -38,7 +39,7 @@ struct Mapper { }; template -struct Mapper>::type> { +struct Mapper>::type> { using Scalar = typename T::Scalar; using Map = Eigen::Map; using ConstMap = Eigen::Map;