From f80818cf3fddebc7b84088443476177cb29bcf0d Mon Sep 17 00:00:00 2001 From: Richard Roberts Date: Thu, 1 Mar 2012 23:53:21 +0000 Subject: [PATCH] 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. --- gtsam/nonlinear/Values.h | 143 +++++++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 60 deletions(-) diff --git a/gtsam/nonlinear/Values.h b/gtsam/nonlinear/Values.h index 63ebf3206..bdd1739da 100644 --- a/gtsam/nonlinear/Values.h +++ b/gtsam/nonlinear/Values.h @@ -34,9 +34,7 @@ #include #include #include -#include -#include // FIXME: adaptors only added to boost in 1.43 -#include +#include #include #include @@ -138,76 +136,111 @@ namespace gtsam { }; public: + template - class Filtered : public boost::transformed_range< - _KeyValuePair(*)(Values::KeyValuePair key_value), - const boost::filtered_range< - boost::function, - const boost::iterator_range > > { + class Filtered { public: + /** A key-value pair, with the value a specific derived Value type. */ typedef _KeyValuePair KeyValuePair; + typedef _ConstKeyValuePair ConstKeyValuePair; + + typedef + boost::transform_iterator< + KeyValuePair(*)(Values::KeyValuePair), + boost::filter_iterator< + boost::function, + Values::iterator> > + iterator; + + typedef iterator const_iterator; + + typedef + boost::transform_iterator< + ConstKeyValuePair(*)(Values::ConstKeyValuePair), + boost::filter_iterator< + boost::function, + 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 */ size_t size() const { - typename Base::iterator it = this->begin(); - size_t i = 0; - for (; it!=this->end(); ++it) - ++i; - return i; + size_t i = 0; + for (const_const_iterator it = beginConst(); it != endConst(); ++it) + ++i; + return i; } private: - - typedef boost::transformed_range< - KeyValuePair(*)(Values::KeyValuePair key_value), - const boost::filtered_range< - boost::function, - const boost::iterator_range > > Base; - - Filtered(const Base& base) : Base(base) {} + Filtered(const boost::function& filter, Values& values) : + begin_(boost::make_transform_iterator( + boost::make_filter_iterator( + filter, values.begin(), values.end()), + &castHelper)), + end_(boost::make_transform_iterator( + boost::make_filter_iterator( + filter, values.end(), values.end()), + &castHelper)), + constBegin_(boost::make_transform_iterator( + boost::make_filter_iterator( + filter, ((const Values&)values).begin(), ((const Values&)values).end()), + &castHelper)), + constEnd_(boost::make_transform_iterator( + boost::make_filter_iterator( + filter, ((const Values&)values).end(), ((const Values&)values).end()), + &castHelper)) {} friend class Values; + iterator begin_; + iterator end_; + const_const_iterator constBegin_; + const_const_iterator constEnd_; }; template - class ConstFiltered : public boost::transformed_range< - _ConstKeyValuePair(*)(Values::ConstKeyValuePair key_value), - const boost::filtered_range< - boost::function, - const boost::iterator_range > > { + class ConstFiltered { public: + /** A const key-value pair, with the value a specific derived Value type. */ typedef _ConstKeyValuePair KeyValuePair; + typedef typename Filtered::const_const_iterator iterator; + typedef typename Filtered::const_const_iterator const_iterator; + /** Conversion from Filtered to ConstFiltered */ - ConstFiltered(const Filtered& rhs) : Base( - boost::adaptors::transform( - boost::adaptors::filter( - boost::make_iterator_range( - const_iterator(rhs.begin().base().base().base(), &make_const_deref_pair), - const_iterator(rhs.end().base().base().base(), &make_const_deref_pair)), - rhs.begin().base().predicate()), - &castHelper, ConstKeyValuePair>)) {} + ConstFiltered(const Filtered& rhs) : + begin_(rhs.beginConst()), + end_(rhs.endConst()) {} + + iterator begin() { return begin_; } + iterator end() { return end_; } + const_iterator begin() const { return begin_; } + const_iterator end() const { return end_; } /** Returns the number of values in this view */ size_t size() const { - typename Base::const_iterator it = this->begin(); - size_t i = 0; - for (; it!=this->end(); ++it) - ++i; - return i; + size_t i = 0; + for (const_iterator it = begin(); it != end(); ++it) + ++i; + return i; } private: - - typedef boost::transformed_range< - KeyValuePair(*)(Values::ConstKeyValuePair key_value), - const boost::filtered_range< - boost::function, - const boost::iterator_range > > Base; - - ConstFiltered(const Base& base) : Base(base) {} - friend class Values; + const_iterator begin_; + const_iterator end_; + ConstFiltered(const boost::function& 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 filtered(filter, const_cast(values)); + begin_ = filtered.beginConst(); + end_ = filtered.endConst(); + } }; /** Default constructor creates an empty Values class */ @@ -410,12 +443,7 @@ namespace gtsam { template Filtered filter(const boost::function& filterFcn = (boost::lambda::_1, true)) { - return boost::adaptors::transform( - boost::adaptors::filter( - boost::make_iterator_range(begin(), end()), - boost::function( - boost::bind(&filterHelper, filterFcn, _1))), - &castHelper, KeyValuePair>); + return Filtered(boost::bind(&filterHelper, filterFcn, _1), *this); } /** @@ -457,12 +485,7 @@ namespace gtsam { template ConstFiltered filter(const boost::function& filterFcn = (boost::lambda::_1, true)) const { - return boost::adaptors::transform( - boost::adaptors::filter( - boost::make_iterator_range(begin(), end()), - boost::function( - boost::bind(&filterHelper, filterFcn, _1))), - &castHelper, ConstKeyValuePair>); + return ConstFiltered(boost::bind(&filterHelper, filterFcn, _1), *this); } private: