/**
* Author: Dmitriy Morozov
* Department of Computer Science, Duke University, 2005-2008
*/
#ifndef __CHAIN_H__
#define __CHAIN_H__
//#include "utilities/types.h"
#include <boost/serialization/access.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/optional.hpp>
#include <iterator>
#include <string>
#include <utilities/containers.h>
/**
* Class: ChainWrapper
* Class storing a chain of simplices. Stores items in the order defined by ConsistencyCmp.
* The actual order of the elements is defined by OrderCmp. Instances of those
* classes are not stored in Chain for efficiency, and are passed as arguments to those methods
* that require them.
*
* \ingroup topology
*
* TODO: add field (defaulting to Z_2)
*/
template <class Container_>
class ChainWrapper: public Container_,
public SizeStorage<Container_>
{
public:
/// \name Template Parameters
/// @{
typedef Container_ Container;
typedef SizeStorage<Container> Size;
typedef typename boost::iterator_value<typename Container::iterator>::type Item;
/// @}
typedef ChainWrapper Self;
typedef Container ChainRepresentation;
/// \name Accessor typedefs
/// @{
typedef typename ChainRepresentation::iterator iterator;
typedef typename ChainRepresentation::const_iterator const_iterator;
typedef typename ChainRepresentation::const_reference const_reference;
typedef typename ChainRepresentation::reference reference;
typedef typename ChainRepresentation::pointer pointer;
typedef typename ChainRepresentation::const_pointer const_pointer;
typedef Item value_type;
/// @}
public:
ChainWrapper();
ChainWrapper(const ChainWrapper& c);
template<class Iterator> ChainWrapper(Iterator bg, Iterator end);
/// \name Whole Chain operations
/// @{
/** Add c to *this assuming both Chains are sorted in increasing order according to cmp. */
template<class ConsistencyComparison>
Self& add(const Self& c, const ConsistencyComparison& cmp);
void swap(ChainWrapper& c); ///< Swaps the contents of c and *this (like STL's swap destroys c)
void clear();
template<class ConsistencyComparison>
void sort(const ConsistencyComparison& cmp); ///< Sort elements to enforce consistency
size_t size() const { return Size::size(*this); }
using ChainRepresentation::empty;
/// @}
/// \name Modifiers
/// @{
void remove(iterator i) { ChainRepresentation::erase(i); Size::operator--(); }
void remove(const_reference x) { remove(std::find(begin(), end(), x)); }
template<class ConsistencyComparison>
void append(const_reference x, const ConsistencyComparison& cmp);
/// @}
/// \name Accessors
/// @{
using ChainRepresentation::begin;
using ChainRepresentation::end;
using ChainRepresentation::front;
using ChainRepresentation::back;
template<class OrderComparison>
const_reference top(const OrderComparison& cmp) const; ///< First element in cmp order
boost::optional<const_iterator> contains(const_reference x) const; ///< tests whether chain contains x
boost::optional<iterator> contains(reference x); ///< tests whether chain contains x
/// @}
/// \name Debugging
/// @{
template<class OrderComparison>
const_reference get_first(const OrderComparison& cmp) const; ///< First element in cmp order
template<class OutputMap>
std::string tostring(const OutputMap& outmap = OutputMap()) const;
/// @}
/// Technically, it's an internal operation, and should be followed by a sort()
using ChainRepresentation::push_back;
private:
using ChainRepresentation::insert;
using ChainRepresentation::erase;
private:
// Serialization
typedef Container Parent;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, boost::serialization::version_type );
};
#include "chain.hpp"
#endif // __CHAIN_H__