include/topology/chain.hpp
author Christos Mantoulidis <cmad@stanford.edu>
Tue, 04 Aug 2009 13:23:16 -0700
branchdev
changeset 156 f75fb57d2831
parent 133 7ccecc57688d
child 174 3f1034dca432
child 179 d15c6d144645
permissions -rw-r--r--
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);
}