commit
0273d94cfd
|
@ -49,8 +49,12 @@ namespace gtsam {
|
||||||
const Key key; ///< The key
|
const Key key; ///< The key
|
||||||
const ValueType& value; ///< The value
|
const ValueType& value; ///< The value
|
||||||
|
|
||||||
_ValuesConstKeyValuePair(Key _key, const ValueType& _value) : key(_key), value(_value) {}
|
_ValuesConstKeyValuePair(Key _key, const ValueType& _value) :
|
||||||
_ValuesConstKeyValuePair(const _ValuesKeyValuePair<ValueType>& rhs) : key(rhs.key), value(rhs.value) {}
|
key(_key), value(_value) {
|
||||||
|
}
|
||||||
|
_ValuesConstKeyValuePair(const _ValuesKeyValuePair<ValueType>& rhs) :
|
||||||
|
key(rhs.key), value(rhs.value) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -59,17 +63,20 @@ namespace gtsam {
|
||||||
// need to use a struct here for later partial specialization
|
// need to use a struct here for later partial specialization
|
||||||
template<class ValueType, class CastedKeyValuePairType, class KeyValuePairType>
|
template<class ValueType, class CastedKeyValuePairType, class KeyValuePairType>
|
||||||
struct ValuesCastHelper {
|
struct ValuesCastHelper {
|
||||||
static CastedKeyValuePairType cast(KeyValuePairType key_value) {
|
static CastedKeyValuePairType cast(KeyValuePairType key_value) {
|
||||||
// Static cast because we already checked the type during filtering
|
// Static cast because we already checked the type during filtering
|
||||||
return CastedKeyValuePairType(key_value.key, const_cast<GenericValue<ValueType>&>(static_cast<const GenericValue<ValueType>&>(key_value.value)).value());
|
return CastedKeyValuePairType(key_value.key,
|
||||||
}
|
const_cast<GenericValue<ValueType>&>(static_cast<const GenericValue<
|
||||||
|
ValueType>&>(key_value.value)).value());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// partial specialized version for ValueType == Value
|
// partial specialized version for ValueType == Value
|
||||||
template<class CastedKeyValuePairType, class KeyValuePairType>
|
template<class CastedKeyValuePairType, class KeyValuePairType>
|
||||||
struct ValuesCastHelper<Value, CastedKeyValuePairType, KeyValuePairType> {
|
struct ValuesCastHelper<Value, CastedKeyValuePairType, KeyValuePairType> {
|
||||||
static CastedKeyValuePairType cast(KeyValuePairType key_value) {
|
static CastedKeyValuePairType cast(KeyValuePairType key_value) {
|
||||||
// Static cast because we already checked the type during filtering
|
// Static cast because we already checked the type during filtering
|
||||||
// in this case the casted and keyvalue pair are essentially the same type (key, Value&) so perhaps this could be done with just a cast of the key_value?
|
// in this case the casted and keyvalue pair are essentially the same type
|
||||||
|
// (key, Value&) so perhaps this could be done with just a cast of the key_value?
|
||||||
return CastedKeyValuePairType(key_value.key, key_value.value);
|
return CastedKeyValuePairType(key_value.key, key_value.value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -78,7 +85,8 @@ namespace gtsam {
|
||||||
struct ValuesCastHelper<const Value, CastedKeyValuePairType, KeyValuePairType> {
|
struct ValuesCastHelper<const Value, CastedKeyValuePairType, KeyValuePairType> {
|
||||||
static CastedKeyValuePairType cast(KeyValuePairType key_value) {
|
static CastedKeyValuePairType cast(KeyValuePairType key_value) {
|
||||||
// Static cast because we already checked the type during filtering
|
// Static cast because we already checked the type during filtering
|
||||||
// in this case the casted and keyvalue pair are essentially the same type (key, Value&) so perhaps this could be done with just a cast of the key_value?
|
// in this case the casted and keyvalue pair are essentially the same type
|
||||||
|
// (key, Value&) so perhaps this could be done with just a cast of the key_value?
|
||||||
return CastedKeyValuePairType(key_value.key, key_value.value);
|
return CastedKeyValuePairType(key_value.key, key_value.value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -126,23 +134,29 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Filtered(const boost::function<bool(const Values::ConstKeyValuePair&)>& filter, Values& values) :
|
Filtered(
|
||||||
begin_(boost::make_transform_iterator(
|
const boost::function<bool(const Values::ConstKeyValuePair&)>& filter,
|
||||||
boost::make_filter_iterator(
|
Values& values) :
|
||||||
filter, values.begin(), values.end()),
|
begin_(
|
||||||
&ValuesCastHelper<ValueType, KeyValuePair, Values::KeyValuePair>::cast)),
|
boost::make_transform_iterator(
|
||||||
end_(boost::make_transform_iterator(
|
boost::make_filter_iterator(filter, values.begin(), values.end()),
|
||||||
boost::make_filter_iterator(
|
&ValuesCastHelper<ValueType, KeyValuePair, Values::KeyValuePair>::cast)), end_(
|
||||||
filter, values.end(), values.end()),
|
boost::make_transform_iterator(
|
||||||
&ValuesCastHelper<ValueType, KeyValuePair, Values::KeyValuePair>::cast)),
|
boost::make_filter_iterator(filter, values.end(), values.end()),
|
||||||
constBegin_(boost::make_transform_iterator(
|
&ValuesCastHelper<ValueType, KeyValuePair, Values::KeyValuePair>::cast)), constBegin_(
|
||||||
boost::make_filter_iterator(
|
boost::make_transform_iterator(
|
||||||
filter, ((const Values&)values).begin(), ((const Values&)values).end()),
|
boost::make_filter_iterator(filter,
|
||||||
&ValuesCastHelper<const ValueType, ConstKeyValuePair, Values::ConstKeyValuePair>::cast)),
|
((const Values&) values).begin(),
|
||||||
constEnd_(boost::make_transform_iterator(
|
((const Values&) values).end()),
|
||||||
boost::make_filter_iterator(
|
&ValuesCastHelper<const ValueType, ConstKeyValuePair,
|
||||||
filter, ((const Values&)values).end(), ((const Values&)values).end()),
|
Values::ConstKeyValuePair>::cast)), constEnd_(
|
||||||
&ValuesCastHelper<const ValueType, ConstKeyValuePair, Values::ConstKeyValuePair>::cast)) {}
|
boost::make_transform_iterator(
|
||||||
|
boost::make_filter_iterator(filter,
|
||||||
|
((const Values&) values).end(),
|
||||||
|
((const Values&) values).end()),
|
||||||
|
&ValuesCastHelper<const ValueType, ConstKeyValuePair,
|
||||||
|
Values::ConstKeyValuePair>::cast)) {
|
||||||
|
}
|
||||||
|
|
||||||
friend class Values;
|
friend class Values;
|
||||||
iterator begin_;
|
iterator begin_;
|
||||||
|
@ -191,7 +205,9 @@ namespace gtsam {
|
||||||
friend class Values;
|
friend class Values;
|
||||||
const_iterator begin_;
|
const_iterator begin_;
|
||||||
const_iterator end_;
|
const_iterator end_;
|
||||||
ConstFiltered(const boost::function<bool(const Values::ConstKeyValuePair&)>& filter, const Values& values) {
|
ConstFiltered(
|
||||||
|
const boost::function<bool(const Values::ConstKeyValuePair&)>& filter,
|
||||||
|
const Values& values) {
|
||||||
// We remove the const from values to create a non-const Filtered
|
// We remove the const from values to create a non-const Filtered
|
||||||
// view, then pull the const_iterators out of it.
|
// view, then pull the const_iterators out of it.
|
||||||
const Filtered<ValueType> filtered(filter, const_cast<Values&>(values));
|
const Filtered<ValueType> filtered(filter, const_cast<Values&>(values));
|
||||||
|
@ -247,7 +263,8 @@ namespace gtsam {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
template<>
|
template<>
|
||||||
inline bool Values::filterHelper<Value>(const boost::function<bool(Key)> filter, const ConstKeyValuePair& key_value) {
|
inline bool Values::filterHelper<Value>(const boost::function<bool(Key)> filter,
|
||||||
|
const ConstKeyValuePair& key_value) {
|
||||||
// Filter and check the type
|
// Filter and check the type
|
||||||
return filter(key_value.key);
|
return filter(key_value.key);
|
||||||
}
|
}
|
||||||
|
@ -263,10 +280,11 @@ namespace gtsam {
|
||||||
throw ValuesKeyDoesNotExist("retrieve", j);
|
throw ValuesKeyDoesNotExist("retrieve", j);
|
||||||
|
|
||||||
// Check the type and throw exception if incorrect
|
// Check the type and throw exception if incorrect
|
||||||
|
const Value& value = *item->second;
|
||||||
try {
|
try {
|
||||||
return dynamic_cast<const GenericValue<ValueType>&>(*item->second).value();
|
return dynamic_cast<const GenericValue<ValueType>&>(value).value();
|
||||||
} catch (std::bad_cast &) {
|
} catch (std::bad_cast &) {
|
||||||
throw ValuesIncorrectType(j, typeid(*item->second), typeid(ValueType));
|
throw ValuesIncorrectType(j, typeid(value), typeid(ValueType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,10 +296,11 @@ namespace gtsam {
|
||||||
|
|
||||||
if(item != values_.end()) {
|
if(item != values_.end()) {
|
||||||
// dynamic cast the type and throw exception if incorrect
|
// dynamic cast the type and throw exception if incorrect
|
||||||
|
const Value& value = *item->second;
|
||||||
try {
|
try {
|
||||||
return dynamic_cast<const GenericValue<ValueType>&>(*item->second).value();
|
return dynamic_cast<const GenericValue<ValueType>&>(value).value();
|
||||||
} catch (std::bad_cast &) {
|
} catch (std::bad_cast &) {
|
||||||
throw ValuesIncorrectType(j, typeid(*item->second), typeid(ValueType));
|
throw ValuesIncorrectType(j, typeid(value), typeid(ValueType));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return boost::none;
|
return boost::none;
|
||||||
|
|
|
@ -58,18 +58,19 @@ namespace gtsam {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
bool Values::equals(const Values& other, double tol) const {
|
bool Values::equals(const Values& other, double tol) const {
|
||||||
if(this->size() != other.size())
|
if (this->size() != other.size())
|
||||||
return false;
|
return false;
|
||||||
for(const_iterator it1=this->begin(), it2=other.begin(); it1!=this->end(); ++it1, ++it2) {
|
for (const_iterator it1 = this->begin(), it2 = other.begin();
|
||||||
if(typeid(it1->value) != typeid(it2->value))
|
it1 != this->end(); ++it1, ++it2) {
|
||||||
return false;
|
const Value& value1 = it1->value;
|
||||||
if(it1->key != it2->key)
|
const Value& value2 = it2->value;
|
||||||
return false;
|
if (typeid(value1) != typeid(value2) || it1->key != it2->key
|
||||||
if(!it1->value.equals_(it2->value, tol))
|
|| !value1.equals_(value2, tol)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true; // We return false earlier if we find anything that does not match
|
return true; // We return false earlier if we find anything that does not match
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
bool Values::exists(Key j) const {
|
bool Values::exists(Key j) const {
|
||||||
|
@ -85,7 +86,6 @@ namespace gtsam {
|
||||||
VectorValues::const_iterator vector_item = delta.find(key_value->key);
|
VectorValues::const_iterator vector_item = delta.find(key_value->key);
|
||||||
Key key = key_value->key; // Non-const duplicate to deal with non-const insert argument
|
Key key = key_value->key; // Non-const duplicate to deal with non-const insert argument
|
||||||
if(vector_item != delta.end()) {
|
if(vector_item != delta.end()) {
|
||||||
// const Vector& singleDelta = delta[key_value->key]; // Delta for this value
|
|
||||||
const Vector& singleDelta = vector_item->second;
|
const Vector& singleDelta = vector_item->second;
|
||||||
Value* retractedValue(key_value->value.retract_(singleDelta)); // Retract
|
Value* retractedValue(key_value->value.retract_(singleDelta)); // Retract
|
||||||
result.values_.insert(key, retractedValue); // Add retracted result directly to result values
|
result.values_.insert(key, retractedValue); // Add retracted result directly to result values
|
||||||
|
@ -184,12 +184,13 @@ namespace gtsam {
|
||||||
void Values::update(Key j, const Value& val) {
|
void Values::update(Key j, const Value& val) {
|
||||||
// Find the value to update
|
// Find the value to update
|
||||||
KeyValueMap::iterator item = values_.find(j);
|
KeyValueMap::iterator item = values_.find(j);
|
||||||
if(item == values_.end())
|
if (item == values_.end())
|
||||||
throw ValuesKeyDoesNotExist("update", j);
|
throw ValuesKeyDoesNotExist("update", j);
|
||||||
|
|
||||||
// Cast to the derived type
|
// Cast to the derived type
|
||||||
if(typeid(*item->second) != typeid(val))
|
const Value& old_value = *item->second;
|
||||||
throw ValuesIncorrectType(j, typeid(*item->second), typeid(val));
|
if (typeid(old_value) != typeid(val))
|
||||||
|
throw ValuesIncorrectType(j, typeid(old_value), typeid(val));
|
||||||
|
|
||||||
values_.replace(item, val.clone_());
|
values_.replace(item, val.clone_());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue