Changed implementation of WeightedRips to store simplex values (max distance between simplices' vertices) as an invisible layer on top of each simplex object, so that the data() field of WeightedRips has been freed for use by the users again.
#include <algorithm>
#include <vector>
#include "utilities/containers.h"
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/utility.hpp>
#include "utilities/log.h"
#include "utilities/counter.h"
using boost::serialization::make_nvp;
using boost::serialization::make_binary_object;
#ifdef LOGGING
static rlog::RLogChannel* rlChain = DEF_CHANNEL( "topology/chain", rlog::Log_Debug);
#endif // LOGGING
#ifdef COUNTERS
static Counter* cChainAddBasic = GetCounter("chain/add/basic");
static Counter* cChainAddComparison = GetCounter("chain/add/comparison");
#endif // COUNTERS
template<class C>
ChainWrapper<C>::
ChainWrapper()
{}
template<class C>
ChainWrapper<C>::
ChainWrapper(const ChainWrapper& c):
ChainRepresentation(c), Size(c)
{}
template<class C>
template<class Iterator>
ChainWrapper<C>::
ChainWrapper(Iterator bg, Iterator end):
ChainRepresentation(bg, end), Size(ChainRepresentation::size())
{}
template<class C>
template<class ConsistencyCmp>
void
ChainWrapper<C>::
append(const_reference x, const ConsistencyCmp& cmp)
{
Size::operator++();
// First try the special cases that x goes at the end
if (empty() || cmp(back(), x))
push_back(x);
// Then try the special case that x goes at the front
else if (cmp(x, front()))
ContainerTraits<C,ConsistencyCmp>::push_front(*this, x);
else
insert(std::upper_bound(begin(), end(), x, cmp), x);
}
template<class C>
template<class OrderComparison>
typename ChainWrapper<C>::const_reference
ChainWrapper<C>::
top(const OrderComparison& cmp) const
{
AssertMsg(!empty(), "Chain must not be empty for low()");
return *std::min_element(begin(), end(), cmp);
}
template<class C>
void
ChainWrapper<C>::
swap(ChainWrapper& c)
{
ChainRepresentation::swap(c);
Size::swap(c);
}
template<class C>
void
ChainWrapper<C>::
clear()
{
ChainRepresentation::clear();
Size::clear();
}
template<class C>
template<class ConsistencyComparison>
void
ChainWrapper<C>::
sort(const ConsistencyComparison& cmp)
{
ContainerTraits<C,ConsistencyComparison>::sort(*this, cmp);
}
template<class C>
boost::optional<typename ChainWrapper<C>::const_iterator>
ChainWrapper<C>::
contains(const_reference x) const
{
const_iterator res = std::find(begin(), end(), x);
return make_optional(res != end(), res);
}
template<class C>
boost::optional<typename ChainWrapper<C>::iterator>
ChainWrapper<C>::
contains(reference x)
{
iterator res = std::find(begin(), end(), x);
return boost::make_optional(res != end(), res);
}
template<class C>
template<class OutputMap>
std::string
ChainWrapper<C>::
tostring(const OutputMap& outmap) const
{
std::string str;
for (const_iterator cur = begin(); cur != end(); ++cur)
{
if (cur != begin()) str += ", ";
str += outmap(*cur);
}
return str;
}
template<class C>
template<class ConsistencyCmp>
typename ChainWrapper<C>::Self&
ChainWrapper<C>::
add(const Self& c, const ConsistencyCmp& cmp)
{
// TODO: tmp-based addition is necessary and useful for Containers that are vectors,
// however, I believe it creates costly overhead for Containers that are lists.
// Need to put some thought into this.
ChainRepresentation tmp;
CountingBackInserter<ChainRepresentation> bi(tmp);
std::set_symmetric_difference(begin(), end(), c.begin(), c.end(), bi, cmp);
static_cast<ChainRepresentation*>(this)->swap(tmp);
static_cast<Size*>(this)->swap(bi);
return *this;
}
template<class C>
template<class OrderComparison>
typename ChainWrapper<C>::const_reference
ChainWrapper<C>::
get_first(const OrderComparison& cmp) const
{ return top(cmp); }
template<class C>
template<class Archive>
void
ChainWrapper<C>::
serialize(Archive& ar, boost::serialization::version_type )
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
}