make SFINAE templates more readable
parent
e8ddbbebff
commit
040eb63949
|
|
@ -308,26 +308,58 @@ class NoiseModelFactorN : public NoiseModelFactor {
|
|||
/// N is the number of variables (N-way factor)
|
||||
enum { N = sizeof...(ValueTypes) };
|
||||
|
||||
/// The type of the i'th template param can be obtained as ValueType<I>
|
||||
template <int I, typename std::enable_if<(I < N), bool>::type = true>
|
||||
using ValueType =
|
||||
typename std::tuple_element<I, std::tuple<ValueTypes...>>::type;
|
||||
|
||||
protected:
|
||||
using Base = NoiseModelFactor;
|
||||
using This = NoiseModelFactorN<ValueTypes...>;
|
||||
|
||||
/* Like std::void_t, except produces `boost::optional<Matrix&>` instead. Used
|
||||
* to expand fixed-type parameter-packs with same length as ValueTypes */
|
||||
/// @name SFINAE aliases
|
||||
/// @{
|
||||
|
||||
template <typename From, typename To>
|
||||
using IsConvertible =
|
||||
typename std::enable_if<std::is_convertible<From, To>::value, void>::type;
|
||||
|
||||
template <int I>
|
||||
using IndexIsValid = typename std::enable_if<(I >= 1) && (I <= N),
|
||||
void>::type; // 1-indexed!
|
||||
|
||||
template <typename Container>
|
||||
using ContainerElementType =
|
||||
typename std::decay<decltype(*std::declval<Container>().begin())>::type;
|
||||
template <typename Container>
|
||||
using IsContainerOfKeys = IsConvertible<ContainerElementType<Container>, Key>;
|
||||
|
||||
/// @}
|
||||
|
||||
/* Like std::void_t, except produces `boost::optional<Matrix&>` instead of
|
||||
* `void`. Used to expand fixed-type parameter-packs with same length as
|
||||
* ValueTypes. */
|
||||
template <typename T>
|
||||
using OptionalMatrix = boost::optional<Matrix&>;
|
||||
|
||||
/* Like std::void_t, except produces `Key` instead. Used to expand fixed-type
|
||||
* parameter-packs with same length as ValueTypes */
|
||||
/* Like std::void_t, except produces `Key` instead of `void`. Used to expand
|
||||
* fixed-type parameter-packs with same length as ValueTypes. */
|
||||
template <typename T>
|
||||
using KeyType = Key;
|
||||
|
||||
public:
|
||||
/**
|
||||
* The type of the I'th template param can be obtained as ValueType<I>.
|
||||
* I is 1-indexed for backwards compatibility/consistency! So for example,
|
||||
* ```
|
||||
* using Factor = NoiseModelFactorN<Pose3, Point3>;
|
||||
* Factor::ValueType<1> // Pose3
|
||||
* Factor::ValueType<2> // Point3
|
||||
* // Factor::ValueType<0> // ERROR! Will not compile.
|
||||
* // Factor::ValueType<3> // ERROR! Will not compile.
|
||||
* ```
|
||||
*/
|
||||
template <int I, typename = IndexIsValid<I>>
|
||||
using ValueType =
|
||||
typename std::tuple_element<I - 1, std::tuple<ValueTypes...>>::type;
|
||||
|
||||
public:
|
||||
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
|
||||
|
|
@ -353,11 +385,7 @@ class NoiseModelFactorN : public NoiseModelFactor {
|
|||
* @param keys A container of keys for the variables in this factor.
|
||||
*/
|
||||
template <typename CONTAINER = std::initializer_list<Key>,
|
||||
// check that CONTAINER is a container of Keys:
|
||||
typename T = typename std::decay<
|
||||
decltype(*std::declval<CONTAINER>().begin())>::type,
|
||||
typename std::enable_if<std::is_convertible<T, Key>::value,
|
||||
bool>::type = true>
|
||||
typename = IsContainerOfKeys<CONTAINER>>
|
||||
NoiseModelFactorN(const SharedNoiseModel& noiseModel, CONTAINER keys)
|
||||
: Base(noiseModel, keys) {
|
||||
assert(keys.size() == N);
|
||||
|
|
@ -367,10 +395,19 @@ class NoiseModelFactorN : public NoiseModelFactor {
|
|||
|
||||
~NoiseModelFactorN() override {}
|
||||
|
||||
/// Returns a key. Usage: `key<I>()` returns the I'th key.
|
||||
template <int I>
|
||||
inline typename std::enable_if<(I < N), Key>::type key() const {
|
||||
return keys_[I];
|
||||
/** Returns a key. Usage: `key<I>()` returns the I'th key.
|
||||
* I is 1-indexed for backwards compatibility/consistency! So for example,
|
||||
* ```
|
||||
* NoiseModelFactorN<Pose3, Point3> factor(noise, key1, key2);
|
||||
* key<1>() // = key1
|
||||
* key<2>() // = key2
|
||||
* // key<0>() // ERROR! Will not compile
|
||||
* // key<3>() // ERROR! Will not compile
|
||||
* ```
|
||||
*/
|
||||
template <int I, typename = IndexIsValid<I>>
|
||||
inline Key key() const {
|
||||
return keys_[I - 1];
|
||||
}
|
||||
|
||||
/// @name NoiseModelFactor methods
|
||||
|
|
@ -433,9 +470,7 @@ class NoiseModelFactorN : public NoiseModelFactor {
|
|||
|
||||
/** Some optional jacobians omitted function overload */
|
||||
template <typename... OptionalJacArgs,
|
||||
typename std::enable_if<(sizeof...(OptionalJacArgs) > 0) &&
|
||||
(sizeof...(OptionalJacArgs) < N),
|
||||
bool>::type = true>
|
||||
typename = IndexIsValid<sizeof...(OptionalJacArgs) + 1>>
|
||||
inline Vector evaluateError(const ValueTypes&... x,
|
||||
OptionalJacArgs&&... H) const {
|
||||
return evaluateError(x..., std::forward<OptionalJacArgs>(H)...,
|
||||
|
|
@ -448,16 +483,17 @@ class NoiseModelFactorN : public NoiseModelFactor {
|
|||
/** Pack expansion with index_sequence template pattern, used to index into
|
||||
* `keys_` and `H`
|
||||
*/
|
||||
template <std::size_t... Inds>
|
||||
template <std::size_t... Indices>
|
||||
inline Vector unwhitenedError(
|
||||
boost::mp11::index_sequence<Inds...>, //
|
||||
boost::mp11::index_sequence<Indices...>, //
|
||||
const Values& x,
|
||||
boost::optional<std::vector<Matrix>&> H = boost::none) const {
|
||||
if (this->active(x)) {
|
||||
if (H) {
|
||||
return evaluateError(x.at<ValueTypes>(keys_[Inds])..., (*H)[Inds]...);
|
||||
return evaluateError(x.at<ValueTypes>(keys_[Indices])...,
|
||||
(*H)[Indices]...);
|
||||
} else {
|
||||
return evaluateError(x.at<ValueTypes>(keys_[Inds])...);
|
||||
return evaluateError(x.at<ValueTypes>(keys_[Indices])...);
|
||||
}
|
||||
} else {
|
||||
return Vector::Zero(this->dim());
|
||||
|
|
|
|||
Loading…
Reference in New Issue