Reworked Values filter to work with Boost 1.40 by using iterator adaptors instead of range adaptors, implementation is a bit ugly now with const_const_iterator.
parent
6ee4043db6
commit
f80818cf3f
|
|
@ -34,9 +34,7 @@
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/ptr_container/serialize_ptr_map.hpp>
|
#include <boost/ptr_container/serialize_ptr_map.hpp>
|
||||||
#include <boost/range/iterator_range.hpp>
|
#include <boost/iterator_adaptors.hpp>
|
||||||
#include <boost/range/adaptor/filtered.hpp> // FIXME: adaptors only added to boost in 1.43
|
|
||||||
#include <boost/range/adaptor/transformed.hpp>
|
|
||||||
#include <boost/lambda/lambda.hpp>
|
#include <boost/lambda/lambda.hpp>
|
||||||
|
|
||||||
#include <gtsam/base/Value.h>
|
#include <gtsam/base/Value.h>
|
||||||
|
|
@ -138,76 +136,111 @@ namespace gtsam {
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template<class ValueType = Value>
|
template<class ValueType = Value>
|
||||||
class Filtered : public boost::transformed_range<
|
class Filtered {
|
||||||
_KeyValuePair<ValueType>(*)(Values::KeyValuePair key_value),
|
|
||||||
const boost::filtered_range<
|
|
||||||
boost::function<bool(const ConstKeyValuePair&)>,
|
|
||||||
const boost::iterator_range<iterator> > > {
|
|
||||||
public:
|
public:
|
||||||
|
/** A key-value pair, with the value a specific derived Value type. */
|
||||||
typedef _KeyValuePair<ValueType> KeyValuePair;
|
typedef _KeyValuePair<ValueType> KeyValuePair;
|
||||||
|
typedef _ConstKeyValuePair<ValueType> ConstKeyValuePair;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
boost::transform_iterator<
|
||||||
|
KeyValuePair(*)(Values::KeyValuePair),
|
||||||
|
boost::filter_iterator<
|
||||||
|
boost::function<bool(const Values::ConstKeyValuePair&)>,
|
||||||
|
Values::iterator> >
|
||||||
|
iterator;
|
||||||
|
|
||||||
|
typedef iterator const_iterator;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
boost::transform_iterator<
|
||||||
|
ConstKeyValuePair(*)(Values::ConstKeyValuePair),
|
||||||
|
boost::filter_iterator<
|
||||||
|
boost::function<bool(const Values::ConstKeyValuePair&)>,
|
||||||
|
Values::const_iterator> >
|
||||||
|
const_const_iterator;
|
||||||
|
|
||||||
|
iterator begin() { return begin_; }
|
||||||
|
iterator end() { return end_; }
|
||||||
|
const_iterator begin() const { return begin_; }
|
||||||
|
const_iterator end() const { return end_; }
|
||||||
|
const_const_iterator beginConst() const { return constBegin_; }
|
||||||
|
const_const_iterator endConst() const { return constEnd_; }
|
||||||
|
|
||||||
/** Returns the number of values in this view */
|
/** Returns the number of values in this view */
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
typename Base::iterator it = this->begin();
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (; it!=this->end(); ++it)
|
for (const_const_iterator it = beginConst(); it != endConst(); ++it)
|
||||||
++i;
|
++i;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Filtered(const boost::function<bool(const Values::ConstKeyValuePair&)>& filter, Values& values) :
|
||||||
typedef boost::transformed_range<
|
begin_(boost::make_transform_iterator(
|
||||||
KeyValuePair(*)(Values::KeyValuePair key_value),
|
boost::make_filter_iterator(
|
||||||
const boost::filtered_range<
|
filter, values.begin(), values.end()),
|
||||||
boost::function<bool(const Values::ConstKeyValuePair&)>,
|
&castHelper<ValueType, KeyValuePair, Values::KeyValuePair>)),
|
||||||
const boost::iterator_range<iterator> > > Base;
|
end_(boost::make_transform_iterator(
|
||||||
|
boost::make_filter_iterator(
|
||||||
Filtered(const Base& base) : Base(base) {}
|
filter, values.end(), values.end()),
|
||||||
|
&castHelper<ValueType, KeyValuePair, Values::KeyValuePair>)),
|
||||||
|
constBegin_(boost::make_transform_iterator(
|
||||||
|
boost::make_filter_iterator(
|
||||||
|
filter, ((const Values&)values).begin(), ((const Values&)values).end()),
|
||||||
|
&castHelper<const ValueType, ConstKeyValuePair, Values::ConstKeyValuePair>)),
|
||||||
|
constEnd_(boost::make_transform_iterator(
|
||||||
|
boost::make_filter_iterator(
|
||||||
|
filter, ((const Values&)values).end(), ((const Values&)values).end()),
|
||||||
|
&castHelper<const ValueType, ConstKeyValuePair, Values::ConstKeyValuePair>)) {}
|
||||||
|
|
||||||
friend class Values;
|
friend class Values;
|
||||||
|
iterator begin_;
|
||||||
|
iterator end_;
|
||||||
|
const_const_iterator constBegin_;
|
||||||
|
const_const_iterator constEnd_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class ValueType = Value>
|
template<class ValueType = Value>
|
||||||
class ConstFiltered : public boost::transformed_range<
|
class ConstFiltered {
|
||||||
_ConstKeyValuePair<ValueType>(*)(Values::ConstKeyValuePair key_value),
|
|
||||||
const boost::filtered_range<
|
|
||||||
boost::function<bool(const ConstKeyValuePair&)>,
|
|
||||||
const boost::iterator_range<const_iterator> > > {
|
|
||||||
public:
|
public:
|
||||||
|
/** A const key-value pair, with the value a specific derived Value type. */
|
||||||
typedef _ConstKeyValuePair<ValueType> KeyValuePair;
|
typedef _ConstKeyValuePair<ValueType> KeyValuePair;
|
||||||
|
|
||||||
|
typedef typename Filtered<ValueType>::const_const_iterator iterator;
|
||||||
|
typedef typename Filtered<ValueType>::const_const_iterator const_iterator;
|
||||||
|
|
||||||
/** Conversion from Filtered to ConstFiltered */
|
/** Conversion from Filtered to ConstFiltered */
|
||||||
ConstFiltered(const Filtered<ValueType>& rhs) : Base(
|
ConstFiltered(const Filtered<ValueType>& rhs) :
|
||||||
boost::adaptors::transform(
|
begin_(rhs.beginConst()),
|
||||||
boost::adaptors::filter(
|
end_(rhs.endConst()) {}
|
||||||
boost::make_iterator_range(
|
|
||||||
const_iterator(rhs.begin().base().base().base(), &make_const_deref_pair),
|
iterator begin() { return begin_; }
|
||||||
const_iterator(rhs.end().base().base().base(), &make_const_deref_pair)),
|
iterator end() { return end_; }
|
||||||
rhs.begin().base().predicate()),
|
const_iterator begin() const { return begin_; }
|
||||||
&castHelper<const ValueType, _ConstKeyValuePair<ValueType>, ConstKeyValuePair>)) {}
|
const_iterator end() const { return end_; }
|
||||||
|
|
||||||
/** Returns the number of values in this view */
|
/** Returns the number of values in this view */
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
typename Base::const_iterator it = this->begin();
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (; it!=this->end(); ++it)
|
for (const_iterator it = begin(); it != end(); ++it)
|
||||||
++i;
|
++i;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef boost::transformed_range<
|
|
||||||
KeyValuePair(*)(Values::ConstKeyValuePair key_value),
|
|
||||||
const boost::filtered_range<
|
|
||||||
boost::function<bool(const Values::ConstKeyValuePair&)>,
|
|
||||||
const boost::iterator_range<const_iterator> > > Base;
|
|
||||||
|
|
||||||
ConstFiltered(const Base& base) : Base(base) {}
|
|
||||||
|
|
||||||
friend class Values;
|
friend class Values;
|
||||||
|
const_iterator begin_;
|
||||||
|
const_iterator end_;
|
||||||
|
ConstFiltered(const boost::function<bool(const Values::ConstKeyValuePair&)>& filter, const Values& values) {
|
||||||
|
// We remove the const from values to create a non-const Filtered
|
||||||
|
// view, then pull the const_iterators out of it.
|
||||||
|
const Filtered<ValueType> filtered(filter, const_cast<Values&>(values));
|
||||||
|
begin_ = filtered.beginConst();
|
||||||
|
end_ = filtered.endConst();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Default constructor creates an empty Values class */
|
/** Default constructor creates an empty Values class */
|
||||||
|
|
@ -410,12 +443,7 @@ namespace gtsam {
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
Filtered<ValueType>
|
Filtered<ValueType>
|
||||||
filter(const boost::function<bool(Key)>& filterFcn = (boost::lambda::_1, true)) {
|
filter(const boost::function<bool(Key)>& filterFcn = (boost::lambda::_1, true)) {
|
||||||
return boost::adaptors::transform(
|
return Filtered<ValueType>(boost::bind(&filterHelper<ValueType>, filterFcn, _1), *this);
|
||||||
boost::adaptors::filter(
|
|
||||||
boost::make_iterator_range(begin(), end()),
|
|
||||||
boost::function<bool(const ConstKeyValuePair&)>(
|
|
||||||
boost::bind(&filterHelper<ValueType>, filterFcn, _1))),
|
|
||||||
&castHelper<ValueType, _KeyValuePair<ValueType>, KeyValuePair>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -457,12 +485,7 @@ namespace gtsam {
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ConstFiltered<ValueType>
|
ConstFiltered<ValueType>
|
||||||
filter(const boost::function<bool(Key)>& filterFcn = (boost::lambda::_1, true)) const {
|
filter(const boost::function<bool(Key)>& filterFcn = (boost::lambda::_1, true)) const {
|
||||||
return boost::adaptors::transform(
|
return ConstFiltered<ValueType>(boost::bind(&filterHelper<ValueType>, filterFcn, _1), *this);
|
||||||
boost::adaptors::filter(
|
|
||||||
boost::make_iterator_range(begin(), end()),
|
|
||||||
boost::function<bool(const ConstKeyValuePair&)>(
|
|
||||||
boost::bind(&filterHelper<ValueType>, filterFcn, _1))),
|
|
||||||
&castHelper<const ValueType, _ConstKeyValuePair<ValueType>, ConstKeyValuePair>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue