Merge pull request #1411 from borglab/feature/no_boost_in_values
commit
ce7fd30da4
|
@ -92,18 +92,28 @@ namespace gtsam {
|
|||
}
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
template <class ValueType>
|
||||
size_t Values::count() const {
|
||||
size_t i = 0;
|
||||
for (const auto& [_, value] : values_) {
|
||||
if (dynamic_cast<const GenericValue<ValueType>*>(value.get())) ++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
template <class ValueType>
|
||||
std::map<Key, ValueType>
|
||||
Values::extract(const std::function<bool(Key)>& filterFcn) const {
|
||||
std::map<Key, ValueType> result;
|
||||
for (const auto& key_value : values_) {
|
||||
for (const auto& [key,value] : values_) {
|
||||
// Check if key matches
|
||||
if (filterFcn(key_value.first)) {
|
||||
if (filterFcn(key)) {
|
||||
// Check if type matches (typically does as symbols matched with types)
|
||||
if (auto t =
|
||||
dynamic_cast<const GenericValue<ValueType>*>(key_value.second))
|
||||
result[key_value.first] = t->value();
|
||||
dynamic_cast<const GenericValue<ValueType>*>(value.get()))
|
||||
result[key] = t->value();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -204,7 +214,7 @@ namespace gtsam {
|
|||
// Check the type and throw exception if incorrect
|
||||
// h() split in two lines to avoid internal compiler error (MSVC2017)
|
||||
auto h = internal::handle<ValueType>();
|
||||
return h(j, item->second);
|
||||
return h(j, item->second.get());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -214,13 +224,13 @@ namespace gtsam {
|
|||
KeyValueMap::const_iterator item = values_.find(j);
|
||||
|
||||
if(item != values_.end()) {
|
||||
const Value* value = item->second.get();
|
||||
// dynamic cast the type and throw exception if incorrect
|
||||
auto ptr = dynamic_cast<const GenericValue<ValueType>*>(item->second);
|
||||
auto ptr = dynamic_cast<const GenericValue<ValueType>*>(value);
|
||||
if (ptr) {
|
||||
return &ptr->value();
|
||||
} else {
|
||||
// NOTE(abe): clang warns about potential side effects if done in typeid
|
||||
const Value* value = item->second;
|
||||
throw ValuesIncorrectType(j, typeid(*value), typeid(ValueType));
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -50,15 +50,14 @@ namespace gtsam {
|
|||
|
||||
/* ************************************************************************* */
|
||||
Values::Values(const Values& other, const VectorValues& delta) {
|
||||
for (const auto& key_value : other.values_) {
|
||||
VectorValues::const_iterator it = delta.find(key_value.first);
|
||||
Key key = key_value.first; // Non-const duplicate to deal with non-const insert argument
|
||||
for (const auto& [key,value] : other.values_) {
|
||||
VectorValues::const_iterator it = delta.find(key);
|
||||
if (it != delta.end()) {
|
||||
const Vector& v = it->second;
|
||||
Value* retractedValue(key_value.second->retract_(v)); // Retract
|
||||
values_.insert(key, retractedValue); // Add retracted result directly to result values
|
||||
Value* retractedValue(value->retract_(v)); // Retract
|
||||
values_.emplace(key, retractedValue); // Add retracted result directly to result values
|
||||
} else {
|
||||
values_.insert(key, key_value.second->clone_()); // Add original version to result values
|
||||
values_.emplace(key, value->clone_()); // Add original version to result values
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,9 +66,9 @@ namespace gtsam {
|
|||
void Values::print(const string& str, const KeyFormatter& keyFormatter) const {
|
||||
cout << str << (str.empty() ? "" : "\n");
|
||||
cout << "Values with " << size() << " values:\n";
|
||||
for (const auto& key_value : values_) {
|
||||
cout << "Value " << keyFormatter(key_value.first) << ": ";
|
||||
key_value.second->print("");
|
||||
for (const auto& [key,value] : values_) {
|
||||
cout << "Value " << keyFormatter(key) << ": ";
|
||||
value->print("");
|
||||
cout << "\n";
|
||||
}
|
||||
}
|
||||
|
@ -80,8 +79,8 @@ namespace gtsam {
|
|||
return false;
|
||||
for (auto it1 = values_.begin(), it2 = other.values_.begin();
|
||||
it1 != values_.end(); ++it1, ++it2) {
|
||||
const Value* value1 = it1->second;
|
||||
const Value* value2 = it2->second;
|
||||
const Value* value1 = it1->second.get();
|
||||
const Value* value2 = it2->second.get();
|
||||
if (typeid(*value1) != typeid(*value2) || it1->first != it2->first
|
||||
|| !value1->equals_(*value2, tol)) {
|
||||
return false;
|
||||
|
@ -144,50 +143,48 @@ namespace gtsam {
|
|||
|
||||
/* ************************************************************************* */
|
||||
const Value& Values::at(Key j) const {
|
||||
// Find the item
|
||||
KeyValueMap::const_iterator item = values_.find(j);
|
||||
KeyValueMap::const_iterator it = values_.find(j);
|
||||
|
||||
// Throw exception if it does not exist
|
||||
if(item == values_.end())
|
||||
if(it == values_.end())
|
||||
throw ValuesKeyDoesNotExist("retrieve", j);
|
||||
return *item->second;
|
||||
return *it->second;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Values::insert(Key j, const Value& val) {
|
||||
auto insertResult = values_.insert(j, val.clone_());
|
||||
auto insertResult = values_.emplace(j, val.clone_());
|
||||
if(!insertResult.second)
|
||||
throw ValuesKeyAlreadyExists(j);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Values::insert(const Values& other) {
|
||||
for (auto key_value = other.values_.begin();
|
||||
key_value != other.values_.end(); ++key_value) {
|
||||
insert(key_value->first, *(key_value->second));
|
||||
for (const auto& [key, value] : other.values_) {
|
||||
insert(key, *(value));
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Values::update(Key j, const Value& val) {
|
||||
// Find the value to update
|
||||
KeyValueMap::iterator item = values_.find(j);
|
||||
if (item == values_.end())
|
||||
KeyValueMap::iterator it = values_.find(j);
|
||||
if (it == values_.end())
|
||||
throw ValuesKeyDoesNotExist("update", j);
|
||||
|
||||
// Cast to the derived type
|
||||
const Value& old_value = *item->second;
|
||||
const Value& old_value = *it->second;
|
||||
if (typeid(old_value) != typeid(val))
|
||||
throw ValuesIncorrectType(j, typeid(old_value), typeid(val));
|
||||
|
||||
values_.replace(item, val.clone_());
|
||||
values_.erase(j);
|
||||
values_.emplace(j, val.clone_());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Values::update(const Values& other) {
|
||||
for (auto key_value = other.values_.begin();
|
||||
key_value != other.values_.end(); ++key_value) {
|
||||
this->update(key_value->first, *(key_value->second));
|
||||
for (auto& [key, value] : other.values_) {
|
||||
this->update(key, *(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,34 +201,33 @@ namespace gtsam {
|
|||
|
||||
/* ************************************************************************ */
|
||||
void Values::insert_or_assign(const Values& other) {
|
||||
for (auto key_value = other.values_.begin();
|
||||
key_value != other.values_.end(); ++key_value) {
|
||||
this->insert_or_assign(key_value->first, *(key_value->second));
|
||||
for (auto& [key, value] : other.values_) {
|
||||
this->insert_or_assign(key, *(value));
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void Values::erase(Key j) {
|
||||
KeyValueMap::iterator item = values_.find(j);
|
||||
if(item == values_.end())
|
||||
KeyValueMap::iterator it = values_.find(j);
|
||||
if(it == values_.end())
|
||||
throw ValuesKeyDoesNotExist("erase", j);
|
||||
values_.erase(item);
|
||||
values_.erase(it);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
KeyVector Values::keys() const {
|
||||
KeyVector result;
|
||||
result.reserve(size());
|
||||
for(const auto& key_value: values_)
|
||||
result.push_back(key_value.first);
|
||||
for(const auto& [key,value]: values_)
|
||||
result.push_back(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
KeySet Values::keySet() const {
|
||||
KeySet result;
|
||||
for(const auto& key_value: values_)
|
||||
result.insert(key_value.first);
|
||||
for(const auto& [key,value]: values_)
|
||||
result.insert(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -245,8 +241,8 @@ namespace gtsam {
|
|||
/* ************************************************************************* */
|
||||
size_t Values::dim() const {
|
||||
size_t result = 0;
|
||||
for (const auto key_value : values_) {
|
||||
result += key_value->second->dim();
|
||||
for (const auto& [key,value] : values_) {
|
||||
result += value->dim();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -254,8 +250,8 @@ namespace gtsam {
|
|||
/* ************************************************************************* */
|
||||
std::map<Key,size_t> Values::dims() const {
|
||||
std::map<Key,size_t> result;
|
||||
for (const auto key_value : values_) {
|
||||
result.emplace(key_value->first, key_value->second->dim());
|
||||
for (const auto& [key,value] : values_) {
|
||||
result.emplace(key, value->dim());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -263,8 +259,8 @@ namespace gtsam {
|
|||
/* ************************************************************************* */
|
||||
VectorValues Values::zeroVectors() const {
|
||||
VectorValues result;
|
||||
for (const auto key_value : values_)
|
||||
result.insert(key_value->first, Vector::Zero(key_value->second->dim()));
|
||||
for (const auto& [key,value] : values_)
|
||||
result.insert(key, Vector::Zero(value->dim()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,13 +24,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <gtsam/inference/Key.h>
|
||||
#include <gtsam/base/FastDefaultAllocator.h>
|
||||
#include <gtsam/base/GenericValue.h>
|
||||
#include <gtsam/base/VectorSpace.h>
|
||||
#include <gtsam/inference/Key.h>
|
||||
#include <boost/ptr_container/serialize_ptr_map.hpp>
|
||||
#include <memory>
|
||||
|
||||
#ifdef GTSAM_ENABLE_BOOST_SERIALIZATION
|
||||
#include <boost/serialization/unique_ptr.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
|
@ -67,12 +71,9 @@ namespace gtsam {
|
|||
// user defines the allocation details (i.e. optimize for memory pool/arenas
|
||||
// concurrency).
|
||||
typedef internal::FastDefaultAllocator<typename std::pair<const Key, void*>>::type KeyValuePtrPairAllocator;
|
||||
typedef boost::ptr_map<
|
||||
Key,
|
||||
Value,
|
||||
std::less<Key>,
|
||||
ValueCloneAllocator,
|
||||
KeyValuePtrPairAllocator > KeyValueMap;
|
||||
using KeyValueMap =
|
||||
std::map<Key, std::unique_ptr<Value>, std::less<Key>,
|
||||
std::allocator<std::pair<const Key, std::unique_ptr<Value>>>>;
|
||||
|
||||
// The member to store the values, see just above
|
||||
KeyValueMap values_;
|
||||
|
@ -265,14 +266,7 @@ namespace gtsam {
|
|||
|
||||
// Count values of given type \c ValueType
|
||||
template <class ValueType>
|
||||
size_t count() const {
|
||||
size_t i = 0;
|
||||
for (const auto key_value : values_) {
|
||||
if (dynamic_cast<const GenericValue<ValueType>*>(key_value.second))
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
size_t count() const;
|
||||
|
||||
/**
|
||||
* Extract a subset of values of the given type \c ValueType.
|
||||
|
|
|
@ -474,13 +474,13 @@ TEST(Values, std_move) {
|
|||
EXPECT_LONGS_EQUAL(2, (long)TestValueData::DestructorCount);
|
||||
EXPECT_LONGS_EQUAL(2, values.size());
|
||||
TestValues moved(std::move(values)); // Move happens here !
|
||||
EXPECT_LONGS_EQUAL(2, values.size()); // Uh oh! Should be 0 !
|
||||
EXPECT_LONGS_EQUAL(0, values.size()); // Should be 0 !
|
||||
EXPECT_LONGS_EQUAL(2, moved.size());
|
||||
EXPECT_LONGS_EQUAL(8, (long)TestValueData::ConstructorCount); // Uh oh! Should be 6 :-(
|
||||
EXPECT_LONGS_EQUAL(6, (long)TestValueData::ConstructorCount); // Should be 6 :-)
|
||||
EXPECT_LONGS_EQUAL(2, (long)TestValueData::DestructorCount); // extra insert copies
|
||||
}
|
||||
EXPECT_LONGS_EQUAL(8, (long)TestValueData::ConstructorCount);
|
||||
EXPECT_LONGS_EQUAL(8, (long)TestValueData::DestructorCount);
|
||||
EXPECT_LONGS_EQUAL(6, (long)TestValueData::ConstructorCount);
|
||||
EXPECT_LONGS_EQUAL(6, (long)TestValueData::DestructorCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue